125 SDL_RenderGetScale(renderer, &rsx, &rsy);
127 render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
128 render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
131 int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
132 int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
133 if (fb_width == 0 || fb_height == 0)
138 if (draw_data->Textures !=
nullptr)
139 for (ImTextureData* tex : *draw_data->Textures)
140 if (tex->Status != ImTextureStatus_OK)
144 struct BackupSDLRendererState
150 BackupSDLRendererState old = {};
151 old.ClipEnabled = SDL_RenderIsClipEnabled(renderer) == SDL_TRUE;
152 SDL_RenderGetViewport(renderer, &old.Viewport);
153 SDL_RenderGetClipRect(renderer, &old.ClipRect);
156 ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
159 ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
160 ImGui_ImplSDLRenderer2_RenderState render_state;
161 render_state.Renderer = renderer;
162 platform_io.Renderer_RenderState = &render_state;
165 ImVec2 clip_off = draw_data->DisplayPos;
166 ImVec2 clip_scale = render_scale;
169 for (
const ImDrawList* draw_list : draw_data->CmdLists)
171 const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
172 const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
174 for (
int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
176 const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
177 if (pcmd->UserCallback)
180 if (pcmd->UserCallback == ImGui_ImplSDLRenderer2_DrawCallback_ResetRenderState)
181 ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
183 pcmd->UserCallback(draw_list, pcmd);
188 ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
189 ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
190 if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
191 if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
192 if (clip_max.x > (
float)fb_width) { clip_max.x = (float)fb_width; }
193 if (clip_max.y > (
float)fb_height) { clip_max.y = (float)fb_height; }
194 if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
197 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) };
198 SDL_RenderSetClipRect(renderer, &r);
200 const float* xy = (
const float*)(
const void*)((
const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos));
201 const float* uv = (
const float*)(
const void*)((
const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv));
202#if SDL_VERSION_ATLEAST(2,0,19)
203 const SDL_Color* color = (
const SDL_Color*)(
const void*)((
const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col));
205 const int* color = (
const int*)(
const void*)((
const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col));
210 SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
211 if (pcmd->ElemCount == 0)
213 const ImDrawIdx* cmd_idx = idx_buffer + pcmd->IdxOffset;
214 unsigned int idx_min = 0xFFFFFFFFu, idx_max = 0;
215 for (
unsigned int i = 0; i < pcmd->ElemCount; i++)
217 const unsigned int v = cmd_idx[i];
218 if (v < idx_min) idx_min = v;
219 if (v > idx_max) idx_max = v;
221 static ImVector<int> rebased;
222 rebased.resize((
int)pcmd->ElemCount);
223 for (
unsigned int i = 0; i < pcmd->ElemCount; i++)
224 rebased[(
int)i] = (int)(cmd_idx[i] - idx_min);
225 const size_t vtx_skip = (size_t)idx_min *
sizeof(ImDrawVert);
226 SDL_RenderGeometryRaw(renderer, tex,
227 (
const float*)(
const void*)((
const char*)xy + vtx_skip), (
int)
sizeof(ImDrawVert),
228 (
decltype(color))(
const void*)((
const char*)color + vtx_skip), (
int)
sizeof(ImDrawVert),
229 (
const float*)(
const void*)((
const char*)uv + vtx_skip), (
int)
sizeof(ImDrawVert),
230 (
int)(idx_max - idx_min + 1),
231 rebased.Data, (
int)pcmd->ElemCount, (
int)
sizeof(
int));
235 platform_io.Renderer_RenderState =
nullptr;
238 SDL_RenderSetViewport(renderer, &old.Viewport);
239 SDL_RenderSetClipRect(renderer, old.ClipEnabled ? &old.ClipRect :
nullptr);
246 if (tex->Status == ImTextureStatus_WantCreate)
250 IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData ==
nullptr);
251 IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
254 SDL_Texture* sdl_texture = SDL_CreateTexture(bd->
Renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, tex->Width, tex->Height);
255 IM_ASSERT(sdl_texture !=
nullptr &&
"Backend failed to create texture!");
256 SDL_UpdateTexture(sdl_texture,
nullptr, tex->GetPixels(), tex->GetPitch());
257 SDL_SetTextureBlendMode(sdl_texture, SDL_BLENDMODE_BLEND);
258 SDL_SetTextureScaleMode(sdl_texture, SDL_ScaleModeLinear);
261 tex->SetTexID((ImTextureID)(intptr_t)sdl_texture);
262 tex->SetStatus(ImTextureStatus_OK);
264 else if (tex->Status == ImTextureStatus_WantUpdates)
268 SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID;
269 for (ImTextureRect& r : tex->Updates)
271 SDL_Rect sdl_r = { r.x, r.y, r.w, r.h };
272 SDL_UpdateTexture(sdl_texture, &sdl_r, tex->GetPixelsAt(r.x, r.y), tex->GetPitch());
274 tex->SetStatus(ImTextureStatus_OK);
276 else if (tex->Status == ImTextureStatus_WantDestroy)
278 if (tex->TexID != ImTextureID_Invalid)
279 if (SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID)
280 SDL_DestroyTexture(sdl_texture);
283 tex->SetTexID(ImTextureID_Invalid);
284 tex->SetStatus(ImTextureStatus_Destroyed);