@@ -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
321322struct 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
329330struct 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
359360Batch::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
784787uniform mat4 mvp_matrix;
785788
786789in vec2 a_vertex;
787- in vec3 a_texcoord;
790+ in vec2 a_texcoord;
788791in vec4 a_tint;
789- in float a_texId;
790792in vec4 a_viewport;
793+ in vec3 a_texId;
791794
792795out vec2 v_screenPos;
793- out vec3 v_texcoord;
796+ out vec2 v_texcoord;
794797out vec4 v_tint;
795- out float v_texId;
796798out vec4 v_viewport;
799+ out vec3 v_texId;
797800
798801void main(void)
799802{
@@ -818,10 +821,10 @@ uniform highp sampler2DArray s_tex[{SG_TEXTURE_COUNT}];
818821uniform vec4 i_tint;
819822
820823in vec2 v_screenPos;
821- in vec3 v_texcoord;
824+ in vec2 v_texcoord;
822825in vec4 v_tint;
823- in float v_texId;
824826in vec4 v_viewport; // x0, y0, x1, y1
827+ in vec3 v_texId;
825828
826829out 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+
15471562void 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
17571772void r_renderer_c::DrawString (float x, float y, int align, int height, const col4_t col, int font, const char * str)
0 commit comments