Skip to content

Commit 886159d

Browse files
committed
feat: allow image draws with stacked mask texture
DrawImage and DrawImageQuad now supports a final maskIdx that indicates which texture in the stack to multiply the final output with; adding the ability to mask out undesired parts of the image. As it needs to be in the same stack, the mask image needs to have the same size and image format as the colour image.
1 parent 168b1e5 commit 886159d

5 files changed

Lines changed: 92 additions & 41 deletions

File tree

engine/render.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class r_shaderHnd_c {
5252
friend class r_renderer_c;
5353
public:
5454
~r_shaderHnd_c();
55+
56+
std::optional<int> StackCount() const;
5557
private:
5658
r_shaderHnd_c(class r_shader_c* sh);
5759
r_shader_c* sh;
@@ -90,8 +92,8 @@ class r_IRenderer {
9092
virtual void SetBlendMode(int mode) = 0;
9193
virtual void DrawColor(const col4_t col = NULL) = 0;
9294
virtual void DrawColor(dword col) = 0;
93-
virtual void DrawImage(r_shaderHnd_c* hnd, glm::vec2 pos, glm::vec2 extent, glm::vec2 uv1 = { 0, 0 }, glm::vec2 uv2 = { 1, 1 }, int stackLayer = 0) = 0;
94-
virtual void DrawImageQuad(r_shaderHnd_c* hnd, glm::vec2 p0, glm::vec2 p1, glm::vec2 p2, glm::vec2 p3, glm::vec2 uv0 = { 0, 0 }, glm::vec2 uv1 = { 1, 0 }, glm::vec2 uv2 = { 1, 1 }, glm::vec2 uv3 = { 0, 1 }, int stackLayer = 0) = 0;
95+
virtual void DrawImage(r_shaderHnd_c* hnd, glm::vec2 pos, glm::vec2 extent, glm::vec2 uv1 = { 0, 0 }, glm::vec2 uv2 = { 1, 1 }, int stackLayer = 0, std::optional<int> maskLayer = {}) = 0;
96+
virtual void DrawImageQuad(r_shaderHnd_c* hnd, glm::vec2 p0, glm::vec2 p1, glm::vec2 p2, glm::vec2 p3, glm::vec2 uv0 = { 0, 0 }, glm::vec2 uv1 = { 1, 0 }, glm::vec2 uv2 = { 1, 1 }, glm::vec2 uv3 = { 0, 1 }, int stackLayer = 0, std::optional<int> maskLayer = {}) = 0;
9597
virtual void DrawString(float x, float y, int align, int height, const col4_t col, int font, const char* str) = 0;
9698
virtual void DrawStringFormat(float x, float y, int align, int height, const col4_t col, int font, const char* fmt, ...) = 0;
9799
virtual int DrawStringWidth(int height, int font, const char* str) = 0;

engine/render/r_main.cpp

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ struct r_layerCmdQuad_s {
163163
float t[4];
164164
float x[4];
165165
float y[4];
166-
int stackLayer;
166+
int stackLayer, maskLayer;
167167
} quad;
168168
};
169169

@@ -263,7 +263,7 @@ void r_layer_c::Color(col4_t col)
263263
}
264264
}
265265

266-
void r_layer_c::Quad(float s0, float t0, float x0, float y0, float s1, float t1, float x1, float y1, float s2, float t2, float x2, float y2, float s3, float t3, float x3, float y3, int stackLayer)
266+
void r_layer_c::Quad(float s0, float t0, float x0, float y0, float s1, float t1, float x1, float y1, float s2, float t2, float x2, float y2, float s3, float t3, float x3, float y3, int stackLayer, int maskLayer)
267267
{
268268
if (auto* cmd = (r_layerCmdQuad_s*)NewCommand(CommandSize(r_layerCmd_s::QUAD))) {
269269
cmd->cmd = r_layerCmd_s::QUAD;
@@ -272,6 +272,7 @@ void r_layer_c::Quad(float s0, float t0, float x0, float y0, float s1, float t1,
272272
cmd->quad.x[0] = x0; cmd->quad.x[1] = x1; cmd->quad.x[2] = x2; cmd->quad.x[3] = x3;
273273
cmd->quad.y[0] = y0; cmd->quad.y[1] = y1; cmd->quad.y[2] = y2; cmd->quad.y[3] = y3;
274274
cmd->quad.stackLayer = stackLayer;
275+
cmd->quad.maskLayer = maskLayer;
275276
}
276277
}
277278

@@ -320,10 +321,10 @@ bool AabbAabbIntersects(r_aabb_s& a, r_aabb_s& b)
320321

321322
struct Vertex {
322323
float x, y;
323-
float u, v, w;
324+
float u, v;
324325
float r, g, b, a;
325326
float viewX, viewY, viewW, viewH;
326-
float texId;
327+
float texId, stackIdx, maskIdx;
327328
};
328329

329330
struct Batch {
@@ -338,8 +339,8 @@ struct Batch {
338339
GLint xyAttr;
339340
GLint uvAttr;
340341
GLint tintAttr;
341-
GLint texIdAttr;
342342
GLint viewportAttr;
343+
GLint texIdAttr;
343344

344345
std::vector<Vertex> vertices;
345346

@@ -352,8 +353,8 @@ Batch::Batch(GLuint prog)
352353
xyAttr = glGetAttribLocation(prog, "a_vertex");
353354
uvAttr = glGetAttribLocation(prog, "a_texcoord");
354355
tintAttr = glGetAttribLocation(prog, "a_tint");
355-
texIdAttr = glGetAttribLocation(prog, "a_texId");
356356
viewportAttr = glGetAttribLocation(prog, "a_viewport");
357+
texIdAttr = glGetAttribLocation(prog, "a_texId");
357358
}
358359

359360
Batch::Batch(Batch&& rhs)
@@ -362,6 +363,7 @@ Batch::Batch(Batch&& rhs)
362363
, uvAttr(rhs.uvAttr)
363364
, tintAttr(rhs.tintAttr)
364365
, viewportAttr(rhs.viewportAttr)
366+
, texIdAttr(rhs.texIdAttr)
365367
, vertices(std::move(rhs.vertices))
366368
{
367369
}
@@ -371,8 +373,8 @@ Batch& Batch::operator = (Batch&& rhs) {
371373
xyAttr = rhs.xyAttr;
372374
uvAttr = rhs.uvAttr;
373375
tintAttr = rhs.tintAttr;
374-
texIdAttr = rhs.texIdAttr;
375376
viewportAttr = rhs.viewportAttr;
377+
texIdAttr = rhs.texIdAttr;
376378
vertices = std::move(rhs.vertices);
377379

378380
return *this;
@@ -392,21 +394,21 @@ void Batch::Execute(GLuint sharedVbo, size_t vertexBase)
392394
auto dataSize = vertices.size() * sizeof(Vertex);
393395
glBufferSubData(GL_ARRAY_BUFFER, dataOff, dataSize, dataPtr);
394396
glVertexAttribPointer(xyAttr, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void const*)offsetof(Vertex, x));
395-
glVertexAttribPointer(uvAttr, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void const*)offsetof(Vertex, u));
397+
glVertexAttribPointer(uvAttr, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void const*)offsetof(Vertex, u));
396398
glVertexAttribPointer(tintAttr, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void const*)offsetof(Vertex, r));
397-
glVertexAttribPointer(texIdAttr, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void const*)offsetof(Vertex, texId));
398399
glVertexAttribPointer(viewportAttr, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void const*)offsetof(Vertex, viewX));
400+
glVertexAttribPointer(texIdAttr, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void const*)offsetof(Vertex, texId));
399401
glEnableVertexAttribArray(xyAttr);
400402
glEnableVertexAttribArray(uvAttr);
401403
glEnableVertexAttribArray(tintAttr);
402-
glEnableVertexAttribArray(texIdAttr);
403404
glEnableVertexAttribArray(viewportAttr);
405+
glEnableVertexAttribArray(texIdAttr);
404406
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertices.size());
405407
glDisableVertexAttribArray(xyAttr);
406408
glDisableVertexAttribArray(uvAttr);
407409
glDisableVertexAttribArray(tintAttr);
408-
glDisableVertexAttribArray(texIdAttr);
409410
glDisableVertexAttribArray(viewportAttr);
411+
glDisableVertexAttribArray(texIdAttr);
410412
glBindBuffer(GL_ARRAY_BUFFER, 0);
411413
vertices.clear();
412414
}
@@ -536,18 +538,19 @@ struct AdjacentMergeStrategy : RenderStrategy {
536538
auto& vp = nextViewport_;
537539
q.u = c->quad.s[v];
538540
q.v = c->quad.t[v];
539-
q.w = (float)c->quad.stackLayer;
540541
q.x = c->quad.x[v];
541542
q.y = c->quad.y[v];
542543
q.r = tint_[0];
543544
q.g = tint_[1];
544545
q.b = tint_[2];
545546
q.a = tint_[3];
546-
q.texId = (float)texSlot;
547547
q.viewX = (float)vp.x;
548548
q.viewY = (float)vp.y;
549549
q.viewW = (float)vp.width;
550550
q.viewH = (float)vp.height;
551+
q.texId = (float)texSlot;
552+
q.stackIdx = (float)c->quad.stackLayer;
553+
q.maskIdx = (float)c->quad.maskLayer;
551554
}
552555
// 3-2
553556
// |/|
@@ -784,16 +787,16 @@ static char const* s_tintedTextureVertexSource = R"(#version 300 es
784787
uniform mat4 mvp_matrix;
785788
786789
in vec2 a_vertex;
787-
in vec3 a_texcoord;
790+
in vec2 a_texcoord;
788791
in vec4 a_tint;
789-
in float a_texId;
790792
in vec4 a_viewport;
793+
in vec3 a_texId;
791794
792795
out vec2 v_screenPos;
793-
out vec3 v_texcoord;
796+
out vec2 v_texcoord;
794797
out vec4 v_tint;
795-
out float v_texId;
796798
out vec4 v_viewport;
799+
out vec3 v_texId;
797800
798801
void main(void)
799802
{
@@ -818,10 +821,10 @@ uniform highp sampler2DArray s_tex[{SG_TEXTURE_COUNT}];
818821
uniform vec4 i_tint;
819822
820823
in vec2 v_screenPos;
821-
in vec3 v_texcoord;
824+
in vec2 v_texcoord;
822825
in vec4 v_tint;
823-
in float v_texId;
824826
in vec4 v_viewport; // x0, y0, x1, y1
827+
in vec3 v_texId;
825828
826829
out vec4 f_fragColor;
827830
@@ -960,15 +963,20 @@ void r_renderer_c::Init(r_featureFlag_e features)
960963
fmt::memory_buffer buf;
961964
for (size_t i = 0; i < maxTextureImageUnits; ++i) {
962965
if (i == 0) {
963-
fmt::format_to(fmt::appender(buf), "if (v_texId < {}.5) ", i);
966+
fmt::format_to(fmt::appender(buf), "if (v_texId.x < {}.5) ", i);
964967
}
965968
else if (i == maxTextureImageUnits - 1) {
966969
fmt::format_to(fmt::appender(buf), "else ");
967970
}
968971
else {
969-
fmt::format_to(fmt::appender(buf), "else if (v_texId < {}.5)", i);
972+
fmt::format_to(fmt::appender(buf), "else if (v_texId.x < {}.5)", i);
970973
}
971-
fmt::format_to(fmt::appender(buf), "color = texture(s_tex[{}], v_texcoord);\n", i);
974+
fmt::format_to(fmt::appender(buf), R"( {{
975+
color = texture(s_tex[{}], vec3(v_texcoord, v_texId.y));
976+
if (v_texId.z > -0.5)
977+
color *= texture(s_tex[{}], vec3(v_texcoord, v_texId.z));
978+
}}
979+
)", i, i);
972980
}
973981
textureSwitch = to_string(buf);
974982
}
@@ -1544,6 +1552,13 @@ void r_renderer_c::EndFrame()
15441552
// Shader Management
15451553
// =================
15461554

1555+
std::optional<int> r_shaderHnd_c::StackCount() const
1556+
{
1557+
if (!sh || sh->tex->status != r_tex_c::Status::DONE)
1558+
return {};
1559+
return (int)sh->tex->stackLayers;
1560+
}
1561+
15471562
void r_renderer_c::PurgeShaders()
15481563
{
15491564
// Delete released shaders
@@ -1721,7 +1736,7 @@ void r_renderer_c::DrawColor(dword col)
17211736
drawColor[3] = (col >> 24) / 255.0f;
17221737
}
17231738

1724-
void r_renderer_c::DrawImage(r_shaderHnd_c* hnd, glm::vec2 pos, glm::vec2 extent, glm::vec2 uv1, glm::vec2 uv2, int stackLayer)
1739+
void r_renderer_c::DrawImage(r_shaderHnd_c* hnd, glm::vec2 pos, glm::vec2 extent, glm::vec2 uv1, glm::vec2 uv2, int stackLayer, std::optional<int> maskLayer)
17251740
{
17261741
DrawImageQuad(hnd,
17271742
pos,
@@ -1732,10 +1747,10 @@ void r_renderer_c::DrawImage(r_shaderHnd_c* hnd, glm::vec2 pos, glm::vec2 extent
17321747
{ uv2.s, uv1.t },
17331748
uv2,
17341749
{ uv1.s, uv2.t },
1735-
stackLayer);
1750+
stackLayer, maskLayer);
17361751
}
17371752

1738-
void r_renderer_c::DrawImageQuad(r_shaderHnd_c* hnd, glm::vec2 p0, glm::vec2 p1, glm::vec2 p2, glm::vec2 p3, glm::vec2 uv0, glm::vec2 uv1, glm::vec2 uv2, glm::vec2 uv3, int stackLayer)
1753+
void r_renderer_c::DrawImageQuad(r_shaderHnd_c* hnd, glm::vec2 p0, glm::vec2 p1, glm::vec2 p2, glm::vec2 p3, glm::vec2 uv0, glm::vec2 uv1, glm::vec2 uv2, glm::vec2 uv3, int stackLayer, std::optional<int> maskLayer)
17391754
{
17401755
if (hnd) {
17411756
curLayer->Bind(hnd->sh->tex);
@@ -1751,7 +1766,7 @@ void r_renderer_c::DrawImageQuad(r_shaderHnd_c* hnd, glm::vec2 p0, glm::vec2 p1,
17511766
uv1.s, uv1.t, p1.x, p1.y,
17521767
uv2.s, uv2.t, p2.x, p2.y,
17531768
uv3.s, uv3.t, p3.x, p3.y,
1754-
stackLayer);
1769+
stackLayer, maskLayer.value_or(-1));
17551770
}
17561771

17571772
void r_renderer_c::DrawString(float x, float y, int align, int height, const col4_t col, int font, const char* str)

engine/render/r_main.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class r_layer_c {
4545
void SetBlendMode(int mode);
4646
void Bind(r_tex_c* tex);
4747
void Color(col4_t col);
48-
void Quad(float s0, float t0, float x0, float y0, float s1, float t1, float x1, float y1, float s2, float t2, float x2, float y2, float s3, float t3, float x3, float y3, int stackLayer = 0);
48+
void Quad(float s0, float t0, float x0, float y0, float s1, float t1, float x1, float y1, float s2, float t2, float x2, float y2, float s3, float t3, float x3, float y3, int stackLayer = 0, int maskLayer = -1);
4949
void Render();
5050
void Discard();
5151

@@ -89,8 +89,8 @@ class r_renderer_c: public r_IRenderer, public conCmdHandler_c {
8989
void SetBlendMode(int mode);
9090
void DrawColor(const col4_t col = NULL);
9191
void DrawColor(dword col);
92-
void DrawImage(r_shaderHnd_c* hnd, glm::vec2 pos, glm::vec2 extent, glm::vec2 uv1 = { 0, 0 }, glm::vec2 uv2 = { 1, 1 }, int stackLayer = 0);
93-
void DrawImageQuad(r_shaderHnd_c* hnd, glm::vec2 p0, glm::vec2 p1, glm::vec2 p2, glm::vec2 p3, glm::vec2 uv0 = { 0, 0 }, glm::vec2 uv1 = { 1, 0 }, glm::vec2 uv2 = { 1, 1 }, glm::vec2 uv3 = { 0, 1 }, int stackLayer = 0);
92+
void DrawImage(r_shaderHnd_c* hnd, glm::vec2 pos, glm::vec2 extent, glm::vec2 uv1 = { 0, 0 }, glm::vec2 uv2 = { 1, 1 }, int stackLayer = 0, std::optional<int> maskLayer = {});
93+
void DrawImageQuad(r_shaderHnd_c* hnd, glm::vec2 p0, glm::vec2 p1, glm::vec2 p2, glm::vec2 p3, glm::vec2 uv0 = { 0, 0 }, glm::vec2 uv1 = { 1, 0 }, glm::vec2 uv2 = { 1, 1 }, glm::vec2 uv3 = { 0, 1 }, int stackLayer = 0, std::optional<int> maskLayer = {});
9494
void DrawString(float x, float y, int align, int height, const col4_t col, int font, const char* str);
9595
void DrawStringFormat(float x, float y, int align, int height, const col4_t col, int font, const char* fmt, ...);
9696
int DrawStringWidth(int height, int font, const char* str);

engine/render/r_texture.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ std::unique_ptr<image_c> r_tex_c::BuildMipSet(std::unique_ptr<image_c> img)
446446
const size_t levels = newTex.levels();
447447
for (size_t level = 1; level < levels; ++level) {
448448
const auto srcExtent = newTex.extent(level - 1);
449-
const auto comp = gli::component_count(format);
449+
const auto comp = (int)gli::component_count(format);
450450
const auto dstExtent = newTex.extent(level);
451451
const bool hasAlpha = comp == 4;
452452
stbir_resize_uint8_srgb_edgemode(

ui_api.cpp

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@
5959
** GetDrawLayer()
6060
** SetViewport([x, y, width, height])
6161
** SetDrawColor(red, green, blue[, alpha]) / SetDrawColor("<escapeStr>")
62-
** DrawImage({imgHandle|nil}, left, top, width, height[, tcLeft, tcTop, tcRight, tcBottom][, stackIdx[, mask]]) mask: nil|"arc"|"circle" // TODO(zao): define how mask works, none implemented yet
63-
** DrawImageQuad({imgHandle|nil}, x1, y1, x2, y2, x3, y3, x4, y4[, s1, t1, s2, t2, s3, t3, s4, t4][, stackIdx[, mask]])
62+
** DrawImage({imgHandle|nil}, left, top, width, height[, tcLeft, tcTop, tcRight, tcBottom][, stackIdx[, maskIdx]]) maskIdx: use a stack layer as multiplicative mask
63+
** DrawImageQuad({imgHandle|nil}, x1, y1, x2, y2, x3, y3, x4, y4[, s1, t1, s2, t2, s3, t3, s4, t4][, stackIdx[, maskIdx]])
6464
** DrawString(left, top, align{"LEFT"|"CENTER"|"RIGHT"|"CENTER_X"|"RIGHT_X"}, height, font{"FIXED"|"VAR"|"VAR BOLD"}, "<text>")
6565
** width = DrawStringWidth(height, font{"FIXED"|"VAR"|"VAR BOLD"}, "<text>")
6666
** index = DrawStringCursorIndex(height, font{"FIXED"|"VAR"|"VAR BOLD"}, "<text>", cursorX, cursorY)
@@ -858,6 +858,7 @@ static int l_DrawImage(lua_State* L)
858858
r_shaderHnd_c* hnd = NULL;
859859
glm::vec2 xys[2]{}, uvs[2]{};
860860
int stackLayer = 0;
861+
std::optional<int> maskLayer{};
861862

862863
// | n |img| corners | uvs | stack | mask |
863864
// | 5 | X | X | | | |
@@ -911,17 +912,33 @@ static int l_DrawImage(lua_State* L)
911912
uvs[1] = { 1, 1 };
912913
}
913914

915+
std::optional<int> maxStackValue;
916+
if (hnd)
917+
maxStackValue = hnd->StackCount();
918+
914919
if (af & AF_STACK) {
915920
ui->LAssert(L, lua_isinteger(L, k), "DrawImage() argument %d: expected integer, got %s", k, luaL_typename(L, k));
916-
stackLayer = (int)lua_tointeger(L, k);
921+
const int val = (int)lua_tointeger(L, k);
922+
ui->LAssert(L, val > 0, "DrawImage() argument %d: expected positive integer, got %d", k, val);
923+
if (maxStackValue.has_value())
924+
ui->LAssert(L, val <= *maxStackValue, "DrawImage() argument %d: expected valid stack index <= %d, got %d", k, *maxStackValue, val);
925+
stackLayer = val - 1;
917926
k += 1;
918927
}
919928

920929
if (af & AF_MASK) {
921-
ui->LAssert(L, lua_isnil(L, k) || lua_istable(L, k), "DrawImage() argument %d: expected integer or nil, got %s", k, luaL_typename(L, k));
930+
ui->LAssert(L, lua_isnil(L, k) || lua_isinteger(L, k), "DrawImage() argument %d: expected integer or nil, got %s", k, luaL_typename(L, k));
931+
if (lua_isinteger(L, k)) {
932+
const int val = (int)lua_tointeger(L, k);
933+
ui->LAssert(L, val > 0, "DrawImage() argument %d: expected positive integer, got %d", k, val);
934+
if (maxStackValue.has_value())
935+
ui->LAssert(L, val <= *maxStackValue, "DrawImage() argument %d: expected valid stack index <= %d, got %d", k, *maxStackValue, val);
936+
maskLayer = val - 1;
937+
}
938+
k += 1;
922939
}
923940

924-
ui->renderer->DrawImage(hnd, xys[0], xys[1], uvs[0], uvs[1], stackLayer);
941+
ui->renderer->DrawImage(hnd, xys[0], xys[1], uvs[0], uvs[1], stackLayer, maskLayer);
925942

926943
return 0;
927944
}
@@ -938,7 +955,8 @@ static int l_DrawImageQuad(lua_State* L)
938955

939956
r_shaderHnd_c* hnd = NULL;
940957
glm::vec2 xys[4]{}, uvs[4]{};
941-
int stackLayer{};
958+
int stackLayer = 0;
959+
std::optional<int> maskLayer{};
942960

943961
// | n |img| corners | uvs | stack | mask |
944962
// | 9 | X | X | | | |
@@ -994,18 +1012,34 @@ static int l_DrawImageQuad(lua_State* L)
9941012
uvs[3] = { 0, 1 };
9951013
}
9961014

1015+
std::optional<int> maxStackValue;
1016+
if (hnd)
1017+
maxStackValue = hnd->StackCount();
1018+
9971019
if (af & AF_STACK) {
9981020
ui->LAssert(L, lua_isinteger(L, k), "DrawImageQuad() argument %d: expected integer, got %s", k, luaL_typename(L, k));
999-
stackLayer = (int)lua_tointeger(L, k);
1021+
const int val = (int)lua_tointeger(L, k);
1022+
ui->LAssert(L, val > 0, "DrawImageQuad() argument %d: expected positive integer, got %d", k, val);
1023+
if (maxStackValue.has_value())
1024+
ui->LAssert(L, val <= *maxStackValue, "DrawImageQuad() argument %d: expected valid stack index <= %d, got %d", k, *maxStackValue, val);
1025+
stackLayer = val - 1;
10001026
k += 1;
10011027
}
10021028

10031029
if (af & AF_MASK) {
1004-
ui->LAssert(L, lua_isnil(L, k) || lua_istable(L, k), "DrawImageQuad() argument %d: expected integer or nil, got %s", k, luaL_typename(L, k));
1030+
ui->LAssert(L, lua_isnil(L, k) || lua_isinteger(L, k), "DrawImageQuad() argument %d: expected integer or nil, got %s", k, luaL_typename(L, k));
1031+
if (lua_isinteger(L, k)) {
1032+
const int val = (int)lua_tointeger(L, k);
1033+
ui->LAssert(L, val > 0, "DrawImageQuad() argument %d: expected positive integer, got %d", k, val);
1034+
if (maxStackValue.has_value())
1035+
ui->LAssert(L, val <= *maxStackValue, "DrawImageQuad() argument %d: expected valid stack index <= %d, got %d", k, *maxStackValue, val);
1036+
maskLayer = val - 1;
1037+
}
1038+
k += 1;
10051039
}
10061040

10071041

1008-
ui->renderer->DrawImageQuad(hnd, xys[0], xys[1], xys[2], xys[3], uvs[0], uvs[1], uvs[2], uvs[3], stackLayer);
1042+
ui->renderer->DrawImageQuad(hnd, xys[0], xys[1], xys[2], xys[3], uvs[0], uvs[1], uvs[2], uvs[3], stackLayer, maskLayer);
10091043

10101044
return 0;
10111045
}

0 commit comments

Comments
 (0)