From f2725791d8c3b5f00ddc830691ed556b48f2f508 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 16 May 2019 00:30:55 +0200 Subject: preliminary, shitty, code for drawing the main window with OpenGL --- src/libui_sdl/main_shaders.h | 72 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/libui_sdl/main_shaders.h (limited to 'src/libui_sdl/main_shaders.h') diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h new file mode 100644 index 0000000..dcf79d9 --- /dev/null +++ b/src/libui_sdl/main_shaders.h @@ -0,0 +1,72 @@ +/* + Copyright 2016-2019 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef MAIN_SHADERS_H +#define MAIN_SHADERS_H + +const char* kScreenVS = R"(#version 420 + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uFilterMode; +}; + +layout(location=0) in vec2 vPosition; +layout(location=1) in vec2 vTexcoord; + +smooth out vec2 fTexcoord; + +void main() +{ + vec4 fpos; + fpos.xy = ((vPosition.xy * 2.0) / uScreenSize) - 1.0; + fpos.y *= -1; + fpos.z = 0.0; + fpos.w = 1.0; + + gl_Position = fpos; + fTexcoord = vTexcoord; +} +)"; + +const char* kScreenFS = R"(#version 420 + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uFilterMode; +}; + +layout(binding=0) uniform usampler2D ScreenTex; + +smooth in vec2 fTexcoord; + +layout(location=0) out vec4 oColor; + +void main() +{ + uvec4 pixel = texelFetch(ScreenTex, ivec2(fTexcoord), 0); + + // TODO: filters + + oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0); +} +)"; + +#endif // MAIN_SHADERS_H -- cgit v1.2.3 From c1746f0c6082afd64834e89ce92591743f238f66 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 16 May 2019 20:58:07 +0200 Subject: BAHAHAHHHH HARK HARK HARK --- src/GPU.cpp | 4 +- src/GPU2D.cpp | 25 +++++++-- src/GPU3D.cpp | 10 ++++ src/GPU3D.h | 3 ++ src/GPU3D_OpenGL43.cpp | 118 +++++++++++++++++------------------------ src/GPU3D_Soft.cpp | 5 ++ src/libui_sdl/main.cpp | 11 ++-- src/libui_sdl/main_shaders.h | 123 ++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 219 insertions(+), 80 deletions(-) (limited to 'src/libui_sdl/main_shaders.h') diff --git a/src/GPU.cpp b/src/GPU.cpp index 1d073f5..8142e47 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -254,7 +254,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[0] = accel ? 0 : topscale; int fbsize; - if (accel) fbsize = 256*3 * 192; + if (accel) fbsize = (256*3 + 1) * 192; else fbsize = (256 * 192) << (FBScale[0] * 2); if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; @@ -283,7 +283,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[1] = accel ? 0 : bottomscale; int fbsize; - if (accel) fbsize = 256*3 * 192; + if (accel) fbsize = (256*3 + 1) * 192; else fbsize = (256 * 192) << (FBScale[1] * 2); if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 34c17ff..f80eb85 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -626,7 +626,7 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - int stride = Accelerated ? (256*3) : LineStride; + int stride = Accelerated ? (256*3 + 1) : LineStride; u32* dst = &Framebuffer[stride * line]; int n3dline = line; @@ -787,7 +787,17 @@ void GPU2D::DrawScanline(u32 line) DoCapture(line, capwidth); } - if (Accelerated) return; + if (Accelerated) + { + u32 ctl = (BlendCnt & 0x3FFF); + ctl |= ((DispCnt & 0x30000) >> 2); + ctl |= (EVA << 16); + ctl |= (EVB << 21); + ctl |= (EVY << 26); + + dst[256*3] = ctl; + return; + } // master brightness if (dispmode != 0) @@ -1367,6 +1377,13 @@ void GPU2D::DrawScanline_Mode1(u32 line) } } } + else + { + for (int i = 0; i < 256; i++) + { + BGOBJLine[i] |= ((WindowMask[i] & 0x20) << 18); + } + } if (BGMosaicY >= BGMosaicYMax) { @@ -1471,11 +1488,13 @@ void GPU2D::DrawBG_3D() { for (; i < iend; i++) { + int pos = xoff++; + if (!(WindowMask[i] & 0x01)) continue; BGOBJLine[i+512] = BGOBJLine[i+256]; BGOBJLine[i+256] = BGOBJLine[i]; - BGOBJLine[i] = 0x40000000; // 3D-layer placeholder + BGOBJLine[i] = 0x40000000 | pos; // 3D-layer placeholder } } else if (LineScale == 1) diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 61629a7..ec395ad 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -612,6 +612,11 @@ void SetDisplaySettings(int scale, bool accel) GLRenderer43::SetDisplaySettings(scale, accel); } +int GetScale() +{ + return GLRenderer43::GetScale(); +} + void MatrixLoadIdentity(s32* m) @@ -2441,6 +2446,11 @@ u32* GetLine(int line) return GLRenderer43::GetLine(line); } +void SetupAccelFrame() +{ + GLRenderer43::SetupAccelFrame(); +} + void WriteToGXFIFO(u32 val) { diff --git a/src/GPU3D.h b/src/GPU3D.h index 2fe5bee..10c8966 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -98,6 +98,7 @@ void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); void SetDisplaySettings(int scale, bool accel); +int GetScale(); void ExecuteCommand(); @@ -129,6 +130,7 @@ void DeInit(); void Reset(); void SetDisplaySettings(int scale, bool accel); +int GetScale(); void SetupRenderThread(); @@ -147,6 +149,7 @@ void DeInit(); void Reset(); void SetDisplaySettings(int scale, bool accel); +int GetScale(); void VCount144(); void RenderFrame(); diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 6db9a18..0181192 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -100,7 +100,8 @@ int ScaleFactor; bool Accelerated; int ScreenW, ScreenH; -GLuint FramebufferTex[4]; +GLuint FramebufferTex[6]; +int FrontBuffer; GLuint FramebufferID[2], PixelbufferID; u32* Framebuffer = NULL; @@ -262,8 +263,10 @@ bool Init() glGenFramebuffers(2, &FramebufferID[0]); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); - // color buffer - glGenTextures(4, &FramebufferTex[0]); + glGenTextures(6, &FramebufferTex[0]); + FrontBuffer = 0; + + // color buffers glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -271,33 +274,39 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); - // depth/stencil buffer glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[1], 0); + + // depth/stencil buffer + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); // attribute buffer // R: opaque polyID (for edgemarking) // G: opaque polyID (for shadows, suppressed when rendering translucent polygons) // B: stencil flag - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[2], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); // downscale framebuffer, for antialiased mode glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[3], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[2], 0); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); @@ -330,7 +339,7 @@ bool Init() glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL); glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); // opaque polyID / shadow bits + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); // opaque polyID / shadow bits return true; } @@ -357,11 +366,13 @@ void SetDisplaySettings(int scale, bool accel) glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); if (accel) glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); @@ -372,6 +383,11 @@ void SetDisplaySettings(int scale, bool accel) else Framebuffer = new u32[ScreenW*ScreenH]; } +int GetScale() +{ + return ScaleFactor; +} + void SetupPolygon(RendererPolygon* rp, Polygon* polygon) { @@ -756,6 +772,12 @@ void RenderFrame() glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMaski(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + if (Accelerated) + { + int backbuf = FrontBuffer ? 0 : 1; + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[backbuf], 0); + } + // clear buffers // TODO: clear bitmap // TODO: check whether 'clear polygon ID' affects translucent polyID @@ -818,15 +840,7 @@ void RenderFrame() glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); - if (!ChunkedRendering) - { - RenderSceneChunk(0, 192); - } - else - { - glEnable(GL_SCISSOR_TEST); - RenderSceneChunk(0, 48); - } + RenderSceneChunk(0, 192); } if (false) @@ -842,63 +856,24 @@ void RenderFrame() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); } - glReadBuffer(GL_COLOR_ATTACHMENT0); - glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); + if (!Accelerated) + { + glReadBuffer(GL_COLOR_ATTACHMENT0); + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - if (!ChunkedRendering) glReadPixels(0, 0, 256<> 6) & 0x3; + + if (dispmode == 1) + { + uint eva = ctl.b & 0x1F; + uint evb = (ctl.b >> 5) | ((ctl.a & 0x03) << 3); + uint evy = ctl.a >> 2; + + uvec4 top = pixel; + uvec4 mid = texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0); + uvec4 bot = texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0); + + uint winmask = top.b >> 7; + + if ((top.a & 0x40) != 0) + { + float xpos = top.r + fract(fTexcoord.x); + uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, fTexcoord.y)*u3DScale), 0).bgra + * vec4(63,63,63,31)); + + if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } + else top = mid; + } + else if ((mid.a & 0x40) != 0) + { + float xpos = mid.r + fract(fTexcoord.x); + uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, fTexcoord.y)*u3DScale), 0).bgra + * vec4(63,63,63,31)); + + if (_3dpix.a > 0) { bot = _3dpix; bot.a |= 0x40; } + } + else + { + // conditional texture fetch no good for performance, apparently + //texelFetch(_3DTex, ivec2(0, fTexcoord.y*2), 0); + bot = mid; + } + + top.b &= 0x3F; + bot.b &= 0x3F; + + uint target2; + if ((bot.a & 0x80) != 0) target2 = 0x10; + else if ((bot.a & 0x40) != 0) target2 = 0x01; + else target2 = bot.a; + bool t2pass = ((ctl.g & target2) != 0); + + uint coloreffect = 0; + + if ((top.a & 0x80) != 0 && t2pass) + { + // sprite blending + + coloreffect = 1; + + if ((top.a & 0x40) != 0) + { + eva = top.a & 0x1F; + evb = 16 - eva; + } + } + else if ((top.a & 0x40) != 0 && t2pass) + { + // 3D layer blending + + coloreffect = 4; + eva = (top.a & 0x1F) + 1; + evb = 32 - eva; + } + else + { + if ((top.a & 0x80) != 0) top.a = 0x10; + else if ((top.a & 0x40) != 0) top.a = 0x01; + + if ((ctl.r & top.a) != 0 && winmask != 0) + { + uint effect = ctl.r >> 6; + if ((effect != 1) || t2pass) coloreffect = effect; + } + } + + if (coloreffect == 0) + { + pixel = top; + } + else if (coloreffect == 1) + { + pixel = ((top * eva) + (bot * evb)) >> 4; + pixel = min(pixel, 0x3F); + } + else if (coloreffect == 2) + { + pixel = top; + pixel += ((uvec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; + } + else if (coloreffect == 3) + { + pixel = top; + pixel -= (pixel * evy) >> 4; + } + else + { + pixel = ((top * eva) + (bot * evb)) >> 5; + if (eva <= 16) pixel += uvec4(1,1,1,0); + pixel = min(pixel, 0x3F); + } + } + + pixel.rgb <<= 2; + pixel.rgb |= (pixel.rgb >> 6); + // TODO: filters - oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0); + oColor = vec4(vec3(pixel.rgb) / 255.0, 1.0); + //oColor = texelFetch(_3DTex, ivec2(fTexcoord*4), 0).bgra; } )"; -- cgit v1.2.3 From 72920bb763c73a761992391568ad418750070c7c Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 16 May 2019 22:04:27 +0200 Subject: fix 3D on bottom screen --- src/libui_sdl/main_shaders.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/libui_sdl/main_shaders.h') diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h index b602013..85ff794 100644 --- a/src/libui_sdl/main_shaders.h +++ b/src/libui_sdl/main_shaders.h @@ -89,7 +89,8 @@ void main() if ((top.a & 0x40) != 0) { float xpos = top.r + fract(fTexcoord.x); - uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, fTexcoord.y)*u3DScale), 0).bgra + float ypos = mod(fTexcoord.y, 768); + uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra * vec4(63,63,63,31)); if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } @@ -98,7 +99,8 @@ void main() else if ((mid.a & 0x40) != 0) { float xpos = mid.r + fract(fTexcoord.x); - uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, fTexcoord.y)*u3DScale), 0).bgra + float ypos = mod(fTexcoord.y, 768); + uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra * vec4(63,63,63,31)); if (_3dpix.a > 0) { bot = _3dpix; bot.a |= 0x40; } -- cgit v1.2.3 From 8bf45571754a1469758f83ab8f98f951122c96f8 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 17 May 2019 15:47:40 +0200 Subject: make screen shaders work with OpenGL 3.1 --- src/OpenGLSupport.h | 5 +++++ src/libui_sdl/main.cpp | 14 +++++++++++- src/libui_sdl/main_shaders.h | 53 ++++++++++++++++++++++---------------------- 3 files changed, 44 insertions(+), 28 deletions(-) (limited to 'src/libui_sdl/main_shaders.h') diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 2cee741..793205b 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -70,6 +70,8 @@ func(GLDISABLEVERTEXATTRIBARRAY, glDisableVertexAttribArray); \ func(GLVERTEXATTRIBPOINTER, glVertexAttribPointer); \ func(GLVERTEXATTRIBIPOINTER, glVertexAttribIPointer); \ + func(GLBINDATTRIBLOCATION, glBindAttribLocation); \ + func(GLBINDFRAGDATALOCATION, glBindFragDataLocation); \ \ func(GLCREATESHADER, glCreateShader); \ func(GLSHADERSOURCE, glShaderSource); \ @@ -85,9 +87,12 @@ func(GLDELETESHADER, glDeleteShader); \ func(GLDELETEPROGRAM, glDeleteProgram); \ \ + func(GLUNIFORM1I, glUniform1i); \ func(GLUNIFORM1UI, glUniform1ui); \ func(GLUNIFORM4UI, glUniform4ui); \ func(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); \ + func(GLGETUNIFORMLOCATION, glGetUniformLocation); \ + func(GLGETUNIFORMBLOCKINDEX, glGetUniformBlockIndex); \ \ func(GLACTIVETEXTURE, glActiveTexture); \ func(GLBINDIMAGETEXTURE, glBindImageTexture); \ diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 9cdb610..f4a1fdb 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -166,13 +166,21 @@ bool GLDrawing_Init() if (!OpenGL_BuildShaderProgram(kScreenVS, kScreenFS, GL_ScreenShader, "ScreenShader")) return false; + GLuint uni_id; memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig)); glGenBuffers(1, &GL_ShaderConfigUBO); glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO); glBufferData(GL_UNIFORM_BUFFER, sizeof(GL_ShaderConfig), &GL_ShaderConfig, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, 16, GL_ShaderConfigUBO); - glUniformBlockBinding(GL_ScreenShader[2], 0, 16); + uni_id = glGetUniformBlockIndex(GL_ScreenShader[2], "uConfig"); + glUniformBlockBinding(GL_ScreenShader[2], uni_id, 16); + + glUseProgram(GL_ScreenShader[2]); + uni_id = glGetUniformLocation(GL_ScreenShader[2], "ScreenTex"); + glUniform1i(uni_id, 0); + uni_id = glGetUniformLocation(GL_ScreenShader[2], "_3DTex"); + glUniform1i(uni_id, 1); glGenBuffers(1, &GL_ScreenVertexBufferID); glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); @@ -185,6 +193,10 @@ bool GLDrawing_Init() glEnableVertexAttribArray(1); // texcoord glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(2*4)); + glBindAttribLocation(GL_ScreenShader[2], 0, "vPosition"); + glBindAttribLocation(GL_ScreenShader[2], 1, "vTexcoord"); + glBindFragDataLocation(GL_ScreenShader[2], 0, "oColor"); + // TODO: consider reallocating the texture when changing screen sizes glGenTextures(1, &GL_ScreenTexture); glActiveTexture(GL_TEXTURE0); diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h index 85ff794..9ed3cc0 100644 --- a/src/libui_sdl/main_shaders.h +++ b/src/libui_sdl/main_shaders.h @@ -19,17 +19,17 @@ #ifndef MAIN_SHADERS_H #define MAIN_SHADERS_H -const char* kScreenVS = R"(#version 420 +const char* kScreenVS = R"(#version 140 -layout(std140, binding=0) uniform uConfig +layout(std140) uniform uConfig { vec2 uScreenSize; uint u3DScale; uint uFilterMode; }; -layout(location=0) in vec2 vPosition; -layout(location=1) in vec2 vTexcoord; +in vec2 vPosition; +in vec2 vTexcoord; smooth out vec2 fTexcoord; @@ -46,51 +46,51 @@ void main() } )"; -const char* kScreenFS = R"(#version 420 +const char* kScreenFS = R"(#version 140 -layout(std140, binding=0) uniform uConfig +layout(std140) uniform uConfig { vec2 uScreenSize; uint u3DScale; uint uFilterMode; }; -layout(binding=0) uniform usampler2D ScreenTex; -layout(binding=1) uniform sampler2D _3DTex; +uniform usampler2D ScreenTex; +uniform sampler2D _3DTex; smooth in vec2 fTexcoord; -layout(location=0) out vec4 oColor; +out vec4 oColor; void main() { - uvec4 pixel = texelFetch(ScreenTex, ivec2(fTexcoord), 0); + ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); // bit0-13: BLDCNT // bit14-15: DISPCNT display mode // bit16-20: EVA // bit21-25: EVB // bit26-30: EVY - uvec4 ctl = texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0); - uint dispmode = (ctl.g >> 6) & 0x3; + ivec4 ctl = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); + int dispmode = (ctl.g >> 6) & 0x3; if (dispmode == 1) { - uint eva = ctl.b & 0x1F; - uint evb = (ctl.b >> 5) | ((ctl.a & 0x03) << 3); - uint evy = ctl.a >> 2; + int eva = ctl.b & 0x1F; + int evb = (ctl.b >> 5) | ((ctl.a & 0x03) << 3); + int evy = ctl.a >> 2; - uvec4 top = pixel; - uvec4 mid = texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0); - uvec4 bot = texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0); + ivec4 top = pixel; + ivec4 mid = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0)); + ivec4 bot = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0)); - uint winmask = top.b >> 7; + int winmask = top.b >> 7; if ((top.a & 0x40) != 0) { float xpos = top.r + fract(fTexcoord.x); float ypos = mod(fTexcoord.y, 768); - uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra * vec4(63,63,63,31)); if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } @@ -100,7 +100,7 @@ void main() { float xpos = mid.r + fract(fTexcoord.x); float ypos = mod(fTexcoord.y, 768); - uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra * vec4(63,63,63,31)); if (_3dpix.a > 0) { bot = _3dpix; bot.a |= 0x40; } @@ -115,13 +115,13 @@ void main() top.b &= 0x3F; bot.b &= 0x3F; - uint target2; + int target2; if ((bot.a & 0x80) != 0) target2 = 0x10; else if ((bot.a & 0x40) != 0) target2 = 0x01; else target2 = bot.a; bool t2pass = ((ctl.g & target2) != 0); - uint coloreffect = 0; + int coloreffect = 0; if ((top.a & 0x80) != 0 && t2pass) { @@ -150,7 +150,7 @@ void main() if ((ctl.r & top.a) != 0 && winmask != 0) { - uint effect = ctl.r >> 6; + int effect = ctl.r >> 6; if ((effect != 1) || t2pass) coloreffect = effect; } } @@ -167,7 +167,7 @@ void main() else if (coloreffect == 2) { pixel = top; - pixel += ((uvec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; + pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; } else if (coloreffect == 3) { @@ -177,7 +177,7 @@ void main() else { pixel = ((top * eva) + (bot * evb)) >> 5; - if (eva <= 16) pixel += uvec4(1,1,1,0); + if (eva <= 16) pixel += ivec4(1,1,1,0); pixel = min(pixel, 0x3F); } } @@ -188,7 +188,6 @@ void main() // TODO: filters oColor = vec4(vec3(pixel.rgb) / 255.0, 1.0); - //oColor = texelFetch(_3DTex, ivec2(fTexcoord*4), 0).bgra; } )"; -- cgit v1.2.3 From de287825eec01aaa5e8ab925171cd75d86a23cb4 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 17 May 2019 22:50:41 +0200 Subject: start work on display capture also fix a bug in the compositing shader --- src/GPU.cpp | 2 +- src/GPU2D.cpp | 20 +++++++++-- src/GPU3D.h | 1 + src/GPU3D_OpenGL43.cpp | 81 ++++++++++++++++++++++++++++++++++++-------- src/libui_sdl/main_shaders.h | 6 ++-- 5 files changed, 88 insertions(+), 22 deletions(-) (limited to 'src/libui_sdl/main_shaders.h') diff --git a/src/GPU.cpp b/src/GPU.cpp index 8142e47..1799ef8 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -907,7 +907,7 @@ void StartScanline(u32 line) else { if (VCount == 192) - {//printf("- VBLANK -\n");vbltime=NDS::ARM9Timestamp; + { // VBlank DispStat[0] |= (1<<0); DispStat[1] |= (1<<0); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index f80eb85..e18f30e 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -656,8 +656,16 @@ void GPU2D::DrawScanline(u32 line) u32 dispmode = DispCnt >> 16; dispmode &= (Num ? 0x1 : 0x3); - if (Num == 0 && !Accelerated) - _3DLine = GPU3D::GetLine(n3dline); + if (Num == 0) + { + if (!Accelerated) + _3DLine = GPU3D::GetLine(n3dline); + else if ((CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) + { + _3DLine = GPU3D::GetLine(n3dline); + //GPU3D::GLRenderer43::PrepareCaptureFrame(); + } + } // always render regular graphics DrawScanline_Mode1(line); @@ -862,6 +870,12 @@ void GPU2D::VBlankEnd() BGMosaicYMax = BGMosaicSize[1]; OBJMosaicY = 0; OBJMosaicYMax = OBJMosaicSize[1]; + + // TODO: make optional + if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) + { + GPU3D::GLRenderer43::PrepareCaptureFrame(); + } } @@ -884,7 +898,7 @@ void GPU2D::DoCapture(u32 line, u32 width) srcA = _3DLine; else srcA = BGOBJLine; - +srcA = _3DLine; u16* srcB = NULL; u32 srcBaddr = line * 256; diff --git a/src/GPU3D.h b/src/GPU3D.h index 10c8966..708811f 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -153,6 +153,7 @@ int GetScale(); void VCount144(); void RenderFrame(); +void PrepareCaptureFrame(); u32* GetLine(int line); void SetupAccelFrame(); diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 062e40e..72956fb 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -100,9 +100,9 @@ int ScaleFactor; bool Accelerated; int ScreenW, ScreenH; -GLuint FramebufferTex[6]; +GLuint FramebufferTex[8]; int FrontBuffer; -GLuint FramebufferID[2], PixelbufferID; +GLuint FramebufferID[4], PixelbufferID; u32* Framebuffer = NULL; bool ChunkedRendering = false; @@ -260,10 +260,10 @@ bool Init() glVertexAttribIPointer(3, 3, GL_UNSIGNED_INT, 7*4, (void*)(4*4)); - glGenFramebuffers(2, &FramebufferID[0]); + glGenFramebuffers(4, &FramebufferID[0]); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); - glGenTextures(6, &FramebufferTex[0]); + glGenTextures(8, &FramebufferTex[0]); FrontBuffer = 0; // color buffers @@ -286,7 +286,12 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); + + glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // attribute buffer // R: opaque polyID (for edgemarking) @@ -297,16 +302,40 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); - // downscale framebuffer, for antialiased mode - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + // downscale framebuffer for antialiased mode + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[2], 0); + + // downscale framebuffer for display capture (always 256x192) + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[3]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + 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_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[3], 0); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[1], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[6], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[7], 0); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); @@ -373,10 +402,13 @@ void SetDisplaySettings(int scale, bool accel) glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - if (accel) glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); - else glBufferData(GL_PIXEL_PACK_BUFFER, 256*192, NULL, GL_DYNAMIC_READ); + glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); if (Framebuffer) delete[] Framebuffer; if (accel) Framebuffer = new u32[256*192]; @@ -774,7 +806,8 @@ void RenderFrame() if (Accelerated) { - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[FrontBuffer], 0); + //glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[FrontBuffer], 0); + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); FrontBuffer = FrontBuffer ? 0 : 1; } @@ -856,18 +889,36 @@ void RenderFrame() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); } - if (!Accelerated) + /*if (!Accelerated) { glReadBuffer(GL_COLOR_ATTACHMENT0); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); glReadPixels(0, 0, 256<> 7; - if ((top.a & 0x40) != 0) + if ((top.a & 0xC0) == 0x40) { float xpos = top.r + fract(fTexcoord.x); float ypos = mod(fTexcoord.y, 768); @@ -96,7 +96,7 @@ void main() if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } else top = mid; } - else if ((mid.a & 0x40) != 0) + else if ((mid.a & 0xC0) == 0x40) { float xpos = mid.r + fract(fTexcoord.x); float ypos = mod(fTexcoord.y, 768); -- cgit v1.2.3 From f5a7cb71fd17d5eb97ce3325892a2c769258c8ce Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 18 May 2019 01:42:50 +0200 Subject: also, do master brightness --- src/GPU.cpp | 4 ++-- src/GPU2D.cpp | 3 ++- src/libui_sdl/main.cpp | 4 ++-- src/libui_sdl/main_shaders.h | 24 +++++++++++++++++++++++- 4 files changed, 29 insertions(+), 6 deletions(-) (limited to 'src/libui_sdl/main_shaders.h') diff --git a/src/GPU.cpp b/src/GPU.cpp index 1799ef8..23e4fa8 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -254,7 +254,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[0] = accel ? 0 : topscale; int fbsize; - if (accel) fbsize = (256*3 + 1) * 192; + if (accel) fbsize = (256*3 + 2) * 192; else fbsize = (256 * 192) << (FBScale[0] * 2); if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; @@ -283,7 +283,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[1] = accel ? 0 : bottomscale; int fbsize; - if (accel) fbsize = (256*3 + 1) * 192; + if (accel) fbsize = (256*3 + 2) * 192; else fbsize = (256 * 192) << (FBScale[1] * 2); if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 9ec240b..88436db 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -626,7 +626,7 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - int stride = Accelerated ? (256*3 + 1) : LineStride; + int stride = Accelerated ? (256*3 + 2) : LineStride; u32* dst = &Framebuffer[stride * line]; int n3dline = line; @@ -804,6 +804,7 @@ void GPU2D::DrawScanline(u32 line) ctl |= (EVY << 26); dst[256*3] = ctl; + dst[256*3 + 1] = MasterBrightness; return; } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index f4a1fdb..27f0369 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -367,9 +367,9 @@ void GLDrawing_DrawScreen() GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256<> 6) & 0x3; if (dispmode == 1) @@ -182,6 +183,27 @@ ivec4 zog=pixel; } } + if (dispmode != 0) + { + int brightmode = mbright.g >> 6; + if (brightmode == 1) + { + // up + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; + } + else if (brightmode == 2) + { + // down + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel -= (pixel * evy) >> 4; + } + } + pixel.rgb <<= 2; pixel.rgb |= (pixel.rgb >> 6); -- cgit v1.2.3 From 70a324371451b872dc5b4bba3cff696ad7a1cbb3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 19:36:47 +0200 Subject: simpler GPU-compositing. will make it easier to grab neighbor 2D/3D pixels individually for filtering. --- src/GPU.cpp | 6 +- src/GPU2D.cpp | 322 ++++++++++++++++++++++--------------------- src/GPU2D.h | 1 + src/GPU3D_OpenGL.cpp | 2 + src/libui_sdl/main.cpp | 44 +++--- src/libui_sdl/main_shaders.h | 142 +++++++------------ 6 files changed, 248 insertions(+), 269 deletions(-) (limited to 'src/libui_sdl/main_shaders.h') diff --git a/src/GPU.cpp b/src/GPU.cpp index a7ea2a4..fe23a77 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -152,7 +152,7 @@ void Reset() VRAMMap_ARM7[1] = 0; int fbsize; - if (Accelerated) fbsize = (256*3 + 2) * 192; + if (Accelerated) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; for (int i = 0; i < fbsize; i++) { @@ -177,7 +177,7 @@ void Reset() void Stop() { int fbsize; - if (Accelerated) fbsize = (256*3 + 2) * 192; + if (Accelerated) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; memset(Framebuffer[0][0], 0, fbsize*4); memset(Framebuffer[0][1], 0, fbsize*4); @@ -257,7 +257,7 @@ void SetDisplaySettings(bool accel) if (accel != Accelerated) { int fbsize; - if (accel) fbsize = (256*3 + 2) * 192; + if (accel) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 88249ba..4fe2209 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -617,10 +617,78 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) return rb | g | 0xFF000000; } +u32 GPU2D::ColorComposite(int i, u32 val1, u32 val2) +{ + u32 coloreffect = 0; + u32 eva, evb; + + u32 flag1 = val1 >> 24; + u32 flag2 = val2 >> 24; + + u32 target2; + if (flag2 & 0x80) target2 = 0x1000; + else if (flag2 & 0x40) target2 = 0x0100; + else target2 = flag2 << 8; + + if ((flag1 & 0x80) && (BlendCnt & target2)) + { + // sprite blending + + coloreffect = 1; + + if (flag1 & 0x40) + { + eva = flag1 & 0x1F; + evb = 16 - eva; + } + else + { + eva = EVA; + evb = EVB; + } + } + else if ((flag1 & 0x40) && (BlendCnt & target2)) + { + // 3D layer blending + + coloreffect = 4; + } + else + { + if (flag1 & 0x80) flag1 = 0x10; + else if (flag1 & 0x40) flag1 = 0x01; + + if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + { + coloreffect = (BlendCnt >> 6) & 0x3; + + if (coloreffect == 1) + { + if (BlendCnt & target2) + { + eva = EVA; + evb = EVB; + } + else + coloreffect = 0; + } + } + } + + switch (coloreffect) + { + case 0: return val1; + case 1: return ColorBlend4(val1, val2, eva, evb); + case 2: return ColorBrightnessUp(val1, EVY); + case 3: return ColorBrightnessDown(val1, EVY); + case 4: return ColorBlend5(val1, val2); + } +} + void GPU2D::DrawScanline(u32 line) { - int stride = Accelerated ? (256*3 + 2) : 256; + int stride = Accelerated ? (256*3 + 1) : 256; u32* dst = &Framebuffer[stride * line]; int n3dline = line; @@ -648,7 +716,6 @@ void GPU2D::DrawScanline(u32 line) if (Accelerated) { dst[256*3] = 0; - dst[256*3 + 1] = 0; } return; } @@ -747,14 +814,7 @@ void GPU2D::DrawScanline(u32 line) if (Accelerated) { - u32 ctl = (BlendCnt & 0x3FFF); - ctl |= ((DispCnt & 0x30000) >> 2); - ctl |= (EVA << 16); - ctl |= (EVB << 21); - ctl |= (EVY << 26); - - dst[256*3] = ctl; - dst[256*3 + 1] = MasterBrightness; + dst[256*3] = MasterBrightness | (DispCnt & 0x30000); return; } @@ -858,111 +918,57 @@ void GPU2D::DoCapture(u32 line, u32 width) // but when doing display capture, we do need the composited output // so we do it here - u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - for (int i = 0; i < 256; i++) { u32 val1 = BGOBJLine[i]; - u32 val3 = BGOBJLine[256+i]; - u32 val2 = BGOBJLine[512+i]; + u32 val2 = BGOBJLine[256+i]; + u32 val3 = BGOBJLine[512+i]; + + u32 compmode = (val3 >> 24) & 0xF; - if ((val1 >> 30) == 1) + if (compmode == 4) { - u32 _3dval = _3DLine[val1 & 0xFF]; + // 3D on top, blending + + u32 _3dval = _3DLine[val3 & 0xFF]; if ((_3dval >> 24) > 0) - { - val1 = _3dval | 0x40000000; - val2 = val3; - } + val1 = ColorBlend5(_3dval, val1); else - val1 = val3; + val1 = val2; } - else if ((val3 >> 30) == 1) + else if (compmode == 1) { + // 3D on bottom, blending + u32 _3dval = _3DLine[val3 & 0xFF]; if ((_3dval >> 24) > 0) - val2 = _3dval | 0x40000000; - } - else - val2 = val3; - - val1 &= ~0x00800000; - val2 &= ~0x00800000; - - u32 coloreffect, eva, evb; - - u32 flag1 = val1 >> 24; - u32 flag2 = val2 >> 24; - - u32 target2; - if (flag2 & 0x80) target2 = 0x1000; - else if (flag2 & 0x40) target2 = 0x0100; - else target2 = flag2 << 8; - - if ((flag1 & 0x80) && (BlendCnt & target2)) - { - // sprite blending - - coloreffect = 1; - - if (flag1 & 0x40) { - eva = flag1 & 0x1F; - evb = 16 - eva; + u32 eva = (val3 >> 8) & 0x1F; + u32 evb = (val3 >> 16) & 0x1F; + + val1 = ColorBlend4(val1, _3dval, eva, evb); } else - { - eva = EVA; - evb = EVB; - } + val1 = val2; } - else if ((flag1 & 0x40) && (BlendCnt & target2)) + else if (compmode <= 3) { - // 3D layer blending + // 3D on top, normal/fade - BGOBJLine[i] = ColorBlend5(val1, val2); - continue; - } - else - { - if (flag1 & 0x80) flag1 = 0x10; - else if (flag1 & 0x40) flag1 = 0x01; - - if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + u32 _3dval = _3DLine[val3 & 0xFF]; + if ((_3dval >> 24) > 0) { - if ((bldcnteffect == 1) && (BlendCnt & target2)) - { - coloreffect = 1; - eva = EVA; - evb = EVB; - } - else if (bldcnteffect >= 2) - coloreffect = bldcnteffect; - else - coloreffect = 0; + u32 evy = (val3 >> 8) & 0x1F; + + val1 = _3dval; + if (compmode == 2) val1 = ColorBrightnessUp(val1, evy); + else if (compmode == 3) val1 = ColorBrightnessDown(val1, evy); } else - coloreffect = 0; + val1 = val2; } - switch (coloreffect) - { - case 0: - BGOBJLine[i] = val1; - break; - - case 1: - BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); - break; - - case 2: - BGOBJLine[i] = ColorBrightnessUp(val1, EVY); - break; - - case 3: - BGOBJLine[i] = ColorBrightnessDown(val1, EVY); - break; - } + BGOBJLine[i] = val1; } } } @@ -1374,94 +1380,102 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) if (!Accelerated) { - u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - for (int i = 0; i < 256; i++) { u32 val1 = BGOBJLine[i]; u32 val2 = BGOBJLine[256+i]; - u32 coloreffect, eva, evb; + BGOBJLine[i] = ColorComposite(i, val1, val2); + } + } + else + { + if (Num == 0) + { + for (int i = 0; i < 256; i++) + { + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[256+i]; + u32 val3 = BGOBJLine[512+i]; - u32 flag1 = val1 >> 24; - u32 flag2 = val2 >> 24; + u32 flag1 = val1 >> 24; + u32 flag2 = val2 >> 24; - u32 target2; - if (flag2 & 0x80) target2 = 0x1000; - else if (flag2 & 0x40) target2 = 0x0100; - else target2 = flag2 << 8; + u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - if ((flag1 & 0x80) && (BlendCnt & target2)) - { - // sprite blending + u32 target1; + if (flag1 & 0x80) target1 = 0x0010; + else if (flag1 & 0x40) target1 = 0x0001; + else target1 = flag1; - coloreffect = 1; + u32 target2; + if (flag2 & 0x80) target2 = 0x1000; + else if (flag2 & 0x40) target2 = 0x0100; + else target2 = flag2 << 8; - if (flag1 & 0x40) + if (((flag1 & 0xC0) == 0x40) && (BlendCnt & target2)) { - eva = flag1 & 0x1F; - evb = 16 - eva; + // 3D on top, blending + + BGOBJLine[i] = val2; + BGOBJLine[256+i] = ColorComposite(i, val2, val3); + BGOBJLine[512+i] = 0x04000000 | (val1 & 0xFF); } - else + else if ((flag1 & 0xC0) == 0x40) { - eva = EVA; - evb = EVB; - } - } - else if ((flag1 & 0x40) && (BlendCnt & target2)) - { - // 3D layer blending + // 3D on top, normal/fade - BGOBJLine[i] = ColorBlend5(val1, val2); - continue; - } - else - { - if (flag1 & 0x80) flag1 = 0x10; - else if (flag1 & 0x40) flag1 = 0x01; + if (bldcnteffect == 1) bldcnteffect = 0; + if (!(BlendCnt & 0x0001)) bldcnteffect = 0; + if (!(WindowMask[i] & 0x20)) bldcnteffect = 0; - if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + BGOBJLine[i] = val2; + BGOBJLine[256+i] = ColorComposite(i, val2, val3); + BGOBJLine[512+i] = (bldcnteffect << 24) | (EVY << 8) | (val1 & 0xFF); + } + else if (((flag2 & 0xC0) == 0x40) && ((BlendCnt & 0x01C0) == 0x0140)) { - if ((bldcnteffect == 1) && (BlendCnt & target2)) + // 3D on bottom, blending + + u32 eva, evb; + if ((flag1 & 0xC0) == 0xC0) + { + eva = flag1 & 0x1F; + evb = 16 - eva; + } + else if ((BlendCnt & target1) && (WindowMask[i] & 0x20)) { - coloreffect = 1; eva = EVA; evb = EVB; } - else if (bldcnteffect >= 2) - coloreffect = bldcnteffect; else - coloreffect = 0; + bldcnteffect = 7; + + BGOBJLine[i] = val1; + BGOBJLine[256+i] = ColorComposite(i, val1, val3); + BGOBJLine[512+i] = (bldcnteffect << 24) | (EVB << 16) | (EVA << 8) | (val1 & 0xFF); } else - coloreffect = 0; - } - - switch (coloreffect) - { - case 0: - BGOBJLine[i] = val1; - break; - - case 1: - BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); - break; - - case 2: - BGOBJLine[i] = ColorBrightnessUp(val1, EVY); - break; + { + // no potential 3D pixel involved - case 3: - BGOBJLine[i] = ColorBrightnessDown(val1, EVY); - break; + BGOBJLine[i] = ColorComposite(i, val1, val2); + BGOBJLine[256+i] = 0; + BGOBJLine[512+i] = 0x07000000; + } } } - } - else - { - for (int i = 0; i < 256; i++) + else { - BGOBJLine[i] |= ((WindowMask[i] & 0x20) << 18); + for (int i = 0; i < 256; i++) + { + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[256+i]; + + BGOBJLine[i] = ColorComposite(i, val1, val2); + BGOBJLine[256+i] = 0; + BGOBJLine[512+i] = 0x07000000; + } } } diff --git a/src/GPU2D.h b/src/GPU2D.h index 78e62f5..21b43f1 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -127,6 +127,7 @@ private: u32 ColorBlend5(u32 val1, u32 val2); u32 ColorBrightnessUp(u32 val, u32 factor); u32 ColorBrightnessDown(u32 val, u32 factor); + u32 ColorComposite(int i, u32 val1, u32 val2); template void DrawScanlineBGMode(u32 line, u32 nsprites); void DrawScanlineBGMode6(u32 line, u32 nsprites); diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 9144792..c759147 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -890,6 +890,8 @@ void RenderSceneChunk(int y, int h) glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID); glBindVertexArray(ClearVertexArrayID); glDrawArrays(GL_TRIANGLES, 0, 2*3); + + glFlush(); } } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 3a99d95..2e0c271 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -216,7 +216,7 @@ bool GLScreen_Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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_RGBA8UI, 1024, 1536, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 256*3 + 1, 192*2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); GL_ScreenSizeDirty = true; @@ -317,31 +317,31 @@ void GLScreen_DrawScreen() switch (ScreenRotation) { case 0: - s0 = 0; t0 = 768; - s1 = scwidth; t1 = 768; - s2 = 0; t2 = 768+scheight; - s3 = scwidth; t3 = 768+scheight; + s0 = 0; t0 = 192; + s1 = scwidth; t1 = 192; + s2 = 0; t2 = 192+scheight; + s3 = scwidth; t3 = 192+scheight; break; case 1: - s0 = 0; t0 = 768+scheight; - s1 = 0; t1 = 768; - s2 = scwidth; t2 = 768+scheight; - s3 = scwidth; t3 = 768; + s0 = 0; t0 = 192+scheight; + s1 = 0; t1 = 192; + s2 = scwidth; t2 = 192+scheight; + s3 = scwidth; t3 = 192; break; case 2: - s0 = scwidth; t0 = 768+scheight; - s1 = 0; t1 = 768+scheight; - s2 = scwidth; t2 = 768; - s3 = 0; t3 = 768; + s0 = scwidth; t0 = 192+scheight; + s1 = 0; t1 = 192+scheight; + s2 = scwidth; t2 = 192; + s3 = 0; t3 = 192; break; case 3: - s0 = scwidth; t0 = 768; - s1 = scwidth; t1 = 768+scheight; - s2 = 0; t2 = 768; - s3 = 0; t3 = 768+scheight; + s0 = scwidth; t0 = 192; + s1 = scwidth; t1 = 192+scheight; + s2 = 0; t2 = 192; + s3 = 0; t3 = 192+scheight; break; } @@ -381,14 +381,14 @@ void GLScreen_DrawScreen() { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256, 192, GL_RGBA_INTEGER, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3 + 2, 192, GL_RGBA_INTEGER, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3 + 1, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256*3 + 2, 192, GL_RGBA_INTEGER, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256*3 + 1, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); } } @@ -2241,11 +2241,13 @@ void DestroyMainWindow() void RecreateMainWindow(bool opengl) { - int winX, winY; + int winX, winY, maxi; uiWindowPosition(MainWindow, &winX, &winY); + maxi = uiWindowMaximized(MainWindow); DestroyMainWindow(); CreateMainWindow(opengl); uiWindowSetPosition(MainWindow, winX, winY); + uiWindowSetMaximized(MainWindow, maxi); } diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h index d6d898d..a855f1b 100644 --- a/src/libui_sdl/main_shaders.h +++ b/src/libui_sdl/main_shaders.h @@ -66,121 +66,81 @@ void main() { ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); - // bit0-13: BLDCNT - // bit14-15: DISPCNT display mode - // bit16-20: EVA - // bit21-25: EVB - // bit26-30: EVY - ivec4 ctl = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); - ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3 + 1, int(fTexcoord.y)), 0)); - int dispmode = (ctl.g >> 6) & 0x3; + ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); + int dispmode = mbright.b & 0x3; if (dispmode == 1) { - int eva = ctl.b & 0x1F; - int evb = (ctl.b >> 5) | ((ctl.a & 0x03) << 3); - int evy = ctl.a >> 2; + ivec4 val1 = pixel; + ivec4 val2 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0)); + ivec4 val3 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0)); - ivec4 top = pixel; - ivec4 mid = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0)); - ivec4 bot = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0)); + int compmode = val3.a & 0xF; + int eva, evb, evy; - int winmask = top.b >> 7; - - if ((top.a & 0xC0) == 0x40) + if (compmode == 4) { - float xpos = top.r + fract(fTexcoord.x); - float ypos = mod(fTexcoord.y, 768); - ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra - * vec4(63,63,63,31)); + // 3D on top, blending - if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } - else top = mid; - } - else if ((mid.a & 0xC0) == 0x40) - { - float xpos = mid.r + fract(fTexcoord.x); - float ypos = mod(fTexcoord.y, 768); + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra * vec4(63,63,63,31)); - if (_3dpix.a > 0) { bot = _3dpix; bot.a |= 0x40; } - } - else - { - // conditional texture fetch no good for performance, apparently - //texelFetch(_3DTex, ivec2(0, fTexcoord.y*2), 0); - bot = mid; - } - - top.b &= 0x3F; - bot.b &= 0x3F; - - int target2; - if ((bot.a & 0x80) != 0) target2 = 0x10; - else if ((bot.a & 0x40) != 0) target2 = 0x01; - else target2 = bot.a; - bool t2pass = ((ctl.g & target2) != 0); - - int coloreffect = 0; + if (_3dpix.a > 0) + { + eva = (_3dpix.a & 0x1F) + 1; + evb = 32 - eva; - if ((top.a & 0x80) != 0 && t2pass) + val1 = ((_3dpix * eva) + (val1 * evb)) >> 5; + if (eva <= 16) val1 += ivec4(1,1,1,0); + val1 = min(val1, 0x3F); + } + else + val1 = val2; + } + else if (compmode == 1) { - // sprite blending + // 3D on bottom, blending - coloreffect = 1; + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + * vec4(63,63,63,31)); - if ((top.a & 0x40) != 0) + if (_3dpix.a > 0) { - eva = top.a & 0x1F; - evb = 16 - eva; + eva = val3.g; + evb = val3.b; + + val1 = ((val1 * eva) + (_3dpix * evb)) >> 4; + val1 = min(val1, 0x3F); } + else + val1 = val2; } - else if ((top.a & 0x40) != 0 && t2pass) + else if (compmode <= 3) { - // 3D layer blending + // 3D on top, normal/fade - coloreffect = 4; - eva = (top.a & 0x1F) + 1; - evb = 32 - eva; - } - else - { - if ((top.a & 0x80) != 0) top.a = 0x10; - else if ((top.a & 0x40) != 0) top.a = 0x01; + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + * vec4(63,63,63,31)); - if ((ctl.r & top.a) != 0 && winmask != 0) + if (_3dpix.a > 0) { - int effect = ctl.r >> 6; - if ((effect != 1) || t2pass) coloreffect = effect; + evy = val3.g; + + val1 = _3dpix; + if (compmode == 2) val1 += ((ivec4(0x3F,0x3F,0x3F,0) - val1) * evy) >> 4; + else if (compmode == 3) val1 -= (val1 * evy) >> 4; } + else + val1 = val2; } - if (coloreffect == 0) - { - pixel = top; - } - else if (coloreffect == 1) - { - pixel = ((top * eva) + (bot * evb)) >> 4; - pixel = min(pixel, 0x3F); - } - else if (coloreffect == 2) - { - pixel = top; - pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; - } - else if (coloreffect == 3) - { - pixel = top; - pixel -= (pixel * evy) >> 4; - } - else - { - pixel = ((top * eva) + (bot * evb)) >> 5; - if (eva <= 16) pixel += ivec4(1,1,1,0); - pixel = min(pixel, 0x3F); - } + pixel = val1; } if (dispmode != 0) -- cgit v1.2.3 From 956c2c5d86a19e8aa5b51b95a4b5cd46f794df58 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 19:47:19 +0200 Subject: finalize the GL/software switch --- src/libui_sdl/main.cpp | 48 +++++++++++++++++++++++++++++--------------- src/libui_sdl/main_shaders.h | 25 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 16 deletions(-) (limited to 'src/libui_sdl/main_shaders.h') diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 2e0c271..f6ef397 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -109,6 +109,7 @@ bool ScreenDrawInited = false; uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; GLuint GL_ScreenShader[3]; +GLuint GL_ScreenShaderAccel[3]; struct { float uScreenSize[2]; @@ -169,29 +170,45 @@ void RecreateMainWindow(bool opengl); +bool GLScreen_InitShader(GLuint* shader, const char* fs) +{ + if (!OpenGL_BuildShaderProgram(kScreenVS, fs, shader, "ScreenShader")) + return false; + + GLuint uni_id; + + uni_id = glGetUniformBlockIndex(shader[2], "uConfig"); + glUniformBlockBinding(shader[2], uni_id, 16); + + glUseProgram(shader[2]); + uni_id = glGetUniformLocation(shader[2], "ScreenTex"); + glUniform1i(uni_id, 0); + uni_id = glGetUniformLocation(shader[2], "_3DTex"); + glUniform1i(uni_id, 1); + + glBindAttribLocation(shader[2], 0, "vPosition"); + glBindAttribLocation(shader[2], 1, "vTexcoord"); + glBindFragDataLocation(shader[2], 0, "oColor"); + + return true; +} + bool GLScreen_Init() { if (!OpenGL_Init()) return false; - if (!OpenGL_BuildShaderProgram(kScreenVS, kScreenFS, GL_ScreenShader, "ScreenShader")) + if (!GLScreen_InitShader(GL_ScreenShader, kScreenFS)) + return false; + if (!GLScreen_InitShader(GL_ScreenShaderAccel, kScreenFS_Accel)) return false; - GLuint uni_id; memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig)); glGenBuffers(1, &GL_ShaderConfigUBO); glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO); glBufferData(GL_UNIFORM_BUFFER, sizeof(GL_ShaderConfig), &GL_ShaderConfig, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, 16, GL_ShaderConfigUBO); - uni_id = glGetUniformBlockIndex(GL_ScreenShader[2], "uConfig"); - glUniformBlockBinding(GL_ScreenShader[2], uni_id, 16); - - glUseProgram(GL_ScreenShader[2]); - uni_id = glGetUniformLocation(GL_ScreenShader[2], "ScreenTex"); - glUniform1i(uni_id, 0); - uni_id = glGetUniformLocation(GL_ScreenShader[2], "_3DTex"); - glUniform1i(uni_id, 1); glGenBuffers(1, &GL_ScreenVertexBufferID); glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); @@ -204,11 +221,6 @@ bool GLScreen_Init() glEnableVertexAttribArray(1); // texcoord glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(2*4)); - glBindAttribLocation(GL_ScreenShader[2], 0, "vPosition"); - glBindAttribLocation(GL_ScreenShader[2], 1, "vTexcoord"); - glBindFragDataLocation(GL_ScreenShader[2], 0, "oColor"); - - // TODO: consider reallocating the texture when changing screen sizes glGenTextures(1, &GL_ScreenTexture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); @@ -231,6 +243,7 @@ void GLScreen_DeInit() glDeleteBuffers(1, &GL_ScreenVertexBufferID); OpenGL_DeleteShaderProgram(GL_ScreenShader); + OpenGL_DeleteShaderProgram(GL_ScreenShaderAccel); } void GLScreen_DrawScreen() @@ -365,7 +378,10 @@ void GLScreen_DrawScreen() glViewport(0, 0, WindowWidth, WindowHeight); - OpenGL_UseShaderProgram(GL_ScreenShader); + if (GPU3D::Renderer == 0) + OpenGL_UseShaderProgram(GL_ScreenShader); + else + OpenGL_UseShaderProgram(GL_ScreenShaderAccel); glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(0, 1, 0, 1); diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h index a855f1b..f03931c 100644 --- a/src/libui_sdl/main_shaders.h +++ b/src/libui_sdl/main_shaders.h @@ -55,6 +55,31 @@ layout(std140) uniform uConfig uint uFilterMode; }; +uniform usampler2D ScreenTex; + +smooth in vec2 fTexcoord; + +out vec4 oColor; + +void main() +{ + ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); + + // TODO: filters + + oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0); +} +)"; + +const char* kScreenFS_Accel = R"(#version 140 + +layout(std140) uniform uConfig +{ + vec2 uScreenSize; + uint u3DScale; + uint uFilterMode; +}; + uniform usampler2D ScreenTex; uniform sampler2D _3DTex; -- cgit v1.2.3 From 2b3ca2089f7420bb938c6bdda67ed0f8c04e51d5 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 3 Jun 2019 16:45:55 +0200 Subject: take the OSD shito somewhere --- src/OpenGLSupport.h | 1 + src/libui_sdl/OSD.cpp | 136 +++++++++++++++++++++++++++++++------------ src/libui_sdl/main.cpp | 45 ++++++++++++-- src/libui_sdl/main_shaders.h | 51 +++++++++++++++- 4 files changed, 190 insertions(+), 43 deletions(-) (limited to 'src/libui_sdl/main_shaders.h') diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 6130c8e..fbc100c 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -106,6 +106,7 @@ \ func(GLUNIFORM1I, glUniform1i); \ func(GLUNIFORM1UI, glUniform1ui); \ + func(GLUNIFORM2I, glUniform2i); \ func(GLUNIFORM4UI, glUniform4ui); \ func(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); \ func(GLGETUNIFORMLOCATION, glGetUniformLocation); \ diff --git a/src/libui_sdl/OSD.cpp b/src/libui_sdl/OSD.cpp index a13ff44..851f9c5 100644 --- a/src/libui_sdl/OSD.cpp +++ b/src/libui_sdl/OSD.cpp @@ -35,7 +35,7 @@ namespace OSD const u32 kOSDMargin = 6; -typedef struct +struct Item { Uint32 Timestamp; char Text[256]; @@ -50,13 +50,45 @@ typedef struct bool GLTextureLoaded; GLuint GLTexture; -} Item; +}; -std::deque ItemQueue; +std::deque ItemQueue; + +GLint uOSDPos, uOSDSize; +GLuint OSDVertexArray; +GLuint OSDVertexBuffer; + +volatile bool Rendering; bool Init(bool opengl) { + if (opengl) + { + GLuint prog; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&prog); + uOSDPos = glGetUniformLocation(prog, "uOSDPos"); + uOSDSize = glGetUniformLocation(prog, "uOSDSize"); + + float vertices[6*2] = + { + 0, 0, + 1, 1, + 1, 0, + 0, 0, + 0, 1, + 1, 1 + }; + + glGenBuffers(1, &OSDVertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, OSDVertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glGenVertexArrays(1, &OSDVertexArray); + glBindVertexArray(OSDVertexArray); + glEnableVertexAttribArray(0); // position + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0)); + } + return true; } @@ -64,15 +96,13 @@ void DeInit(bool opengl) { for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) { - Item* item = *it; - - if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap); - if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture); - if (item->Bitmap) delete[] item->Bitmap; + Item& item = *it; - delete item; + if (item.DrawBitmapLoaded && item.DrawBitmap) uiDrawFreeBitmap(item.DrawBitmap); + if (item.GLTextureLoaded && opengl) glDeleteTextures(1, &item.GLTexture); + if (item.Bitmap) delete[] item.Bitmap; - ItemQueue.erase(it); + it = ItemQueue.erase(it); } } @@ -276,15 +306,17 @@ void RenderText(u32 color, const char* text, Item* item) void AddMessage(u32 color, const char* text) { - Item* item = new Item; + while (Rendering); + + Item item; - item->Timestamp = SDL_GetTicks(); - strncpy(item->Text, text, 255); item->Text[255] = '\0'; - item->Color = color; - item->Bitmap = NULL; + item.Timestamp = SDL_GetTicks(); + strncpy(item.Text, text, 255); item.Text[255] = '\0'; + item.Color = color; + item.Bitmap = NULL; - item->DrawBitmapLoaded = false; - item->GLTextureLoaded = false; + item.DrawBitmapLoaded = false; + item.GLTextureLoaded = false; ItemQueue.push_back(item); } @@ -293,7 +325,7 @@ void WindowResized(bool opengl) { /*for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) { - Item* item = *it; + Item& item = *it; if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap); //if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture); @@ -309,53 +341,83 @@ void WindowResized(bool opengl) void Update(bool opengl, uiAreaDrawParams* params) { + Rendering = true; + Uint32 tick_now = SDL_GetTicks(); Uint32 tick_min = tick_now - 2500; u32 y = kOSDMargin; + if (opengl) + { + glBindBuffer(GL_ARRAY_BUFFER, OSDVertexBuffer); + glBindVertexArray(OSDVertexArray); + + glActiveTexture(GL_TEXTURE0); + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) { - Item* item = *it; + Item& item = *it; - if (item->Timestamp < tick_min) + if (item.Timestamp < tick_min) { - if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap); - if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture); - if (item->Bitmap) delete[] item->Bitmap; - - delete item; + if (item.DrawBitmapLoaded && item.DrawBitmap) uiDrawFreeBitmap(item.DrawBitmap); + if (item.GLTextureLoaded && opengl) glDeleteTextures(1, &item.GLTexture); + if (item.Bitmap) delete[] item.Bitmap; - ItemQueue.erase(it); + it = ItemQueue.erase(it); continue; } - if (!item->Bitmap) + if (!item.Bitmap) { - RenderText(item->Color, item->Text, item); + RenderText(item.Color, item.Text, &item); } if (opengl) { - // + if (!item.GLTextureLoaded) + { + glGenTextures(1, &item.GLTexture); + glBindTexture(GL_TEXTURE_2D, item.GLTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + 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_RGBA, item.Width, item.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, item.Bitmap); + + item.GLTextureLoaded = true; + } + + glBindTexture(GL_TEXTURE_2D, item.GLTexture); + glUniform2i(uOSDPos, kOSDMargin, y); + glUniform2i(uOSDSize, item.Width, item.Height); + glDrawArrays(GL_TRIANGLES, 0, 2*3); } else { - if (!item->DrawBitmapLoaded) + if (!item.DrawBitmapLoaded) { - item->DrawBitmap = uiDrawNewBitmap(params->Context, item->Width, item->Height, 1); - uiDrawBitmapUpdate(item->DrawBitmap, item->Bitmap); - item->DrawBitmapLoaded = true; + item.DrawBitmap = uiDrawNewBitmap(params->Context, item.Width, item.Height, 1); + uiDrawBitmapUpdate(item.DrawBitmap, item.Bitmap); + + item.DrawBitmapLoaded = true; } - uiRect rc_src = {0, 0, item->Width, item->Height}; - uiRect rc_dst = {kOSDMargin, y, item->Width, item->Height}; + uiRect rc_src = {0, 0, item.Width, item.Height}; + uiRect rc_dst = {kOSDMargin, y, item.Width, item.Height}; - uiDrawBitmapDraw(params->Context, item->DrawBitmap, &rc_src, &rc_dst, 0); + uiDrawBitmapDraw(params->Context, item.DrawBitmap, &rc_src, &rc_dst, 0); } - y += item->Height; + y += item.Height; it++; } + + Rendering = false; } } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 5407403..073c8ac 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -112,6 +112,7 @@ uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; GLuint GL_ScreenShader[3]; GLuint GL_ScreenShaderAccel[3]; +GLuint GL_ScreenShaderOSD[3]; struct { float uScreenSize[2]; @@ -198,6 +199,29 @@ bool GLScreen_InitShader(GLuint* shader, const char* fs) return true; } +bool GLScreen_InitOSDShader(GLuint* shader) +{ + if (!OpenGL_BuildShaderProgram(kScreenVS_OSD, kScreenFS_OSD, shader, "ScreenShaderOSD")) + return false; + + glBindAttribLocation(shader[2], 0, "vPosition"); + glBindFragDataLocation(shader[2], 0, "oColor"); + + if (!OpenGL_LinkShaderProgram(shader)) + return false; + + GLuint uni_id; + + uni_id = glGetUniformBlockIndex(shader[2], "uConfig"); + glUniformBlockBinding(shader[2], uni_id, 16); + + glUseProgram(shader[2]); + uni_id = glGetUniformLocation(shader[2], "OSDTex"); + glUniform1i(uni_id, 0); + + return true; +} + bool GLScreen_Init() { // TODO: consider using epoxy? @@ -213,6 +237,8 @@ bool GLScreen_Init() return false; if (!GLScreen_InitShader(GL_ScreenShaderAccel, kScreenFS_Accel)) return false; + if (!GLScreen_InitOSDShader(GL_ScreenShaderOSD)) + return false; memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig)); @@ -255,6 +281,7 @@ void GLScreen_DeInit() OpenGL_DeleteShaderProgram(GL_ScreenShader); OpenGL_DeleteShaderProgram(GL_ScreenShaderAccel); + OpenGL_DeleteShaderProgram(GL_ScreenShaderOSD); } void GLScreen_DrawScreen() @@ -396,7 +423,7 @@ void GLScreen_DrawScreen() else OpenGL_UseShaderProgram(GL_ScreenShaderAccel); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, uiGLGetFramebuffer(GLContext)); + glBindFramebuffer(GL_FRAMEBUFFER, uiGLGetFramebuffer(GLContext)); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); @@ -434,6 +461,7 @@ void GLScreen_DrawScreen() glDrawArrays(GL_TRIANGLES, 0, 4*3); } + OpenGL_UseShaderProgram(GL_ScreenShaderOSD); OSD::Update(true, NULL); glFlush(); @@ -947,19 +975,21 @@ int EmuThreadFunc(void* burp) if (joybuttons) delete[] joybuttons; + if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); + NDS::DeInit(); Platform::LAN_DeInit(); if (Screen_UseGL) { - uiGLMakeContextCurrent(GLContext); OSD::DeInit(true); GLScreen_DeInit(); - uiGLMakeContextCurrent(NULL); } else OSD::DeInit(false); + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + return 44203; } @@ -1128,7 +1158,7 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt) MicCommand |= 1; if (evt->Scancode == 0x57) // F11 - OSD::AddMessage(0, "OSD test"); + OSD::AddMessage(0x00FFFF, "OSD test"); //NDS::debug(0); } @@ -2302,6 +2332,11 @@ void CreateMainWindow(bool opengl) { uiGLMakeContextCurrent(GLContext); if (!GLScreen_Init()) opengl_good = false; + if (opengl_good) + { + OpenGL_UseShaderProgram(GL_ScreenShaderOSD); + OSD::Init(true); + } uiGLMakeContextCurrent(NULL); } @@ -2312,7 +2347,7 @@ void CreateMainWindow(bool opengl) Screen_UseGL = false; } - OSD::Init(opengl); + if (!opengl) OSD::Init(false); } void DestroyMainWindow() diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h index f03931c..6504520 100644 --- a/src/libui_sdl/main_shaders.h +++ b/src/libui_sdl/main_shaders.h @@ -36,7 +36,7 @@ smooth out vec2 fTexcoord; void main() { vec4 fpos; - fpos.xy = ((vPosition.xy * 2.0) / uScreenSize) - 1.0; + fpos.xy = ((vPosition * 2.0) / uScreenSize) - 1.0; fpos.y *= -1; fpos.z = 0.0; fpos.w = 1.0; @@ -198,4 +198,53 @@ void main() } )"; + +const char* kScreenVS_OSD = R"(#version 140 + +layout(std140) uniform uConfig +{ + vec2 uScreenSize; + uint u3DScale; + uint uFilterMode; +}; + +uniform ivec2 uOSDPos; +uniform ivec2 uOSDSize; + +in vec2 vPosition; + +smooth out vec2 fTexcoord; + +void main() +{ + vec4 fpos; + + vec2 osdpos = (vPosition * vec2(uOSDSize)); + fTexcoord = osdpos; + osdpos += uOSDPos; + + fpos.xy = ((osdpos * 2.0) / uScreenSize) - 1.0; + fpos.y *= -1; + fpos.z = 0.0; + fpos.w = 1.0; + + gl_Position = fpos; +} +)"; + +const char* kScreenFS_OSD = R"(#version 140 + +uniform sampler2D OSDTex; + +smooth in vec2 fTexcoord; + +out vec4 oColor; + +void main() +{ + vec4 pixel = texelFetch(OSDTex, ivec2(fTexcoord), 0); + oColor = pixel.bgra; +} +)"; + #endif // MAIN_SHADERS_H -- cgit v1.2.3