mirror of https://github.com/mgba-emu/mgba.git
GBA Video: Convert OpenGL VRAM texture to integer
This commit is contained in:
parent
e11dc3fad0
commit
b5ca2b89e2
1
CHANGES
1
CHANGES
|
@ -81,6 +81,7 @@ Misc:
|
|||
- GB: Add support for sleep and shutdown callbacks
|
||||
- GBA: Allow pausing event loop while CPU is blocked
|
||||
- GBA BIOS: Division by zero should emit a FATAL error
|
||||
- GBA Video: Convert OpenGL VRAM texture to integer
|
||||
- Debugger: Keep track of global cycle count
|
||||
- FFmpeg: Add looping option for GIF/APNG
|
||||
- mGUI: Show battery percentage
|
||||
|
|
|
@ -84,8 +84,8 @@ static const char* const _vertexShader =
|
|||
static const char* const _renderTile16 =
|
||||
"vec4 renderTile(int tile, int paletteId, ivec2 localCoord) {\n"
|
||||
" int address = charBase + tile * 16 + (localCoord.x >> 2) + (localCoord.y << 1);\n"
|
||||
" vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n"
|
||||
" int entry = int(halfrow[3 - (localCoord.x & 3)] * 15.9);\n"
|
||||
" int halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0).r;\n"
|
||||
" int entry = (halfrow >> (4 * (localCoord.x & 3))) & 15;\n"
|
||||
" if (entry == 0) {\n"
|
||||
" discard;\n"
|
||||
" }\n"
|
||||
|
@ -97,13 +97,12 @@ static const char* const _renderTile16 =
|
|||
static const char* const _renderTile256 =
|
||||
"vec4 renderTile(int tile, int paletteId, ivec2 localCoord) {\n"
|
||||
" int address = charBase + tile * 32 + (localCoord.x >> 1) + (localCoord.y << 2);\n"
|
||||
" vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n"
|
||||
" int entry = int(halfrow[3 - 2 * (localCoord.x & 1)] * 15.9);\n"
|
||||
" int pal2 = int(halfrow[2 - 2 * (localCoord.x & 1)] * 15.9);\n"
|
||||
" if ((pal2 | entry) == 0) {\n"
|
||||
" int halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0).r;\n"
|
||||
" int entry = (halfrow >> (8 * (localCoord.x & 1))) & 255;\n"
|
||||
" if (entry == 0) {\n"
|
||||
" discard;\n"
|
||||
" }\n"
|
||||
" int paletteEntry = palette[pal2 * 16 + entry];\n"
|
||||
" int paletteEntry = palette[entry];\n"
|
||||
" vec4 color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n"
|
||||
" return color;\n"
|
||||
"}";
|
||||
|
@ -123,7 +122,7 @@ static const struct GBAVideoGLUniform _uniformsMode0[] = {
|
|||
|
||||
static const char* const _renderMode0 =
|
||||
"in vec2 texCoord;\n"
|
||||
"uniform sampler2D vram;\n"
|
||||
"uniform isampler2D vram;\n"
|
||||
"uniform int palette[256];\n"
|
||||
"uniform int screenBase;\n"
|
||||
"uniform int charBase;\n"
|
||||
|
@ -158,16 +157,15 @@ static const char* const _renderMode0 =
|
|||
" coord &= 255;\n"
|
||||
" coord.y += wrap.x + wrap.y * doty;\n"
|
||||
" int mapAddress = screenBase + (coord.x >> 3) + (coord.y >> 3) * 32;\n"
|
||||
" vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n"
|
||||
" int tileFlags = int(map.g * 15.9);\n"
|
||||
" if ((tileFlags & 4) == 4) {\n"
|
||||
" int map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0).r;\n"
|
||||
" if ((map & 1024) == 1024) {\n"
|
||||
" coord.x ^= 7;\n"
|
||||
" }\n"
|
||||
" if ((tileFlags & 8) == 8) {\n"
|
||||
" if ((map & 2048) == 2048) {\n"
|
||||
" coord.y ^= 7;\n"
|
||||
" }\n"
|
||||
" int tile = int(map.a * 15.9) + int(map.b * 15.9) * 16 + (tileFlags & 0x3) * 256;\n"
|
||||
" color = renderTile(tile, int(map.r * 15.9), coord & 7);\n"
|
||||
" int tile = map & 1023;\n"
|
||||
" color = renderTile(tile, map >> 12, coord & 7);\n"
|
||||
"}";
|
||||
|
||||
static const char* const _fetchTileOverflow =
|
||||
|
@ -225,7 +223,7 @@ static const char* const _interpolate =
|
|||
|
||||
static const char* const _renderMode2 =
|
||||
"in vec2 texCoord;\n"
|
||||
"uniform sampler2D vram;\n"
|
||||
"uniform isampler2D vram;\n"
|
||||
"uniform int palette[256];\n"
|
||||
"uniform int screenBase;\n"
|
||||
"uniform int charBase;\n"
|
||||
|
@ -242,16 +240,15 @@ static const char* const _renderMode2 =
|
|||
"vec4 renderTile(ivec2 coord) {\n"
|
||||
" int map = (coord.x >> 11) + (((coord.y >> 7) & 0x7F0) << size);\n"
|
||||
" int mapAddress = screenBase + (map >> 1);\n"
|
||||
" vec4 twomaps = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n"
|
||||
" int tile = int(twomaps[3 - 2 * (map & 1)] * 15.9) + int(twomaps[2 - 2 * (map & 1)] * 15.9) * 16;\n"
|
||||
" int twomaps = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0).r;\n"
|
||||
" int tile = (twomaps >> (8 * (map & 1))) & 255;\n"
|
||||
" int address = charBase + tile * 32 + ((coord.x >> 9) & 3) + ((coord.y >> 6) & 0x1C);\n"
|
||||
" vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n"
|
||||
" int entry = int(halfrow[3 - ((coord.x >> 7) & 2)] * 15.9);\n"
|
||||
" int pal2 = int(halfrow[2 - ((coord.x >> 7) & 2)] * 15.9);\n"
|
||||
" if ((pal2 | entry) == 0) {\n"
|
||||
" int halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0).r;\n"
|
||||
" int entry = (halfrow >> (8 * ((coord.x >> 8) & 1))) & 255;\n"
|
||||
" if (entry == 0) {\n"
|
||||
" discard;\n"
|
||||
" }\n"
|
||||
" int paletteEntry = palette[pal2 * 16 + entry];\n"
|
||||
" int paletteEntry = palette[entry];\n"
|
||||
" vec4 color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n"
|
||||
" return color;\n"
|
||||
"}\n"
|
||||
|
@ -294,7 +291,7 @@ static const struct GBAVideoGLUniform _uniformsMode35[] = {
|
|||
|
||||
static const char* const _renderMode35 =
|
||||
"in vec2 texCoord;\n"
|
||||
"uniform sampler2D vram;\n"
|
||||
"uniform isampler2D vram;\n"
|
||||
"uniform int charBase;\n"
|
||||
"uniform ivec2 size;\n"
|
||||
"uniform ivec4 transform[160];\n"
|
||||
|
@ -333,9 +330,8 @@ static const char* const _renderMode35 =
|
|||
" discard;\n"
|
||||
" }\n"
|
||||
" int address = charBase + (coord.x >> 8) + (coord.y >> 8) * size.x;\n"
|
||||
" ivec4 entry = ivec4(texelFetch(vram, ivec2(address & 255, address >> 8), 0) * 15.9);\n"
|
||||
" int sixteen = (entry.x << 12) | (entry.y << 8) | (entry.z << 4) | entry.w;\n"
|
||||
" color = vec4(float(sixteen & 0x1F) / 31., float((sixteen >> 5) & 0x1F) / 31., float((sixteen >> 10) & 0x1F) / 31., 1.);\n"
|
||||
" int entry = texelFetch(vram, ivec2(address & 255, address >> 8), 0).r;\n"
|
||||
" color = vec4(float(entry & 0x1F) / 31., float((entry >> 5) & 0x1F) / 31., float((entry >> 10) & 0x1F) / 31., 1.);\n"
|
||||
"}";
|
||||
|
||||
static const struct GBAVideoGLUniform _uniformsMode4[] = {
|
||||
|
@ -354,7 +350,7 @@ static const struct GBAVideoGLUniform _uniformsMode4[] = {
|
|||
|
||||
static const char* const _renderMode4 =
|
||||
"in vec2 texCoord;\n"
|
||||
"uniform sampler2D vram;\n"
|
||||
"uniform isampler2D vram;\n"
|
||||
"uniform int palette[256];\n"
|
||||
"uniform int charBase;\n"
|
||||
"uniform ivec2 size;\n"
|
||||
|
@ -394,9 +390,8 @@ static const char* const _renderMode4 =
|
|||
" discard;\n"
|
||||
" }\n"
|
||||
" int address = charBase + (coord.x >> 8) + (coord.y >> 8) * size.x;\n"
|
||||
" vec4 twoEntries = texelFetch(vram, ivec2((address >> 1) & 255, address >> 9), 0);\n"
|
||||
" ivec2 entry = ivec2(twoEntries[3 - 2 * (address & 1)] * 15.9, twoEntries[2 - 2 * (address & 1)] * 15.9);\n"
|
||||
" int paletteEntry = palette[entry.y * 16 + entry.x];\n"
|
||||
" int twoEntries = texelFetch(vram, ivec2((address >> 1) & 255, address >> 9), 0).r;\n"
|
||||
" int paletteEntry = palette[(twoEntries >> (8 * (address & 1)) & 255)];\n"
|
||||
" color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n"
|
||||
"}";
|
||||
|
||||
|
@ -419,7 +414,7 @@ static const struct GBAVideoGLUniform _uniformsObj[] = {
|
|||
|
||||
static const char* const _renderObj =
|
||||
"in vec2 texCoord;\n"
|
||||
"uniform sampler2D vram;\n"
|
||||
"uniform isampler2D vram;\n"
|
||||
"uniform int palette[256];\n"
|
||||
"uniform int charBase;\n"
|
||||
"uniform int stride;\n"
|
||||
|
@ -781,7 +776,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) {
|
|||
glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 256, 192, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, 256, 192, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
glGenBuffers(1, &glRenderer->vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, glRenderer->vbo);
|
||||
|
@ -1355,7 +1350,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) {
|
|||
for (i = 0; i < 25; ++i) {
|
||||
if (!(glRenderer->vramDirty & (1 << i))) {
|
||||
if (first >= 0) {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 8 * first, 256, 8 * (i - first), GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &glRenderer->d.vram[2048 * first]);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 8 * first, 256, 8 * (i - first), GL_RED_INTEGER, GL_UNSIGNED_SHORT, &glRenderer->d.vram[2048 * first]);
|
||||
first = -1;
|
||||
}
|
||||
} else if (first < 0) {
|
||||
|
|
Loading…
Reference in New Issue