diff --git a/Src/Graphics/New3D/New3D.cpp b/Src/Graphics/New3D/New3D.cpp index 55cba60..45ae512 100644 --- a/Src/Graphics/New3D/New3D.cpp +++ b/Src/Graphics/New3D/New3D.cpp @@ -330,8 +330,6 @@ void CNew3D::SetRenderStates() glDisable (GL_CULL_FACE); // we'll emulate this in the shader glEnable (GL_STENCIL_TEST); - glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); - glStencilMask (0xFF); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable (GL_BLEND); @@ -1876,6 +1874,9 @@ bool CNew3D::ProcessLos(int priority) GLubyte stencilVal; glReadPixels(losX, losY, 1, 1, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &stencilVal); + // apply our mask to stencil, because layered poly attributes use the lower bits + stencilVal &= 0x80; + // if the stencil val is zero that means we've hit sky or whatever, if it hits a 1 we've hit geometry // the real3d returns 1 in the top bit of the float if the line of sight test passes (ie doesn't hit geometry) diff --git a/Src/Graphics/New3D/R3DShader.cpp b/Src/Graphics/New3D/R3DShader.cpp index ead8ef5..fb7a6bd 100644 --- a/Src/Graphics/New3D/R3DShader.cpp +++ b/Src/Graphics/New3D/R3DShader.cpp @@ -298,14 +298,26 @@ void R3DShader::SetMeshUniforms(const Mesh* m) glUniform2iv(m_locTexWrapMode, 1, m_texWrapMode); } + if (m_dirtyMesh || m->noLosReturn != m_noLosReturn) { + m_noLosReturn = m->noLosReturn; + glStencilFunc(GL_ALWAYS, m_noLosReturn << 7, 0b10000000); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0b10000000); + } + if (m_dirtyMesh || m->layered != m_layered) { m_layered = m->layered; // i think it should just disable z write, but the polys I think must be written first - } - - if (m_dirtyMesh || m->noLosReturn != m_noLosReturn) { - m_noLosReturn = m->noLosReturn; - glStencilFunc(GL_ALWAYS, m_noLosReturn, -1); // we'll write either a 0 or 1 to the stencil buffer + if (m_layered) { + glStencilFunc(GL_EQUAL, 0, 0b01111111); // basically stencil test passes if the value is zero + glStencilOp(GL_KEEP, GL_INCR, GL_INCR); // if the stencil test passes, we increment the value + glStencilMask(0b01111111); + } + else { + glStencilFunc(GL_ALWAYS, m_noLosReturn << 7, 0b10000000); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0b10000000); + } } m_dirtyMesh = false;