mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-23 04:55:13 +00:00
asfdafds
This commit is contained in:
parent
484f6570aa
commit
d4c48a06a1
1 changed files with 502 additions and 506 deletions
100
extern/imgui_software_renderer/imgui_sw.cpp
vendored
100
extern/imgui_software_renderer/imgui_sw.cpp
vendored
|
@ -32,14 +32,11 @@ static ImGui_ImplSW_Data* ImGui_ImplSW_GetBackendData()
|
|||
return ImGui::GetCurrentContext() ? (ImGui_ImplSW_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// TODO: de-namespace and static-ize
|
||||
namespace {
|
||||
struct PaintTarget
|
||||
{
|
||||
uint32_t *pixels;
|
||||
int width;
|
||||
int height;
|
||||
ImVec2 scale;// Multiply ImGui (point) coordinates with this to get pixel coordinates.
|
||||
ImVec2 DisplayPos;
|
||||
};
|
||||
|
||||
|
@ -55,13 +52,16 @@ namespace {
|
|||
ColorInt():
|
||||
u32(0) {}
|
||||
|
||||
ColorInt(uint32_t c):
|
||||
u32(c) {}
|
||||
|
||||
|
||||
ColorInt &operator*=(const ColorInt &other)
|
||||
{
|
||||
r = r * other.r / 255;
|
||||
g = g * other.g / 255;
|
||||
b = b * other.b / 255;
|
||||
a = a * other.a / 255;
|
||||
r = (r * other.r + 255) >> 8;
|
||||
g = (g * other.g + 255) >> 8;
|
||||
b = (b * other.b + 255) >> 8;
|
||||
a = (a * other.a + 255) >> 8;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
@ -69,7 +69,7 @@ namespace {
|
|||
|
||||
uint32_t blend(const ColorInt &target, const ColorInt &source)
|
||||
{
|
||||
if (source.a >= 255) return *reinterpret_cast<const uint32_t *>(&source);
|
||||
if (source.a >= 255) return source.u32;
|
||||
return (target.a << 24u) | (((source.b * source.a + target.b * (255 - source.a)) / 255) << 16u)
|
||||
| (((source.g * source.a + target.g * (255 - source.a)) / 255) << 8u)
|
||||
| ((source.r * source.a + target.r * (255 - source.a)) / 255);
|
||||
|
@ -109,7 +109,7 @@ namespace {
|
|||
// ----------------------------------------------------------------------------
|
||||
// Copies of functions in ImGui, inlined for speed:
|
||||
|
||||
ImVec4 color_convert_u32_to_float4(ImU32 in)
|
||||
inline ImVec4 color_convert_u32_to_float4(ImU32 in)
|
||||
{
|
||||
const float s = 1.0f / 255.0f;
|
||||
return ImVec4(((in >> IM_COL32_R_SHIFT) & 0xFF) * s,
|
||||
|
@ -118,7 +118,7 @@ namespace {
|
|||
((in >> IM_COL32_A_SHIFT) & 0xFF) * s);
|
||||
}
|
||||
|
||||
ImU32 color_convert_float4_to_u32(const ImVec4 &in)
|
||||
inline ImU32 color_convert_float4_to_u32(const ImVec4 &in)
|
||||
{
|
||||
ImU32 out;
|
||||
out = uint32_t(in.x * 255.0f + 0.5f) << IM_COL32_R_SHIFT;
|
||||
|
@ -152,19 +152,19 @@ namespace {
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
float min3(float a, float b, float c)
|
||||
inline float min3(float a, float b, float c)
|
||||
{
|
||||
if (a < b && a < c) { return a; }
|
||||
return b < c ? b : c;
|
||||
}
|
||||
|
||||
float max3(float a, float b, float c)
|
||||
inline float max3(float a, float b, float c)
|
||||
{
|
||||
if (a > b && a > c) { return a; }
|
||||
return b > c ? b : c;
|
||||
}
|
||||
|
||||
float barycentric(const ImVec2 &a, const ImVec2 &b, const ImVec2 &point)
|
||||
inline float barycentric(const ImVec2 &a, const ImVec2 &b, const ImVec2 &point)
|
||||
{
|
||||
return (b.x - a.x) * (point.y - a.y) - (b.y - a.y) * (point.x - a.x);
|
||||
}
|
||||
|
@ -176,16 +176,16 @@ namespace {
|
|||
|
||||
inline uint32_t sample_texture(const SWTexture &texture, int x, int y) { return texture.pixels[x + y * texture.width]; }
|
||||
|
||||
void paint_uniform_rectangle(const PaintTarget &target,
|
||||
static void paint_uniform_rectangle(const PaintTarget &target,
|
||||
const ImVec2 &min_f,
|
||||
const ImVec2 &max_f,
|
||||
const ColorInt &color)
|
||||
{
|
||||
// Integer bounding box [min, max):
|
||||
int min_x_i = static_cast<int>(target.scale.x * min_f.x + 0.5f);
|
||||
int min_y_i = static_cast<int>(target.scale.y * min_f.y + 0.5f);
|
||||
int max_x_i = static_cast<int>(target.scale.x * max_f.x + 0.5f);
|
||||
int max_y_i = static_cast<int>(target.scale.y * max_f.y + 0.5f);
|
||||
int min_x_i = static_cast<int>(min_f.x + 0.5f);
|
||||
int min_y_i = static_cast<int>(min_f.y + 0.5f);
|
||||
int max_x_i = static_cast<int>(max_f.x + 0.5f);
|
||||
int max_y_i = static_cast<int>(max_f.y + 0.5f);
|
||||
|
||||
// Clamp to render target:
|
||||
min_x_i = std::max(min_x_i, 0);
|
||||
|
@ -213,14 +213,14 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
void paint_uniform_textured_rectangle(const PaintTarget &target,
|
||||
static void paint_uniform_textured_rectangle(const PaintTarget &target,
|
||||
const SWTexture &texture,
|
||||
const ImVec4 &clip_rect,
|
||||
const ImDrawVert &min_v,
|
||||
const ImDrawVert &max_v)
|
||||
{
|
||||
const ImVec2 min_p = ImVec2(target.scale.x * min_v.pos.x, target.scale.y * min_v.pos.y);
|
||||
const ImVec2 max_p = ImVec2(target.scale.x * max_v.pos.x, target.scale.y * max_v.pos.y);
|
||||
const ImVec2 min_p = ImVec2(min_v.pos.x, min_v.pos.y);
|
||||
const ImVec2 max_p = ImVec2(max_v.pos.x, max_v.pos.y);
|
||||
|
||||
float distanceX = max_p.x - min_p.x;
|
||||
float distanceY = max_p.y - min_p.y;
|
||||
|
@ -233,10 +233,10 @@ namespace {
|
|||
float max_y_f = max_p.y;
|
||||
|
||||
// Clip against clip_rect:
|
||||
min_x_f = std::max(min_x_f, target.scale.x * clip_rect.x - target.DisplayPos.x);
|
||||
min_y_f = std::max(min_y_f, target.scale.y * clip_rect.y - target.DisplayPos.y);
|
||||
max_x_f = std::min(max_x_f, target.scale.x * clip_rect.z - 0.5f - target.DisplayPos.x);
|
||||
max_y_f = std::min(max_y_f, target.scale.y * clip_rect.w - 0.5f - target.DisplayPos.y);
|
||||
min_x_f = std::max(min_x_f, clip_rect.x - target.DisplayPos.x);
|
||||
min_y_f = std::max(min_y_f, clip_rect.y - target.DisplayPos.y);
|
||||
max_x_f = std::min(max_x_f, clip_rect.z - 0.5f - target.DisplayPos.x);
|
||||
max_y_f = std::min(max_y_f, clip_rect.w - 0.5f - target.DisplayPos.y);
|
||||
|
||||
// Integer bounding box [min, max):
|
||||
int min_x_i = static_cast<int>(min_x_f);
|
||||
|
@ -250,7 +250,7 @@ namespace {
|
|||
max_x_i = std::min(max_x_i, target.width);
|
||||
max_y_i = std::min(max_y_i, target.height);
|
||||
|
||||
const auto topleft = ImVec2(min_x_i + 0.5f * target.scale.x, min_y_i + 0.5f * target.scale.y);
|
||||
const auto topleft = ImVec2(min_x_i + 0.5f, min_y_i + 0.5f);
|
||||
const ImVec2 delta_uv_per_pixel = {
|
||||
(max_v.uv.x - min_v.uv.x) / distanceX,
|
||||
(max_v.uv.y - min_v.uv.y) / distanceY,
|
||||
|
@ -273,8 +273,8 @@ namespace {
|
|||
currentX = startX;
|
||||
for (int x = min_x_i; x < max_x_i; ++x) {
|
||||
uint32_t& target_pixel = target.pixels[y * target.width + x];
|
||||
const auto *targetColorRef = reinterpret_cast<const ColorInt *>(&target_pixel);
|
||||
const auto *colorRef = reinterpret_cast<const ColorInt *>(&min_v.col);
|
||||
const ColorInt targetColorRef = ColorInt(target_pixel);
|
||||
const ColorInt colorRef = ColorInt(min_v.col);
|
||||
|
||||
if (texture.isAlpha) {
|
||||
uint8_t texel = sample_font_texture(texture, currentX, currentY);
|
||||
|
@ -283,18 +283,18 @@ namespace {
|
|||
// The font texture is all black or all white, so optimize for this:
|
||||
if (texel == 0) { continue; }
|
||||
if (texel == 255) {
|
||||
target_pixel = blend(*targetColorRef, *colorRef);
|
||||
target_pixel = blend(targetColorRef, colorRef);
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
auto texColor = sample_texture(texture, currentX, currentY);
|
||||
auto src_color = reinterpret_cast<ColorInt *>(&texColor);
|
||||
uint32_t texColor = sample_texture(texture, currentX, currentY);
|
||||
auto src_color = ColorInt(texColor);
|
||||
|
||||
if (deltaX != 0 && currentX < texture.width - 1) { currentX += 1; }
|
||||
|
||||
*src_color *= *colorRef;
|
||||
target_pixel = blend(*targetColorRef, *src_color);
|
||||
src_color *= colorRef;
|
||||
target_pixel = blend(targetColorRef, src_color);
|
||||
}
|
||||
}
|
||||
if (deltaY != 0 && currentY < texture.height - 1) { currentY += 1; }
|
||||
|
@ -305,23 +305,23 @@ namespace {
|
|||
// The edge will be the same, but the direction will be the opposite
|
||||
// (assuming the two triangles have the same winding order).
|
||||
// Which edge wins? This functions decides.
|
||||
bool is_dominant_edge(ImVec2 edge)
|
||||
static bool is_dominant_edge(ImVec2 edge)
|
||||
{
|
||||
// return edge.x < 0 || (edge.x == 0 && edge.y > 0);
|
||||
return edge.y > 0 || (edge.y == 0 && edge.x < 0);
|
||||
}
|
||||
|
||||
// Handles triangles in any winding order (CW/CCW)
|
||||
void paint_triangle(const PaintTarget &target,
|
||||
static void paint_triangle(const PaintTarget &target,
|
||||
const SWTexture *texture,
|
||||
const ImVec4 &clip_rect,
|
||||
const ImDrawVert &v0,
|
||||
const ImDrawVert &v1,
|
||||
const ImDrawVert &v2)
|
||||
{
|
||||
const ImVec2 p0 = ImVec2(target.scale.x * v0.pos.x, target.scale.y * v0.pos.y);
|
||||
const ImVec2 p1 = ImVec2(target.scale.x * v1.pos.x, target.scale.y * v1.pos.y);
|
||||
const ImVec2 p2 = ImVec2(target.scale.x * v2.pos.x, target.scale.y * v2.pos.y);
|
||||
const ImVec2 p0 = ImVec2(v0.pos.x, v0.pos.y);
|
||||
const ImVec2 p1 = ImVec2(v1.pos.x, v1.pos.y);
|
||||
const ImVec2 p2 = ImVec2(v2.pos.x, v2.pos.y);
|
||||
|
||||
const auto rect_area = barycentric(p0, p1, p2);// Can be positive or negative depending on winding order
|
||||
if (rect_area == 0.0f) { return; }
|
||||
|
@ -334,10 +334,10 @@ namespace {
|
|||
float max_y_f = max3(p0.y, p1.y, p2.y);
|
||||
|
||||
// Clip against clip_rect:
|
||||
min_x_f = std::max(min_x_f, target.scale.x * clip_rect.x - target.DisplayPos.x);
|
||||
min_y_f = std::max(min_y_f, target.scale.y * clip_rect.y - target.DisplayPos.y);
|
||||
max_x_f = std::min(max_x_f, target.scale.x * clip_rect.z - 0.5f - target.DisplayPos.x);
|
||||
max_y_f = std::min(max_y_f, target.scale.y * clip_rect.w - 0.5f - target.DisplayPos.y);
|
||||
min_x_f = std::max(min_x_f, clip_rect.x - target.DisplayPos.x);
|
||||
min_y_f = std::max(min_y_f, clip_rect.y - target.DisplayPos.y);
|
||||
max_x_f = std::min(max_x_f, clip_rect.z - 0.5f - target.DisplayPos.x);
|
||||
max_y_f = std::min(max_y_f, clip_rect.w - 0.5f - target.DisplayPos.y);
|
||||
|
||||
// Integer bounding box [min, max):
|
||||
int min_x_i = static_cast<int>(min_x_f);
|
||||
|
@ -354,7 +354,7 @@ namespace {
|
|||
// ------------------------------------------------------------------------
|
||||
// Set up interpolation of barycentric coordinates:
|
||||
|
||||
const auto topleft = ImVec2(min_x_i + 0.5f * target.scale.x, min_y_i + 0.5f * target.scale.y);
|
||||
const auto topleft = ImVec2(min_x_i + 0.5f, min_y_i + 0.5f);
|
||||
const auto dx = ImVec2(1, 0);
|
||||
const auto dy = ImVec2(0, 1);
|
||||
|
||||
|
@ -481,7 +481,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
void paint_draw_cmd(const PaintTarget &target,
|
||||
static void paint_draw_cmd(const PaintTarget &target,
|
||||
const ImDrawVert *vertices,
|
||||
const ImDrawIdx *idx_buffer,
|
||||
const ImDrawCmd &pcmd,
|
||||
|
@ -582,7 +582,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
void paint_draw_list(const PaintTarget &target, const ImDrawList *cmd_list, const SwOptions &options)
|
||||
static void paint_draw_list(const PaintTarget &target, const ImDrawList *cmd_list, const SwOptions &options)
|
||||
{
|
||||
const ImDrawIdx *idx_buffer = &cmd_list->IdxBuffer[0];
|
||||
const ImDrawVert *vertices = cmd_list->VtxBuffer.Data;
|
||||
|
@ -598,15 +598,11 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
}// namespace
|
||||
|
||||
void paint_imgui(uint32_t *pixels, ImDrawData *drawData, const SwOptions &options = {})
|
||||
static void paint_imgui(uint32_t *pixels, ImDrawData *drawData, int fb_width, int fb_height, const SwOptions &options = {})
|
||||
{
|
||||
int fb_width = (int)(drawData->DisplaySize.x * drawData->FramebufferScale.x);
|
||||
int fb_height = (int)(drawData->DisplaySize.y * drawData->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0) return;
|
||||
|
||||
PaintTarget target{ pixels, fb_width, fb_height, drawData->FramebufferScale, drawData->DisplayPos };
|
||||
PaintTarget target{ pixels, fb_width, fb_height, drawData->DisplayPos };
|
||||
|
||||
for (int i = 0; i < drawData->CmdListsCount; ++i) {
|
||||
paint_draw_list(target, drawData->CmdLists[i], options);
|
||||
|
@ -662,7 +658,7 @@ void ImGui_ImplSW_RenderDrawData(ImDrawData* draw_data) {
|
|||
if (mustLock) {
|
||||
if (SDL_LockSurface(surf)!=0) return;
|
||||
}
|
||||
paint_imgui((uint32_t*)surf->pixels,draw_data);
|
||||
paint_imgui((uint32_t*)surf->pixels,draw_data,surf->w,surf->h);
|
||||
if (mustLock) {
|
||||
SDL_UnlockSurface(surf);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue