mirror of https://github.com/mgba-emu/mgba.git
GBA Video: Add transformed objects to GL
This commit is contained in:
parent
bd69c9fb26
commit
c15dedf3f4
|
@ -95,7 +95,7 @@ struct GBAVideoGLRenderer {
|
||||||
unsigned vramDirty;
|
unsigned vramDirty;
|
||||||
|
|
||||||
GLuint bgProgram[6];
|
GLuint bgProgram[6];
|
||||||
GLuint objProgram[4];
|
GLuint objProgram[2];
|
||||||
|
|
||||||
GLuint compositeProgram;
|
GLuint compositeProgram;
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,7 @@ static const char* const _renderMode2 =
|
||||||
" flags = inflags / flagCoeff;\n"
|
" flags = inflags / flagCoeff;\n"
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
static const char* const _renderObjNoTransform =
|
static const char* const _renderObj =
|
||||||
"varying vec2 texCoord;\n"
|
"varying vec2 texCoord;\n"
|
||||||
"uniform sampler2D vram;\n"
|
"uniform sampler2D vram;\n"
|
||||||
"uniform sampler2D palette;\n"
|
"uniform sampler2D palette;\n"
|
||||||
|
@ -195,6 +195,8 @@ static const char* const _renderObjNoTransform =
|
||||||
"uniform int stride;\n"
|
"uniform int stride;\n"
|
||||||
"uniform int localPalette;\n"
|
"uniform int localPalette;\n"
|
||||||
"uniform ivec3 inflags;\n"
|
"uniform ivec3 inflags;\n"
|
||||||
|
"uniform mat2x2 transform;\n"
|
||||||
|
"uniform ivec4 dims;\n"
|
||||||
"out vec4 color;\n"
|
"out vec4 color;\n"
|
||||||
"out vec3 flags;\n"
|
"out vec3 flags;\n"
|
||||||
"const vec3 flagCoeff = vec3(32., 8., 4.);\n"
|
"const vec3 flagCoeff = vec3(32., 8., 4.);\n"
|
||||||
|
@ -202,7 +204,10 @@ static const char* const _renderObjNoTransform =
|
||||||
"vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n"
|
"vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n"
|
||||||
|
|
||||||
"void main() {\n"
|
"void main() {\n"
|
||||||
" ivec2 coord = ivec2(texCoord);\n"
|
" ivec2 coord = ivec2(transform * (texCoord - dims.zw / 2) + dims.xy / 2);\n"
|
||||||
|
" if ((coord & ~(dims.xy - 1)) != ivec2(0, 0)) {\n"
|
||||||
|
" discard;\n"
|
||||||
|
" }\n"
|
||||||
" color = renderTile((coord.x >> 3) + (coord.y >> 3) * stride, 16 + localPalette, coord & 7);\n"
|
" color = renderTile((coord.x >> 3) + (coord.y >> 3) * stride, 16 + localPalette, coord & 7);\n"
|
||||||
" flags = inflags / flagCoeff;\n"
|
" flags = inflags / flagCoeff;\n"
|
||||||
"}";
|
"}";
|
||||||
|
@ -378,8 +383,6 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) {
|
||||||
glRenderer->compositeProgram = glCreateProgram();
|
glRenderer->compositeProgram = glCreateProgram();
|
||||||
glRenderer->objProgram[0] = glCreateProgram();
|
glRenderer->objProgram[0] = glCreateProgram();
|
||||||
glRenderer->objProgram[1] = glCreateProgram();
|
glRenderer->objProgram[1] = glCreateProgram();
|
||||||
glRenderer->objProgram[2] = glCreateProgram();
|
|
||||||
glRenderer->objProgram[3] = glCreateProgram();
|
|
||||||
glRenderer->bgProgram[0] = glCreateProgram();
|
glRenderer->bgProgram[0] = glCreateProgram();
|
||||||
glRenderer->bgProgram[1] = glCreateProgram();
|
glRenderer->bgProgram[1] = glCreateProgram();
|
||||||
glRenderer->bgProgram[2] = glCreateProgram();
|
glRenderer->bgProgram[2] = glCreateProgram();
|
||||||
|
@ -416,13 +419,13 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) {
|
||||||
shaderBuffer[2] = _fetchTileNoOverflow;
|
shaderBuffer[2] = _fetchTileNoOverflow;
|
||||||
_compileShader(glRenderer, glRenderer->bgProgram[3], shaderBuffer, 3, vs, log);
|
_compileShader(glRenderer, glRenderer->bgProgram[3], shaderBuffer, 3, vs, log);
|
||||||
|
|
||||||
shaderBuffer[1] = _renderObjNoTransform;
|
shaderBuffer[1] = _renderObj;
|
||||||
|
|
||||||
shaderBuffer[2] = _renderTile16;
|
shaderBuffer[2] = _renderTile16;
|
||||||
_compileShader(glRenderer, glRenderer->objProgram[0], shaderBuffer, 3, vs, log);
|
_compileShader(glRenderer, glRenderer->objProgram[0], shaderBuffer, 3, vs, log);
|
||||||
|
|
||||||
shaderBuffer[2] = _renderTile256;
|
shaderBuffer[2] = _renderTile256;
|
||||||
_compileShader(glRenderer, glRenderer->objProgram[2], shaderBuffer, 3, vs, log);
|
_compileShader(glRenderer, glRenderer->objProgram[1], shaderBuffer, 3, vs, log);
|
||||||
|
|
||||||
shaderBuffer[1] = _composite;
|
shaderBuffer[1] = _composite;
|
||||||
_compileShader(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log);
|
_compileShader(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log);
|
||||||
|
@ -449,8 +452,6 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) {
|
||||||
glDeleteProgram(glRenderer->bgProgram[6]);
|
glDeleteProgram(glRenderer->bgProgram[6]);
|
||||||
glDeleteProgram(glRenderer->objProgram[0]);
|
glDeleteProgram(glRenderer->objProgram[0]);
|
||||||
glDeleteProgram(glRenderer->objProgram[1]);
|
glDeleteProgram(glRenderer->objProgram[1]);
|
||||||
glDeleteProgram(glRenderer->objProgram[2]);
|
|
||||||
glDeleteProgram(glRenderer->objProgram[3]);
|
|
||||||
glDeleteProgram(glRenderer->compositeProgram);
|
glDeleteProgram(glRenderer->compositeProgram);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -966,26 +967,45 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB
|
||||||
spriteY -= 256;
|
spriteY -= 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GBAObjAttributesBIsVFlip(sprite->b)) {
|
if (!GBAObjAttributesAIsTransformed(sprite->a) && GBAObjAttributesBIsVFlip(sprite->b)) {
|
||||||
spriteY = (y - height) + (y - spriteY) + 1;
|
spriteY = (y - height) + (y - spriteY) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int totalWidth = width;
|
||||||
|
int totalHeight = height;
|
||||||
|
if (GBAObjAttributesAIsTransformed(sprite->a) && GBAObjAttributesAIsDoubleSize(sprite->a)) {
|
||||||
|
totalWidth <<= 1;
|
||||||
|
totalHeight <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]);
|
glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]);
|
||||||
glViewport(x * renderer->scale, spriteY * renderer->scale, width * renderer->scale, height * renderer->scale);
|
glViewport(x * renderer->scale, spriteY * renderer->scale, totalWidth * renderer->scale, totalHeight * renderer->scale);
|
||||||
glScissor(x * renderer->scale, y * renderer->scale, width * renderer->scale, renderer->scale);
|
glScissor(x * renderer->scale, y * renderer->scale, totalWidth * renderer->scale, renderer->scale);
|
||||||
glUseProgram(renderer->objProgram[GBAObjAttributesAIs256Color(sprite->a) ? 2 : 0]);
|
glUseProgram(renderer->objProgram[GBAObjAttributesAGet256Color(sprite->a)]);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, renderer->vramTex);
|
glBindTexture(GL_TEXTURE_2D, renderer->vramTex);
|
||||||
glActiveTexture(GL_TEXTURE0 + 1);
|
glActiveTexture(GL_TEXTURE0 + 1);
|
||||||
glBindTexture(GL_TEXTURE_2D, renderer->paletteTex);
|
glBindTexture(GL_TEXTURE_2D, renderer->paletteTex);
|
||||||
glUniform2i(0, 1, y - spriteY);
|
glUniform2i(0, 1, y - spriteY);
|
||||||
glUniform2i(1, GBAObjAttributesBIsHFlip(sprite->b) ? -width : width, height);
|
glUniform2i(1, (GBAObjAttributesBIsHFlip(sprite->b) && !GBAObjAttributesAIsTransformed(sprite->a)) ? -totalWidth : totalWidth, totalHeight);
|
||||||
glUniform1i(2, 0);
|
glUniform1i(2, 0);
|
||||||
glUniform1i(3, 1);
|
glUniform1i(3, 1);
|
||||||
glUniform1i(4, charBase);
|
glUniform1i(4, charBase);
|
||||||
glUniform1i(5, stride);
|
glUniform1i(5, stride);
|
||||||
glUniform1i(6, GBAObjAttributesCGetPalette(sprite->c));
|
glUniform1i(6, GBAObjAttributesCGetPalette(sprite->c));
|
||||||
glUniform3i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, (renderer->target1Obj | (renderer->target2Obj * 2)) / 8.f, 0);
|
glUniform3i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, renderer->target1Obj | (renderer->target2Obj * 2), 0);
|
||||||
|
if (GBAObjAttributesAIsTransformed(sprite->a)) {
|
||||||
|
struct GBAOAMMatrix mat;
|
||||||
|
LOAD_16(mat.a, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].a);
|
||||||
|
LOAD_16(mat.b, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].b);
|
||||||
|
LOAD_16(mat.c, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].c);
|
||||||
|
LOAD_16(mat.d, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].d);
|
||||||
|
|
||||||
|
glUniformMatrix2fv(8, 1, GL_FALSE, (GLfloat[]) { mat.a / 256.f, mat.c / 256.f, mat.b / 256.f, mat.d / 256.f });
|
||||||
|
} else {
|
||||||
|
glUniformMatrix2fv(8, 1, GL_FALSE, (GLfloat[]) { 1.f, 0, 0, 1.f });
|
||||||
|
}
|
||||||
|
glUniform4i(9, width, height, totalWidth, totalHeight);
|
||||||
glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices);
|
glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 });
|
glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 });
|
||||||
|
|
Loading…
Reference in New Issue