144 SDL_RenderGetScale(renderer, &rsx, &rsy);
146 render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
147 render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
150 int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
151 int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
152 if (fb_width == 0 || fb_height == 0)
157 if (draw_data->Textures !=
nullptr)
158 for (ImTextureData* tex : *draw_data->Textures)
159 if (tex->Status != ImTextureStatus_OK)
163 struct BackupSDLRendererState
169 BackupSDLRendererState old = {};
170 old.ClipEnabled = SDL_RenderIsClipEnabled(renderer) == SDL_TRUE;
171 SDL_RenderGetViewport(renderer, &old.Viewport);
172 SDL_RenderGetClipRect(renderer, &old.ClipRect);
175 ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
178 ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
179 ImGui_ImplSDLRenderer2_RenderState render_state;
180 render_state.Renderer = renderer;
181 platform_io.Renderer_RenderState = &render_state;
184 ImVec2 clip_off = draw_data->DisplayPos;
185 ImVec2 clip_scale = render_scale;
188 for (
const ImDrawList* draw_list : draw_data->CmdLists)
190 const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
191 const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
193 for (
int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
195 const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
196 if (pcmd->UserCallback)
200 if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
201 ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
203 pcmd->UserCallback(draw_list, pcmd);
208 ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
209 ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
210 if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
211 if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
212 if (clip_max.x > (
float)fb_width) { clip_max.x = (float)fb_width; }
213 if (clip_max.y > (
float)fb_height) { clip_max.y = (float)fb_height; }
214 if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
217 SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) };
218 SDL_RenderSetClipRect(renderer, &r);
220 const float* xy = (
const float*)(
const void*)((
const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos));
221 const float* uv = (
const float*)(
const void*)((
const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv));
222#if SDL_VERSION_ATLEAST(2,0,19)
223 const SDL_Color* color = (
const SDL_Color*)(
const void*)((
const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col));
225 const int* color = (
const int*)(
const void*)((
const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col));
230 SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
231 if (pcmd->ElemCount == 0)
233 const ImDrawIdx* cmd_idx = idx_buffer + pcmd->IdxOffset;
234 unsigned int idx_min = 0xFFFFFFFFu, idx_max = 0;
235 for (
unsigned int i = 0; i < pcmd->ElemCount; i++)
237 const unsigned int v = cmd_idx[i];
238 if (v < idx_min) idx_min = v;
239 if (v > idx_max) idx_max = v;
241 static ImVector<int> rebased;
242 rebased.resize((
int)pcmd->ElemCount);
243 for (
unsigned int i = 0; i < pcmd->ElemCount; i++)
244 rebased[(
int)i] = (int)(cmd_idx[i] - idx_min);
245 const size_t vtx_skip = (size_t)idx_min *
sizeof(ImDrawVert);
246 SDL_RenderGeometryRaw(renderer, tex,
247 (
const float*)(
const void*)((
const char*)xy + vtx_skip), (
int)
sizeof(ImDrawVert),
248 (
decltype(color))(
const void*)((
const char*)color + vtx_skip), (
int)
sizeof(ImDrawVert),
249 (
const float*)(
const void*)((
const char*)uv + vtx_skip), (
int)
sizeof(ImDrawVert),
250 (
int)(idx_max - idx_min + 1),
251 rebased.Data, (
int)pcmd->ElemCount, (
int)
sizeof(
int));
255 platform_io.Renderer_RenderState =
nullptr;
258 SDL_RenderSetViewport(renderer, &old.Viewport);
259 SDL_RenderSetClipRect(renderer, old.ClipEnabled ? &old.ClipRect :
nullptr);
266 if (tex->Status == ImTextureStatus_WantCreate)
270 IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData ==
nullptr);
271 IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
275 SDL_Texture* sdl_texture = SDL_CreateTexture(bd->
Renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, tex->Width, tex->Height);
276 IM_ASSERT(sdl_texture !=
nullptr &&
"Backend failed to create texture!");
277 SDL_UpdateTexture(sdl_texture,
nullptr, tex->GetPixels(), tex->GetPitch());
278 SDL_SetTextureBlendMode(sdl_texture, SDL_BLENDMODE_BLEND);
279 SDL_SetTextureScaleMode(sdl_texture, SDL_ScaleModeLinear);
282 tex->SetTexID((ImTextureID)(intptr_t)sdl_texture);
283 tex->SetStatus(ImTextureStatus_OK);
285 else if (tex->Status == ImTextureStatus_WantUpdates)
289 SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID;
290 for (ImTextureRect& r : tex->Updates)
292 SDL_Rect sdl_r = { r.x, r.y, r.w, r.h };
293 SDL_UpdateTexture(sdl_texture, &sdl_r, tex->GetPixelsAt(r.x, r.y), tex->GetPitch());
295 tex->SetStatus(ImTextureStatus_OK);
297 else if (tex->Status == ImTextureStatus_WantDestroy)
299 if (tex->TexID != ImTextureID_Invalid)
300 if (SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID)
301 SDL_DestroyTexture(sdl_texture);
304 tex->SetTexID(ImTextureID_Invalid);
305 tex->SetStatus(ImTextureStatus_Destroyed);