1 #include <bz/renderer/renderer_internal.h>
3 #include <bz/gfx/gfx_internal.h>
4 #include <bz/math/math.h>
5 #include <bz/memory/allocator.h>
6 #include <bz/renderer/palette_internal.h>
7 #include <bz/renderer/render_pass_internal.h>
10 struct BZRendererPass
{
15 const static size_t kMaxRenderPasses
= 8;
18 BZRendererConfiguration configuration
;
20 SDL_Renderer
*renderer
;
21 SDL_Texture
*renderTexture
;
22 SDL_Texture
*renderTextureIntermediate
;
23 size_t intermediateWidth
, intermediateHeight
;
24 int outputWidth
, outputHeight
;
25 //static size_t numRenderPasses = 0;
26 BZRendererPass rendererPasses
[kMaxRenderPasses
];
29 BZRendererID
bzRendererInit(BZMemoryArenaID arena
, const BZRendererConfiguration
*configuration
, const char *title
) {
30 BZRendererID renderer
= (BZRenderer
*)bzMemoryAlloc(arena
, sizeof(BZRenderer
));
32 renderer
->configuration
= *configuration
;
34 renderer
->window
= SDL_CreateWindow(title
, SDL_WINDOWPOS_UNDEFINED
, SDL_WINDOWPOS_UNDEFINED
, configuration
->outputWidth
, configuration
->outputHeight
, SDL_WINDOW_ALLOW_HIGHDPI
);
35 if (renderer
->window
== NULL
) {
36 bzError("Could not make window: SDL_Error='%s'", SDL_GetError());
40 renderer
->renderer
= SDL_CreateRenderer(renderer
->window
, -1, SDL_RENDERER_PRESENTVSYNC
| SDL_RENDERER_ACCELERATED
/*SDL_RENDERER_ACCELERATED*/);
42 //SDL_Surface *windowSurface = SDL_GetWindowSurface(window);
43 SDL_GetWindowSizeInPixels(renderer
->window
, &renderer
->outputWidth
, &renderer
->outputHeight
);
45 renderer
->renderTexture
= SDL_CreateTexture(renderer
->renderer
, SDL_PIXELFORMAT_ABGR8888
/*SDL_PIXELFORMAT_RBZA8888*/, SDL_TEXTUREACCESS_STREAMING
, configuration
->rendererWidth
, configuration
->rendererHeight
);
47 renderer
->intermediateWidth
= configuration
->rendererWidth
* bzFloor((renderer
->outputWidth
/ configuration
->rendererWidth
) + 1);
48 renderer
->intermediateHeight
= configuration
->rendererHeight
* bzFloor((renderer
->outputHeight
/ configuration
->rendererHeight
) + 1);
49 renderer
->renderTextureIntermediate
= SDL_CreateTexture(renderer
->renderer
, SDL_PIXELFORMAT_ABGR8888
/*SDL_PIXELFORMAT_RBZA8888*/, SDL_TEXTUREACCESS_TARGET
, renderer
->intermediateWidth
, renderer
->intermediateHeight
);
50 SDL_SetTextureScaleMode(renderer
->renderTextureIntermediate
, SDL_ScaleModeBest
);
52 // drawSurface/*tmpSurface*/ = SDL_CreateRBZSurface(0, RENDERER_WIDTH, RENDERER_HEIGHT, windowSurface->format->BytesPerPixel * 8, windowSurface->format->Rmask, windowSurface->format->Gmask, windowSurface->format->Bmask, windowSurface->format->Amask);
53 //drawSurface = SDL_CreateRBZSurface(0, RENDERER_WIDTH, RENDERER_HEIGHT, 8, 0, 0, 0, 0);
55 for (size_t i
= 0; i
< kMaxRenderPasses
; ++i
) {
56 renderer
->rendererPasses
[i
].pass
= NULL
;
59 SDL_ShowCursor(SDL_DISABLE
);
61 bzGfxPreparePalettes(arena
, 8, configuration
->palette
->numColors
);
62 bzGfxPrepareCanvasBuffer(arena
, configuration
->gameWidth
, configuration
->gameHeight
);
67 void bzRendererTeardown(BZRendererID renderer
) {
68 SDL_DestroyWindow(renderer
->window
);
71 BZRendererPassID
bzRendererRegisterPass(BZRendererID renderer
, BZRenderPassID renderPass
) {
72 for (size_t i
= 0; i
< kMaxRenderPasses
; ++i
) {
73 if (renderer
->rendererPasses
[i
].pass
== NULL
) {
74 renderer
->rendererPasses
[i
].pass
= renderPass
;
75 return &renderer
->rendererPasses
[i
];
81 void bzRendererUnregisterPass(BZRendererPassID rendererPass
) {
82 rendererPass
->pass
= NULL
;
85 void bzRendererBlit(BZRendererID renderer
) {
86 //SDL_LockSurface(drawSurface);
88 //SDL_Rect srcRect = { .x = 0, .y = 0, .w = drawSurface->w, .h = drawSurface->h };
92 SDL_LockTexture(renderer
->renderTexture
, NULL
, &pixels
, &pitch
);
94 for (size_t i
= 0; i
< kMaxRenderPasses
; ++i
) {
95 BZRenderPass
*renderPass
= renderer
->rendererPasses
[i
].pass
;
96 if (renderPass
!= NULL
) {
97 if (renderPass
->softwareHook
!= NULL
) {
98 renderPass
->softwareHook(renderer
->configuration
.palette
, (uint32_t *)pixels
/*drawSurface->pixels*/, renderer
->configuration
.gameWidth
, renderer
->configuration
.gameHeight
, renderer
->configuration
.rendererWidth
/ renderer
->configuration
.gameWidth
, renderer
->configuration
.rendererHeight
/ renderer
->configuration
.gameHeight
);
103 //SDL_UnlockSurface(drawSurface);
105 SDL_UnlockTexture(renderer
->renderTexture
);
107 //SDL_Rect srcRect = { .x = 0, .y = 0, .w = drawSurface->w, .h = drawSurface->h };
108 //SDL_Rect dstRect = { .x = 0, .y = 0, .w = windowSurface->w, .h = windowSurface->h};
109 //SDL_FillRect(windowSurface, &dstRect, 100);
110 // int zis = SDL_BlitSurface(drawSurface, &srcRect, tmpSurface, &srcRect);
111 // int zi = SDL_BlitScaled(drawSurface, &srcRect, windowSurface, &dstRect);
113 //SDL_SetRenderTarget(renderer, NULL);
114 //SDL_RenderClear(renderer);
116 SDL_SetRenderTarget(renderer
->renderer
, renderer
->renderTextureIntermediate
);
117 //renderTextureIntermediate
118 SDL_RenderCopyEx(renderer
->renderer
, renderer
->renderTexture
, NULL
, NULL
, 0, NULL
, 0);
119 SDL_SetRenderTarget(renderer
->renderer
, NULL
);
122 //SDL_RenderCopyEx(renderer, renderTextureIntermediate, NULL, NULL, 0, NULL, 0);
125 // SDL_RenderPresent(renderer);
126 //SDL_RenderPresent(renderer);
127 //SDL_SetRenderTarget(renderer, renderTexture);
129 //SDL_UpdateWindowSurface(window);
130 //SDL_UpdateWindowSurface(window);
131 //SDL_UpdateWindowSurface(window);
134 void bzRendererVBlank(BZRendererID renderer
) {
135 SDL_RenderClear(renderer
->renderer
);
136 size_t height
= (size_t)((float)renderer
->outputWidth
* (float)renderer
->configuration
.rendererHeight
/ (float)renderer
->configuration
.rendererWidth
);
137 SDL_Rect dstRect
= { .x
= 0, .y
= (renderer
->outputHeight
- height
) / 2, .w
= renderer
->outputWidth
, .h
= height
};
138 SDL_RenderCopyEx(renderer
->renderer
, renderer
->renderTextureIntermediate
, NULL
, &dstRect
, 0, NULL
, 0);
139 SDL_RenderPresent(renderer
->renderer
);