mirror of https://github.com/mgba-emu/mgba.git
GBA Video: Fix OBJWIN erratic rendering in OpenGL renderer
This commit is contained in:
parent
65c988aaad
commit
7d2020910d
1
CHANGES
1
CHANGES
|
@ -4,6 +4,7 @@ Emulation fixes:
|
||||||
- GBA I/O: Ignore high bits on IME
|
- GBA I/O: Ignore high bits on IME
|
||||||
- GBA Memory: Mark Famicom Mini games 22 through 28 as non-mirroring
|
- GBA Memory: Mark Famicom Mini games 22 through 28 as non-mirroring
|
||||||
- GBA Memory: Return correct byte for odd ROM open bus addresses
|
- GBA Memory: Return correct byte for odd ROM open bus addresses
|
||||||
|
- GBA Video: Fix OBJWIN erratic rendering in OpenGL renderer
|
||||||
Other fixes:
|
Other fixes:
|
||||||
- CMake: Fix build with downstream minizip that exports incompatible symbols
|
- CMake: Fix build with downstream minizip that exports incompatible symbols
|
||||||
- Core: Fix threading improperly setting paused state while interrupted
|
- Core: Fix threading improperly setting paused state while interrupted
|
||||||
|
|
|
@ -445,7 +445,7 @@ static const char* const _renderObj =
|
||||||
"uniform ivec4 inflags;\n"
|
"uniform ivec4 inflags;\n"
|
||||||
"uniform mat2x2 transform;\n"
|
"uniform mat2x2 transform;\n"
|
||||||
"uniform ivec4 dims;\n"
|
"uniform ivec4 dims;\n"
|
||||||
"uniform ivec4 objwin;\n"
|
"uniform ivec3 objwin;\n"
|
||||||
"uniform ivec4 mosaic;\n"
|
"uniform ivec4 mosaic;\n"
|
||||||
"OUT(0) out vec4 color;\n"
|
"OUT(0) out vec4 color;\n"
|
||||||
"OUT(1) out ivec4 flags;\n"
|
"OUT(1) out ivec4 flags;\n"
|
||||||
|
@ -474,7 +474,7 @@ static const char* const _renderObj =
|
||||||
" color = pix;\n"
|
" color = pix;\n"
|
||||||
" flags = inflags;\n"
|
" flags = inflags;\n"
|
||||||
" gl_FragDepth = float(flags.x) / 16.;\n"
|
" gl_FragDepth = float(flags.x) / 16.;\n"
|
||||||
" window = ivec4(objwin.yzw, 0);\n"
|
" window = ivec4(objwin, 0);\n"
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
static const struct GBAVideoGLUniform _uniformsObjPriority[] = {
|
static const struct GBAVideoGLUniform _uniformsObjPriority[] = {
|
||||||
|
@ -1431,7 +1431,6 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) {
|
||||||
if (GBARegisterDISPCNTIsObjEnable(glRenderer->dispcnt) && !glRenderer->d.disableOBJ) {
|
if (GBARegisterDISPCNTIsObjEnable(glRenderer->dispcnt) && !glRenderer->d.disableOBJ) {
|
||||||
int i;
|
int i;
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
glEnable(GL_STENCIL_TEST);
|
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
for (i = 0; i < glRenderer->oamMax; ++i) {
|
for (i = 0; i < glRenderer->oamMax; ++i) {
|
||||||
struct GBAVideoRendererSprite* sprite = &glRenderer->sprites[i];
|
struct GBAVideoRendererSprite* sprite = &glRenderer->sprites[i];
|
||||||
|
@ -1708,20 +1707,21 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB
|
||||||
glUniformMatrix2fv(uniforms[GBA_GL_OBJ_TRANSFORM], 1, GL_FALSE, (GLfloat[]) { flipX, 0, 0, flipY });
|
glUniformMatrix2fv(uniforms[GBA_GL_OBJ_TRANSFORM], 1, GL_FALSE, (GLfloat[]) { flipX, 0, 0, flipY });
|
||||||
}
|
}
|
||||||
glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight);
|
glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight);
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) {
|
if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) {
|
||||||
// OBJWIN writes do not affect pixel priority
|
// OBJWIN writes do not affect pixel priority
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
glStencilMask(GL_FALSE);
|
glStencilMask(GL_FALSE);
|
||||||
int window = renderer->objwin & 0x3F;
|
int window = renderer->objwin & 0x3F;
|
||||||
glUniform4i(uniforms[GBA_GL_OBJ_OBJWIN], 1, window, renderer->bldb, renderer->bldy);
|
glUniform3i(uniforms[GBA_GL_OBJ_OBJWIN], window, renderer->bldb, renderer->bldy);
|
||||||
glDrawBuffers(3, (GLenum[]) { GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT2 });
|
glDrawBuffers(3, (GLenum[]) { GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT2 });
|
||||||
} else {
|
} else {
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
glStencilMask(GL_TRUE);
|
glStencilMask(GL_TRUE);
|
||||||
glStencilFunc(GL_ALWAYS, 1, 1);
|
glStencilFunc(GL_ALWAYS, 1, 1);
|
||||||
glUniform4i(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0, 0);
|
glUniform3i(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0);
|
||||||
glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 });
|
glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 });
|
||||||
}
|
}
|
||||||
if (GBAObjAttributesAIsMosaic(sprite->a) && GBAObjAttributesAGetMode(sprite->a) != OBJ_MODE_OBJWIN) {
|
if (GBAObjAttributesAIsMosaic(sprite->a) && GBAObjAttributesAGetMode(sprite->a) != OBJ_MODE_OBJWIN) {
|
||||||
|
@ -1741,6 +1741,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB
|
||||||
// Update the pixel priority for already-written pixels
|
// Update the pixel priority for already-written pixels
|
||||||
shader = &renderer->objShader[2];
|
shader = &renderer->objShader[2];
|
||||||
uniforms = shader->uniforms;
|
uniforms = shader->uniforms;
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
glStencilFunc(GL_EQUAL, 1, 1);
|
glStencilFunc(GL_EQUAL, 1, 1);
|
||||||
glUseProgram(shader->program);
|
glUseProgram(shader->program);
|
||||||
glDrawBuffers(2, (GLenum[]) { GL_NONE, GL_COLOR_ATTACHMENT1 });
|
glDrawBuffers(2, (GLenum[]) { GL_NONE, GL_COLOR_ATTACHMENT1 });
|
||||||
|
|
Loading…
Reference in New Issue