Refactor SDL surface backend for improved quad rendering and performance
- Introduced a new structure ImGui_ImplSDLSurface3_Quad to represent quads. - Added functions to detect quads and check for constant colors and linear UVs. - Enhanced rendering functions to utilize quad detection for faster rendering paths. - Updated the rendering logic in ImGui_ImplSDLSurface3_RenderDrawData to leverage the new quad rendering capabilities. - Optimized Makefiles and build scripts to include optimization flags for better performance.
This commit is contained in:
@@ -70,10 +70,12 @@ examples/example_null/example_null
|
||||
examples/example_sdl2_metal/example_sdl2_metal
|
||||
examples/example_sdl2_opengl2/example_sdl2_opengl2
|
||||
examples/example_sdl2_opengl3/example_sdl2_opengl3
|
||||
examples/example_sdl2_surface/example_sdl2_surface
|
||||
examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2
|
||||
examples/example_sdl2_vulkan/example_sdl2_vulkan
|
||||
examples/example_sdl3_metal/example_sdl3_metal
|
||||
examples/example_sdl3_opengl3/example_sdl3_opengl3
|
||||
examples/example_sdl3_surface/example_sdl3_surface
|
||||
examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3
|
||||
examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3
|
||||
examples/example_sdl3_vulkan/example_sdl3_vulkan
|
||||
|
||||
@@ -38,15 +38,6 @@ struct ImGui_ImplSDLSurface2_SurfaceInfo
|
||||
ImGui_ImplSDLSurface2_SurfaceInfo() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLSurface2_Data
|
||||
{
|
||||
SDL_Surface* TargetSurface;
|
||||
SDL_Surface* FontSurface;
|
||||
ImGui_ImplSDLSurface2_SurfaceInfo TargetInfo;
|
||||
|
||||
ImGui_ImplSDLSurface2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLSurface2_RasterVertex
|
||||
{
|
||||
float X;
|
||||
@@ -59,6 +50,24 @@ struct ImGui_ImplSDLSurface2_RasterVertex
|
||||
float A;
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLSurface2_Quad
|
||||
{
|
||||
const ImGui_ImplSDLSurface2_RasterVertex* TL;
|
||||
const ImGui_ImplSDLSurface2_RasterVertex* TR;
|
||||
const ImGui_ImplSDLSurface2_RasterVertex* BR;
|
||||
const ImGui_ImplSDLSurface2_RasterVertex* BL;
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLSurface2_Data
|
||||
{
|
||||
SDL_Surface* TargetSurface;
|
||||
SDL_Surface* FontSurface;
|
||||
ImGui_ImplSDLSurface2_SurfaceInfo TargetInfo;
|
||||
ImVector<ImGui_ImplSDLSurface2_RasterVertex> VertexCache;
|
||||
|
||||
ImGui_ImplSDLSurface2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
static ImGui_ImplSDLSurface2_Data* ImGui_ImplSDLSurface2_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLSurface2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
@@ -69,6 +78,11 @@ static inline float ImGui_ImplSDLSurface2_Edge(float ax, float ay, float bx, flo
|
||||
return (bx - ax) * (py - ay) - (by - ay) * (px - ax);
|
||||
}
|
||||
|
||||
static inline bool ImGui_ImplSDLSurface2_NearEqual(float a, float b)
|
||||
{
|
||||
return fabsf(a - b) <= 0.0001f;
|
||||
}
|
||||
|
||||
static inline int ImGui_ImplSDLSurface2_ClampInt(int v, int lo, int hi)
|
||||
{
|
||||
return (v < lo) ? lo : (v > hi ? hi : v);
|
||||
@@ -227,6 +241,20 @@ static inline void ImGui_ImplSDLSurface2_ReadPixelRGBA(const ImGui_ImplSDLSurfac
|
||||
SDL_GetRGBA(pixel, surface.Format, r, g, b, a);
|
||||
}
|
||||
|
||||
static inline Uint8 ImGui_ImplSDLSurface2_ReadPixelAlpha(const ImGui_ImplSDLSurface2_SurfaceInfo& surface, int x, int y)
|
||||
{
|
||||
if (surface.IsFast)
|
||||
{
|
||||
const Uint32* src = (const Uint32*)(surface.Pixels + y * surface.Pitch) + x;
|
||||
return surface.FastFormat.HasAlpha ? (Uint8)((*src & surface.FastFormat.Amask) >> surface.FastFormat.Ashift) : 255;
|
||||
}
|
||||
|
||||
Uint8 a = 255;
|
||||
Uint32 pixel = ImGui_ImplSDLSurface2_ReadPixelRaw(surface, x, y);
|
||||
SDL_GetRGBA(pixel, surface.Format, nullptr, nullptr, nullptr, &a);
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline void ImGui_ImplSDLSurface2_BlendPixelFast(const ImGui_ImplSDLSurface2_SurfaceInfo& target, Uint32* dst, Uint8 sr, Uint8 sg, Uint8 sb, Uint8 sa)
|
||||
{
|
||||
if (sa == 0)
|
||||
@@ -270,6 +298,11 @@ static inline void ImGui_ImplSDLSurface2_BlendPixelGeneric(const ImGui_ImplSDLSu
|
||||
ImGui_ImplSDLSurface2_WritePixelRaw(target, x, y, pixel);
|
||||
}
|
||||
|
||||
static inline bool ImGui_ImplSDLSurface2_SameColor(const ImGui_ImplSDLSurface2_RasterVertex& a, const ImGui_ImplSDLSurface2_RasterVertex& b)
|
||||
{
|
||||
return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
|
||||
}
|
||||
|
||||
static inline void ImGui_ImplSDLSurface2_SetupRasterVertex(ImGui_ImplSDLSurface2_RasterVertex* out, const ImDrawVert& v, const ImVec2& display_pos, const ImVec2& framebuffer_scale)
|
||||
{
|
||||
out->X = (v.pos.x - display_pos.x) * framebuffer_scale.x;
|
||||
@@ -282,8 +315,16 @@ static inline void ImGui_ImplSDLSurface2_SetupRasterVertex(ImGui_ImplSDLSurface2
|
||||
out->A = (float)((v.col >> IM_COL32_A_SHIFT) & 0xFF);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface2_RenderTriangleFast(const ImGui_ImplSDLSurface2_SurfaceInfo& target, const ImGui_ImplSDLSurface2_SurfaceInfo* texture, const ImGui_ImplSDLSurface2_RasterVertex& v0, const ImGui_ImplSDLSurface2_RasterVertex& v1, const ImGui_ImplSDLSurface2_RasterVertex& v2, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
static void ImGui_ImplSDLSurface2_BuildVertexCache(ImVector<ImGui_ImplSDLSurface2_RasterVertex>* out, const ImDrawList* draw_list, const ImVec2& display_pos, const ImVec2& framebuffer_scale)
|
||||
{
|
||||
out->resize(draw_list->VtxBuffer.Size);
|
||||
for (int vtx_i = 0; vtx_i < draw_list->VtxBuffer.Size; vtx_i++)
|
||||
ImGui_ImplSDLSurface2_SetupRasterVertex(&out->Data[vtx_i], draw_list->VtxBuffer[vtx_i], display_pos, framebuffer_scale);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface2_RenderTriangleFast(const ImGui_ImplSDLSurface2_SurfaceInfo& target, const ImGui_ImplSDLSurface2_SurfaceInfo* texture, bool texture_is_font, const ImGui_ImplSDLSurface2_RasterVertex& v0, const ImGui_ImplSDLSurface2_RasterVertex& v1, const ImGui_ImplSDLSurface2_RasterVertex& v2, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
IM_UNUSED(texture_is_font);
|
||||
int min_x = std::max((int)std::floor(std::min(v0.X, std::min(v1.X, v2.X))), clip_min_x);
|
||||
int min_y = std::max((int)std::floor(std::min(v0.Y, std::min(v1.Y, v2.Y))), clip_min_y);
|
||||
int max_x = std::min((int)std::ceil(std::max(v0.X, std::max(v1.X, v2.X))) - 1, clip_max_x - 1);
|
||||
@@ -409,8 +450,9 @@ static void ImGui_ImplSDLSurface2_RenderTriangleFast(const ImGui_ImplSDLSurface2
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface2_RenderTriangleGeneric(const ImGui_ImplSDLSurface2_SurfaceInfo& target, const ImGui_ImplSDLSurface2_SurfaceInfo* texture, const ImGui_ImplSDLSurface2_RasterVertex& v0, const ImGui_ImplSDLSurface2_RasterVertex& v1, const ImGui_ImplSDLSurface2_RasterVertex& v2, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
static void ImGui_ImplSDLSurface2_RenderTriangleGeneric(const ImGui_ImplSDLSurface2_SurfaceInfo& target, const ImGui_ImplSDLSurface2_SurfaceInfo* texture, bool texture_is_font, const ImGui_ImplSDLSurface2_RasterVertex& v0, const ImGui_ImplSDLSurface2_RasterVertex& v1, const ImGui_ImplSDLSurface2_RasterVertex& v2, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
IM_UNUSED(texture_is_font);
|
||||
int min_x = std::max((int)std::floor(std::min(v0.X, std::min(v1.X, v2.X))), clip_min_x);
|
||||
int min_y = std::max((int)std::floor(std::min(v0.Y, std::min(v1.Y, v2.Y))), clip_min_y);
|
||||
int max_x = std::min((int)std::ceil(std::max(v0.X, std::max(v1.X, v2.X))) - 1, clip_max_x - 1);
|
||||
@@ -534,6 +576,359 @@ static void ImGui_ImplSDLSurface2_RenderTriangleGeneric(const ImGui_ImplSDLSurfa
|
||||
}
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface2_DetectQuad(const ImGui_ImplSDLSurface2_RasterVertex* vertices, const ImDrawIdx* idx_buffer, int vtx_offset, unsigned int elem_offset, ImGui_ImplSDLSurface2_Quad* out)
|
||||
{
|
||||
int unique_indices[4];
|
||||
int unique_count = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
int idx = vtx_offset + idx_buffer[elem_offset + i];
|
||||
bool found = false;
|
||||
for (int j = 0; j < unique_count; j++)
|
||||
if (unique_indices[j] == idx)
|
||||
found = true;
|
||||
if (!found)
|
||||
{
|
||||
if (unique_count >= 4)
|
||||
return false;
|
||||
unique_indices[unique_count++] = idx;
|
||||
}
|
||||
}
|
||||
if (unique_count != 4)
|
||||
return false;
|
||||
|
||||
const ImGui_ImplSDLSurface2_RasterVertex* candidates[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
candidates[i] = &vertices[unique_indices[i]];
|
||||
|
||||
float min_x = candidates[0]->X;
|
||||
float max_x = candidates[0]->X;
|
||||
float min_y = candidates[0]->Y;
|
||||
float max_y = candidates[0]->Y;
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
min_x = std::min(min_x, candidates[i]->X);
|
||||
max_x = std::max(max_x, candidates[i]->X);
|
||||
min_y = std::min(min_y, candidates[i]->Y);
|
||||
max_y = std::max(max_y, candidates[i]->Y);
|
||||
}
|
||||
if (!(max_x > min_x) || !(max_y > min_y))
|
||||
return false;
|
||||
|
||||
out->TL = nullptr;
|
||||
out->TR = nullptr;
|
||||
out->BR = nullptr;
|
||||
out->BL = nullptr;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
const ImGui_ImplSDLSurface2_RasterVertex* v = candidates[i];
|
||||
if (ImGui_ImplSDLSurface2_NearEqual(v->X, min_x) && ImGui_ImplSDLSurface2_NearEqual(v->Y, min_y))
|
||||
out->TL = v;
|
||||
else if (ImGui_ImplSDLSurface2_NearEqual(v->X, max_x) && ImGui_ImplSDLSurface2_NearEqual(v->Y, min_y))
|
||||
out->TR = v;
|
||||
else if (ImGui_ImplSDLSurface2_NearEqual(v->X, max_x) && ImGui_ImplSDLSurface2_NearEqual(v->Y, max_y))
|
||||
out->BR = v;
|
||||
else if (ImGui_ImplSDLSurface2_NearEqual(v->X, min_x) && ImGui_ImplSDLSurface2_NearEqual(v->Y, max_y))
|
||||
out->BL = v;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return out->TL != nullptr && out->TR != nullptr && out->BR != nullptr && out->BL != nullptr;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface2_QuadHasConstantColor(const ImGui_ImplSDLSurface2_Quad& quad)
|
||||
{
|
||||
return ImGui_ImplSDLSurface2_SameColor(*quad.TL, *quad.TR) && ImGui_ImplSDLSurface2_SameColor(*quad.TL, *quad.BR) && ImGui_ImplSDLSurface2_SameColor(*quad.TL, *quad.BL);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface2_QuadHasLinearUV(const ImGui_ImplSDLSurface2_Quad& quad)
|
||||
{
|
||||
if (!ImGui_ImplSDLSurface2_NearEqual(quad.TL->Y, quad.TR->Y) || !ImGui_ImplSDLSurface2_NearEqual(quad.BL->Y, quad.BR->Y) || !ImGui_ImplSDLSurface2_NearEqual(quad.TL->X, quad.BL->X) || !ImGui_ImplSDLSurface2_NearEqual(quad.TR->X, quad.BR->X))
|
||||
return false;
|
||||
float u = quad.TL->U + (quad.TR->U - quad.TL->U) + (quad.BL->U - quad.TL->U);
|
||||
float v = quad.TL->V + (quad.TR->V - quad.TL->V) + (quad.BL->V - quad.TL->V);
|
||||
return ImGui_ImplSDLSurface2_NearEqual(u, quad.BR->U) && ImGui_ImplSDLSurface2_NearEqual(v, quad.BR->V);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface2_QuadGetConstantTexel(const ImGui_ImplSDLSurface2_SurfaceInfo& texture, const ImGui_ImplSDLSurface2_Quad& quad, int* out_x, int* out_y)
|
||||
{
|
||||
int max_x = texture.Width - 1;
|
||||
int max_y = texture.Height - 1;
|
||||
int tx = ImGui_ImplSDLSurface2_ClampInt((int)(quad.TL->U * (float)max_x + 0.5f), 0, max_x);
|
||||
int ty = ImGui_ImplSDLSurface2_ClampInt((int)(quad.TL->V * (float)max_y + 0.5f), 0, max_y);
|
||||
int corner_tx[3] =
|
||||
{
|
||||
ImGui_ImplSDLSurface2_ClampInt((int)(quad.TR->U * (float)max_x + 0.5f), 0, max_x),
|
||||
ImGui_ImplSDLSurface2_ClampInt((int)(quad.BR->U * (float)max_x + 0.5f), 0, max_x),
|
||||
ImGui_ImplSDLSurface2_ClampInt((int)(quad.BL->U * (float)max_x + 0.5f), 0, max_x)
|
||||
};
|
||||
int corner_ty[3] =
|
||||
{
|
||||
ImGui_ImplSDLSurface2_ClampInt((int)(quad.TR->V * (float)max_y + 0.5f), 0, max_y),
|
||||
ImGui_ImplSDLSurface2_ClampInt((int)(quad.BR->V * (float)max_y + 0.5f), 0, max_y),
|
||||
ImGui_ImplSDLSurface2_ClampInt((int)(quad.BL->V * (float)max_y + 0.5f), 0, max_y)
|
||||
};
|
||||
for (int i = 0; i < 3; i++)
|
||||
if (corner_tx[i] != tx || corner_ty[i] != ty)
|
||||
return false;
|
||||
*out_x = tx;
|
||||
*out_y = ty;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface2_RenderSolidRectFast(const ImGui_ImplSDLSurface2_SurfaceInfo& target, const ImGui_ImplSDLSurface2_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
{
|
||||
int min_x = std::max((int)ceilf(quad.TL->X - 0.5f), clip_min_x);
|
||||
int max_x = std::min((int)floorf(quad.TR->X - 0.5f), clip_max_x - 1);
|
||||
int min_y = std::max((int)ceilf(quad.TL->Y - 0.5f), clip_min_y);
|
||||
int max_y = std::min((int)floorf(quad.BL->Y - 0.5f), clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
int count = max_x - min_x + 1;
|
||||
if (a == 255)
|
||||
{
|
||||
Uint32 pixel = ImGui_ImplSDLSurface2_PackFastRGBA(target.FastFormat, r, g, b, 255);
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
Uint32* dst = (Uint32*)(target.Pixels + y * target.Pitch) + min_x;
|
||||
std::fill_n(dst, count, pixel);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
Uint32* dst = (Uint32*)(target.Pixels + y * target.Pitch) + min_x;
|
||||
for (int x = 0; x < count; x++)
|
||||
ImGui_ImplSDLSurface2_BlendPixelFast(target, dst + x, r, g, b, a);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface2_RenderSolidRectGeneric(const ImGui_ImplSDLSurface2_SurfaceInfo& target, const ImGui_ImplSDLSurface2_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
{
|
||||
int min_x = std::max((int)ceilf(quad.TL->X - 0.5f), clip_min_x);
|
||||
int max_x = std::min((int)floorf(quad.TR->X - 0.5f), clip_max_x - 1);
|
||||
int min_y = std::max((int)ceilf(quad.TL->Y - 0.5f), clip_min_y);
|
||||
int max_y = std::min((int)floorf(quad.BL->Y - 0.5f), clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
Uint32 opaque_pixel = 0;
|
||||
if (a == 255)
|
||||
opaque_pixel = SDL_MapRGBA(target.Format, r, g, b, 255);
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
if (a == 255)
|
||||
ImGui_ImplSDLSurface2_WritePixelRaw(target, x, y, opaque_pixel);
|
||||
else
|
||||
ImGui_ImplSDLSurface2_BlendPixelGeneric(target, x, y, r, g, b, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface2_RenderTexturedRectFast(const ImGui_ImplSDLSurface2_SurfaceInfo& target, const ImGui_ImplSDLSurface2_SurfaceInfo& texture, bool texture_is_font, const ImGui_ImplSDLSurface2_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
int min_x = std::max((int)ceilf(quad.TL->X - 0.5f), clip_min_x);
|
||||
int max_x = std::min((int)floorf(quad.TR->X - 0.5f), clip_max_x - 1);
|
||||
int min_y = std::max((int)ceilf(quad.TL->Y - 0.5f), clip_min_y);
|
||||
int max_y = std::min((int)floorf(quad.BL->Y - 0.5f), clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
Uint8 color_r = (Uint8)quad.TL->R;
|
||||
Uint8 color_g = (Uint8)quad.TL->G;
|
||||
Uint8 color_b = (Uint8)quad.TL->B;
|
||||
Uint8 color_a = (Uint8)quad.TL->A;
|
||||
float du_dx = (quad.TR->U - quad.TL->U) / (quad.TR->X - quad.TL->X);
|
||||
float dv_dx = (quad.TR->V - quad.TL->V) / (quad.TR->X - quad.TL->X);
|
||||
float du_dy = (quad.BL->U - quad.TL->U) / (quad.BL->Y - quad.TL->Y);
|
||||
float dv_dy = (quad.BL->V - quad.TL->V) / (quad.BL->Y - quad.TL->Y);
|
||||
float u_const = quad.TL->U - quad.TL->X * du_dx - quad.TL->Y * du_dy;
|
||||
float v_const = quad.TL->V - quad.TL->X * dv_dx - quad.TL->Y * dv_dy;
|
||||
int texture_max_x = texture.Width - 1;
|
||||
int texture_max_y = texture.Height - 1;
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
float py = (float)y + 0.5f;
|
||||
float px = (float)min_x + 0.5f;
|
||||
float u = u_const + px * du_dx + py * du_dy;
|
||||
float v = v_const + px * dv_dx + py * dv_dy;
|
||||
Uint32* dst = (Uint32*)(target.Pixels + y * target.Pitch) + min_x;
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
int tx = ImGui_ImplSDLSurface2_ClampInt((int)(u * (float)texture_max_x + 0.5f), 0, texture_max_x);
|
||||
int ty = ImGui_ImplSDLSurface2_ClampInt((int)(v * (float)texture_max_y + 0.5f), 0, texture_max_y);
|
||||
Uint8 out_r = color_r;
|
||||
Uint8 out_g = color_g;
|
||||
Uint8 out_b = color_b;
|
||||
Uint8 out_a = color_a;
|
||||
if (texture_is_font)
|
||||
{
|
||||
out_a = ImGui_ImplSDLSurface2_Mul255(out_a, ImGui_ImplSDLSurface2_ReadPixelAlpha(texture, tx, ty));
|
||||
ImGui_ImplSDLSurface2_BlendPixelFast(target, dst, out_r, out_g, out_b, out_a);
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint8 tr, tg, tb, ta;
|
||||
ImGui_ImplSDLSurface2_ReadPixelRGBA(texture, tx, ty, &tr, &tg, &tb, &ta);
|
||||
out_r = ImGui_ImplSDLSurface2_Mul255(out_r, tr);
|
||||
out_g = ImGui_ImplSDLSurface2_Mul255(out_g, tg);
|
||||
out_b = ImGui_ImplSDLSurface2_Mul255(out_b, tb);
|
||||
out_a = ImGui_ImplSDLSurface2_Mul255(out_a, ta);
|
||||
ImGui_ImplSDLSurface2_BlendPixelFast(target, dst, out_r, out_g, out_b, out_a);
|
||||
}
|
||||
dst++;
|
||||
u += du_dx;
|
||||
v += dv_dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface2_RenderTexturedRectGeneric(const ImGui_ImplSDLSurface2_SurfaceInfo& target, const ImGui_ImplSDLSurface2_SurfaceInfo& texture, bool texture_is_font, const ImGui_ImplSDLSurface2_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
int min_x = std::max((int)ceilf(quad.TL->X - 0.5f), clip_min_x);
|
||||
int max_x = std::min((int)floorf(quad.TR->X - 0.5f), clip_max_x - 1);
|
||||
int min_y = std::max((int)ceilf(quad.TL->Y - 0.5f), clip_min_y);
|
||||
int max_y = std::min((int)floorf(quad.BL->Y - 0.5f), clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
Uint8 color_r = (Uint8)quad.TL->R;
|
||||
Uint8 color_g = (Uint8)quad.TL->G;
|
||||
Uint8 color_b = (Uint8)quad.TL->B;
|
||||
Uint8 color_a = (Uint8)quad.TL->A;
|
||||
float du_dx = (quad.TR->U - quad.TL->U) / (quad.TR->X - quad.TL->X);
|
||||
float dv_dx = (quad.TR->V - quad.TL->V) / (quad.TR->X - quad.TL->X);
|
||||
float du_dy = (quad.BL->U - quad.TL->U) / (quad.BL->Y - quad.TL->Y);
|
||||
float dv_dy = (quad.BL->V - quad.TL->V) / (quad.BL->Y - quad.TL->Y);
|
||||
float u_const = quad.TL->U - quad.TL->X * du_dx - quad.TL->Y * du_dy;
|
||||
float v_const = quad.TL->V - quad.TL->X * dv_dx - quad.TL->Y * dv_dy;
|
||||
int texture_max_x = texture.Width - 1;
|
||||
int texture_max_y = texture.Height - 1;
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
float py = (float)y + 0.5f;
|
||||
float px = (float)min_x + 0.5f;
|
||||
float u = u_const + px * du_dx + py * du_dy;
|
||||
float v = v_const + px * dv_dx + py * dv_dy;
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
int tx = ImGui_ImplSDLSurface2_ClampInt((int)(u * (float)texture_max_x + 0.5f), 0, texture_max_x);
|
||||
int ty = ImGui_ImplSDLSurface2_ClampInt((int)(v * (float)texture_max_y + 0.5f), 0, texture_max_y);
|
||||
Uint8 out_r = color_r;
|
||||
Uint8 out_g = color_g;
|
||||
Uint8 out_b = color_b;
|
||||
Uint8 out_a = color_a;
|
||||
if (texture_is_font)
|
||||
{
|
||||
out_a = ImGui_ImplSDLSurface2_Mul255(out_a, ImGui_ImplSDLSurface2_ReadPixelAlpha(texture, tx, ty));
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint8 tr, tg, tb, ta;
|
||||
ImGui_ImplSDLSurface2_ReadPixelRGBA(texture, tx, ty, &tr, &tg, &tb, &ta);
|
||||
out_r = ImGui_ImplSDLSurface2_Mul255(out_r, tr);
|
||||
out_g = ImGui_ImplSDLSurface2_Mul255(out_g, tg);
|
||||
out_b = ImGui_ImplSDLSurface2_Mul255(out_b, tb);
|
||||
out_a = ImGui_ImplSDLSurface2_Mul255(out_a, ta);
|
||||
}
|
||||
ImGui_ImplSDLSurface2_BlendPixelGeneric(target, x, y, out_r, out_g, out_b, out_a);
|
||||
u += du_dx;
|
||||
v += dv_dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface2_TryRenderQuadFast(const ImGui_ImplSDLSurface2_SurfaceInfo& target, const ImGui_ImplSDLSurface2_SurfaceInfo* texture, bool texture_is_font, const ImGui_ImplSDLSurface2_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
if (!ImGui_ImplSDLSurface2_QuadHasConstantColor(quad))
|
||||
return false;
|
||||
|
||||
Uint8 r = (Uint8)quad.TL->R;
|
||||
Uint8 g = (Uint8)quad.TL->G;
|
||||
Uint8 b = (Uint8)quad.TL->B;
|
||||
Uint8 a = (Uint8)quad.TL->A;
|
||||
if (texture == nullptr)
|
||||
{
|
||||
ImGui_ImplSDLSurface2_RenderSolidRectFast(target, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y, r, g, b, a);
|
||||
return true;
|
||||
}
|
||||
|
||||
int tx = 0;
|
||||
int ty = 0;
|
||||
if (ImGui_ImplSDLSurface2_QuadGetConstantTexel(*texture, quad, &tx, &ty))
|
||||
{
|
||||
if (texture_is_font)
|
||||
{
|
||||
a = ImGui_ImplSDLSurface2_Mul255(a, ImGui_ImplSDLSurface2_ReadPixelAlpha(*texture, tx, ty));
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint8 tr, tg, tb, ta;
|
||||
ImGui_ImplSDLSurface2_ReadPixelRGBA(*texture, tx, ty, &tr, &tg, &tb, &ta);
|
||||
r = ImGui_ImplSDLSurface2_Mul255(r, tr);
|
||||
g = ImGui_ImplSDLSurface2_Mul255(g, tg);
|
||||
b = ImGui_ImplSDLSurface2_Mul255(b, tb);
|
||||
a = ImGui_ImplSDLSurface2_Mul255(a, ta);
|
||||
}
|
||||
ImGui_ImplSDLSurface2_RenderSolidRectFast(target, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y, r, g, b, a);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ImGui_ImplSDLSurface2_QuadHasLinearUV(quad))
|
||||
return false;
|
||||
ImGui_ImplSDLSurface2_RenderTexturedRectFast(target, *texture, texture_is_font, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface2_TryRenderQuadGeneric(const ImGui_ImplSDLSurface2_SurfaceInfo& target, const ImGui_ImplSDLSurface2_SurfaceInfo* texture, bool texture_is_font, const ImGui_ImplSDLSurface2_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
if (!ImGui_ImplSDLSurface2_QuadHasConstantColor(quad))
|
||||
return false;
|
||||
|
||||
Uint8 r = (Uint8)quad.TL->R;
|
||||
Uint8 g = (Uint8)quad.TL->G;
|
||||
Uint8 b = (Uint8)quad.TL->B;
|
||||
Uint8 a = (Uint8)quad.TL->A;
|
||||
if (texture == nullptr)
|
||||
{
|
||||
ImGui_ImplSDLSurface2_RenderSolidRectGeneric(target, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y, r, g, b, a);
|
||||
return true;
|
||||
}
|
||||
|
||||
int tx = 0;
|
||||
int ty = 0;
|
||||
if (ImGui_ImplSDLSurface2_QuadGetConstantTexel(*texture, quad, &tx, &ty))
|
||||
{
|
||||
if (texture_is_font)
|
||||
{
|
||||
a = ImGui_ImplSDLSurface2_Mul255(a, ImGui_ImplSDLSurface2_ReadPixelAlpha(*texture, tx, ty));
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint8 tr, tg, tb, ta;
|
||||
ImGui_ImplSDLSurface2_ReadPixelRGBA(*texture, tx, ty, &tr, &tg, &tb, &ta);
|
||||
r = ImGui_ImplSDLSurface2_Mul255(r, tr);
|
||||
g = ImGui_ImplSDLSurface2_Mul255(g, tg);
|
||||
b = ImGui_ImplSDLSurface2_Mul255(b, tb);
|
||||
a = ImGui_ImplSDLSurface2_Mul255(a, ta);
|
||||
}
|
||||
ImGui_ImplSDLSurface2_RenderSolidRectGeneric(target, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y, r, g, b, a);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ImGui_ImplSDLSurface2_QuadHasLinearUV(quad))
|
||||
return false;
|
||||
ImGui_ImplSDLSurface2_RenderTexturedRectGeneric(target, *texture, texture_is_font, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_Surface* ImGui_ImplSDLSurface2_CreateFontAtlasSurface()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -627,14 +1022,20 @@ void ImGui_ImplSDLSurface2_RenderDrawData(ImDrawData* draw_data)
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_Surface* active_texture_surface = nullptr;
|
||||
ImGui_ImplSDLSurface2_SurfaceInfo active_texture_info;
|
||||
bool active_texture_valid = false;
|
||||
bool active_texture_locked = false;
|
||||
bool active_texture_is_font = false;
|
||||
const ImVec2 clip_off = draw_data->DisplayPos;
|
||||
const ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
ImGui_ImplSDLSurface2_BuildVertexCache(&bd->VertexCache, draw_list, clip_off, clip_scale);
|
||||
const ImGui_ImplSDLSurface2_RasterVertex* vertex_cache = bd->VertexCache.Data;
|
||||
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
@@ -663,51 +1064,68 @@ void ImGui_ImplSDLSurface2_RenderDrawData(ImDrawData* draw_data)
|
||||
int clip_max_y = (int)clip_max.y;
|
||||
|
||||
SDL_Surface* texture_surface = (SDL_Surface*)pcmd->GetTexID();
|
||||
ImGui_ImplSDLSurface2_SurfaceInfo texture_info;
|
||||
ImGui_ImplSDLSurface2_SurfaceInfo* texture_ptr = nullptr;
|
||||
bool texture_locked = false;
|
||||
|
||||
if (texture_surface != nullptr)
|
||||
if (texture_surface != active_texture_surface)
|
||||
{
|
||||
if (SDL_MUSTLOCK(texture_surface))
|
||||
{
|
||||
if (SDL_LockSurface(texture_surface) != 0)
|
||||
texture_surface = nullptr;
|
||||
else
|
||||
texture_locked = true;
|
||||
}
|
||||
if (active_texture_locked && active_texture_surface != nullptr)
|
||||
SDL_UnlockSurface(active_texture_surface);
|
||||
active_texture_surface = texture_surface;
|
||||
active_texture_valid = false;
|
||||
active_texture_locked = false;
|
||||
active_texture_is_font = false;
|
||||
if (texture_surface != nullptr)
|
||||
{
|
||||
ImGui_ImplSDLSurface2_InitSurfaceInfo(&texture_info, texture_surface);
|
||||
if (texture_info.Width > 0 && texture_info.Height > 0)
|
||||
texture_ptr = &texture_info;
|
||||
if (SDL_MUSTLOCK(texture_surface))
|
||||
{
|
||||
if (SDL_LockSurface(texture_surface) != 0)
|
||||
active_texture_surface = texture_surface;
|
||||
else
|
||||
active_texture_locked = true;
|
||||
}
|
||||
if (!SDL_MUSTLOCK(texture_surface) || active_texture_locked)
|
||||
{
|
||||
ImGui_ImplSDLSurface2_InitSurfaceInfo(&active_texture_info, texture_surface);
|
||||
active_texture_valid = active_texture_info.Width > 0 && active_texture_info.Height > 0;
|
||||
active_texture_is_font = texture_surface == bd->FontSurface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int idx = 0; idx + 2 < (unsigned int)pcmd->ElemCount; idx += 3)
|
||||
const ImGui_ImplSDLSurface2_SurfaceInfo* texture_ptr = active_texture_valid ? &active_texture_info : nullptr;
|
||||
for (unsigned int idx = 0; idx + 2 < (unsigned int)pcmd->ElemCount;)
|
||||
{
|
||||
if (idx + 5 < (unsigned int)pcmd->ElemCount)
|
||||
{
|
||||
ImGui_ImplSDLSurface2_Quad quad;
|
||||
if (ImGui_ImplSDLSurface2_DetectQuad(vertex_cache, idx_buffer, pcmd->VtxOffset, pcmd->IdxOffset + idx, &quad))
|
||||
{
|
||||
bool rendered = bd->TargetInfo.IsFast
|
||||
? ImGui_ImplSDLSurface2_TryRenderQuadFast(bd->TargetInfo, texture_ptr, active_texture_is_font, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y)
|
||||
: ImGui_ImplSDLSurface2_TryRenderQuadGeneric(bd->TargetInfo, texture_ptr, active_texture_is_font, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
if (rendered)
|
||||
{
|
||||
idx += 6;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImDrawIdx idx0 = idx_buffer[pcmd->IdxOffset + idx + 0];
|
||||
ImDrawIdx idx1 = idx_buffer[pcmd->IdxOffset + idx + 1];
|
||||
ImDrawIdx idx2 = idx_buffer[pcmd->IdxOffset + idx + 2];
|
||||
|
||||
ImGui_ImplSDLSurface2_RasterVertex v0;
|
||||
ImGui_ImplSDLSurface2_RasterVertex v1;
|
||||
ImGui_ImplSDLSurface2_RasterVertex v2;
|
||||
ImGui_ImplSDLSurface2_SetupRasterVertex(&v0, vtx_buffer[pcmd->VtxOffset + idx0], clip_off, clip_scale);
|
||||
ImGui_ImplSDLSurface2_SetupRasterVertex(&v1, vtx_buffer[pcmd->VtxOffset + idx1], clip_off, clip_scale);
|
||||
ImGui_ImplSDLSurface2_SetupRasterVertex(&v2, vtx_buffer[pcmd->VtxOffset + idx2], clip_off, clip_scale);
|
||||
|
||||
const ImGui_ImplSDLSurface2_RasterVertex& v0 = vertex_cache[pcmd->VtxOffset + idx0];
|
||||
const ImGui_ImplSDLSurface2_RasterVertex& v1 = vertex_cache[pcmd->VtxOffset + idx1];
|
||||
const ImGui_ImplSDLSurface2_RasterVertex& v2 = vertex_cache[pcmd->VtxOffset + idx2];
|
||||
if (bd->TargetInfo.IsFast)
|
||||
ImGui_ImplSDLSurface2_RenderTriangleFast(bd->TargetInfo, texture_ptr, v0, v1, v2, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
ImGui_ImplSDLSurface2_RenderTriangleFast(bd->TargetInfo, texture_ptr, active_texture_is_font, v0, v1, v2, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
else
|
||||
ImGui_ImplSDLSurface2_RenderTriangleGeneric(bd->TargetInfo, texture_ptr, v0, v1, v2, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
ImGui_ImplSDLSurface2_RenderTriangleGeneric(bd->TargetInfo, texture_ptr, active_texture_is_font, v0, v1, v2, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
idx += 3;
|
||||
}
|
||||
|
||||
if (texture_locked)
|
||||
SDL_UnlockSurface(texture_surface);
|
||||
}
|
||||
}
|
||||
|
||||
if (active_texture_locked && active_texture_surface != nullptr)
|
||||
SDL_UnlockSurface(active_texture_surface);
|
||||
if (SDL_MUSTLOCK(bd->TargetSurface))
|
||||
SDL_UnlockSurface(bd->TargetSurface);
|
||||
}
|
||||
|
||||
@@ -38,15 +38,6 @@ struct ImGui_ImplSDLSurface3_SurfaceInfo
|
||||
ImGui_ImplSDLSurface3_SurfaceInfo() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLSurface3_Data
|
||||
{
|
||||
SDL_Surface* TargetSurface;
|
||||
SDL_Surface* FontSurface;
|
||||
ImGui_ImplSDLSurface3_SurfaceInfo TargetInfo;
|
||||
|
||||
ImGui_ImplSDLSurface3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLSurface3_RasterVertex
|
||||
{
|
||||
float X;
|
||||
@@ -59,6 +50,24 @@ struct ImGui_ImplSDLSurface3_RasterVertex
|
||||
float A;
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLSurface3_Quad
|
||||
{
|
||||
const ImGui_ImplSDLSurface3_RasterVertex* TL;
|
||||
const ImGui_ImplSDLSurface3_RasterVertex* TR;
|
||||
const ImGui_ImplSDLSurface3_RasterVertex* BR;
|
||||
const ImGui_ImplSDLSurface3_RasterVertex* BL;
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLSurface3_Data
|
||||
{
|
||||
SDL_Surface* TargetSurface;
|
||||
SDL_Surface* FontSurface;
|
||||
ImGui_ImplSDLSurface3_SurfaceInfo TargetInfo;
|
||||
ImVector<ImGui_ImplSDLSurface3_RasterVertex> VertexCache;
|
||||
|
||||
ImGui_ImplSDLSurface3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
static ImGui_ImplSDLSurface3_Data* ImGui_ImplSDLSurface3_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLSurface3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
@@ -69,6 +78,11 @@ static inline float ImGui_ImplSDLSurface3_Edge(float ax, float ay, float bx, flo
|
||||
return (bx - ax) * (py - ay) - (by - ay) * (px - ax);
|
||||
}
|
||||
|
||||
static inline bool ImGui_ImplSDLSurface3_NearEqual(float a, float b)
|
||||
{
|
||||
return fabsf(a - b) <= 0.0001f;
|
||||
}
|
||||
|
||||
static inline int ImGui_ImplSDLSurface3_ClampInt(int v, int lo, int hi)
|
||||
{
|
||||
return (v < lo) ? lo : (v > hi ? hi : v);
|
||||
@@ -227,6 +241,20 @@ static inline void ImGui_ImplSDLSurface3_ReadPixelRGBA(const ImGui_ImplSDLSurfac
|
||||
SDL_GetRGBA(pixel, surface.Format, surface.Palette, r, g, b, a);
|
||||
}
|
||||
|
||||
static inline Uint8 ImGui_ImplSDLSurface3_ReadPixelAlpha(const ImGui_ImplSDLSurface3_SurfaceInfo& surface, int x, int y)
|
||||
{
|
||||
if (surface.IsFast)
|
||||
{
|
||||
const Uint32* src = (const Uint32*)(surface.Pixels + y * surface.Pitch) + x;
|
||||
return surface.FastFormat.HasAlpha ? (Uint8)((*src & surface.FastFormat.Amask) >> surface.FastFormat.Ashift) : 255;
|
||||
}
|
||||
|
||||
Uint8 a = 255;
|
||||
Uint32 pixel = ImGui_ImplSDLSurface3_ReadPixelRaw(surface, x, y);
|
||||
SDL_GetRGBA(pixel, surface.Format, surface.Palette, nullptr, nullptr, nullptr, &a);
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline void ImGui_ImplSDLSurface3_BlendPixelFast(const ImGui_ImplSDLSurface3_SurfaceInfo& target, Uint32* dst, Uint8 sr, Uint8 sg, Uint8 sb, Uint8 sa)
|
||||
{
|
||||
if (sa == 0)
|
||||
@@ -270,6 +298,11 @@ static inline void ImGui_ImplSDLSurface3_BlendPixelGeneric(const ImGui_ImplSDLSu
|
||||
ImGui_ImplSDLSurface3_WritePixelRaw(target, x, y, pixel);
|
||||
}
|
||||
|
||||
static inline bool ImGui_ImplSDLSurface3_SameColor(const ImGui_ImplSDLSurface3_RasterVertex& a, const ImGui_ImplSDLSurface3_RasterVertex& b)
|
||||
{
|
||||
return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
|
||||
}
|
||||
|
||||
static inline void ImGui_ImplSDLSurface3_SetupRasterVertex(ImGui_ImplSDLSurface3_RasterVertex* out, const ImDrawVert& v, const ImVec2& display_pos, const ImVec2& framebuffer_scale)
|
||||
{
|
||||
out->X = (v.pos.x - display_pos.x) * framebuffer_scale.x;
|
||||
@@ -282,8 +315,16 @@ static inline void ImGui_ImplSDLSurface3_SetupRasterVertex(ImGui_ImplSDLSurface3
|
||||
out->A = (float)((v.col >> IM_COL32_A_SHIFT) & 0xFF);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface3_RenderTriangleFast(const ImGui_ImplSDLSurface3_SurfaceInfo& target, const ImGui_ImplSDLSurface3_SurfaceInfo* texture, const ImGui_ImplSDLSurface3_RasterVertex& v0, const ImGui_ImplSDLSurface3_RasterVertex& v1, const ImGui_ImplSDLSurface3_RasterVertex& v2, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
static void ImGui_ImplSDLSurface3_BuildVertexCache(ImVector<ImGui_ImplSDLSurface3_RasterVertex>* out, const ImDrawList* draw_list, const ImVec2& display_pos, const ImVec2& framebuffer_scale)
|
||||
{
|
||||
out->resize(draw_list->VtxBuffer.Size);
|
||||
for (int vtx_i = 0; vtx_i < draw_list->VtxBuffer.Size; vtx_i++)
|
||||
ImGui_ImplSDLSurface3_SetupRasterVertex(&out->Data[vtx_i], draw_list->VtxBuffer[vtx_i], display_pos, framebuffer_scale);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface3_RenderTriangleFast(const ImGui_ImplSDLSurface3_SurfaceInfo& target, const ImGui_ImplSDLSurface3_SurfaceInfo* texture, bool texture_is_font, const ImGui_ImplSDLSurface3_RasterVertex& v0, const ImGui_ImplSDLSurface3_RasterVertex& v1, const ImGui_ImplSDLSurface3_RasterVertex& v2, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
IM_UNUSED(texture_is_font);
|
||||
int min_x = std::max((int)std::floor(std::min(v0.X, std::min(v1.X, v2.X))), clip_min_x);
|
||||
int min_y = std::max((int)std::floor(std::min(v0.Y, std::min(v1.Y, v2.Y))), clip_min_y);
|
||||
int max_x = std::min((int)std::ceil(std::max(v0.X, std::max(v1.X, v2.X))) - 1, clip_max_x - 1);
|
||||
@@ -409,8 +450,9 @@ static void ImGui_ImplSDLSurface3_RenderTriangleFast(const ImGui_ImplSDLSurface3
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface3_RenderTriangleGeneric(const ImGui_ImplSDLSurface3_SurfaceInfo& target, const ImGui_ImplSDLSurface3_SurfaceInfo* texture, const ImGui_ImplSDLSurface3_RasterVertex& v0, const ImGui_ImplSDLSurface3_RasterVertex& v1, const ImGui_ImplSDLSurface3_RasterVertex& v2, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
static void ImGui_ImplSDLSurface3_RenderTriangleGeneric(const ImGui_ImplSDLSurface3_SurfaceInfo& target, const ImGui_ImplSDLSurface3_SurfaceInfo* texture, bool texture_is_font, const ImGui_ImplSDLSurface3_RasterVertex& v0, const ImGui_ImplSDLSurface3_RasterVertex& v1, const ImGui_ImplSDLSurface3_RasterVertex& v2, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
IM_UNUSED(texture_is_font);
|
||||
int min_x = std::max((int)std::floor(std::min(v0.X, std::min(v1.X, v2.X))), clip_min_x);
|
||||
int min_y = std::max((int)std::floor(std::min(v0.Y, std::min(v1.Y, v2.Y))), clip_min_y);
|
||||
int max_x = std::min((int)std::ceil(std::max(v0.X, std::max(v1.X, v2.X))) - 1, clip_max_x - 1);
|
||||
@@ -534,6 +576,359 @@ static void ImGui_ImplSDLSurface3_RenderTriangleGeneric(const ImGui_ImplSDLSurfa
|
||||
}
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface3_DetectQuad(const ImGui_ImplSDLSurface3_RasterVertex* vertices, const ImDrawIdx* idx_buffer, int vtx_offset, unsigned int elem_offset, ImGui_ImplSDLSurface3_Quad* out)
|
||||
{
|
||||
int unique_indices[4];
|
||||
int unique_count = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
int idx = vtx_offset + idx_buffer[elem_offset + i];
|
||||
bool found = false;
|
||||
for (int j = 0; j < unique_count; j++)
|
||||
if (unique_indices[j] == idx)
|
||||
found = true;
|
||||
if (!found)
|
||||
{
|
||||
if (unique_count >= 4)
|
||||
return false;
|
||||
unique_indices[unique_count++] = idx;
|
||||
}
|
||||
}
|
||||
if (unique_count != 4)
|
||||
return false;
|
||||
|
||||
const ImGui_ImplSDLSurface3_RasterVertex* candidates[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
candidates[i] = &vertices[unique_indices[i]];
|
||||
|
||||
float min_x = candidates[0]->X;
|
||||
float max_x = candidates[0]->X;
|
||||
float min_y = candidates[0]->Y;
|
||||
float max_y = candidates[0]->Y;
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
min_x = std::min(min_x, candidates[i]->X);
|
||||
max_x = std::max(max_x, candidates[i]->X);
|
||||
min_y = std::min(min_y, candidates[i]->Y);
|
||||
max_y = std::max(max_y, candidates[i]->Y);
|
||||
}
|
||||
if (!(max_x > min_x) || !(max_y > min_y))
|
||||
return false;
|
||||
|
||||
out->TL = nullptr;
|
||||
out->TR = nullptr;
|
||||
out->BR = nullptr;
|
||||
out->BL = nullptr;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
const ImGui_ImplSDLSurface3_RasterVertex* v = candidates[i];
|
||||
if (ImGui_ImplSDLSurface3_NearEqual(v->X, min_x) && ImGui_ImplSDLSurface3_NearEqual(v->Y, min_y))
|
||||
out->TL = v;
|
||||
else if (ImGui_ImplSDLSurface3_NearEqual(v->X, max_x) && ImGui_ImplSDLSurface3_NearEqual(v->Y, min_y))
|
||||
out->TR = v;
|
||||
else if (ImGui_ImplSDLSurface3_NearEqual(v->X, max_x) && ImGui_ImplSDLSurface3_NearEqual(v->Y, max_y))
|
||||
out->BR = v;
|
||||
else if (ImGui_ImplSDLSurface3_NearEqual(v->X, min_x) && ImGui_ImplSDLSurface3_NearEqual(v->Y, max_y))
|
||||
out->BL = v;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return out->TL != nullptr && out->TR != nullptr && out->BR != nullptr && out->BL != nullptr;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface3_QuadHasConstantColor(const ImGui_ImplSDLSurface3_Quad& quad)
|
||||
{
|
||||
return ImGui_ImplSDLSurface3_SameColor(*quad.TL, *quad.TR) && ImGui_ImplSDLSurface3_SameColor(*quad.TL, *quad.BR) && ImGui_ImplSDLSurface3_SameColor(*quad.TL, *quad.BL);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface3_QuadHasLinearUV(const ImGui_ImplSDLSurface3_Quad& quad)
|
||||
{
|
||||
if (!ImGui_ImplSDLSurface3_NearEqual(quad.TL->Y, quad.TR->Y) || !ImGui_ImplSDLSurface3_NearEqual(quad.BL->Y, quad.BR->Y) || !ImGui_ImplSDLSurface3_NearEqual(quad.TL->X, quad.BL->X) || !ImGui_ImplSDLSurface3_NearEqual(quad.TR->X, quad.BR->X))
|
||||
return false;
|
||||
float u = quad.TL->U + (quad.TR->U - quad.TL->U) + (quad.BL->U - quad.TL->U);
|
||||
float v = quad.TL->V + (quad.TR->V - quad.TL->V) + (quad.BL->V - quad.TL->V);
|
||||
return ImGui_ImplSDLSurface3_NearEqual(u, quad.BR->U) && ImGui_ImplSDLSurface3_NearEqual(v, quad.BR->V);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface3_QuadGetConstantTexel(const ImGui_ImplSDLSurface3_SurfaceInfo& texture, const ImGui_ImplSDLSurface3_Quad& quad, int* out_x, int* out_y)
|
||||
{
|
||||
int max_x = texture.Width - 1;
|
||||
int max_y = texture.Height - 1;
|
||||
int tx = ImGui_ImplSDLSurface3_ClampInt((int)(quad.TL->U * (float)max_x + 0.5f), 0, max_x);
|
||||
int ty = ImGui_ImplSDLSurface3_ClampInt((int)(quad.TL->V * (float)max_y + 0.5f), 0, max_y);
|
||||
int corner_tx[3] =
|
||||
{
|
||||
ImGui_ImplSDLSurface3_ClampInt((int)(quad.TR->U * (float)max_x + 0.5f), 0, max_x),
|
||||
ImGui_ImplSDLSurface3_ClampInt((int)(quad.BR->U * (float)max_x + 0.5f), 0, max_x),
|
||||
ImGui_ImplSDLSurface3_ClampInt((int)(quad.BL->U * (float)max_x + 0.5f), 0, max_x)
|
||||
};
|
||||
int corner_ty[3] =
|
||||
{
|
||||
ImGui_ImplSDLSurface3_ClampInt((int)(quad.TR->V * (float)max_y + 0.5f), 0, max_y),
|
||||
ImGui_ImplSDLSurface3_ClampInt((int)(quad.BR->V * (float)max_y + 0.5f), 0, max_y),
|
||||
ImGui_ImplSDLSurface3_ClampInt((int)(quad.BL->V * (float)max_y + 0.5f), 0, max_y)
|
||||
};
|
||||
for (int i = 0; i < 3; i++)
|
||||
if (corner_tx[i] != tx || corner_ty[i] != ty)
|
||||
return false;
|
||||
*out_x = tx;
|
||||
*out_y = ty;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface3_RenderSolidRectFast(const ImGui_ImplSDLSurface3_SurfaceInfo& target, const ImGui_ImplSDLSurface3_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
{
|
||||
int min_x = std::max((int)ceilf(quad.TL->X - 0.5f), clip_min_x);
|
||||
int max_x = std::min((int)floorf(quad.TR->X - 0.5f), clip_max_x - 1);
|
||||
int min_y = std::max((int)ceilf(quad.TL->Y - 0.5f), clip_min_y);
|
||||
int max_y = std::min((int)floorf(quad.BL->Y - 0.5f), clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
int count = max_x - min_x + 1;
|
||||
if (a == 255)
|
||||
{
|
||||
Uint32 pixel = ImGui_ImplSDLSurface3_PackFastRGBA(target.FastFormat, r, g, b, 255);
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
Uint32* dst = (Uint32*)(target.Pixels + y * target.Pitch) + min_x;
|
||||
std::fill_n(dst, count, pixel);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
Uint32* dst = (Uint32*)(target.Pixels + y * target.Pitch) + min_x;
|
||||
for (int x = 0; x < count; x++)
|
||||
ImGui_ImplSDLSurface3_BlendPixelFast(target, dst + x, r, g, b, a);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface3_RenderSolidRectGeneric(const ImGui_ImplSDLSurface3_SurfaceInfo& target, const ImGui_ImplSDLSurface3_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
{
|
||||
int min_x = std::max((int)ceilf(quad.TL->X - 0.5f), clip_min_x);
|
||||
int max_x = std::min((int)floorf(quad.TR->X - 0.5f), clip_max_x - 1);
|
||||
int min_y = std::max((int)ceilf(quad.TL->Y - 0.5f), clip_min_y);
|
||||
int max_y = std::min((int)floorf(quad.BL->Y - 0.5f), clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
Uint32 opaque_pixel = 0;
|
||||
if (a == 255)
|
||||
opaque_pixel = SDL_MapRGBA(target.Format, target.Palette, r, g, b, 255);
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
if (a == 255)
|
||||
ImGui_ImplSDLSurface3_WritePixelRaw(target, x, y, opaque_pixel);
|
||||
else
|
||||
ImGui_ImplSDLSurface3_BlendPixelGeneric(target, x, y, r, g, b, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface3_RenderTexturedRectFast(const ImGui_ImplSDLSurface3_SurfaceInfo& target, const ImGui_ImplSDLSurface3_SurfaceInfo& texture, bool texture_is_font, const ImGui_ImplSDLSurface3_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
int min_x = std::max((int)ceilf(quad.TL->X - 0.5f), clip_min_x);
|
||||
int max_x = std::min((int)floorf(quad.TR->X - 0.5f), clip_max_x - 1);
|
||||
int min_y = std::max((int)ceilf(quad.TL->Y - 0.5f), clip_min_y);
|
||||
int max_y = std::min((int)floorf(quad.BL->Y - 0.5f), clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
Uint8 color_r = (Uint8)quad.TL->R;
|
||||
Uint8 color_g = (Uint8)quad.TL->G;
|
||||
Uint8 color_b = (Uint8)quad.TL->B;
|
||||
Uint8 color_a = (Uint8)quad.TL->A;
|
||||
float du_dx = (quad.TR->U - quad.TL->U) / (quad.TR->X - quad.TL->X);
|
||||
float dv_dx = (quad.TR->V - quad.TL->V) / (quad.TR->X - quad.TL->X);
|
||||
float du_dy = (quad.BL->U - quad.TL->U) / (quad.BL->Y - quad.TL->Y);
|
||||
float dv_dy = (quad.BL->V - quad.TL->V) / (quad.BL->Y - quad.TL->Y);
|
||||
float u_const = quad.TL->U - quad.TL->X * du_dx - quad.TL->Y * du_dy;
|
||||
float v_const = quad.TL->V - quad.TL->X * dv_dx - quad.TL->Y * dv_dy;
|
||||
int texture_max_x = texture.Width - 1;
|
||||
int texture_max_y = texture.Height - 1;
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
float py = (float)y + 0.5f;
|
||||
float px = (float)min_x + 0.5f;
|
||||
float u = u_const + px * du_dx + py * du_dy;
|
||||
float v = v_const + px * dv_dx + py * dv_dy;
|
||||
Uint32* dst = (Uint32*)(target.Pixels + y * target.Pitch) + min_x;
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
int tx = ImGui_ImplSDLSurface3_ClampInt((int)(u * (float)texture_max_x + 0.5f), 0, texture_max_x);
|
||||
int ty = ImGui_ImplSDLSurface3_ClampInt((int)(v * (float)texture_max_y + 0.5f), 0, texture_max_y);
|
||||
Uint8 out_r = color_r;
|
||||
Uint8 out_g = color_g;
|
||||
Uint8 out_b = color_b;
|
||||
Uint8 out_a = color_a;
|
||||
if (texture_is_font)
|
||||
{
|
||||
out_a = ImGui_ImplSDLSurface3_Mul255(out_a, ImGui_ImplSDLSurface3_ReadPixelAlpha(texture, tx, ty));
|
||||
ImGui_ImplSDLSurface3_BlendPixelFast(target, dst, out_r, out_g, out_b, out_a);
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint8 tr, tg, tb, ta;
|
||||
ImGui_ImplSDLSurface3_ReadPixelRGBA(texture, tx, ty, &tr, &tg, &tb, &ta);
|
||||
out_r = ImGui_ImplSDLSurface3_Mul255(out_r, tr);
|
||||
out_g = ImGui_ImplSDLSurface3_Mul255(out_g, tg);
|
||||
out_b = ImGui_ImplSDLSurface3_Mul255(out_b, tb);
|
||||
out_a = ImGui_ImplSDLSurface3_Mul255(out_a, ta);
|
||||
ImGui_ImplSDLSurface3_BlendPixelFast(target, dst, out_r, out_g, out_b, out_a);
|
||||
}
|
||||
dst++;
|
||||
u += du_dx;
|
||||
v += dv_dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface3_RenderTexturedRectGeneric(const ImGui_ImplSDLSurface3_SurfaceInfo& target, const ImGui_ImplSDLSurface3_SurfaceInfo& texture, bool texture_is_font, const ImGui_ImplSDLSurface3_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
int min_x = std::max((int)ceilf(quad.TL->X - 0.5f), clip_min_x);
|
||||
int max_x = std::min((int)floorf(quad.TR->X - 0.5f), clip_max_x - 1);
|
||||
int min_y = std::max((int)ceilf(quad.TL->Y - 0.5f), clip_min_y);
|
||||
int max_y = std::min((int)floorf(quad.BL->Y - 0.5f), clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
Uint8 color_r = (Uint8)quad.TL->R;
|
||||
Uint8 color_g = (Uint8)quad.TL->G;
|
||||
Uint8 color_b = (Uint8)quad.TL->B;
|
||||
Uint8 color_a = (Uint8)quad.TL->A;
|
||||
float du_dx = (quad.TR->U - quad.TL->U) / (quad.TR->X - quad.TL->X);
|
||||
float dv_dx = (quad.TR->V - quad.TL->V) / (quad.TR->X - quad.TL->X);
|
||||
float du_dy = (quad.BL->U - quad.TL->U) / (quad.BL->Y - quad.TL->Y);
|
||||
float dv_dy = (quad.BL->V - quad.TL->V) / (quad.BL->Y - quad.TL->Y);
|
||||
float u_const = quad.TL->U - quad.TL->X * du_dx - quad.TL->Y * du_dy;
|
||||
float v_const = quad.TL->V - quad.TL->X * dv_dx - quad.TL->Y * dv_dy;
|
||||
int texture_max_x = texture.Width - 1;
|
||||
int texture_max_y = texture.Height - 1;
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
float py = (float)y + 0.5f;
|
||||
float px = (float)min_x + 0.5f;
|
||||
float u = u_const + px * du_dx + py * du_dy;
|
||||
float v = v_const + px * dv_dx + py * dv_dy;
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
int tx = ImGui_ImplSDLSurface3_ClampInt((int)(u * (float)texture_max_x + 0.5f), 0, texture_max_x);
|
||||
int ty = ImGui_ImplSDLSurface3_ClampInt((int)(v * (float)texture_max_y + 0.5f), 0, texture_max_y);
|
||||
Uint8 out_r = color_r;
|
||||
Uint8 out_g = color_g;
|
||||
Uint8 out_b = color_b;
|
||||
Uint8 out_a = color_a;
|
||||
if (texture_is_font)
|
||||
{
|
||||
out_a = ImGui_ImplSDLSurface3_Mul255(out_a, ImGui_ImplSDLSurface3_ReadPixelAlpha(texture, tx, ty));
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint8 tr, tg, tb, ta;
|
||||
ImGui_ImplSDLSurface3_ReadPixelRGBA(texture, tx, ty, &tr, &tg, &tb, &ta);
|
||||
out_r = ImGui_ImplSDLSurface3_Mul255(out_r, tr);
|
||||
out_g = ImGui_ImplSDLSurface3_Mul255(out_g, tg);
|
||||
out_b = ImGui_ImplSDLSurface3_Mul255(out_b, tb);
|
||||
out_a = ImGui_ImplSDLSurface3_Mul255(out_a, ta);
|
||||
}
|
||||
ImGui_ImplSDLSurface3_BlendPixelGeneric(target, x, y, out_r, out_g, out_b, out_a);
|
||||
u += du_dx;
|
||||
v += dv_dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface3_TryRenderQuadFast(const ImGui_ImplSDLSurface3_SurfaceInfo& target, const ImGui_ImplSDLSurface3_SurfaceInfo* texture, bool texture_is_font, const ImGui_ImplSDLSurface3_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
if (!ImGui_ImplSDLSurface3_QuadHasConstantColor(quad))
|
||||
return false;
|
||||
|
||||
Uint8 r = (Uint8)quad.TL->R;
|
||||
Uint8 g = (Uint8)quad.TL->G;
|
||||
Uint8 b = (Uint8)quad.TL->B;
|
||||
Uint8 a = (Uint8)quad.TL->A;
|
||||
if (texture == nullptr)
|
||||
{
|
||||
ImGui_ImplSDLSurface3_RenderSolidRectFast(target, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y, r, g, b, a);
|
||||
return true;
|
||||
}
|
||||
|
||||
int tx = 0;
|
||||
int ty = 0;
|
||||
if (ImGui_ImplSDLSurface3_QuadGetConstantTexel(*texture, quad, &tx, &ty))
|
||||
{
|
||||
if (texture_is_font)
|
||||
{
|
||||
a = ImGui_ImplSDLSurface3_Mul255(a, ImGui_ImplSDLSurface3_ReadPixelAlpha(*texture, tx, ty));
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint8 tr, tg, tb, ta;
|
||||
ImGui_ImplSDLSurface3_ReadPixelRGBA(*texture, tx, ty, &tr, &tg, &tb, &ta);
|
||||
r = ImGui_ImplSDLSurface3_Mul255(r, tr);
|
||||
g = ImGui_ImplSDLSurface3_Mul255(g, tg);
|
||||
b = ImGui_ImplSDLSurface3_Mul255(b, tb);
|
||||
a = ImGui_ImplSDLSurface3_Mul255(a, ta);
|
||||
}
|
||||
ImGui_ImplSDLSurface3_RenderSolidRectFast(target, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y, r, g, b, a);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ImGui_ImplSDLSurface3_QuadHasLinearUV(quad))
|
||||
return false;
|
||||
ImGui_ImplSDLSurface3_RenderTexturedRectFast(target, *texture, texture_is_font, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface3_TryRenderQuadGeneric(const ImGui_ImplSDLSurface3_SurfaceInfo& target, const ImGui_ImplSDLSurface3_SurfaceInfo* texture, bool texture_is_font, const ImGui_ImplSDLSurface3_Quad& quad, int clip_min_x, int clip_min_y, int clip_max_x, int clip_max_y)
|
||||
{
|
||||
if (!ImGui_ImplSDLSurface3_QuadHasConstantColor(quad))
|
||||
return false;
|
||||
|
||||
Uint8 r = (Uint8)quad.TL->R;
|
||||
Uint8 g = (Uint8)quad.TL->G;
|
||||
Uint8 b = (Uint8)quad.TL->B;
|
||||
Uint8 a = (Uint8)quad.TL->A;
|
||||
if (texture == nullptr)
|
||||
{
|
||||
ImGui_ImplSDLSurface3_RenderSolidRectGeneric(target, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y, r, g, b, a);
|
||||
return true;
|
||||
}
|
||||
|
||||
int tx = 0;
|
||||
int ty = 0;
|
||||
if (ImGui_ImplSDLSurface3_QuadGetConstantTexel(*texture, quad, &tx, &ty))
|
||||
{
|
||||
if (texture_is_font)
|
||||
{
|
||||
a = ImGui_ImplSDLSurface3_Mul255(a, ImGui_ImplSDLSurface3_ReadPixelAlpha(*texture, tx, ty));
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint8 tr, tg, tb, ta;
|
||||
ImGui_ImplSDLSurface3_ReadPixelRGBA(*texture, tx, ty, &tr, &tg, &tb, &ta);
|
||||
r = ImGui_ImplSDLSurface3_Mul255(r, tr);
|
||||
g = ImGui_ImplSDLSurface3_Mul255(g, tg);
|
||||
b = ImGui_ImplSDLSurface3_Mul255(b, tb);
|
||||
a = ImGui_ImplSDLSurface3_Mul255(a, ta);
|
||||
}
|
||||
ImGui_ImplSDLSurface3_RenderSolidRectGeneric(target, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y, r, g, b, a);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ImGui_ImplSDLSurface3_QuadHasLinearUV(quad))
|
||||
return false;
|
||||
ImGui_ImplSDLSurface3_RenderTexturedRectGeneric(target, *texture, texture_is_font, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_Surface* ImGui_ImplSDLSurface3_CreateFontAtlasSurface()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -627,14 +1022,20 @@ void ImGui_ImplSDLSurface3_RenderDrawData(ImDrawData* draw_data)
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_Surface* active_texture_surface = nullptr;
|
||||
ImGui_ImplSDLSurface3_SurfaceInfo active_texture_info;
|
||||
bool active_texture_valid = false;
|
||||
bool active_texture_locked = false;
|
||||
bool active_texture_is_font = false;
|
||||
const ImVec2 clip_off = draw_data->DisplayPos;
|
||||
const ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
ImGui_ImplSDLSurface3_BuildVertexCache(&bd->VertexCache, draw_list, clip_off, clip_scale);
|
||||
const ImGui_ImplSDLSurface3_RasterVertex* vertex_cache = bd->VertexCache.Data;
|
||||
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
@@ -663,51 +1064,68 @@ void ImGui_ImplSDLSurface3_RenderDrawData(ImDrawData* draw_data)
|
||||
int clip_max_y = (int)clip_max.y;
|
||||
|
||||
SDL_Surface* texture_surface = (SDL_Surface*)pcmd->GetTexID();
|
||||
ImGui_ImplSDLSurface3_SurfaceInfo texture_info;
|
||||
ImGui_ImplSDLSurface3_SurfaceInfo* texture_ptr = nullptr;
|
||||
bool texture_locked = false;
|
||||
|
||||
if (texture_surface != nullptr)
|
||||
if (texture_surface != active_texture_surface)
|
||||
{
|
||||
if (SDL_MUSTLOCK(texture_surface))
|
||||
{
|
||||
if (!SDL_LockSurface(texture_surface))
|
||||
texture_surface = nullptr;
|
||||
else
|
||||
texture_locked = true;
|
||||
}
|
||||
if (active_texture_locked && active_texture_surface != nullptr)
|
||||
SDL_UnlockSurface(active_texture_surface);
|
||||
active_texture_surface = texture_surface;
|
||||
active_texture_valid = false;
|
||||
active_texture_locked = false;
|
||||
active_texture_is_font = false;
|
||||
if (texture_surface != nullptr)
|
||||
{
|
||||
ImGui_ImplSDLSurface3_InitSurfaceInfo(&texture_info, texture_surface);
|
||||
if (texture_info.Width > 0 && texture_info.Height > 0)
|
||||
texture_ptr = &texture_info;
|
||||
if (SDL_MUSTLOCK(texture_surface))
|
||||
{
|
||||
if (!SDL_LockSurface(texture_surface))
|
||||
active_texture_surface = texture_surface;
|
||||
else
|
||||
active_texture_locked = true;
|
||||
}
|
||||
if (!SDL_MUSTLOCK(texture_surface) || active_texture_locked)
|
||||
{
|
||||
ImGui_ImplSDLSurface3_InitSurfaceInfo(&active_texture_info, texture_surface);
|
||||
active_texture_valid = active_texture_info.Width > 0 && active_texture_info.Height > 0;
|
||||
active_texture_is_font = texture_surface == bd->FontSurface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int idx = 0; idx + 2 < (unsigned int)pcmd->ElemCount; idx += 3)
|
||||
const ImGui_ImplSDLSurface3_SurfaceInfo* texture_ptr = active_texture_valid ? &active_texture_info : nullptr;
|
||||
for (unsigned int idx = 0; idx + 2 < (unsigned int)pcmd->ElemCount;)
|
||||
{
|
||||
if (idx + 5 < (unsigned int)pcmd->ElemCount)
|
||||
{
|
||||
ImGui_ImplSDLSurface3_Quad quad;
|
||||
if (ImGui_ImplSDLSurface3_DetectQuad(vertex_cache, idx_buffer, pcmd->VtxOffset, pcmd->IdxOffset + idx, &quad))
|
||||
{
|
||||
bool rendered = bd->TargetInfo.IsFast
|
||||
? ImGui_ImplSDLSurface3_TryRenderQuadFast(bd->TargetInfo, texture_ptr, active_texture_is_font, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y)
|
||||
: ImGui_ImplSDLSurface3_TryRenderQuadGeneric(bd->TargetInfo, texture_ptr, active_texture_is_font, quad, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
if (rendered)
|
||||
{
|
||||
idx += 6;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImDrawIdx idx0 = idx_buffer[pcmd->IdxOffset + idx + 0];
|
||||
ImDrawIdx idx1 = idx_buffer[pcmd->IdxOffset + idx + 1];
|
||||
ImDrawIdx idx2 = idx_buffer[pcmd->IdxOffset + idx + 2];
|
||||
|
||||
ImGui_ImplSDLSurface3_RasterVertex v0;
|
||||
ImGui_ImplSDLSurface3_RasterVertex v1;
|
||||
ImGui_ImplSDLSurface3_RasterVertex v2;
|
||||
ImGui_ImplSDLSurface3_SetupRasterVertex(&v0, vtx_buffer[pcmd->VtxOffset + idx0], clip_off, clip_scale);
|
||||
ImGui_ImplSDLSurface3_SetupRasterVertex(&v1, vtx_buffer[pcmd->VtxOffset + idx1], clip_off, clip_scale);
|
||||
ImGui_ImplSDLSurface3_SetupRasterVertex(&v2, vtx_buffer[pcmd->VtxOffset + idx2], clip_off, clip_scale);
|
||||
|
||||
const ImGui_ImplSDLSurface3_RasterVertex& v0 = vertex_cache[pcmd->VtxOffset + idx0];
|
||||
const ImGui_ImplSDLSurface3_RasterVertex& v1 = vertex_cache[pcmd->VtxOffset + idx1];
|
||||
const ImGui_ImplSDLSurface3_RasterVertex& v2 = vertex_cache[pcmd->VtxOffset + idx2];
|
||||
if (bd->TargetInfo.IsFast)
|
||||
ImGui_ImplSDLSurface3_RenderTriangleFast(bd->TargetInfo, texture_ptr, v0, v1, v2, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
ImGui_ImplSDLSurface3_RenderTriangleFast(bd->TargetInfo, texture_ptr, active_texture_is_font, v0, v1, v2, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
else
|
||||
ImGui_ImplSDLSurface3_RenderTriangleGeneric(bd->TargetInfo, texture_ptr, v0, v1, v2, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
ImGui_ImplSDLSurface3_RenderTriangleGeneric(bd->TargetInfo, texture_ptr, active_texture_is_font, v0, v1, v2, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
idx += 3;
|
||||
}
|
||||
|
||||
if (texture_locked)
|
||||
SDL_UnlockSurface(texture_surface);
|
||||
}
|
||||
}
|
||||
|
||||
if (active_texture_locked && active_texture_surface != nullptr)
|
||||
SDL_UnlockSurface(active_texture_surface);
|
||||
if (SDL_MUSTLOCK(bd->TargetSurface))
|
||||
SDL_UnlockSurface(bd->TargetSurface);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS += -g -Wall -Wformat
|
||||
OPTFLAGS ?= -O2
|
||||
CXXFLAGS += -g $(OPTFLAGS) -Wall -Wformat
|
||||
LIBS =
|
||||
|
||||
##---------------------------------------------------------------------
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl2.cpp ..\..\backends\imgui_impl_sdlsurface2.cpp ..\..\imgui*.cpp
|
||||
@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib
|
||||
mkdir %OUT_DIR%
|
||||
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||
cl /nologo /Zi /O2 /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||
|
||||
@@ -7,7 +7,8 @@ OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS += -g -Wall -Wformat
|
||||
OPTFLAGS ?= -O2
|
||||
CXXFLAGS += -g $(OPTFLAGS) -Wall -Wformat
|
||||
LIBS =
|
||||
|
||||
ifeq ($(UNAME_S), Linux)
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_sdlsurface3.cpp ..\..\imgui*.cpp
|
||||
@set LIBS=/LIBPATH:%SDL3_DIR%\lib\x86 SDL3.lib
|
||||
mkdir %OUT_DIR%
|
||||
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||
cl /nologo /Zi /O2 /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||
|
||||
Reference in New Issue
Block a user