Add SDL3 surface backend for ImGui example
- Created imgui_impl_sdlsurface3.h and corresponding implementation file. - Added Makefile for building the SDL3 surface example on Linux and macOS. - Included README.md with build instructions for Windows, Linux, and macOS. - Added build script for Windows (build_win32.bat) and Visual Studio project files. - Implemented main application logic in main.cpp to demonstrate ImGui with SDL3 and surface rendering.
This commit is contained in:
+632
-241
@@ -1,324 +1,715 @@
|
||||
// imgui_impl_sdlsurface2.cpp
|
||||
// CPU-only SDL_Surface backend for Dear ImGui
|
||||
|
||||
#include "imgui_impl_sdlsurface2.h"
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include <SDL.h>
|
||||
#include <cstring>
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
// No clamp in C++11
|
||||
template<typename T>
|
||||
static inline T ImClamp(T v, T lo, T hi)
|
||||
struct ImGui_ImplSDLSurface2_FastFormat32
|
||||
{
|
||||
if (v < lo) return lo;
|
||||
if (v > hi) return hi;
|
||||
return v;
|
||||
Uint32 Rmask;
|
||||
Uint32 Gmask;
|
||||
Uint32 Bmask;
|
||||
Uint32 Amask;
|
||||
Uint8 Rshift;
|
||||
Uint8 Gshift;
|
||||
Uint8 Bshift;
|
||||
Uint8 Ashift;
|
||||
bool HasAlpha;
|
||||
bool Valid;
|
||||
|
||||
ImGui_ImplSDLSurface2_FastFormat32() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLSurface2_SurfaceInfo
|
||||
{
|
||||
SDL_Surface* Surface;
|
||||
Uint8* Pixels;
|
||||
int Pitch;
|
||||
int Width;
|
||||
int Height;
|
||||
SDL_PixelFormat* Format;
|
||||
SDL_Palette* Palette;
|
||||
ImGui_ImplSDLSurface2_FastFormat32 FastFormat;
|
||||
bool IsFast;
|
||||
|
||||
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;
|
||||
float Y;
|
||||
float U;
|
||||
float V;
|
||||
float R;
|
||||
float G;
|
||||
float B;
|
||||
float A;
|
||||
};
|
||||
|
||||
static ImGui_ImplSDLSurface2_Data* ImGui_ImplSDLSurface2_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLSurface2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
|
||||
static SDL_Surface* g_TargetSurface = nullptr;
|
||||
static SDL_Surface* g_FontSurface = nullptr;
|
||||
|
||||
static inline Uint32 GetPixel(SDL_Surface* s, int x, int y)
|
||||
static inline float ImGui_ImplSDLSurface2_Edge(float ax, float ay, float bx, float by, float px, float py)
|
||||
{
|
||||
Uint8* p = (Uint8*)s->pixels + y * s->pitch + x * s->format->BytesPerPixel;
|
||||
switch (s->format->BytesPerPixel)
|
||||
return (bx - ax) * (py - ay) - (by - ay) * (px - ax);
|
||||
}
|
||||
|
||||
static inline int ImGui_ImplSDLSurface2_ClampInt(int v, int lo, int hi)
|
||||
{
|
||||
return (v < lo) ? lo : (v > hi ? hi : v);
|
||||
}
|
||||
|
||||
static inline Uint8 ImGui_ImplSDLSurface2_ClampByte(float v)
|
||||
{
|
||||
if (v <= 0.0f)
|
||||
return 0;
|
||||
if (v >= 255.0f)
|
||||
return 255;
|
||||
return (Uint8)(v + 0.5f);
|
||||
}
|
||||
|
||||
static inline Uint8 ImGui_ImplSDLSurface2_Mul255(Uint32 a, Uint32 b)
|
||||
{
|
||||
Uint32 t = a * b + 128;
|
||||
return (Uint8)((t + (t >> 8)) >> 8);
|
||||
}
|
||||
|
||||
static ImGui_ImplSDLSurface2_FastFormat32 ImGui_ImplSDLSurface2_BuildFastFormat(SDL_PixelFormat* format)
|
||||
{
|
||||
ImGui_ImplSDLSurface2_FastFormat32 out;
|
||||
if (format == nullptr)
|
||||
return out;
|
||||
if (format->BitsPerPixel != 32 || format->BytesPerPixel != 4)
|
||||
return out;
|
||||
if (format->Rloss != 0 || format->Gloss != 0 || format->Bloss != 0)
|
||||
return out;
|
||||
if (format->Amask != 0 && format->Aloss != 0)
|
||||
return out;
|
||||
out.Rmask = format->Rmask;
|
||||
out.Gmask = format->Gmask;
|
||||
out.Bmask = format->Bmask;
|
||||
out.Amask = format->Amask;
|
||||
out.Rshift = format->Rshift;
|
||||
out.Gshift = format->Gshift;
|
||||
out.Bshift = format->Bshift;
|
||||
out.Ashift = format->Ashift;
|
||||
out.HasAlpha = format->Amask != 0;
|
||||
out.Valid = true;
|
||||
return out;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface2_CanUseFastPath(SDL_Surface* surface, const ImGui_ImplSDLSurface2_FastFormat32& format)
|
||||
{
|
||||
#ifdef IMGUI_IMPL_SDLSURFACE_DISABLE_FAST_PATH
|
||||
IM_UNUSED(surface);
|
||||
IM_UNUSED(format);
|
||||
return false;
|
||||
#else
|
||||
if (surface == nullptr || !format.Valid)
|
||||
return false;
|
||||
if ((surface->pitch & 3) != 0)
|
||||
return false;
|
||||
if ((((uintptr_t)surface->pixels) & 3) != 0)
|
||||
return false;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface2_InitSurfaceInfo(ImGui_ImplSDLSurface2_SurfaceInfo* out, SDL_Surface* surface)
|
||||
{
|
||||
out->Surface = surface;
|
||||
out->Pixels = surface ? (Uint8*)surface->pixels : nullptr;
|
||||
out->Pitch = surface ? surface->pitch : 0;
|
||||
out->Width = surface ? surface->w : 0;
|
||||
out->Height = surface ? surface->h : 0;
|
||||
out->Format = surface ? surface->format : nullptr;
|
||||
out->Palette = (surface && surface->format) ? surface->format->palette : nullptr;
|
||||
out->FastFormat = ImGui_ImplSDLSurface2_BuildFastFormat(out->Format);
|
||||
out->IsFast = ImGui_ImplSDLSurface2_CanUseFastPath(surface, out->FastFormat);
|
||||
}
|
||||
|
||||
static inline Uint32 ImGui_ImplSDLSurface2_ReadPixelRaw(const ImGui_ImplSDLSurface2_SurfaceInfo& surface, int x, int y)
|
||||
{
|
||||
const Uint8* p = surface.Pixels + y * surface.Pitch + x * surface.Format->BytesPerPixel;
|
||||
switch (surface.Format->BytesPerPixel)
|
||||
{
|
||||
case 1: return *p;
|
||||
case 2: return *(Uint16*)p;
|
||||
case 3:
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
return (p[0] << 16) | (p[1] << 8) | p[2];
|
||||
else
|
||||
return p[0] | (p[1] << 8) | (p[2] << 16);
|
||||
case 4: return *(Uint32*)p;
|
||||
case 1:
|
||||
return *p;
|
||||
case 2:
|
||||
return *(const Uint16*)p;
|
||||
case 3:
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
return (Uint32)((p[0] << 16) | (p[1] << 8) | p[2]);
|
||||
return (Uint32)(p[0] | (p[1] << 8) | (p[2] << 16));
|
||||
case 4:
|
||||
return *(const Uint32*)p;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void BlendPixel(SDL_Surface* s, int x, int y,
|
||||
Uint8 sr, Uint8 sg, Uint8 sb, Uint8 sa)
|
||||
static inline void ImGui_ImplSDLSurface2_WritePixelRaw(const ImGui_ImplSDLSurface2_SurfaceInfo& surface, int x, int y, Uint32 pixel)
|
||||
{
|
||||
if (!s || sa == 0) return;
|
||||
if (x < 0 || y < 0 || x >= s->w || y >= s->h) return;
|
||||
|
||||
if (sa == 255)
|
||||
Uint8* p = surface.Pixels + y * surface.Pitch + x * surface.Format->BytesPerPixel;
|
||||
switch (surface.Format->BytesPerPixel)
|
||||
{
|
||||
Uint32 out_pix = SDL_MapRGBA(s->format, sr, sg, sb, sa);
|
||||
Uint8* p = (Uint8*)s->pixels + y * s->pitch + x * s->format->BytesPerPixel;
|
||||
switch (s->format->BytesPerPixel)
|
||||
case 1:
|
||||
*p = (Uint8)pixel;
|
||||
return;
|
||||
case 2:
|
||||
*(Uint16*)p = (Uint16)pixel;
|
||||
return;
|
||||
case 3:
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
{
|
||||
case 1: *p = (Uint8)out_pix; break;
|
||||
case 2: *(Uint16*)p = (Uint16)out_pix; break;
|
||||
case 3:
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
{
|
||||
p[0] = (out_pix >> 16) & 0xFF;
|
||||
p[1] = (out_pix >> 8) & 0xFF;
|
||||
p[2] = out_pix & 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
p[0] = out_pix & 0xFF;
|
||||
p[1] = (out_pix >> 8) & 0xFF;
|
||||
p[2] = (out_pix >> 16) & 0xFF;
|
||||
}
|
||||
break;
|
||||
case 4: *(Uint32*)p = out_pix; break;
|
||||
p[0] = (Uint8)((pixel >> 16) & 0xFF);
|
||||
p[1] = (Uint8)((pixel >> 8) & 0xFF);
|
||||
p[2] = (Uint8)(pixel & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
p[0] = (Uint8)(pixel & 0xFF);
|
||||
p[1] = (Uint8)((pixel >> 8) & 0xFF);
|
||||
p[2] = (Uint8)((pixel >> 16) & 0xFF);
|
||||
}
|
||||
return;
|
||||
case 4:
|
||||
*(Uint32*)p = pixel;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ImGui_ImplSDLSurface2_UnpackFastRGBA(const ImGui_ImplSDLSurface2_FastFormat32& format, Uint32 pixel, Uint8* r, Uint8* g, Uint8* b, Uint8* a)
|
||||
{
|
||||
*r = (Uint8)((pixel & format.Rmask) >> format.Rshift);
|
||||
*g = (Uint8)((pixel & format.Gmask) >> format.Gshift);
|
||||
*b = (Uint8)((pixel & format.Bmask) >> format.Bshift);
|
||||
*a = format.HasAlpha ? (Uint8)((pixel & format.Amask) >> format.Ashift) : 255;
|
||||
}
|
||||
|
||||
static inline Uint32 ImGui_ImplSDLSurface2_PackFastRGBA(const ImGui_ImplSDLSurface2_FastFormat32& format, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
{
|
||||
Uint32 pixel = (((Uint32)r << format.Rshift) & format.Rmask)
|
||||
| (((Uint32)g << format.Gshift) & format.Gmask)
|
||||
| (((Uint32)b << format.Bshift) & format.Bmask);
|
||||
if (format.HasAlpha)
|
||||
pixel |= (((Uint32)a << format.Ashift) & format.Amask);
|
||||
return pixel;
|
||||
}
|
||||
|
||||
static inline void ImGui_ImplSDLSurface2_ReadPixelRGBA(const ImGui_ImplSDLSurface2_SurfaceInfo& surface, int x, int y, Uint8* r, Uint8* g, Uint8* b, Uint8* a)
|
||||
{
|
||||
if (surface.IsFast)
|
||||
{
|
||||
const Uint32* src = (const Uint32*)(surface.Pixels + y * surface.Pitch) + x;
|
||||
ImGui_ImplSDLSurface2_UnpackFastRGBA(surface.FastFormat, *src, r, g, b, a);
|
||||
return;
|
||||
}
|
||||
|
||||
Uint32 dst_pix = GetPixel(s, x, y);
|
||||
Uint8 dr, dg, db, da;
|
||||
SDL_GetRGBA(dst_pix, s->format, &dr, &dg, &db, &da);
|
||||
Uint32 pixel = ImGui_ImplSDLSurface2_ReadPixelRaw(surface, x, y);
|
||||
SDL_GetRGBA(pixel, surface.Format, r, g, b, a);
|
||||
}
|
||||
|
||||
Uint8 out_r = (Uint8)((sr * sa + dr * (255 - sa)) / 255);
|
||||
Uint8 out_g = (Uint8)((sg * sa + dg * (255 - sa)) / 255);
|
||||
Uint8 out_b = (Uint8)((sb * sa + db * (255 - sa)) / 255);
|
||||
Uint8 out_a = (Uint8)((sa + (da * (255 - sa)) / 255));
|
||||
|
||||
Uint32 out_pix = SDL_MapRGBA(s->format, out_r, out_g, out_b, out_a);
|
||||
Uint8* p = (Uint8*)s->pixels + y * s->pitch + x * s->format->BytesPerPixel;
|
||||
switch (s->format->BytesPerPixel)
|
||||
static inline void ImGui_ImplSDLSurface2_BlendPixelFast(const ImGui_ImplSDLSurface2_SurfaceInfo& target, Uint32* dst, Uint8 sr, Uint8 sg, Uint8 sb, Uint8 sa)
|
||||
{
|
||||
if (sa == 0)
|
||||
return;
|
||||
if (sa == 255)
|
||||
{
|
||||
case 1: *p = (Uint8)out_pix; break;
|
||||
case 2: *(Uint16*)p = (Uint16)out_pix; break;
|
||||
case 3:
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
*dst = ImGui_ImplSDLSurface2_PackFastRGBA(target.FastFormat, sr, sg, sb, 255);
|
||||
return;
|
||||
}
|
||||
|
||||
Uint8 dr, dg, db, da;
|
||||
ImGui_ImplSDLSurface2_UnpackFastRGBA(target.FastFormat, *dst, &dr, &dg, &db, &da);
|
||||
Uint8 inv_a = (Uint8)(255 - sa);
|
||||
Uint8 out_r = (Uint8)(ImGui_ImplSDLSurface2_Mul255(sr, sa) + ImGui_ImplSDLSurface2_Mul255(dr, inv_a));
|
||||
Uint8 out_g = (Uint8)(ImGui_ImplSDLSurface2_Mul255(sg, sa) + ImGui_ImplSDLSurface2_Mul255(dg, inv_a));
|
||||
Uint8 out_b = (Uint8)(ImGui_ImplSDLSurface2_Mul255(sb, sa) + ImGui_ImplSDLSurface2_Mul255(db, inv_a));
|
||||
Uint8 out_a = target.FastFormat.HasAlpha ? (Uint8)(sa + ImGui_ImplSDLSurface2_Mul255(da, inv_a)) : 255;
|
||||
*dst = ImGui_ImplSDLSurface2_PackFastRGBA(target.FastFormat, out_r, out_g, out_b, out_a);
|
||||
}
|
||||
|
||||
static inline void ImGui_ImplSDLSurface2_BlendPixelGeneric(const ImGui_ImplSDLSurface2_SurfaceInfo& target, int x, int y, Uint8 sr, Uint8 sg, Uint8 sb, Uint8 sa)
|
||||
{
|
||||
if (sa == 0)
|
||||
return;
|
||||
if (sa == 255)
|
||||
{
|
||||
Uint32 pixel = SDL_MapRGBA(target.Format, sr, sg, sb, 255);
|
||||
ImGui_ImplSDLSurface2_WritePixelRaw(target, x, y, pixel);
|
||||
return;
|
||||
}
|
||||
|
||||
Uint8 dr, dg, db, da;
|
||||
Uint32 dst_pixel = ImGui_ImplSDLSurface2_ReadPixelRaw(target, x, y);
|
||||
SDL_GetRGBA(dst_pixel, target.Format, &dr, &dg, &db, &da);
|
||||
Uint8 inv_a = (Uint8)(255 - sa);
|
||||
Uint8 out_r = (Uint8)(ImGui_ImplSDLSurface2_Mul255(sr, sa) + ImGui_ImplSDLSurface2_Mul255(dr, inv_a));
|
||||
Uint8 out_g = (Uint8)(ImGui_ImplSDLSurface2_Mul255(sg, sa) + ImGui_ImplSDLSurface2_Mul255(dg, inv_a));
|
||||
Uint8 out_b = (Uint8)(ImGui_ImplSDLSurface2_Mul255(sb, sa) + ImGui_ImplSDLSurface2_Mul255(db, inv_a));
|
||||
Uint8 out_a = target.Format->Amask ? (Uint8)(sa + ImGui_ImplSDLSurface2_Mul255(da, inv_a)) : 255;
|
||||
Uint32 pixel = SDL_MapRGBA(target.Format, out_r, out_g, out_b, out_a);
|
||||
ImGui_ImplSDLSurface2_WritePixelRaw(target, x, y, pixel);
|
||||
}
|
||||
|
||||
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;
|
||||
out->Y = (v.pos.y - display_pos.y) * framebuffer_scale.y;
|
||||
out->U = v.uv.x;
|
||||
out->V = v.uv.y;
|
||||
out->R = (float)((v.col >> IM_COL32_R_SHIFT) & 0xFF);
|
||||
out->G = (float)((v.col >> IM_COL32_G_SHIFT) & 0xFF);
|
||||
out->B = (float)((v.col >> IM_COL32_B_SHIFT) & 0xFF);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
int max_y = std::min((int)std::ceil(std::max(v0.Y, std::max(v1.Y, v2.Y))) - 1, clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
float area = ImGui_ImplSDLSurface2_Edge(v0.X, v0.Y, v1.X, v1.Y, v2.X, v2.Y);
|
||||
if (area == 0.0f)
|
||||
return;
|
||||
|
||||
float sign = (area < 0.0f) ? -1.0f : 1.0f;
|
||||
area *= sign;
|
||||
|
||||
float e0_dx = (v1.Y - v2.Y) * sign;
|
||||
float e0_dy = (v2.X - v1.X) * sign;
|
||||
float e1_dx = (v2.Y - v0.Y) * sign;
|
||||
float e1_dy = (v0.X - v2.X) * sign;
|
||||
float e2_dx = (v0.Y - v1.Y) * sign;
|
||||
float e2_dy = (v1.X - v0.X) * sign;
|
||||
|
||||
float inv_area = 1.0f / area;
|
||||
float dw0_dx = e0_dx * inv_area;
|
||||
float dw0_dy = e0_dy * inv_area;
|
||||
float dw1_dx = e1_dx * inv_area;
|
||||
float dw1_dy = e1_dy * inv_area;
|
||||
float dw2_dx = e2_dx * inv_area;
|
||||
float dw2_dy = e2_dy * inv_area;
|
||||
|
||||
float dr_dx = dw0_dx * v0.R + dw1_dx * v1.R + dw2_dx * v2.R;
|
||||
float dg_dx = dw0_dx * v0.G + dw1_dx * v1.G + dw2_dx * v2.G;
|
||||
float db_dx = dw0_dx * v0.B + dw1_dx * v1.B + dw2_dx * v2.B;
|
||||
float da_dx = dw0_dx * v0.A + dw1_dx * v1.A + dw2_dx * v2.A;
|
||||
float du_dx = dw0_dx * v0.U + dw1_dx * v1.U + dw2_dx * v2.U;
|
||||
float dv_dx = dw0_dx * v0.V + dw1_dx * v1.V + dw2_dx * v2.V;
|
||||
|
||||
float dr_dy = dw0_dy * v0.R + dw1_dy * v1.R + dw2_dy * v2.R;
|
||||
float dg_dy = dw0_dy * v0.G + dw1_dy * v1.G + dw2_dy * v2.G;
|
||||
float db_dy = dw0_dy * v0.B + dw1_dy * v1.B + dw2_dy * v2.B;
|
||||
float da_dy = dw0_dy * v0.A + dw1_dy * v1.A + dw2_dy * v2.A;
|
||||
float du_dy = dw0_dy * v0.U + dw1_dy * v1.U + dw2_dy * v2.U;
|
||||
float dv_dy = dw0_dy * v0.V + dw1_dy * v1.V + dw2_dy * v2.V;
|
||||
|
||||
float start_x = (float)min_x + 0.5f;
|
||||
float start_y = (float)min_y + 0.5f;
|
||||
|
||||
float e0_row = ImGui_ImplSDLSurface2_Edge(v1.X, v1.Y, v2.X, v2.Y, start_x, start_y) * sign;
|
||||
float e1_row = ImGui_ImplSDLSurface2_Edge(v2.X, v2.Y, v0.X, v0.Y, start_x, start_y) * sign;
|
||||
float e2_row = ImGui_ImplSDLSurface2_Edge(v0.X, v0.Y, v1.X, v1.Y, start_x, start_y) * sign;
|
||||
|
||||
float w0_row = e0_row * inv_area;
|
||||
float w1_row = e1_row * inv_area;
|
||||
float w2_row = e2_row * inv_area;
|
||||
|
||||
float r_row = w0_row * v0.R + w1_row * v1.R + w2_row * v2.R;
|
||||
float g_row = w0_row * v0.G + w1_row * v1.G + w2_row * v2.G;
|
||||
float b_row = w0_row * v0.B + w1_row * v1.B + w2_row * v2.B;
|
||||
float a_row = w0_row * v0.A + w1_row * v1.A + w2_row * v2.A;
|
||||
float u_row = w0_row * v0.U + w1_row * v1.U + w2_row * v2.U;
|
||||
float v_row = w0_row * v0.V + w1_row * v1.V + w2_row * v2.V;
|
||||
|
||||
int texture_max_x = texture ? (texture->Width - 1) : 0;
|
||||
int texture_max_y = texture ? (texture->Height - 1) : 0;
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
float e0 = e0_row;
|
||||
float e1 = e1_row;
|
||||
float e2 = e2_row;
|
||||
float r = r_row;
|
||||
float g = g_row;
|
||||
float b = b_row;
|
||||
float a = a_row;
|
||||
float u = u_row;
|
||||
float v = v_row;
|
||||
Uint32* dst = (Uint32*)(target.Pixels + y * target.Pitch) + min_x;
|
||||
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
if (e0 >= 0.0f && e1 >= 0.0f && e2 >= 0.0f)
|
||||
{
|
||||
p[0] = (out_pix >> 16) & 0xFF;
|
||||
p[1] = (out_pix >> 8) & 0xFF;
|
||||
p[2] = out_pix & 0xFF;
|
||||
Uint8 out_r = ImGui_ImplSDLSurface2_ClampByte(r);
|
||||
Uint8 out_g = ImGui_ImplSDLSurface2_ClampByte(g);
|
||||
Uint8 out_b = ImGui_ImplSDLSurface2_ClampByte(b);
|
||||
Uint8 out_a = ImGui_ImplSDLSurface2_ClampByte(a);
|
||||
|
||||
if (texture != nullptr)
|
||||
{
|
||||
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 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
p[0] = out_pix & 0xFF;
|
||||
p[1] = (out_pix >> 8) & 0xFF;
|
||||
p[2] = (out_pix >> 16) & 0xFF;
|
||||
}
|
||||
break;
|
||||
case 4: *(Uint32*)p = out_pix; break;
|
||||
|
||||
dst++;
|
||||
e0 += e0_dx;
|
||||
e1 += e1_dx;
|
||||
e2 += e2_dx;
|
||||
r += dr_dx;
|
||||
g += dg_dx;
|
||||
b += db_dx;
|
||||
a += da_dx;
|
||||
u += du_dx;
|
||||
v += dv_dx;
|
||||
}
|
||||
|
||||
e0_row += e0_dy;
|
||||
e1_row += e1_dy;
|
||||
e2_row += e2_dy;
|
||||
r_row += dr_dy;
|
||||
g_row += dg_dy;
|
||||
b_row += db_dy;
|
||||
a_row += da_dy;
|
||||
u_row += du_dy;
|
||||
v_row += dv_dy;
|
||||
}
|
||||
}
|
||||
|
||||
static inline float Edge(const ImVec2& a, const ImVec2& b, float x, float y)
|
||||
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)
|
||||
{
|
||||
return (b.x - a.x) * (y - a.y) - (b.y - a.y) * (x - a.x);
|
||||
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);
|
||||
int max_y = std::min((int)std::ceil(std::max(v0.Y, std::max(v1.Y, v2.Y))) - 1, clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
float area = ImGui_ImplSDLSurface2_Edge(v0.X, v0.Y, v1.X, v1.Y, v2.X, v2.Y);
|
||||
if (area == 0.0f)
|
||||
return;
|
||||
|
||||
float sign = (area < 0.0f) ? -1.0f : 1.0f;
|
||||
area *= sign;
|
||||
|
||||
float e0_dx = (v1.Y - v2.Y) * sign;
|
||||
float e0_dy = (v2.X - v1.X) * sign;
|
||||
float e1_dx = (v2.Y - v0.Y) * sign;
|
||||
float e1_dy = (v0.X - v2.X) * sign;
|
||||
float e2_dx = (v0.Y - v1.Y) * sign;
|
||||
float e2_dy = (v1.X - v0.X) * sign;
|
||||
|
||||
float inv_area = 1.0f / area;
|
||||
float dw0_dx = e0_dx * inv_area;
|
||||
float dw0_dy = e0_dy * inv_area;
|
||||
float dw1_dx = e1_dx * inv_area;
|
||||
float dw1_dy = e1_dy * inv_area;
|
||||
float dw2_dx = e2_dx * inv_area;
|
||||
float dw2_dy = e2_dy * inv_area;
|
||||
|
||||
float dr_dx = dw0_dx * v0.R + dw1_dx * v1.R + dw2_dx * v2.R;
|
||||
float dg_dx = dw0_dx * v0.G + dw1_dx * v1.G + dw2_dx * v2.G;
|
||||
float db_dx = dw0_dx * v0.B + dw1_dx * v1.B + dw2_dx * v2.B;
|
||||
float da_dx = dw0_dx * v0.A + dw1_dx * v1.A + dw2_dx * v2.A;
|
||||
float du_dx = dw0_dx * v0.U + dw1_dx * v1.U + dw2_dx * v2.U;
|
||||
float dv_dx = dw0_dx * v0.V + dw1_dx * v1.V + dw2_dx * v2.V;
|
||||
|
||||
float dr_dy = dw0_dy * v0.R + dw1_dy * v1.R + dw2_dy * v2.R;
|
||||
float dg_dy = dw0_dy * v0.G + dw1_dy * v1.G + dw2_dy * v2.G;
|
||||
float db_dy = dw0_dy * v0.B + dw1_dy * v1.B + dw2_dy * v2.B;
|
||||
float da_dy = dw0_dy * v0.A + dw1_dy * v1.A + dw2_dy * v2.A;
|
||||
float du_dy = dw0_dy * v0.U + dw1_dy * v1.U + dw2_dy * v2.U;
|
||||
float dv_dy = dw0_dy * v0.V + dw1_dy * v1.V + dw2_dy * v2.V;
|
||||
|
||||
float start_x = (float)min_x + 0.5f;
|
||||
float start_y = (float)min_y + 0.5f;
|
||||
|
||||
float e0_row = ImGui_ImplSDLSurface2_Edge(v1.X, v1.Y, v2.X, v2.Y, start_x, start_y) * sign;
|
||||
float e1_row = ImGui_ImplSDLSurface2_Edge(v2.X, v2.Y, v0.X, v0.Y, start_x, start_y) * sign;
|
||||
float e2_row = ImGui_ImplSDLSurface2_Edge(v0.X, v0.Y, v1.X, v1.Y, start_x, start_y) * sign;
|
||||
|
||||
float w0_row = e0_row * inv_area;
|
||||
float w1_row = e1_row * inv_area;
|
||||
float w2_row = e2_row * inv_area;
|
||||
|
||||
float r_row = w0_row * v0.R + w1_row * v1.R + w2_row * v2.R;
|
||||
float g_row = w0_row * v0.G + w1_row * v1.G + w2_row * v2.G;
|
||||
float b_row = w0_row * v0.B + w1_row * v1.B + w2_row * v2.B;
|
||||
float a_row = w0_row * v0.A + w1_row * v1.A + w2_row * v2.A;
|
||||
float u_row = w0_row * v0.U + w1_row * v1.U + w2_row * v2.U;
|
||||
float v_row = w0_row * v0.V + w1_row * v1.V + w2_row * v2.V;
|
||||
|
||||
int texture_max_x = texture ? (texture->Width - 1) : 0;
|
||||
int texture_max_y = texture ? (texture->Height - 1) : 0;
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
float e0 = e0_row;
|
||||
float e1 = e1_row;
|
||||
float e2 = e2_row;
|
||||
float r = r_row;
|
||||
float g = g_row;
|
||||
float b = b_row;
|
||||
float a = a_row;
|
||||
float u = u_row;
|
||||
float v = v_row;
|
||||
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
if (e0 >= 0.0f && e1 >= 0.0f && e2 >= 0.0f)
|
||||
{
|
||||
Uint8 out_r = ImGui_ImplSDLSurface2_ClampByte(r);
|
||||
Uint8 out_g = ImGui_ImplSDLSurface2_ClampByte(g);
|
||||
Uint8 out_b = ImGui_ImplSDLSurface2_ClampByte(b);
|
||||
Uint8 out_a = ImGui_ImplSDLSurface2_ClampByte(a);
|
||||
|
||||
if (texture != nullptr)
|
||||
{
|
||||
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 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);
|
||||
}
|
||||
|
||||
e0 += e0_dx;
|
||||
e1 += e1_dx;
|
||||
e2 += e2_dx;
|
||||
r += dr_dx;
|
||||
g += dg_dx;
|
||||
b += db_dx;
|
||||
a += da_dx;
|
||||
u += du_dx;
|
||||
v += dv_dx;
|
||||
}
|
||||
|
||||
e0_row += e0_dy;
|
||||
e1_row += e1_dy;
|
||||
e2_row += e2_dy;
|
||||
r_row += dr_dy;
|
||||
g_row += dg_dy;
|
||||
b_row += db_dy;
|
||||
a_row += da_dy;
|
||||
u_row += du_dy;
|
||||
v_row += dv_dy;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Surface* ImGui_ImplSDLSurface2_CreateFontAtlasSurface()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
unsigned char* pixels = nullptr;
|
||||
int width = 0, height = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
if (!pixels || width <= 0 || height <= 0) return nullptr;
|
||||
if (pixels == nullptr || width <= 0 || height <= 0)
|
||||
return nullptr;
|
||||
|
||||
SDL_Surface* surf = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_RGBA32);
|
||||
if (!surf) return nullptr;
|
||||
SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_RGBA32);
|
||||
if (surface == nullptr)
|
||||
return nullptr;
|
||||
if (SDL_MUSTLOCK(surface) && SDL_LockSurface(surface) != 0)
|
||||
{
|
||||
SDL_FreeSurface(surface);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SDL_LockSurface(surf);
|
||||
std::memcpy(surf->pixels, pixels, width * height * 4);
|
||||
SDL_UnlockSurface(surf);
|
||||
SDL_SetSurfaceBlendMode(surf, SDL_BLENDMODE_NONE);
|
||||
return surf;
|
||||
for (int y = 0; y < height; y++)
|
||||
memcpy((Uint8*)surface->pixels + y * surface->pitch, pixels + (size_t)y * (size_t)width * 4, (size_t)width * 4);
|
||||
|
||||
if (SDL_MUSTLOCK(surface))
|
||||
SDL_UnlockSurface(surface);
|
||||
|
||||
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
|
||||
return surface;
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLSurface2_Init(SDL_Surface* surface)
|
||||
{
|
||||
if (!surface) return false;
|
||||
if (surface == nullptr)
|
||||
return false;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererName == nullptr && "Already initialized a renderer backend!");
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
ImGui_ImplSDLSurface2_Data* bd = IM_NEW(ImGui_ImplSDLSurface2_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_sdlsurface2";
|
||||
|
||||
g_TargetSurface = surface;
|
||||
g_FontSurface = ImGui_ImplSDLSurface2_CreateFontAtlasSurface();
|
||||
if (g_FontSurface)
|
||||
{
|
||||
if (g_TargetSurface && g_FontSurface->format->format != g_TargetSurface->format->format)
|
||||
{
|
||||
SDL_Surface* converted = SDL_ConvertSurfaceFormat(g_FontSurface, g_TargetSurface->format->format, 0);
|
||||
if (converted)
|
||||
{
|
||||
SDL_FreeSurface(g_FontSurface);
|
||||
g_FontSurface = converted;
|
||||
}
|
||||
}
|
||||
ImGui::GetIO().Fonts->TexID = (ImTextureID)g_FontSurface;
|
||||
}
|
||||
bd->TargetSurface = surface;
|
||||
ImGui_ImplSDLSurface2_InitSurfaceInfo(&bd->TargetInfo, surface);
|
||||
bd->FontSurface = ImGui_ImplSDLSurface2_CreateFontAtlasSurface();
|
||||
if (bd->FontSurface != nullptr)
|
||||
io.Fonts->TexID = (ImTextureID)bd->FontSurface;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLSurface2_Shutdown()
|
||||
{
|
||||
ImGui_ImplSDLSurface2_Data* bd = ImGui_ImplSDLSurface2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasTextures;
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui::GetIO().Fonts->TexID = nullptr;
|
||||
if (g_FontSurface)
|
||||
{
|
||||
SDL_FreeSurface(g_FontSurface);
|
||||
g_FontSurface = nullptr;
|
||||
}
|
||||
g_TargetSurface = nullptr;
|
||||
io.Fonts->TexID = nullptr;
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
platform_io.ClearRendererHandlers();
|
||||
|
||||
if (bd->FontSurface != nullptr)
|
||||
SDL_FreeSurface(bd->FontSurface);
|
||||
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLSurface2_NewFrame()
|
||||
{
|
||||
// noop
|
||||
ImGui_ImplSDLSurface2_Data* bd = ImGui_ImplSDLSurface2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLSurface2_Init()?");
|
||||
IM_UNUSED(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLSurface2_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
if (!draw_data || !g_TargetSurface) return;
|
||||
ImGui_ImplSDLSurface2_Data* bd = ImGui_ImplSDLSurface2_GetBackendData();
|
||||
if (bd == nullptr || draw_data == nullptr || bd->TargetSurface == nullptr)
|
||||
return;
|
||||
|
||||
if (SDL_MUSTLOCK(g_TargetSurface)) SDL_LockSurface(g_TargetSurface);
|
||||
if (SDL_MUSTLOCK(bd->TargetSurface) && SDL_LockSurface(bd->TargetSurface) != 0)
|
||||
return;
|
||||
|
||||
const ImVec2 display_pos = draw_data->DisplayPos;
|
||||
const ImVec2 fb_scale = draw_data->FramebufferScale;
|
||||
ImGui_ImplSDLSurface2_InitSurfaceInfo(&bd->TargetInfo, bd->TargetSurface);
|
||||
if (bd->TargetInfo.Width <= 0 || bd->TargetInfo.Height <= 0)
|
||||
{
|
||||
if (SDL_MUSTLOCK(bd->TargetSurface))
|
||||
SDL_UnlockSurface(bd->TargetSurface);
|
||||
return;
|
||||
}
|
||||
|
||||
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* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
|
||||
int idx_offset = 0;
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
if (pcmd->UserCallback != ImDrawCallback_ResetRenderState)
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
continue;
|
||||
}
|
||||
if (pcmd->ElemCount == 0)
|
||||
continue;
|
||||
|
||||
ImVec2 clip_min = ImVec2(
|
||||
(pcmd->ClipRect.x - display_pos.x) * fb_scale.x,
|
||||
(pcmd->ClipRect.y - display_pos.y) * fb_scale.y);
|
||||
ImVec2 clip_max = ImVec2(
|
||||
(pcmd->ClipRect.z - display_pos.x) * fb_scale.x,
|
||||
(pcmd->ClipRect.w - display_pos.y) * fb_scale.y);
|
||||
|
||||
int cx0 = (int)std::floor(clip_min.x);
|
||||
int cy0 = (int)std::floor(clip_min.y);
|
||||
int cx1 = (int)std::ceil (clip_max.x);
|
||||
int cy1 = (int)std::ceil (clip_max.y);
|
||||
|
||||
cx0 = std::max(cx0, 0);
|
||||
cy0 = std::max(cy0, 0);
|
||||
cx1 = std::min(cx1, g_TargetSurface->w);
|
||||
cy1 = std::min(cy1, g_TargetSurface->h);
|
||||
|
||||
if (cx0 >= cx1 || cy0 >= cy1)
|
||||
{
|
||||
idx_offset += pcmd->ElemCount;
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
if (clip_min.x < 0.0f) clip_min.x = 0.0f;
|
||||
if (clip_min.y < 0.0f) clip_min.y = 0.0f;
|
||||
if (clip_max.x > (float)bd->TargetInfo.Width) clip_max.x = (float)bd->TargetInfo.Width;
|
||||
if (clip_max.y > (float)bd->TargetInfo.Height) clip_max.y = (float)bd->TargetInfo.Height;
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
}
|
||||
|
||||
SDL_Rect srect{ cx0, cy0, cx1 - cx0, cy1 - cy0 };
|
||||
SDL_SetClipRect(g_TargetSurface, &srect);
|
||||
int clip_min_x = (int)clip_min.x;
|
||||
int clip_min_y = (int)clip_min.y;
|
||||
int clip_max_x = (int)clip_max.x;
|
||||
int clip_max_y = (int)clip_max.y;
|
||||
|
||||
SDL_Surface* tex = (SDL_Surface*)pcmd->GetTexID();
|
||||
SDL_Surface* texture_surface = (SDL_Surface*)pcmd->GetTexID();
|
||||
ImGui_ImplSDLSurface2_SurfaceInfo texture_info;
|
||||
ImGui_ImplSDLSurface2_SurfaceInfo* texture_ptr = nullptr;
|
||||
bool texture_locked = false;
|
||||
|
||||
for (unsigned int i = 0; i + 2 < (unsigned int)pcmd->ElemCount; i += 3)
|
||||
if (texture_surface != nullptr)
|
||||
{
|
||||
ImDrawIdx i0 = idx_buffer[idx_offset + i + 0];
|
||||
ImDrawIdx i1 = idx_buffer[idx_offset + i + 1];
|
||||
ImDrawIdx i2 = idx_buffer[idx_offset + i + 2];
|
||||
|
||||
const ImDrawVert& v0 = vtx_buffer[i0];
|
||||
const ImDrawVert& v1 = vtx_buffer[i1];
|
||||
const ImDrawVert& v2 = vtx_buffer[i2];
|
||||
|
||||
ImVec2 p0 = ImVec2((v0.pos.x - display_pos.x) * fb_scale.x, (v0.pos.y - display_pos.y) * fb_scale.y);
|
||||
ImVec2 p1 = ImVec2((v1.pos.x - display_pos.x) * fb_scale.x, (v1.pos.y - display_pos.y) * fb_scale.y);
|
||||
ImVec2 p2 = ImVec2((v2.pos.x - display_pos.x) * fb_scale.x, (v2.pos.y - display_pos.y) * fb_scale.y);
|
||||
|
||||
int minx = (int)std::floor(std::min({ p0.x, p1.x, p2.x }));
|
||||
int miny = (int)std::floor(std::min({ p0.y, p1.y, p2.y }));
|
||||
int maxx = (int)std::ceil (std::max({ p0.x, p1.x, p2.x }));
|
||||
int maxy = (int)std::ceil (std::max({ p0.y, p1.y, p2.y }));
|
||||
|
||||
minx = std::max(minx, cx0);
|
||||
miny = std::max(miny, cy0);
|
||||
maxx = std::min(maxx, cx1 - 1);
|
||||
maxy = std::min(maxy, cy1 - 1);
|
||||
|
||||
if (minx > maxx || miny > maxy) continue;
|
||||
|
||||
float area = Edge(p0, p1, p2.x, p2.y);
|
||||
if (area == 0.0f) continue;
|
||||
|
||||
auto unpack_col = [](ImU32 c, float out[4]) {
|
||||
out[0] = (float)((c >> IM_COL32_R_SHIFT) & 0xFF) / 255.0f;
|
||||
out[1] = (float)((c >> IM_COL32_G_SHIFT) & 0xFF) / 255.0f;
|
||||
out[2] = (float)((c >> IM_COL32_B_SHIFT) & 0xFF) / 255.0f;
|
||||
out[3] = (float)((c >> IM_COL32_A_SHIFT) & 0xFF) / 255.0f;
|
||||
};
|
||||
|
||||
float c0[4], c1[4], c2[4];
|
||||
unpack_col(v0.col, c0); unpack_col(v1.col, c1); unpack_col(v2.col, c2);
|
||||
|
||||
for (int y = miny; y <= maxy; y++)
|
||||
if (SDL_MUSTLOCK(texture_surface))
|
||||
{
|
||||
for (int x = minx; x <= maxx; x++)
|
||||
{
|
||||
float px = (float)x + 0.5f;
|
||||
float py = (float)y + 0.5f;
|
||||
|
||||
float w0 = Edge(p1, p2, px, py) / area;
|
||||
float w1 = Edge(p2, p0, px, py) / area;
|
||||
float w2 = Edge(p0, p1, px, py) / area;
|
||||
|
||||
if (w0 < 0.0f || w1 < 0.0f || w2 < 0.0f) continue;
|
||||
|
||||
float r = w0 * c0[0] + w1 * c1[0] + w2 * c2[0];
|
||||
float g = w0 * c0[1] + w1 * c1[1] + w2 * c2[1];
|
||||
float b = w0 * c0[2] + w1 * c1[2] + w2 * c2[2];
|
||||
float a = w0 * c0[3] + w1 * c1[3] + w2 * c2[3];
|
||||
|
||||
Uint8 out_r = (Uint8)(ImClamp(r, 0.0f, 1.0f) * 255.0f);
|
||||
Uint8 out_g = (Uint8)(ImClamp(g, 0.0f, 1.0f) * 255.0f);
|
||||
Uint8 out_b = (Uint8)(ImClamp(b, 0.0f, 1.0f) * 255.0f);
|
||||
Uint8 out_a = (Uint8)(ImClamp(a, 0.0f, 1.0f) * 255.0f);
|
||||
|
||||
if (tex)
|
||||
{
|
||||
ImVec2 uv0 = v0.uv, uv1 = v1.uv, uv2 = v2.uv;
|
||||
float u = w0 * uv0.x + w1 * uv1.x + w2 * uv2.x;
|
||||
float v = w0 * uv0.y + w1 * uv1.y + w2 * uv2.y;
|
||||
|
||||
int tx = (int)(u * (tex->w - 1) + 0.5f);
|
||||
int ty = (int)(v * (tex->h - 1) + 0.5f);
|
||||
tx = ImClamp(tx, 0, tex->w - 1);
|
||||
ty = ImClamp(ty, 0, tex->h - 1);
|
||||
|
||||
Uint32 tpx = GetPixel(tex, tx, ty);
|
||||
Uint8 tr, tg, tb, ta;
|
||||
SDL_GetRGBA(tpx, tex->format, &tr, &tg, &tb, &ta);
|
||||
|
||||
Uint8 final_r = (Uint8)((tr * out_r) / 255);
|
||||
Uint8 final_g = (Uint8)((tg * out_g) / 255);
|
||||
Uint8 final_b = (Uint8)((tb * out_b) / 255);
|
||||
Uint8 final_a = (Uint8)((ta * out_a) / 255);
|
||||
|
||||
BlendPixel(g_TargetSurface, x, y, final_r, final_g, final_b, final_a);
|
||||
}
|
||||
else
|
||||
{
|
||||
BlendPixel(g_TargetSurface, x, y, out_r, out_g, out_b, out_a);
|
||||
}
|
||||
}
|
||||
if (SDL_LockSurface(texture_surface) != 0)
|
||||
texture_surface = nullptr;
|
||||
else
|
||||
texture_locked = true;
|
||||
}
|
||||
if (texture_surface != nullptr)
|
||||
{
|
||||
ImGui_ImplSDLSurface2_InitSurfaceInfo(&texture_info, texture_surface);
|
||||
if (texture_info.Width > 0 && texture_info.Height > 0)
|
||||
texture_ptr = &texture_info;
|
||||
}
|
||||
}
|
||||
|
||||
idx_offset += pcmd->ElemCount;
|
||||
for (unsigned int idx = 0; idx + 2 < (unsigned int)pcmd->ElemCount; idx += 3)
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
else
|
||||
ImGui_ImplSDLSurface2_RenderTriangleGeneric(bd->TargetInfo, texture_ptr, v0, v1, v2, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
}
|
||||
|
||||
if (texture_locked)
|
||||
SDL_UnlockSurface(texture_surface);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SetClipRect(g_TargetSurface, nullptr);
|
||||
if (SDL_MUSTLOCK(g_TargetSurface)) SDL_UnlockSurface(g_TargetSurface);
|
||||
if (SDL_MUSTLOCK(bd->TargetSurface))
|
||||
SDL_UnlockSurface(bd->TargetSurface);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,715 @@
|
||||
#include "imgui_impl_sdlsurface3.h"
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include <SDL3/SDL.h>
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
struct ImGui_ImplSDLSurface3_FastFormat32
|
||||
{
|
||||
Uint32 Rmask;
|
||||
Uint32 Gmask;
|
||||
Uint32 Bmask;
|
||||
Uint32 Amask;
|
||||
Uint8 Rshift;
|
||||
Uint8 Gshift;
|
||||
Uint8 Bshift;
|
||||
Uint8 Ashift;
|
||||
bool HasAlpha;
|
||||
bool Valid;
|
||||
|
||||
ImGui_ImplSDLSurface3_FastFormat32() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLSurface3_SurfaceInfo
|
||||
{
|
||||
SDL_Surface* Surface;
|
||||
Uint8* Pixels;
|
||||
int Pitch;
|
||||
int Width;
|
||||
int Height;
|
||||
const SDL_PixelFormatDetails* Format;
|
||||
SDL_Palette* Palette;
|
||||
ImGui_ImplSDLSurface3_FastFormat32 FastFormat;
|
||||
bool IsFast;
|
||||
|
||||
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;
|
||||
float Y;
|
||||
float U;
|
||||
float V;
|
||||
float R;
|
||||
float G;
|
||||
float B;
|
||||
float A;
|
||||
};
|
||||
|
||||
static ImGui_ImplSDLSurface3_Data* ImGui_ImplSDLSurface3_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLSurface3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
static inline float ImGui_ImplSDLSurface3_Edge(float ax, float ay, float bx, float by, float px, float py)
|
||||
{
|
||||
return (bx - ax) * (py - ay) - (by - ay) * (px - ax);
|
||||
}
|
||||
|
||||
static inline int ImGui_ImplSDLSurface3_ClampInt(int v, int lo, int hi)
|
||||
{
|
||||
return (v < lo) ? lo : (v > hi ? hi : v);
|
||||
}
|
||||
|
||||
static inline Uint8 ImGui_ImplSDLSurface3_ClampByte(float v)
|
||||
{
|
||||
if (v <= 0.0f)
|
||||
return 0;
|
||||
if (v >= 255.0f)
|
||||
return 255;
|
||||
return (Uint8)(v + 0.5f);
|
||||
}
|
||||
|
||||
static inline Uint8 ImGui_ImplSDLSurface3_Mul255(Uint32 a, Uint32 b)
|
||||
{
|
||||
Uint32 t = a * b + 128;
|
||||
return (Uint8)((t + (t >> 8)) >> 8);
|
||||
}
|
||||
|
||||
static ImGui_ImplSDLSurface3_FastFormat32 ImGui_ImplSDLSurface3_BuildFastFormat(const SDL_PixelFormatDetails* format)
|
||||
{
|
||||
ImGui_ImplSDLSurface3_FastFormat32 out;
|
||||
if (format == nullptr)
|
||||
return out;
|
||||
if (format->bits_per_pixel != 32 || format->bytes_per_pixel != 4)
|
||||
return out;
|
||||
if (format->Rbits != 8 || format->Gbits != 8 || format->Bbits != 8)
|
||||
return out;
|
||||
if (format->Amask != 0 && format->Abits != 8)
|
||||
return out;
|
||||
out.Rmask = format->Rmask;
|
||||
out.Gmask = format->Gmask;
|
||||
out.Bmask = format->Bmask;
|
||||
out.Amask = format->Amask;
|
||||
out.Rshift = format->Rshift;
|
||||
out.Gshift = format->Gshift;
|
||||
out.Bshift = format->Bshift;
|
||||
out.Ashift = format->Ashift;
|
||||
out.HasAlpha = format->Amask != 0;
|
||||
out.Valid = true;
|
||||
return out;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDLSurface3_CanUseFastPath(SDL_Surface* surface, const ImGui_ImplSDLSurface3_FastFormat32& format)
|
||||
{
|
||||
#ifdef IMGUI_IMPL_SDLSURFACE_DISABLE_FAST_PATH
|
||||
IM_UNUSED(surface);
|
||||
IM_UNUSED(format);
|
||||
return false;
|
||||
#else
|
||||
if (surface == nullptr || !format.Valid)
|
||||
return false;
|
||||
if ((surface->pitch & 3) != 0)
|
||||
return false;
|
||||
if ((((uintptr_t)surface->pixels) & 3) != 0)
|
||||
return false;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLSurface3_InitSurfaceInfo(ImGui_ImplSDLSurface3_SurfaceInfo* out, SDL_Surface* surface)
|
||||
{
|
||||
out->Surface = surface;
|
||||
out->Pixels = surface ? (Uint8*)surface->pixels : nullptr;
|
||||
out->Pitch = surface ? surface->pitch : 0;
|
||||
out->Width = surface ? surface->w : 0;
|
||||
out->Height = surface ? surface->h : 0;
|
||||
out->Format = surface ? SDL_GetPixelFormatDetails(surface->format) : nullptr;
|
||||
out->Palette = surface ? SDL_GetSurfacePalette(surface) : nullptr;
|
||||
out->FastFormat = ImGui_ImplSDLSurface3_BuildFastFormat(out->Format);
|
||||
out->IsFast = ImGui_ImplSDLSurface3_CanUseFastPath(surface, out->FastFormat);
|
||||
}
|
||||
|
||||
static inline Uint32 ImGui_ImplSDLSurface3_ReadPixelRaw(const ImGui_ImplSDLSurface3_SurfaceInfo& surface, int x, int y)
|
||||
{
|
||||
const Uint8* p = surface.Pixels + y * surface.Pitch + x * surface.Format->bytes_per_pixel;
|
||||
switch (surface.Format->bytes_per_pixel)
|
||||
{
|
||||
case 1:
|
||||
return *p;
|
||||
case 2:
|
||||
return *(const Uint16*)p;
|
||||
case 3:
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
return (Uint32)((p[0] << 16) | (p[1] << 8) | p[2]);
|
||||
return (Uint32)(p[0] | (p[1] << 8) | (p[2] << 16));
|
||||
case 4:
|
||||
return *(const Uint32*)p;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ImGui_ImplSDLSurface3_WritePixelRaw(const ImGui_ImplSDLSurface3_SurfaceInfo& surface, int x, int y, Uint32 pixel)
|
||||
{
|
||||
Uint8* p = surface.Pixels + y * surface.Pitch + x * surface.Format->bytes_per_pixel;
|
||||
switch (surface.Format->bytes_per_pixel)
|
||||
{
|
||||
case 1:
|
||||
*p = (Uint8)pixel;
|
||||
return;
|
||||
case 2:
|
||||
*(Uint16*)p = (Uint16)pixel;
|
||||
return;
|
||||
case 3:
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
{
|
||||
p[0] = (Uint8)((pixel >> 16) & 0xFF);
|
||||
p[1] = (Uint8)((pixel >> 8) & 0xFF);
|
||||
p[2] = (Uint8)(pixel & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
p[0] = (Uint8)(pixel & 0xFF);
|
||||
p[1] = (Uint8)((pixel >> 8) & 0xFF);
|
||||
p[2] = (Uint8)((pixel >> 16) & 0xFF);
|
||||
}
|
||||
return;
|
||||
case 4:
|
||||
*(Uint32*)p = pixel;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ImGui_ImplSDLSurface3_UnpackFastRGBA(const ImGui_ImplSDLSurface3_FastFormat32& format, Uint32 pixel, Uint8* r, Uint8* g, Uint8* b, Uint8* a)
|
||||
{
|
||||
*r = (Uint8)((pixel & format.Rmask) >> format.Rshift);
|
||||
*g = (Uint8)((pixel & format.Gmask) >> format.Gshift);
|
||||
*b = (Uint8)((pixel & format.Bmask) >> format.Bshift);
|
||||
*a = format.HasAlpha ? (Uint8)((pixel & format.Amask) >> format.Ashift) : 255;
|
||||
}
|
||||
|
||||
static inline Uint32 ImGui_ImplSDLSurface3_PackFastRGBA(const ImGui_ImplSDLSurface3_FastFormat32& format, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
{
|
||||
Uint32 pixel = (((Uint32)r << format.Rshift) & format.Rmask)
|
||||
| (((Uint32)g << format.Gshift) & format.Gmask)
|
||||
| (((Uint32)b << format.Bshift) & format.Bmask);
|
||||
if (format.HasAlpha)
|
||||
pixel |= (((Uint32)a << format.Ashift) & format.Amask);
|
||||
return pixel;
|
||||
}
|
||||
|
||||
static inline void ImGui_ImplSDLSurface3_ReadPixelRGBA(const ImGui_ImplSDLSurface3_SurfaceInfo& surface, int x, int y, Uint8* r, Uint8* g, Uint8* b, Uint8* a)
|
||||
{
|
||||
if (surface.IsFast)
|
||||
{
|
||||
const Uint32* src = (const Uint32*)(surface.Pixels + y * surface.Pitch) + x;
|
||||
ImGui_ImplSDLSurface3_UnpackFastRGBA(surface.FastFormat, *src, r, g, b, a);
|
||||
return;
|
||||
}
|
||||
|
||||
Uint32 pixel = ImGui_ImplSDLSurface3_ReadPixelRaw(surface, x, y);
|
||||
SDL_GetRGBA(pixel, surface.Format, surface.Palette, r, g, b, 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)
|
||||
return;
|
||||
if (sa == 255)
|
||||
{
|
||||
*dst = ImGui_ImplSDLSurface3_PackFastRGBA(target.FastFormat, sr, sg, sb, 255);
|
||||
return;
|
||||
}
|
||||
|
||||
Uint8 dr, dg, db, da;
|
||||
ImGui_ImplSDLSurface3_UnpackFastRGBA(target.FastFormat, *dst, &dr, &dg, &db, &da);
|
||||
Uint8 inv_a = (Uint8)(255 - sa);
|
||||
Uint8 out_r = (Uint8)(ImGui_ImplSDLSurface3_Mul255(sr, sa) + ImGui_ImplSDLSurface3_Mul255(dr, inv_a));
|
||||
Uint8 out_g = (Uint8)(ImGui_ImplSDLSurface3_Mul255(sg, sa) + ImGui_ImplSDLSurface3_Mul255(dg, inv_a));
|
||||
Uint8 out_b = (Uint8)(ImGui_ImplSDLSurface3_Mul255(sb, sa) + ImGui_ImplSDLSurface3_Mul255(db, inv_a));
|
||||
Uint8 out_a = (target.Format != nullptr && target.Format->Amask != 0) ? (Uint8)(sa + ImGui_ImplSDLSurface3_Mul255(da, inv_a)) : 255;
|
||||
*dst = ImGui_ImplSDLSurface3_PackFastRGBA(target.FastFormat, out_r, out_g, out_b, out_a);
|
||||
}
|
||||
|
||||
static inline void ImGui_ImplSDLSurface3_BlendPixelGeneric(const ImGui_ImplSDLSurface3_SurfaceInfo& target, int x, int y, Uint8 sr, Uint8 sg, Uint8 sb, Uint8 sa)
|
||||
{
|
||||
if (sa == 0)
|
||||
return;
|
||||
if (sa == 255)
|
||||
{
|
||||
Uint32 pixel = SDL_MapRGBA(target.Format, target.Palette, sr, sg, sb, 255);
|
||||
ImGui_ImplSDLSurface3_WritePixelRaw(target, x, y, pixel);
|
||||
return;
|
||||
}
|
||||
|
||||
Uint8 dr, dg, db, da;
|
||||
Uint32 dst_pixel = ImGui_ImplSDLSurface3_ReadPixelRaw(target, x, y);
|
||||
SDL_GetRGBA(dst_pixel, target.Format, target.Palette, &dr, &dg, &db, &da);
|
||||
Uint8 inv_a = (Uint8)(255 - sa);
|
||||
Uint8 out_r = (Uint8)(ImGui_ImplSDLSurface3_Mul255(sr, sa) + ImGui_ImplSDLSurface3_Mul255(dr, inv_a));
|
||||
Uint8 out_g = (Uint8)(ImGui_ImplSDLSurface3_Mul255(sg, sa) + ImGui_ImplSDLSurface3_Mul255(dg, inv_a));
|
||||
Uint8 out_b = (Uint8)(ImGui_ImplSDLSurface3_Mul255(sb, sa) + ImGui_ImplSDLSurface3_Mul255(db, inv_a));
|
||||
Uint8 out_a = target.FastFormat.HasAlpha ? (Uint8)(sa + ImGui_ImplSDLSurface3_Mul255(da, inv_a)) : 255;
|
||||
Uint32 pixel = SDL_MapRGBA(target.Format, target.Palette, out_r, out_g, out_b, out_a);
|
||||
ImGui_ImplSDLSurface3_WritePixelRaw(target, x, y, pixel);
|
||||
}
|
||||
|
||||
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;
|
||||
out->Y = (v.pos.y - display_pos.y) * framebuffer_scale.y;
|
||||
out->U = v.uv.x;
|
||||
out->V = v.uv.y;
|
||||
out->R = (float)((v.col >> IM_COL32_R_SHIFT) & 0xFF);
|
||||
out->G = (float)((v.col >> IM_COL32_G_SHIFT) & 0xFF);
|
||||
out->B = (float)((v.col >> IM_COL32_B_SHIFT) & 0xFF);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
int max_y = std::min((int)std::ceil(std::max(v0.Y, std::max(v1.Y, v2.Y))) - 1, clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
float area = ImGui_ImplSDLSurface3_Edge(v0.X, v0.Y, v1.X, v1.Y, v2.X, v2.Y);
|
||||
if (area == 0.0f)
|
||||
return;
|
||||
|
||||
float sign = (area < 0.0f) ? -1.0f : 1.0f;
|
||||
area *= sign;
|
||||
|
||||
float e0_dx = (v1.Y - v2.Y) * sign;
|
||||
float e0_dy = (v2.X - v1.X) * sign;
|
||||
float e1_dx = (v2.Y - v0.Y) * sign;
|
||||
float e1_dy = (v0.X - v2.X) * sign;
|
||||
float e2_dx = (v0.Y - v1.Y) * sign;
|
||||
float e2_dy = (v1.X - v0.X) * sign;
|
||||
|
||||
float inv_area = 1.0f / area;
|
||||
float dw0_dx = e0_dx * inv_area;
|
||||
float dw0_dy = e0_dy * inv_area;
|
||||
float dw1_dx = e1_dx * inv_area;
|
||||
float dw1_dy = e1_dy * inv_area;
|
||||
float dw2_dx = e2_dx * inv_area;
|
||||
float dw2_dy = e2_dy * inv_area;
|
||||
|
||||
float dr_dx = dw0_dx * v0.R + dw1_dx * v1.R + dw2_dx * v2.R;
|
||||
float dg_dx = dw0_dx * v0.G + dw1_dx * v1.G + dw2_dx * v2.G;
|
||||
float db_dx = dw0_dx * v0.B + dw1_dx * v1.B + dw2_dx * v2.B;
|
||||
float da_dx = dw0_dx * v0.A + dw1_dx * v1.A + dw2_dx * v2.A;
|
||||
float du_dx = dw0_dx * v0.U + dw1_dx * v1.U + dw2_dx * v2.U;
|
||||
float dv_dx = dw0_dx * v0.V + dw1_dx * v1.V + dw2_dx * v2.V;
|
||||
|
||||
float dr_dy = dw0_dy * v0.R + dw1_dy * v1.R + dw2_dy * v2.R;
|
||||
float dg_dy = dw0_dy * v0.G + dw1_dy * v1.G + dw2_dy * v2.G;
|
||||
float db_dy = dw0_dy * v0.B + dw1_dy * v1.B + dw2_dy * v2.B;
|
||||
float da_dy = dw0_dy * v0.A + dw1_dy * v1.A + dw2_dy * v2.A;
|
||||
float du_dy = dw0_dy * v0.U + dw1_dy * v1.U + dw2_dy * v2.U;
|
||||
float dv_dy = dw0_dy * v0.V + dw1_dy * v1.V + dw2_dy * v2.V;
|
||||
|
||||
float start_x = (float)min_x + 0.5f;
|
||||
float start_y = (float)min_y + 0.5f;
|
||||
|
||||
float e0_row = ImGui_ImplSDLSurface3_Edge(v1.X, v1.Y, v2.X, v2.Y, start_x, start_y) * sign;
|
||||
float e1_row = ImGui_ImplSDLSurface3_Edge(v2.X, v2.Y, v0.X, v0.Y, start_x, start_y) * sign;
|
||||
float e2_row = ImGui_ImplSDLSurface3_Edge(v0.X, v0.Y, v1.X, v1.Y, start_x, start_y) * sign;
|
||||
|
||||
float w0_row = e0_row * inv_area;
|
||||
float w1_row = e1_row * inv_area;
|
||||
float w2_row = e2_row * inv_area;
|
||||
|
||||
float r_row = w0_row * v0.R + w1_row * v1.R + w2_row * v2.R;
|
||||
float g_row = w0_row * v0.G + w1_row * v1.G + w2_row * v2.G;
|
||||
float b_row = w0_row * v0.B + w1_row * v1.B + w2_row * v2.B;
|
||||
float a_row = w0_row * v0.A + w1_row * v1.A + w2_row * v2.A;
|
||||
float u_row = w0_row * v0.U + w1_row * v1.U + w2_row * v2.U;
|
||||
float v_row = w0_row * v0.V + w1_row * v1.V + w2_row * v2.V;
|
||||
|
||||
int texture_max_x = texture ? (texture->Width - 1) : 0;
|
||||
int texture_max_y = texture ? (texture->Height - 1) : 0;
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
float e0 = e0_row;
|
||||
float e1 = e1_row;
|
||||
float e2 = e2_row;
|
||||
float r = r_row;
|
||||
float g = g_row;
|
||||
float b = b_row;
|
||||
float a = a_row;
|
||||
float u = u_row;
|
||||
float v = v_row;
|
||||
Uint32* dst = (Uint32*)(target.Pixels + y * target.Pitch) + min_x;
|
||||
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
if (e0 >= 0.0f && e1 >= 0.0f && e2 >= 0.0f)
|
||||
{
|
||||
Uint8 out_r = ImGui_ImplSDLSurface3_ClampByte(r);
|
||||
Uint8 out_g = ImGui_ImplSDLSurface3_ClampByte(g);
|
||||
Uint8 out_b = ImGui_ImplSDLSurface3_ClampByte(b);
|
||||
Uint8 out_a = ImGui_ImplSDLSurface3_ClampByte(a);
|
||||
|
||||
if (texture != nullptr)
|
||||
{
|
||||
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 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++;
|
||||
e0 += e0_dx;
|
||||
e1 += e1_dx;
|
||||
e2 += e2_dx;
|
||||
r += dr_dx;
|
||||
g += dg_dx;
|
||||
b += db_dx;
|
||||
a += da_dx;
|
||||
u += du_dx;
|
||||
v += dv_dx;
|
||||
}
|
||||
|
||||
e0_row += e0_dy;
|
||||
e1_row += e1_dy;
|
||||
e2_row += e2_dy;
|
||||
r_row += dr_dy;
|
||||
g_row += dg_dy;
|
||||
b_row += db_dy;
|
||||
a_row += da_dy;
|
||||
u_row += du_dy;
|
||||
v_row += dv_dy;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
int max_y = std::min((int)std::ceil(std::max(v0.Y, std::max(v1.Y, v2.Y))) - 1, clip_max_y - 1);
|
||||
if (min_x > max_x || min_y > max_y)
|
||||
return;
|
||||
|
||||
float area = ImGui_ImplSDLSurface3_Edge(v0.X, v0.Y, v1.X, v1.Y, v2.X, v2.Y);
|
||||
if (area == 0.0f)
|
||||
return;
|
||||
|
||||
float sign = (area < 0.0f) ? -1.0f : 1.0f;
|
||||
area *= sign;
|
||||
|
||||
float e0_dx = (v1.Y - v2.Y) * sign;
|
||||
float e0_dy = (v2.X - v1.X) * sign;
|
||||
float e1_dx = (v2.Y - v0.Y) * sign;
|
||||
float e1_dy = (v0.X - v2.X) * sign;
|
||||
float e2_dx = (v0.Y - v1.Y) * sign;
|
||||
float e2_dy = (v1.X - v0.X) * sign;
|
||||
|
||||
float inv_area = 1.0f / area;
|
||||
float dw0_dx = e0_dx * inv_area;
|
||||
float dw0_dy = e0_dy * inv_area;
|
||||
float dw1_dx = e1_dx * inv_area;
|
||||
float dw1_dy = e1_dy * inv_area;
|
||||
float dw2_dx = e2_dx * inv_area;
|
||||
float dw2_dy = e2_dy * inv_area;
|
||||
|
||||
float dr_dx = dw0_dx * v0.R + dw1_dx * v1.R + dw2_dx * v2.R;
|
||||
float dg_dx = dw0_dx * v0.G + dw1_dx * v1.G + dw2_dx * v2.G;
|
||||
float db_dx = dw0_dx * v0.B + dw1_dx * v1.B + dw2_dx * v2.B;
|
||||
float da_dx = dw0_dx * v0.A + dw1_dx * v1.A + dw2_dx * v2.A;
|
||||
float du_dx = dw0_dx * v0.U + dw1_dx * v1.U + dw2_dx * v2.U;
|
||||
float dv_dx = dw0_dx * v0.V + dw1_dx * v1.V + dw2_dx * v2.V;
|
||||
|
||||
float dr_dy = dw0_dy * v0.R + dw1_dy * v1.R + dw2_dy * v2.R;
|
||||
float dg_dy = dw0_dy * v0.G + dw1_dy * v1.G + dw2_dy * v2.G;
|
||||
float db_dy = dw0_dy * v0.B + dw1_dy * v1.B + dw2_dy * v2.B;
|
||||
float da_dy = dw0_dy * v0.A + dw1_dy * v1.A + dw2_dy * v2.A;
|
||||
float du_dy = dw0_dy * v0.U + dw1_dy * v1.U + dw2_dy * v2.U;
|
||||
float dv_dy = dw0_dy * v0.V + dw1_dy * v1.V + dw2_dy * v2.V;
|
||||
|
||||
float start_x = (float)min_x + 0.5f;
|
||||
float start_y = (float)min_y + 0.5f;
|
||||
|
||||
float e0_row = ImGui_ImplSDLSurface3_Edge(v1.X, v1.Y, v2.X, v2.Y, start_x, start_y) * sign;
|
||||
float e1_row = ImGui_ImplSDLSurface3_Edge(v2.X, v2.Y, v0.X, v0.Y, start_x, start_y) * sign;
|
||||
float e2_row = ImGui_ImplSDLSurface3_Edge(v0.X, v0.Y, v1.X, v1.Y, start_x, start_y) * sign;
|
||||
|
||||
float w0_row = e0_row * inv_area;
|
||||
float w1_row = e1_row * inv_area;
|
||||
float w2_row = e2_row * inv_area;
|
||||
|
||||
float r_row = w0_row * v0.R + w1_row * v1.R + w2_row * v2.R;
|
||||
float g_row = w0_row * v0.G + w1_row * v1.G + w2_row * v2.G;
|
||||
float b_row = w0_row * v0.B + w1_row * v1.B + w2_row * v2.B;
|
||||
float a_row = w0_row * v0.A + w1_row * v1.A + w2_row * v2.A;
|
||||
float u_row = w0_row * v0.U + w1_row * v1.U + w2_row * v2.U;
|
||||
float v_row = w0_row * v0.V + w1_row * v1.V + w2_row * v2.V;
|
||||
|
||||
int texture_max_x = texture ? (texture->Width - 1) : 0;
|
||||
int texture_max_y = texture ? (texture->Height - 1) : 0;
|
||||
|
||||
for (int y = min_y; y <= max_y; y++)
|
||||
{
|
||||
float e0 = e0_row;
|
||||
float e1 = e1_row;
|
||||
float e2 = e2_row;
|
||||
float r = r_row;
|
||||
float g = g_row;
|
||||
float b = b_row;
|
||||
float a = a_row;
|
||||
float u = u_row;
|
||||
float v = v_row;
|
||||
|
||||
for (int x = min_x; x <= max_x; x++)
|
||||
{
|
||||
if (e0 >= 0.0f && e1 >= 0.0f && e2 >= 0.0f)
|
||||
{
|
||||
Uint8 out_r = ImGui_ImplSDLSurface3_ClampByte(r);
|
||||
Uint8 out_g = ImGui_ImplSDLSurface3_ClampByte(g);
|
||||
Uint8 out_b = ImGui_ImplSDLSurface3_ClampByte(b);
|
||||
Uint8 out_a = ImGui_ImplSDLSurface3_ClampByte(a);
|
||||
|
||||
if (texture != nullptr)
|
||||
{
|
||||
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 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);
|
||||
}
|
||||
|
||||
e0 += e0_dx;
|
||||
e1 += e1_dx;
|
||||
e2 += e2_dx;
|
||||
r += dr_dx;
|
||||
g += dg_dx;
|
||||
b += db_dx;
|
||||
a += da_dx;
|
||||
u += du_dx;
|
||||
v += dv_dx;
|
||||
}
|
||||
|
||||
e0_row += e0_dy;
|
||||
e1_row += e1_dy;
|
||||
e2_row += e2_dy;
|
||||
r_row += dr_dy;
|
||||
g_row += dg_dy;
|
||||
b_row += db_dy;
|
||||
a_row += da_dy;
|
||||
u_row += du_dy;
|
||||
v_row += dv_dy;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Surface* ImGui_ImplSDLSurface3_CreateFontAtlasSurface()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
unsigned char* pixels = nullptr;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
if (pixels == nullptr || width <= 0 || height <= 0)
|
||||
return nullptr;
|
||||
|
||||
SDL_Surface* surface = SDL_CreateSurface(width, height, SDL_PIXELFORMAT_RGBA32);
|
||||
if (surface == nullptr)
|
||||
return nullptr;
|
||||
if (SDL_MUSTLOCK(surface) && !SDL_LockSurface(surface))
|
||||
{
|
||||
SDL_DestroySurface(surface);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
memcpy((Uint8*)surface->pixels + y * surface->pitch, pixels + (size_t)y * (size_t)width * 4, (size_t)width * 4);
|
||||
|
||||
if (SDL_MUSTLOCK(surface))
|
||||
SDL_UnlockSurface(surface);
|
||||
|
||||
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
|
||||
return surface;
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLSurface3_Init(SDL_Surface* surface)
|
||||
{
|
||||
if (surface == nullptr)
|
||||
return false;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
ImGui_ImplSDLSurface3_Data* bd = IM_NEW(ImGui_ImplSDLSurface3_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_sdlsurface3";
|
||||
|
||||
bd->TargetSurface = surface;
|
||||
ImGui_ImplSDLSurface3_InitSurfaceInfo(&bd->TargetInfo, surface);
|
||||
bd->FontSurface = ImGui_ImplSDLSurface3_CreateFontAtlasSurface();
|
||||
if (bd->FontSurface != nullptr)
|
||||
io.Fonts->TexID = (ImTextureID)bd->FontSurface;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLSurface3_Shutdown()
|
||||
{
|
||||
ImGui_ImplSDLSurface3_Data* bd = ImGui_ImplSDLSurface3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
io.Fonts->TexID = nullptr;
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
platform_io.ClearRendererHandlers();
|
||||
|
||||
if (bd->FontSurface != nullptr)
|
||||
SDL_DestroySurface(bd->FontSurface);
|
||||
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLSurface3_NewFrame()
|
||||
{
|
||||
ImGui_ImplSDLSurface3_Data* bd = ImGui_ImplSDLSurface3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLSurface3_Init()?");
|
||||
IM_UNUSED(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLSurface3_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
ImGui_ImplSDLSurface3_Data* bd = ImGui_ImplSDLSurface3_GetBackendData();
|
||||
if (bd == nullptr || draw_data == nullptr || bd->TargetSurface == nullptr)
|
||||
return;
|
||||
|
||||
if (SDL_MUSTLOCK(bd->TargetSurface) && !SDL_LockSurface(bd->TargetSurface))
|
||||
return;
|
||||
|
||||
ImGui_ImplSDLSurface3_InitSurfaceInfo(&bd->TargetInfo, bd->TargetSurface);
|
||||
if (bd->TargetInfo.Width <= 0 || bd->TargetInfo.Height <= 0)
|
||||
{
|
||||
if (SDL_MUSTLOCK(bd->TargetSurface))
|
||||
SDL_UnlockSurface(bd->TargetSurface);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
if (pcmd->UserCallback != ImDrawCallback_ResetRenderState)
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
continue;
|
||||
}
|
||||
if (pcmd->ElemCount == 0)
|
||||
continue;
|
||||
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
if (clip_min.x < 0.0f) clip_min.x = 0.0f;
|
||||
if (clip_min.y < 0.0f) clip_min.y = 0.0f;
|
||||
if (clip_max.x > (float)bd->TargetInfo.Width) clip_max.x = (float)bd->TargetInfo.Width;
|
||||
if (clip_max.y > (float)bd->TargetInfo.Height) clip_max.y = (float)bd->TargetInfo.Height;
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
int clip_min_x = (int)clip_min.x;
|
||||
int clip_min_y = (int)clip_min.y;
|
||||
int clip_max_x = (int)clip_max.x;
|
||||
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 (SDL_MUSTLOCK(texture_surface))
|
||||
{
|
||||
if (!SDL_LockSurface(texture_surface))
|
||||
texture_surface = nullptr;
|
||||
else
|
||||
texture_locked = true;
|
||||
}
|
||||
if (texture_surface != nullptr)
|
||||
{
|
||||
ImGui_ImplSDLSurface3_InitSurfaceInfo(&texture_info, texture_surface);
|
||||
if (texture_info.Width > 0 && texture_info.Height > 0)
|
||||
texture_ptr = &texture_info;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int idx = 0; idx + 2 < (unsigned int)pcmd->ElemCount; idx += 3)
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
else
|
||||
ImGui_ImplSDLSurface3_RenderTriangleGeneric(bd->TargetInfo, texture_ptr, v0, v1, v2, clip_min_x, clip_min_y, clip_max_x, clip_max_y);
|
||||
}
|
||||
|
||||
if (texture_locked)
|
||||
SDL_UnlockSurface(texture_surface);
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_MUSTLOCK(bd->TargetSurface))
|
||||
SDL_UnlockSurface(bd->TargetSurface);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "imgui.h"
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
IMGUI_API bool ImGui_ImplSDLSurface3_Init(SDL_Surface* surface);
|
||||
IMGUI_API void ImGui_ImplSDLSurface3_Shutdown();
|
||||
IMGUI_API void ImGui_ImplSDLSurface3_NewFrame();
|
||||
IMGUI_API void ImGui_ImplSDLSurface3_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
IMGUI_API SDL_Surface* ImGui_ImplSDLSurface3_CreateFontAtlasSurface();
|
||||
@@ -94,6 +94,8 @@ List of Renderer Backends:
|
||||
imgui_impl_sdlgpu3.cpp ; SDL_GPU (portable 3D graphics API of SDL3)
|
||||
imgui_impl_sdlrenderer2.cpp ; SDL_Renderer (optional component of SDL2 available from SDL 2.0.18+)
|
||||
imgui_impl_sdlrenderer3.cpp ; SDL_Renderer (optional component of SDL3. Prefer using SDL_GPU!).
|
||||
imgui_impl_sdlsurface2.cpp ; SDL_Surface CPU renderer for SDL2
|
||||
imgui_impl_sdlsurface3.cpp ; SDL_Surface CPU renderer for SDL3
|
||||
imgui_impl_vulkan.cpp ; Vulkan
|
||||
imgui_impl_wgpu.cpp ; WebGPU (web + desktop)
|
||||
|
||||
|
||||
+8
-1
@@ -145,6 +145,10 @@ SDL2 (Win32, Mac, Linux, etc.) + SDL_Renderer for SDL2 example.<BR>
|
||||
= main.cpp + imgui_impl_sdl2.cpp + imgui_impl_sdlrenderer2.cpp <BR>
|
||||
This requires SDL 2.0.18+ (released November 2021) <BR>
|
||||
|
||||
[example_sdl2_surface/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_surface/) <BR>
|
||||
SDL2 (Win32, Mac, Linux, etc.) + SDL_Surface CPU renderer example.<BR>
|
||||
= main.cpp + imgui_impl_sdl2.cpp + imgui_impl_sdlsurface2.cpp <BR>
|
||||
|
||||
[example_sdl2_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_vulkan/) <BR>
|
||||
SDL2 (Win32, Mac, Linux, etc.) + Vulkan example. <BR>
|
||||
= main.cpp + imgui_impl_sdl2.cpp + imgui_impl_vulkan.cpp <BR>
|
||||
@@ -178,6 +182,10 @@ SDL3 (Win32, Mac, Linux, etc.) + SDL_GPU for SDL3 example.<BR>
|
||||
SDL3 (Win32, Mac, Linux, etc.) + SDL_Renderer for SDL3 example.<BR>
|
||||
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_sdlrenderer3.cpp <BR>
|
||||
|
||||
[example_sdl3_surface/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_surface/) <BR>
|
||||
SDL3 (Win32, Mac, Linux, etc.) + SDL_Surface CPU renderer example.<BR>
|
||||
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_sdlsurface3.cpp <BR>
|
||||
|
||||
[example_sdl3_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_vulkan/) <BR>
|
||||
SDL3 (Win32, Mac, Linux, etc.) + Vulkan example. <BR>
|
||||
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_vulkan.cpp <BR>
|
||||
@@ -253,4 +261,3 @@ when an interactive drag is in progress.
|
||||
Note that some setup configurations or GPU drivers may introduce additional display lag depending on their settings.
|
||||
If you notice that dragging windows is laggy and you are not sure what the cause is: try drawing a simple
|
||||
2D shape directly under the mouse cursor to help identify the issue!
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
EXE = example_sdl3_surface
|
||||
IMGUI_DIR = ../..
|
||||
SOURCES = main.cpp
|
||||
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
|
||||
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_sdlsurface3.cpp
|
||||
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
|
||||
LIBS =
|
||||
|
||||
ifeq ($(UNAME_S), Linux)
|
||||
ECHO_MESSAGE = "Linux"
|
||||
LIBS += -ldl `pkg-config sdl3 --libs`
|
||||
CXXFLAGS += `pkg-config sdl3 --cflags`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_S), Darwin)
|
||||
ECHO_MESSAGE = "Mac OS X"
|
||||
LIBS += -framework Cocoa -framework IOKit -framework CoreVideo
|
||||
LIBS += `pkg-config --libs sdl3`
|
||||
LIBS += -L/usr/local/lib -L/opt/local/lib
|
||||
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||
CXXFLAGS += -I/usr/local/include -I/opt/local/include
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
ECHO_MESSAGE = "MinGW"
|
||||
LIBS += -lgdi32 -limm32 `pkg-config --static --libs sdl3`
|
||||
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
%.o:%.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
%.o:$(IMGUI_DIR)/%.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
%.o:$(IMGUI_DIR)/backends/%.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
all: $(EXE)
|
||||
@echo Build complete for $(ECHO_MESSAGE)
|
||||
|
||||
$(EXE): $(OBJS)
|
||||
$(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f $(EXE) $(OBJS)
|
||||
@@ -0,0 +1,33 @@
|
||||
# How to Build
|
||||
|
||||
## Windows with Visual Studio's IDE
|
||||
|
||||
Use the provided project file (`example_sdl3_surface.vcxproj`) or open `imgui_examples.sln`.
|
||||
|
||||
## Windows with Visual Studio's CLI
|
||||
|
||||
Use `build_win32.bat` or directly:
|
||||
```bat
|
||||
set SDL3_DIR=path_to_your_sdl3_folder
|
||||
cl /Zi /MD /utf-8 /I.. /I..\.. /I%SDL3_DIR%\include main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_sdlsurface3.cpp ..\..\imgui*.cpp /FeDebug/example_sdl3_surface.exe /FoDebug/ /link /libpath:%SDL3_DIR%\lib\x86 SDL3.lib /subsystem:console
|
||||
cl /Zi /MD /utf-8 /I.. /I..\.. /I%SDL3_DIR%\include main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_sdlsurface3.cpp ..\..\imgui*.cpp /FeDebug/example_sdl3_surface.exe /FoDebug/ /link /libpath:%SDL3_DIR%\lib\x64 SDL3.lib /subsystem:console
|
||||
```
|
||||
|
||||
## Linux and similar Unixes
|
||||
|
||||
Use the provided `Makefile` or directly:
|
||||
```sh
|
||||
c++ `pkg-config --cflags sdl3` -I .. -I ../.. -I ../../backends \
|
||||
main.cpp ../../backends/imgui_impl_sdl3.cpp ../../backends/imgui_impl_sdlsurface3.cpp ../../imgui*.cpp \
|
||||
-ldl `pkg-config --libs sdl3`
|
||||
```
|
||||
|
||||
## macOS
|
||||
|
||||
Use the provided `Makefile` or directly:
|
||||
```sh
|
||||
brew install sdl3
|
||||
c++ `pkg-config --cflags sdl3` -I .. -I ../.. -I ../../backends \
|
||||
main.cpp ../../backends/imgui_impl_sdl3.cpp ../../backends/imgui_impl_sdlsurface3.cpp ../../imgui*.cpp \
|
||||
-framework Cocoa -framework IOKit -framework CoreVideo `pkg-config --libs sdl3`
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
@set OUT_DIR=Debug
|
||||
@set OUT_EXE=example_sdl3_surface
|
||||
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL3_DIR%\include
|
||||
@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
|
||||
@@ -0,0 +1,187 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{08DD87C0-C734-45D6-9B44-D23F19F2D4B6}</ProjectGuid>
|
||||
<RootNamespace>example_sdl3_surface</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<ProjectName>example_sdl3_surface</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\imgui.cpp" />
|
||||
<ClCompile Include="..\..\imgui_demo.cpp" />
|
||||
<ClCompile Include="..\..\imgui_draw.cpp" />
|
||||
<ClCompile Include="..\..\imgui_tables.cpp" />
|
||||
<ClCompile Include="..\..\imgui_widgets.cpp" />
|
||||
<ClCompile Include="..\..\backends\imgui_impl_sdl3.cpp" />
|
||||
<ClCompile Include="..\..\backends\imgui_impl_sdlsurface3.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\imconfig.h" />
|
||||
<ClInclude Include="..\..\imgui.h" />
|
||||
<ClInclude Include="..\..\imgui_internal.h" />
|
||||
<ClInclude Include="..\..\backends\imgui_impl_sdl3.h" />
|
||||
<ClInclude Include="..\..\backends\imgui_impl_sdlsurface3.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\misc\debuggers\imgui.natstepfilter" />
|
||||
<None Include="..\..\misc\debuggers\imgui.natvis" />
|
||||
<None Include="..\README.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="imgui">
|
||||
<UniqueIdentifier>{20b90ce4-7fcb-4731-b9a0-075f875de82d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sources">
|
||||
<UniqueIdentifier>{f18ab499-84e1-499f-8eff-9754361e0e52}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\imgui.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_demo.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_draw.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_tables.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_widgets.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\backends\imgui_impl_sdl3.cpp">
|
||||
<Filter>sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\backends\imgui_impl_sdlsurface3.cpp">
|
||||
<Filter>sources</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\imconfig.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\imgui.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\imgui_internal.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\backends\imgui_impl_sdl3.h">
|
||||
<Filter>sources</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\backends\imgui_impl_sdlsurface3.h">
|
||||
<Filter>sources</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\README.txt" />
|
||||
<None Include="..\..\misc\debuggers\imgui.natvis">
|
||||
<Filter>imgui</Filter>
|
||||
</None>
|
||||
<None Include="..\..\misc\debuggers\imgui.natstepfilter">
|
||||
<Filter>imgui</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,176 @@
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
#include "imgui_impl_sdlsurface3.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
|
||||
SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+Surface Example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
SDL_ShowWindow(window);
|
||||
|
||||
SDL_Surface* window_surface = SDL_GetWindowSurface(window);
|
||||
if (window_surface == nullptr)
|
||||
{
|
||||
printf("Error: SDL_GetWindowSurface(): %s\n", SDL_GetError());
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_SetWindowSurfaceVSync(window, 1);
|
||||
|
||||
int framebuffer_w = window_surface->w;
|
||||
int framebuffer_h = window_surface->h;
|
||||
SDL_Surface* framebuffer = SDL_CreateSurface(framebuffer_w, framebuffer_h, SDL_PIXELFORMAT_RGBA32);
|
||||
if (framebuffer == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateSurface(): %s\n", SDL_GetError());
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
||||
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(main_scale);
|
||||
style.FontScaleDpi = main_scale;
|
||||
|
||||
ImGui_ImplSDL3_InitForOther(window);
|
||||
ImGui_ImplSDLSurface3_Init(framebuffer);
|
||||
|
||||
bool show_demo_window = true;
|
||||
bool show_another_window = false;
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
bool done = false;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||
if (event.type == SDL_EVENT_QUIT)
|
||||
done = true;
|
||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||
done = true;
|
||||
if ((event.type == SDL_EVENT_WINDOW_RESIZED || event.type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) && event.window.windowID == SDL_GetWindowID(window))
|
||||
{
|
||||
window_surface = SDL_GetWindowSurface(window);
|
||||
if (window_surface != nullptr)
|
||||
{
|
||||
int new_w = window_surface->w;
|
||||
int new_h = window_surface->h;
|
||||
if (new_w != framebuffer_w || new_h != framebuffer_h)
|
||||
{
|
||||
SDL_DestroySurface(framebuffer);
|
||||
framebuffer = SDL_CreateSurface(new_w, new_h, SDL_PIXELFORMAT_RGBA32);
|
||||
if (framebuffer == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateSurface(): %s\n", SDL_GetError());
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
framebuffer_w = new_w;
|
||||
framebuffer_h = new_h;
|
||||
ImGui_ImplSDLSurface3_Shutdown();
|
||||
ImGui_ImplSDLSurface3_Init(framebuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (done)
|
||||
break;
|
||||
|
||||
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
|
||||
{
|
||||
SDL_Delay(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui_ImplSDLSurface3_NewFrame();
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
if (show_demo_window)
|
||||
ImGui::ShowDemoWindow(&show_demo_window);
|
||||
|
||||
{
|
||||
static float f = 0.0f;
|
||||
static int counter = 0;
|
||||
|
||||
ImGui::Begin("Hello, world!");
|
||||
ImGui::Text("This is some useful text.");
|
||||
ImGui::Checkbox("Demo Window", &show_demo_window);
|
||||
ImGui::Checkbox("Another Window", &show_another_window);
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
|
||||
ImGui::ColorEdit3("clear color", (float*)&clear_color);
|
||||
if (ImGui::Button("Button"))
|
||||
counter++;
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("counter = %d", counter);
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window);
|
||||
ImGui::Text("Hello from another window!");
|
||||
if (ImGui::Button("Close Me"))
|
||||
show_another_window = false;
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
SDL_FillSurfaceRect(framebuffer, nullptr, SDL_MapSurfaceRGBA(framebuffer,
|
||||
(Uint8)(clear_color.x * 255.0f),
|
||||
(Uint8)(clear_color.y * 255.0f),
|
||||
(Uint8)(clear_color.z * 255.0f),
|
||||
(Uint8)(clear_color.w * 255.0f)));
|
||||
|
||||
ImGui_ImplSDLSurface3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
window_surface = SDL_GetWindowSurface(window);
|
||||
if (window_surface != nullptr)
|
||||
{
|
||||
SDL_BlitSurface(framebuffer, nullptr, window_surface, nullptr);
|
||||
SDL_UpdateWindowSurface(window);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui_ImplSDLSurface3_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
SDL_DestroySurface(framebuffer);
|
||||
SDL_DestroyWindowSurface(window);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -35,6 +35,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_opengl3", "exa
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_sdlrenderer3", "example_sdl3_sdlrenderer3\example_sdl3_sdlrenderer3.vcxproj", "{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_surface", "example_sdl3_surface\example_sdl3_surface.vcxproj", "{08DD87C0-C734-45D6-9B44-D23F19F2D4B6}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_vulkan", "example_sdl3_vulkan\example_sdl3_vulkan.vcxproj", "{663A7E89-1E42-4222-921C-177F5B5910DF}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_vulkan", "example_win32_vulkan\example_win32_vulkan.vcxproj", "{0A1E32DF-E0F4-4CCE-B3DC-9644C503BD88}"
|
||||
@@ -181,6 +183,14 @@ Global
|
||||
{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|Win32.Build.0 = Release|Win32
|
||||
{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.ActiveCfg = Release|x64
|
||||
{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.Build.0 = Release|x64
|
||||
{08DD87C0-C734-45D6-9B44-D23F19F2D4B6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{08DD87C0-C734-45D6-9B44-D23F19F2D4B6}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{08DD87C0-C734-45D6-9B44-D23F19F2D4B6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{08DD87C0-C734-45D6-9B44-D23F19F2D4B6}.Debug|x64.Build.0 = Debug|x64
|
||||
{08DD87C0-C734-45D6-9B44-D23F19F2D4B6}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{08DD87C0-C734-45D6-9B44-D23F19F2D4B6}.Release|Win32.Build.0 = Release|Win32
|
||||
{08DD87C0-C734-45D6-9B44-D23F19F2D4B6}.Release|x64.ActiveCfg = Release|x64
|
||||
{08DD87C0-C734-45D6-9B44-D23F19F2D4B6}.Release|x64.Build.0 = Release|x64
|
||||
{663A7E89-1E42-4222-921C-177F5B5910DF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{663A7E89-1E42-4222-921C-177F5B5910DF}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{663A7E89-1E42-4222-921C-177F5B5910DF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
||||
Reference in New Issue
Block a user