GBA Video: Do not affect OBJ pixel priority when writing OBJWIN (fixes #1890)
Vicki Pfau vi@endrift.com
Sun, 04 Oct 2020 01:02:28 -0700
2 files changed,
23 insertions(+),
13 deletions(-)
M
CHANGES
→
CHANGES
@@ -47,6 +47,7 @@ - GBA Video: Don't draw sprites using unmapped VRAM in GL renderer (fixes mgba.io/i/1865)
- GBA Video: Implement green swap (fixes mgba.io/i/1609) - GBA Video: Fix rare regression blending semitransparent sprites (fixes mgba.io/i/1876) - GBA Video: Emulate sprite cycle limits in OpenGL renderer (fixes mgba.io/i/1635) + - GBA Video: Do not affect OBJ pixel priority when writing OBJWIN (fixes mgba.io/i/1890) - SM83: Emulate HALT bug Other fixes: - 3DS: Redo video sync to be more precise
M
src/gba/renderers/gl.c
→
src/gba/renderers/gl.c
@@ -898,6 +898,7 @@ _deleteShader(&glRenderer->bgShader[2]);
_deleteShader(&glRenderer->bgShader[3]); _deleteShader(&glRenderer->objShader[0]); _deleteShader(&glRenderer->objShader[1]); + _deleteShader(&glRenderer->objShader[2]); _deleteShader(&glRenderer->finalizeShader); int i;@@ -1712,12 +1713,18 @@ glUniformMatrix2fv(uniforms[GBA_GL_OBJ_TRANSFORM], 1, GL_FALSE, (GLfloat[]) { flipX, 0, 0, flipY });
} glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight); if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) { + // OBJWIN writes do not affect pixel priority glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + glStencilMask(GL_FALSE); int window = renderer->objwin & 0x3F; glUniform4i(uniforms[GBA_GL_OBJ_OBJWIN], 1, window, renderer->bldb, renderer->bldy); glDrawBuffers(3, (GLenum[]) { GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT2 }); } else { glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glStencilMask(GL_TRUE); + glStencilFunc(GL_ALWAYS, 1, 1); glUniform4i(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0, 0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); }@@ -1730,23 +1737,25 @@ glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], mosaicH, GBAMosaicControlGetObjV(renderer->mosaic) + 1, x, spriteY);
} else { glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], 0, 0, x, spriteY); } - glStencilFunc(GL_ALWAYS, 1, 1); if (GBAObjAttributesAGetMode(sprite->a) != OBJ_MODE_OBJWIN || GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt)) { glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } - shader = &renderer->objShader[2]; - uniforms = shader->uniforms; - glStencilFunc(GL_EQUAL, 1, 1); - glUseProgram(shader->program); - glDrawBuffers(2, (GLenum[]) { GL_NONE, GL_COLOR_ATTACHMENT1 }); - glBindVertexArray(shader->vao); - glUniform2i(uniforms[GBA_GL_VS_LOC], totalHeight, 0); - glUniform2i(uniforms[GBA_GL_VS_MAXPOS], totalWidth, totalHeight); - glUniform4i(uniforms[GBA_GL_OBJ_INFLAGS], GBAObjAttributesCGetPriority(sprite->c), - (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2) | (renderer->blendEffect * 4), - renderer->blda, GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + if (GBAObjAttributesAGetMode(sprite->a) != OBJ_MODE_OBJWIN) { + // Update the pixel priority for already-written pixels + shader = &renderer->objShader[2]; + uniforms = shader->uniforms; + glStencilFunc(GL_EQUAL, 1, 1); + glUseProgram(shader->program); + glDrawBuffers(2, (GLenum[]) { GL_NONE, GL_COLOR_ATTACHMENT1 }); + glBindVertexArray(shader->vao); + glUniform2i(uniforms[GBA_GL_VS_LOC], totalHeight, 0); + glUniform2i(uniforms[GBA_GL_VS_MAXPOS], totalWidth, totalHeight); + glUniform4i(uniforms[GBA_GL_OBJ_INFLAGS], GBAObjAttributesCGetPriority(sprite->c), + (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2) | (renderer->blendEffect * 4), + renderer->blda, GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); }