yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
sdl3_renderer.cc
Go to the documentation of this file.
1#ifdef YAZE_USE_SDL3
2
4
5#include <SDL3/SDL.h>
6
8
9namespace yaze {
10namespace gfx {
11
12SDL3Renderer::SDL3Renderer() = default;
13
14SDL3Renderer::~SDL3Renderer() {
15 Shutdown();
16}
17
25bool SDL3Renderer::Initialize(SDL_Window* window) {
26 // Create an SDL3 renderer.
27 // SDL3 API: SDL_CreateRenderer(window, driver_name)
28 // Pass nullptr to let SDL choose the best available driver.
29 renderer_ = SDL_CreateRenderer(window, nullptr);
30
31 if (renderer_ == nullptr) {
32 SDL_Log("SDL_CreateRenderer Error: %s", SDL_GetError());
33 return false;
34 }
35
36 // Set blend mode for transparency support.
37 SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);
38
39 // Enable vsync for smoother rendering.
40 SDL_SetRenderVSync(renderer_, 1);
41
42 return true;
43}
44
48void SDL3Renderer::Shutdown() {
49 if (renderer_) {
50 SDL_DestroyRenderer(renderer_);
51 renderer_ = nullptr;
52 }
53}
54
61TextureHandle SDL3Renderer::CreateTexture(int width, int height) {
62 // SDL3 texture creation is largely unchanged from SDL2.
63 return static_cast<TextureHandle>(SDL_CreateTexture(
64 renderer_, static_cast<SDL_PixelFormat>(SDL_PIXELFORMAT_RGBA8888),
65 static_cast<SDL_TextureAccess>(SDL_TEXTUREACCESS_STREAMING), width,
66 height));
67}
68
69TextureHandle SDL3Renderer::CreateRenderTargetTexture(int width, int height) {
70 return static_cast<TextureHandle>(SDL_CreateTexture(
71 renderer_, static_cast<SDL_PixelFormat>(SDL_PIXELFORMAT_RGBA8888),
72 static_cast<SDL_TextureAccess>(SDL_TEXTUREACCESS_TARGET), width, height));
73}
74
81TextureHandle SDL3Renderer::CreateTextureWithFormat(int width, int height,
82 uint32_t format,
83 int access) {
84 return static_cast<TextureHandle>(
85 SDL_CreateTexture(renderer_, static_cast<SDL_PixelFormat>(format),
86 static_cast<SDL_TextureAccess>(access), width, height));
87}
88
96void SDL3Renderer::UpdateTexture(TextureHandle texture, const Bitmap& bitmap) {
97 SDL_Surface* surface = bitmap.surface();
98
99 // Validate texture, surface, and surface format
100 if (!texture || !surface || surface->format == SDL_PIXELFORMAT_UNKNOWN) {
101 return;
102 }
103
104 // Validate surface has pixels
105 if (!surface->pixels || surface->w <= 0 || surface->h <= 0) {
106 return;
107 }
108
109 // Convert the bitmap's surface to RGBA8888 format for compatibility with the
110 // texture.
111 // SDL3 API: SDL_ConvertSurface(surface, format) - no flags parameter
112 SDL_Surface* converted_surface =
113 SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBA8888);
114
115 if (!converted_surface || !converted_surface->pixels) {
116 if (converted_surface) {
117 SDL_DestroySurface(converted_surface);
118 }
119 return;
120 }
121
122 // Update the texture with the pixels from the converted surface.
123 SDL_UpdateTexture(static_cast<SDL_Texture*>(texture), nullptr,
124 converted_surface->pixels, converted_surface->pitch);
125
126 // SDL3 uses SDL_DestroySurface instead of SDL_FreeSurface
127 SDL_DestroySurface(converted_surface);
128}
129
133void SDL3Renderer::DestroyTexture(TextureHandle texture) {
134 if (texture) {
135 SDL_DestroyTexture(static_cast<SDL_Texture*>(texture));
136 }
137}
138
142bool SDL3Renderer::LockTexture(TextureHandle texture, SDL_Rect* rect,
143 void** pixels, int* pitch) {
144 // SDL3 LockTexture now takes SDL_FRect*, but for simplicity we use the
145 // integer version when available. In SDL3, LockTexture still accepts
146 // SDL_Rect* for the region.
147 return SDL_LockTexture(static_cast<SDL_Texture*>(texture), rect, pixels,
148 pitch);
149}
150
154void SDL3Renderer::UnlockTexture(TextureHandle texture) {
155 SDL_UnlockTexture(static_cast<SDL_Texture*>(texture));
156}
157
161void SDL3Renderer::Clear() {
162 SDL_RenderClear(renderer_);
163}
164
168void SDL3Renderer::Present() {
169 SDL_RenderPresent(renderer_);
170}
171
178void SDL3Renderer::RenderCopy(TextureHandle texture, const SDL_Rect* srcrect,
179 const SDL_Rect* dstrect) {
180 SDL_FRect src_frect, dst_frect;
181 SDL_FRect* src_ptr = ToFRect(srcrect, &src_frect);
182 SDL_FRect* dst_ptr = ToFRect(dstrect, &dst_frect);
183
184 // SDL3 API: SDL_RenderTexture(renderer, texture, srcrect, dstrect)
185 // Both rectangles use SDL_FRect (float) in SDL3.
186 SDL_RenderTexture(renderer_, static_cast<SDL_Texture*>(texture), src_ptr,
187 dst_ptr);
188}
189
193void SDL3Renderer::SetRenderTarget(TextureHandle texture) {
194 SDL_SetRenderTarget(renderer_, static_cast<SDL_Texture*>(texture));
195}
196
200void SDL3Renderer::SetDrawColor(SDL_Color color) {
201 SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, color.a);
202}
203
214SDL_FRect* SDL3Renderer::ToFRect(const SDL_Rect* rect, SDL_FRect* frect) {
215 if (!rect || !frect) {
216 return nullptr;
217 }
218
219 frect->x = static_cast<float>(rect->x);
220 frect->y = static_cast<float>(rect->y);
221 frect->w = static_cast<float>(rect->w);
222 frect->h = static_cast<float>(rect->h);
223
224 return frect;
225}
226
227} // namespace gfx
228} // namespace yaze
229
230#endif // YAZE_USE_SDL3
void * TextureHandle
An abstract handle representing a texture.
Definition irenderer.h:47