From b493c24128758f87abed5767240828fa74d05dab Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 20 May 2019 00:05:37 +0200 Subject: remove reference to GL version 4.3 from filenames and namespaces --- src/GPU3D_OpenGL.cpp | 974 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 974 insertions(+) create mode 100644 src/GPU3D_OpenGL.cpp (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp new file mode 100644 index 0000000..0bb7e42 --- /dev/null +++ b/src/GPU3D_OpenGL.cpp @@ -0,0 +1,974 @@ +/* + 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/. +*/ + +#include +#include +#include "NDS.h" +#include "GPU.h" +#include "OpenGLSupport.h" +#include "GPU3D_OpenGL_shaders.h" + +namespace GPU3D +{ +namespace GLRenderer +{ + +// GL version requirements +// * texelFetch: 3.0 (GLSL 1.30) (3.2/1.50 for MS) +// * UBO: 3.1 + + +enum +{ + RenderFlag_WBuffer = 0x01, + RenderFlag_Trans = 0x02, + RenderFlag_ShadowMask = 0x04, +}; + + +GLuint ClearShaderPlain[3]; + +GLuint RenderShader[16][3]; + +struct +{ + float uScreenSize[2]; + u32 uDispCnt; + u32 __pad0; + float uToonColors[32][4]; + +} ShaderConfig; + +GLuint ShaderConfigUBO; + +typedef struct +{ + Polygon* PolyData; + + u16* Indices; + u32 RenderKey; + +} RendererPolygon; + +RendererPolygon PolygonList[2048]; +int NumFinalPolys, NumOpaqueFinalPolys; + +GLuint ClearVertexBufferID, ClearVertexArrayID; +GLint ClearUniformLoc[4]; + +// vertex buffer +// * XYZW: 4x16bit +// * RGBA: 4x8bit +// * ST: 2x16bit +// * polygon data: 3x32bit (polygon/texture attributes) +// +// polygon attributes: +// * bit4-7, 11, 14-15, 24-29: POLYGON_ATTR +// * bit16-20: Z shift +// * bit8: front-facing (?) +// * bit9: W-buffering (?) + +GLuint VertexBufferID; +u32 VertexBuffer[10240 * 7]; +u32 NumVertices; + +GLuint VertexArrayID; +u16 IndexBuffer[2048 * 10]; +u32 NumTriangles; + +GLuint TexMemID; +GLuint TexPalMemID; + +int ScaleFactor; +bool Accelerated; +int ScreenW, ScreenH; + +GLuint FramebufferTex[8]; +int FrontBuffer; +GLuint FramebufferID[4], PixelbufferID; +u32* Framebuffer = NULL; + + + +bool BuildRenderShader(u32 flags, const char* vs, const char* fs) +{ + char shadername[32]; + sprintf(shadername, "RenderShader%02X", flags); + + int headerlen = strlen(kShaderHeader); + + int vslen = strlen(vs); + int vsclen = strlen(kRenderVSCommon); + char* vsbuf = new char[headerlen + vsclen + vslen + 1]; + strcpy(&vsbuf[0], kShaderHeader); + strcpy(&vsbuf[headerlen], kRenderVSCommon); + strcpy(&vsbuf[headerlen + vsclen], vs); + + int fslen = strlen(fs); + int fsclen = strlen(kRenderFSCommon); + char* fsbuf = new char[headerlen + fsclen + fslen + 1]; + strcpy(&fsbuf[0], kShaderHeader); + strcpy(&fsbuf[headerlen], kRenderFSCommon); + strcpy(&fsbuf[headerlen + fsclen], fs); + + bool ret = OpenGL_BuildShaderProgram(vsbuf, fsbuf, RenderShader[flags], shadername); + + delete[] vsbuf; + delete[] fsbuf; + + if (!ret) return false; + + GLuint prog = RenderShader[flags][2]; + + GLint uni_id = glGetUniformBlockIndex(prog, "uConfig"); + glUniformBlockBinding(prog, uni_id, 0); + + glBindAttribLocation(prog, 0, "vPosition"); + glBindAttribLocation(prog, 1, "vColor"); + glBindAttribLocation(prog, 2, "vTexcoord"); + glBindAttribLocation(prog, 3, "vPolygonAttr"); + glBindFragDataLocation(prog, 0, "oColor"); + glBindFragDataLocation(prog, 1, "oAttr"); + + glUseProgram(prog); + + uni_id = glGetUniformLocation(prog, "TexMem"); + glUniform1i(uni_id, 0); + uni_id = glGetUniformLocation(prog, "TexPalMem"); + glUniform1i(uni_id, 1); + + return true; +} + +void UseRenderShader(u32 flags) +{ + glUseProgram(RenderShader[flags][2]); +} + +void SetupDefaultTexParams(GLuint tex) +{ + glBindTexture(GL_TEXTURE_2D, tex); + 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); +} + +bool Init() +{ + const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string + const GLubyte* version = glGetString(GL_VERSION); // version as a string + printf("OpenGL: renderer: %s\n", renderer); + printf("OpenGL: version: %s\n", version); + + int barg1, barg2; + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &barg1); + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &barg2); + printf("max texture: %d\n", barg1); + printf("max comb. texture: %d\n", barg2); + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &barg1); + printf("max tex size: %d\n", barg1); + + glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &barg1); + printf("max arraytex levels: %d\n", barg1); + + /*glGetIntegerv(GL_NUM_EXTENSIONS, &barg1); + printf("extensions: %d\n", barg1); + for (int i = 0; i < barg1; i++) + { + const GLubyte* ext = glGetStringi(GL_EXTENSIONS, i); + printf("- %s\n", ext); + }*/ + + glEnable(GL_DEPTH_TEST); + glEnable(GL_STENCIL_TEST); + + + glDepthRange(0, 1); + glClearDepth(1.0); + + + if (!OpenGL_BuildShaderProgram(kClearVS, kClearFS, ClearShaderPlain, "ClearShader")) + return false; + + glBindAttribLocation(ClearShaderPlain[2], 0, "vPosition"); + glBindFragDataLocation(ClearShaderPlain[2], 0, "oColor"); + glBindFragDataLocation(ClearShaderPlain[2], 1, "oAttr"); + ClearUniformLoc[0] = glGetUniformLocation(ClearShaderPlain[2], "uColor"); + ClearUniformLoc[1] = glGetUniformLocation(ClearShaderPlain[2], "uDepth"); + ClearUniformLoc[2] = glGetUniformLocation(ClearShaderPlain[2], "uOpaquePolyId"); + ClearUniformLoc[3] = glGetUniformLocation(ClearShaderPlain[2], "uFogFlag"); + + memset(RenderShader, 0, sizeof(RenderShader)); + + if (!BuildRenderShader(0, + kRenderVS_Z, kRenderFS_ZO)) return false; + if (!BuildRenderShader(RenderFlag_WBuffer, + kRenderVS_W, kRenderFS_WO)) return false; + if (!BuildRenderShader(RenderFlag_Trans, + kRenderVS_Z, kRenderFS_ZT)) return false; + if (!BuildRenderShader(RenderFlag_Trans | RenderFlag_WBuffer, + kRenderVS_W, kRenderFS_WT)) return false; + if (!BuildRenderShader(RenderFlag_ShadowMask, + kRenderVS_Z, kRenderFS_ZSM)) return false; + if (!BuildRenderShader(RenderFlag_ShadowMask | RenderFlag_WBuffer, + kRenderVS_W, kRenderFS_WSM)) return false; + + + memset(&ShaderConfig, 0, sizeof(ShaderConfig)); + + glGenBuffers(1, &ShaderConfigUBO); + glBindBuffer(GL_UNIFORM_BUFFER, ShaderConfigUBO); + glBufferData(GL_UNIFORM_BUFFER, sizeof(ShaderConfig), &ShaderConfig, GL_STATIC_DRAW); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, ShaderConfigUBO); + + + float clearvtx[6*2] = + { + -1.0, -1.0, + 1.0, 1.0, + -1.0, 1.0, + + -1.0, -1.0, + 1.0, -1.0, + 1.0, 1.0 + }; + + glGenBuffers(1, &ClearVertexBufferID); + glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID); + glBufferData(GL_ARRAY_BUFFER, sizeof(clearvtx), clearvtx, GL_STATIC_DRAW); + + glGenVertexArrays(1, &ClearVertexArrayID); + glBindVertexArray(ClearVertexArrayID); + glEnableVertexAttribArray(0); // position + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0)); + + + glGenBuffers(1, &VertexBufferID); + glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); + glBufferData(GL_ARRAY_BUFFER, sizeof(VertexBuffer), NULL, GL_DYNAMIC_DRAW); + + glGenVertexArrays(1, &VertexArrayID); + glBindVertexArray(VertexArrayID); + glEnableVertexAttribArray(0); // position + glVertexAttribIPointer(0, 4, GL_UNSIGNED_SHORT, 7*4, (void*)(0)); + glEnableVertexAttribArray(1); // color + glVertexAttribIPointer(1, 4, GL_UNSIGNED_BYTE, 7*4, (void*)(2*4)); + glEnableVertexAttribArray(2); // texcoords + glVertexAttribIPointer(2, 2, GL_SHORT, 7*4, (void*)(3*4)); + glEnableVertexAttribArray(3); // attrib + glVertexAttribIPointer(3, 3, GL_UNSIGNED_INT, 7*4, (void*)(4*4)); + + + glGenFramebuffers(4, &FramebufferID[0]); + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); + + glGenTextures(8, &FramebufferTex[0]); + FrontBuffer = 0; + + // color buffers + SetupDefaultTexParams(FramebufferTex[0]); + SetupDefaultTexParams(FramebufferTex[1]); + + // depth/stencil buffer + SetupDefaultTexParams(FramebufferTex[4]); + SetupDefaultTexParams(FramebufferTex[6]); + + // attribute buffer + // R: opaque polyID (for edgemarking) + // G: opaque polyID (for shadows, suppressed when rendering translucent polygons) + // B: stencil flag + SetupDefaultTexParams(FramebufferTex[5]); + SetupDefaultTexParams(FramebufferTex[7]); + + // downscale framebuffer for antialiased mode + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); + SetupDefaultTexParams(FramebufferTex[2]); + + // downscale framebuffer for display capture (always 256x192) + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[3]); + SetupDefaultTexParams(FramebufferTex[3]); + 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); + + GLenum fbassign[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; + + 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); + glDrawBuffers(2, fbassign); + + 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); + glDrawBuffers(2, fbassign); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); + + glEnable(GL_BLEND); + glBlendFuncSeparatei(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + glBlendEquationSeparatei(0, GL_ADD, GL_MAX); + glBlendFuncSeparatei(1, GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); + + glGenBuffers(1, &PixelbufferID); + + glActiveTexture(GL_TEXTURE0); + glGenTextures(1, &TexMemID); + glBindTexture(GL_TEXTURE_2D, TexMemID); + 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_R8UI, 1024, 512, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NULL); + + glActiveTexture(GL_TEXTURE1); + glGenTextures(1, &TexPalMemID); + glBindTexture(GL_TEXTURE_2D, TexPalMemID); + 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_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL); + + return true; +} + +void DeInit() +{ + glDeleteTextures(1, &TexMemID); + glDeleteTextures(1, &TexPalMemID); + + glDeleteFramebuffers(4, &FramebufferID[0]); + glDeleteTextures(8, &FramebufferTex[0]); + + glDeleteVertexArrays(1, &VertexArrayID); + glDeleteBuffers(1, &VertexBufferID); + glDeleteVertexArrays(1, &ClearVertexArrayID); + glDeleteBuffers(1, &ClearVertexBufferID); + + glDeleteBuffers(1, &ShaderConfigUBO); + + for (int i = 0; i < 16; i++) + { + if (!RenderShader[i][2]) continue; + OpenGL_DeleteShaderProgram(RenderShader[i]); + } +} + +void Reset() +{ + // +} + +void SetDisplaySettings(int scale, bool accel) +{ + ScaleFactor = scale; + Accelerated = accel; + + // TODO: antialiasing setting + ScreenW = 256 << scale; + ScreenH = 192 << scale; + + 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_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + 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); + 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); + glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); + + if (Framebuffer) delete[] Framebuffer; + if (accel) Framebuffer = new u32[256*192]; + else Framebuffer = new u32[ScreenW*ScreenH]; +} + +int GetScale() +{ + return ScaleFactor; +} + + +void SetupPolygon(RendererPolygon* rp, Polygon* polygon) +{ + rp->PolyData = polygon; + + // render key: depending on what we're drawing + // opaque polygons: + // - depthfunc + // -- alpha=0 + // regular translucent polygons: + // - depthfunc + // -- depthwrite + // --- polyID + // shadow mask polygons: + // - depthfunc????? + // shadow polygons: + // - depthfunc + // -- depthwrite + // --- polyID + + rp->RenderKey = (polygon->Attr >> 14) & 0x1; // bit14 - depth func + if (!polygon->IsShadowMask) + { + if (polygon->Translucent) + { + if (polygon->IsShadow) rp->RenderKey |= 0x20000; + else rp->RenderKey |= 0x10000; + rp->RenderKey |= (polygon->Attr >> 10) & 0x2; // bit11 - depth write + rp->RenderKey |= (polygon->Attr & 0x3F000000) >> 16; // polygon ID + } + else + { + if ((polygon->Attr & 0x001F0000) == 0) + rp->RenderKey |= 0x2; + rp->RenderKey |= (polygon->Attr & 0x3F000000) >> 16; // polygon ID + } + } + else + { + rp->RenderKey |= 0x30000; + } +} + +void BuildPolygons(RendererPolygon* polygons, int npolys) +{ + u32* vptr = &VertexBuffer[0]; + u32 vidx = 0; + + u16* iptr = &IndexBuffer[0]; + u32 numtriangles = 0; + + for (int i = 0; i < npolys; i++) + { + RendererPolygon* rp = &polygons[i]; + Polygon* poly = rp->PolyData; + + rp->Indices = iptr; + + u32 vidx_first = vidx; + + u32 polyattr = poly->Attr; + + u32 alpha = (polyattr >> 16) & 0x1F; + + u32 vtxattr = polyattr & 0x1F00C8F0; + if (poly->FacingView) vtxattr |= (1<<8); + if (poly->WBuffer) vtxattr |= (1<<9); + + // assemble vertices + for (int j = 0; j < poly->NumVertices; j++) + { + Vertex* vtx = poly->Vertices[j]; + + u32 z = poly->FinalZ[j]; + u32 w = poly->FinalW[j]; + + // Z should always fit within 16 bits, so it's okay to do this + u32 zshift = 0; + while (z > 0xFFFF) { z >>= 1; zshift++; } + + u32 x, y; + if (ScaleFactor > 0) + { + x = vtx->HiresPosition[0] >> (4-ScaleFactor); + y = vtx->HiresPosition[1] >> (4-ScaleFactor); + } + else + { + x = vtx->FinalPosition[0]; + y = vtx->FinalPosition[1]; + } + + *vptr++ = x | (y << 16); + *vptr++ = z | (w << 16); + + *vptr++ = (vtx->FinalColor[0] >> 1) | + ((vtx->FinalColor[1] >> 1) << 8) | + ((vtx->FinalColor[2] >> 1) << 16) | + (alpha << 24); + + *vptr++ = (u16)vtx->TexCoords[0] | ((u16)vtx->TexCoords[1] << 16); + + *vptr++ = vtxattr | (zshift << 16); + *vptr++ = poly->TexParam; + *vptr++ = poly->TexPalette; + + if (j >= 2) + { + // build a triangle + *iptr++ = vidx_first; + *iptr++ = vidx - 1; + *iptr++ = vidx; + numtriangles++; + } + + vidx++; + } + } + + NumTriangles = numtriangles; + NumVertices = vidx; +} + +void RenderSceneChunk(int y, int h) +{ + u32 flags = 0; + if (RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer; + + u16* iptr; + u32 curkey; + + if (h != 192) glScissor(0, y<RenderKey != curkey) + { + u16* endptr = rp->Indices; + u32 num = (u32)(endptr - iptr); + if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + + iptr = rp->Indices; + curkey = rp->RenderKey; + + // zorp + glDepthFunc(GL_LESS); + + u32 polyattr = rp->PolyData->Attr; + u32 polyid = (polyattr >> 24) & 0x3F; + + glStencilFunc(GL_ALWAYS, polyid, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0xFF); + } + } + + { + u16* endptr = &IndexBuffer[NumTriangles*3]; + u32 num = (u32)(endptr - iptr); + if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + } + + glEnable(GL_BLEND); + UseRenderShader(flags | RenderFlag_Trans); + + if (NumOpaqueFinalPolys > -1) + { + glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + if (PolygonList[NumOpaqueFinalPolys].PolyData->IsShadow) printf("!! GLORG!!! %08X\n", PolygonList[NumOpaqueFinalPolys].PolyData->Attr); + + // pass 2: if needed, render translucent pixels that are against background pixels + // when background alpha is zero, those need to be rendered with blending disabled + + if ((RenderClearAttr1 & 0x001F0000) == 0) + { + iptr = PolygonList[NumOpaqueFinalPolys].Indices; + curkey = 0xFFFFFFFF; + + glDisable(GL_BLEND); + + for (int i = NumOpaqueFinalPolys; i < NumFinalPolys; i++) + { + RendererPolygon* rp = &PolygonList[i]; + if (rp->RenderKey != curkey) + { + u16* endptr = rp->Indices; + u32 num = (u32)(endptr - iptr); + if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + + iptr = rp->Indices; + curkey = rp->RenderKey; + + // configure new one + + // shadows aren't likely to pass against the clear-plane, so + if (rp->PolyData->IsShadow) continue; + + // zorp + glDepthFunc(GL_LESS); + + u32 polyattr = rp->PolyData->Attr; + u32 polyid = (polyattr >> 24) & 0x3F; + + glStencilFunc(GL_EQUAL, 0xFF, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); + glStencilMask(~(0x40|polyid)); // heheh + + if (polyattr & (1<<11)) glDepthMask(GL_TRUE); + else glDepthMask(GL_FALSE); + } + } + + { + u16* endptr = &IndexBuffer[NumTriangles*3]; + u32 num = (u32)(endptr - iptr); + if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + } + + glEnable(GL_BLEND); + glStencilMask(0xFF); + } + + // pass 3: translucent pixels + + iptr = PolygonList[NumOpaqueFinalPolys].Indices; + curkey = 0xFFFFFFFF; + + for (int i = NumOpaqueFinalPolys; i < NumFinalPolys; i++) + { + RendererPolygon* rp = &PolygonList[i]; + if (rp->RenderKey != curkey) + { + u16* endptr = rp->Indices; + u32 num = (u32)(endptr - iptr); + if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + + iptr = rp->Indices; + curkey = rp->RenderKey; + + // configure new one + + if (rp->PolyData->IsShadowMask) + { + // clear shadow bits in stencil buffer + + glStencilMask(0x80); + glClear(GL_STENCIL_BUFFER_BIT); + + // draw actual shadow mask + + UseRenderShader(flags | RenderFlag_ShadowMask); + + glDisable(GL_BLEND); + glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glDepthMask(GL_FALSE); + + glDepthFunc(GL_LESS); + glStencilFunc(GL_ALWAYS, 0x80, 0x80); + glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); + + glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); + glBindVertexArray(VertexArrayID); + } + else + { + UseRenderShader(flags | RenderFlag_Trans); + + u32 polyattr = rp->PolyData->Attr; + u32 polyid = (polyattr >> 24) & 0x3F; + + // zorp + glDepthFunc(GL_LESS); + + if (rp->PolyData->IsShadow) + { + glDisable(GL_BLEND); + glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glDepthMask(GL_FALSE); + glStencilFunc(GL_EQUAL, polyid, 0x3F); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glStencilMask(0x80); + + { + u16* _endptr = &IndexBuffer[NumTriangles*3]; + for (int j = i; j < NumFinalPolys; j++) + { + RendererPolygon* rp = &PolygonList[j]; + if (!rp->PolyData->IsShadow) + { + _endptr = rp->Indices; + break; + } + + // berg. + } + u32 num = (u32)(_endptr - iptr); + if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + } + + glEnable(GL_BLEND); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + + glStencilFunc(GL_EQUAL, 0xC0|polyid, 0x80); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0x7F); + } + else + { + glEnable(GL_BLEND); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + + glStencilFunc(GL_NOTEQUAL, 0x40|polyid, 0x7F); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0x7F); + } + + if (polyattr & (1<<11)) glDepthMask(GL_TRUE); + else glDepthMask(GL_FALSE); + } + } + } + + { + u16* endptr = &IndexBuffer[NumTriangles*3]; + u32 num = (u32)(endptr - iptr); + if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + } + } + + glFlush(); +} + + +void RenderFrame() +{ + ShaderConfig.uScreenSize[0] = ScreenW; + ShaderConfig.uScreenSize[1] = ScreenH; + ShaderConfig.uDispCnt = RenderDispCnt; + + for (int i = 0; i < 32; i++) + { + u16 c = RenderToonTable[i]; + u32 r = c & 0x1F; + u32 g = (c >> 5) & 0x1F; + u32 b = (c >> 10) & 0x1F; + + ShaderConfig.uToonColors[i][0] = (float)r / 31.0; + ShaderConfig.uToonColors[i][1] = (float)g / 31.0; + ShaderConfig.uToonColors[i][2] = (float)b / 31.0; + } + + glBindBuffer(GL_UNIFORM_BUFFER, ShaderConfigUBO); + void* unibuf = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); + if (unibuf) memcpy(unibuf, &ShaderConfig, sizeof(ShaderConfig)); + glUnmapBuffer(GL_UNIFORM_BUFFER); + + // SUCKY!!!!!!!!!!!!!!!!!! + // TODO: detect when VRAM blocks are modified! + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, TexMemID); + for (int i = 0; i < 4; i++) + { + u32 mask = GPU::VRAMMap_Texture[i]; + u8* vram; + if (!mask) continue; + else if (mask & (1<<0)) vram = GPU::VRAM_A; + else if (mask & (1<<1)) vram = GPU::VRAM_B; + else if (mask & (1<<2)) vram = GPU::VRAM_C; + else if (mask & (1<<3)) vram = GPU::VRAM_D; + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i*128, 1024, 128, GL_RED_INTEGER, GL_UNSIGNED_BYTE, vram); + } + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, TexPalMemID); + for (int i = 0; i < 6; i++) + { + // 6 x 16K chunks + u32 mask = GPU::VRAMMap_TexPal[i]; + u8* vram; + if (!mask) continue; + else if (mask & (1<<4)) vram = &GPU::VRAM_E[(i&3)*0x4000]; + else if (mask & (1<<5)) vram = GPU::VRAM_F; + else if (mask & (1<<6)) vram = GPU::VRAM_G; + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i*8, 1024, 8, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, vram); + } + + glDisable(GL_SCISSOR_TEST); + glEnable(GL_DEPTH_TEST); + glEnable(GL_STENCIL_TEST); + + glViewport(0, 0, ScreenW, ScreenH); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); + FrontBuffer = FrontBuffer ? 0 : 1; + + glDisable(GL_BLEND); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + glDepthMask(GL_TRUE); + glStencilMask(0xFF); + + // clear buffers + // TODO: clear bitmap + // TODO: check whether 'clear polygon ID' affects translucent polyID + // (for example when alpha is 1..30) + { + glUseProgram(ClearShaderPlain[2]); + glDepthFunc(GL_ALWAYS); + + u32 r = RenderClearAttr1 & 0x1F; + u32 g = (RenderClearAttr1 >> 5) & 0x1F; + u32 b = (RenderClearAttr1 >> 10) & 0x1F; + u32 fog = (RenderClearAttr1 >> 15) & 0x1; + u32 a = (RenderClearAttr1 >> 16) & 0x1F; + u32 polyid = (RenderClearAttr1 >> 24) & 0x3F; + u32 z = ((RenderClearAttr2 & 0x7FFF) * 0x200) + 0x1FF; + + glStencilFunc(GL_ALWAYS, 0xFF, 0xFF); + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + + /*if (r) r = r*2 + 1; + if (g) g = g*2 + 1; + if (b) b = b*2 + 1;*/ + + glUniform4ui(ClearUniformLoc[0], r, g, b, a); + glUniform1ui(ClearUniformLoc[1], z); + glUniform1ui(ClearUniformLoc[2], polyid); + glUniform1ui(ClearUniformLoc[3], fog); + + glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID); + glBindVertexArray(ClearVertexArrayID); + glDrawArrays(GL_TRIANGLES, 0, 2*3); + } + + if (RenderNumPolygons) + { + // render shit here + u32 flags = 0; + if (RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer; + + int npolys = 0; + int firsttrans = -1; + for (int i = 0; i < RenderNumPolygons; i++) + { + if (RenderPolygonRAM[i]->Degenerate) continue; + + // zog. + //if (RenderPolygonRAM[i]->YBottom <= 96 || RenderPolygonRAM[i]->YTop >= 144) continue; + + SetupPolygon(&PolygonList[npolys], RenderPolygonRAM[i]); + if (firsttrans < 0 && RenderPolygonRAM[i]->Translucent) + firsttrans = npolys; + + npolys++; + } + NumFinalPolys = npolys; + NumOpaqueFinalPolys = firsttrans; + + BuildPolygons(&PolygonList[0], npolys); + glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); + glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); + + RenderSceneChunk(0, 192); + } + + if (false) + { + glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferID[0]); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[1]); + glBlitFramebuffer(0, 0, ScreenW, ScreenH, 0, 0, ScreenW/2, ScreenH/2, GL_COLOR_BUFFER_BIT, GL_LINEAR); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); + } + else + { + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); + } + + /*if (!Accelerated) + { + glReadBuffer(GL_COLOR_ATTACHMENT0); + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); + + glReadPixels(0, 0, 256<> 2) | (a >> 3); + } + + return &Framebuffer[stride * line]; +} + +void SetupAccelFrame() +{ + glBindTexture(GL_TEXTURE_2D, FramebufferTex[FrontBuffer]); +} + +} +} -- cgit v1.2.3 From db396e992b670fa419123474068e100c9f706b2f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 21 May 2019 22:28:46 +0200 Subject: welp. progress --- src/Config.cpp | 2 + src/Config.h | 1 + src/GPU.cpp | 42 +---- src/GPU.h | 2 +- src/GPU2D.cpp | 2 +- src/GPU2D.h | 2 +- src/GPU3D.cpp | 51 ++++--- src/GPU3D.h | 11 +- src/GPU3D_OpenGL.cpp | 144 ++++++++---------- src/GPU3D_Soft.cpp | 15 -- src/libui_sdl/DlgVideoSettings.cpp | 174 ++++++++++++++++----- src/libui_sdl/PlatformConfig.cpp | 6 +- src/libui_sdl/PlatformConfig.h | 3 +- src/libui_sdl/main.cpp | 303 ++++++++++++++++++++----------------- 14 files changed, 403 insertions(+), 355 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/Config.cpp b/src/Config.cpp index aca3d4f..42f18c7 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -31,6 +31,7 @@ const char* kConfigFile = "melonDS.ini"; int _3DRenderer; int Threaded3D; +int GL_ScaleFactor; int GL_Antialias; ConfigEntry ConfigFile[] = @@ -38,6 +39,7 @@ ConfigEntry ConfigFile[] = {"3DRenderer", 0, &_3DRenderer, 1, NULL, 0}, {"Threaded3D", 0, &Threaded3D, 1, NULL, 0}, + {"GL_ScaleFactor", 0, &GL_ScaleFactor, 1, NULL, 0}, {"GL_Antialias", 0, &GL_Antialias, 0, NULL, 0}, {"", -1, NULL, 0, NULL, 0} diff --git a/src/Config.h b/src/Config.h index 8dc97d5..6ffc495 100644 --- a/src/Config.h +++ b/src/Config.h @@ -43,6 +43,7 @@ void Save(); extern int _3DRenderer; extern int Threaded3D; +extern int GL_ScaleFactor; extern int GL_Antialias; } diff --git a/src/GPU.cpp b/src/GPU.cpp index 8b94c94..959129e 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -73,7 +73,6 @@ u32 VRAMMap_ARM7[2]; int FrontBuffer; u32* Framebuffer[2][2]; -int ScreenScale[2]; bool Accelerated; GPU2D* GPU2D_A; @@ -89,8 +88,8 @@ bool Init() FrontBuffer = 0; Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL; Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL; - ScreenScale[0] = -1; ScreenScale[1] = -1; Accelerated = false; - SetDisplaySettings(0, 0, false); + Accelerated = false; + SetDisplaySettings(false); return true; } @@ -247,12 +246,10 @@ void AssignFramebuffers() } } -void SetDisplaySettings(int topscale, int bottomscale, bool accel) -{accel=true; +void SetDisplaySettings(bool accel) +{ if (accel != Accelerated) { - ScreenScale[0] = accel ? 0 : topscale; - int fbsize; if (accel) fbsize = (256*3 + 2) * 192; else fbsize = 256 * 192; @@ -273,35 +270,8 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) AssignFramebuffers(); } - if (topscale != ScreenScale[0]) - { - ScreenScale[0] = topscale; - - if (NDS::PowerControl9 & (1<<15)) - { - GPU2D_A->SetDisplaySettings(ScreenScale[0], accel); - GPU3D::SetDisplaySettings(ScreenScale[0], accel); - } - else - { - GPU2D_B->SetDisplaySettings(ScreenScale[0], accel); - } - } - - if (bottomscale != ScreenScale[1] || accel != Accelerated) - { - ScreenScale[1] = bottomscale; - - if (NDS::PowerControl9 & (1<<15)) - { - GPU2D_B->SetDisplaySettings(ScreenScale[1], accel); - } - else - { - GPU2D_A->SetDisplaySettings(ScreenScale[1], accel); - GPU3D::SetDisplaySettings(ScreenScale[1], accel); - } - } + GPU2D_A->SetDisplaySettings(accel); + GPU2D_B->SetDisplaySettings(accel); Accelerated = accel; } diff --git a/src/GPU.h b/src/GPU.h index cfa8d7d..b6f6473 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -75,7 +75,7 @@ void Stop(); void DoSavestate(Savestate* file); -void SetDisplaySettings(int topscale, int bottomscale, bool accel); +void SetDisplaySettings(bool accel); void MapVRAM_AB(u32 bank, u8 cnt); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index fe1645e..88249ba 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -215,7 +215,7 @@ void GPU2D::SetFramebuffer(u32* buf) Framebuffer = buf; } -void GPU2D::SetDisplaySettings(int scale, bool accel) +void GPU2D::SetDisplaySettings(bool accel) { Accelerated = accel; diff --git a/src/GPU2D.h b/src/GPU2D.h index eb159f7..78e62f5 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -31,7 +31,7 @@ public: void SetEnabled(bool enable) { Enabled = enable; } void SetFramebuffer(u32* buf); - void SetDisplaySettings(int scale, bool accel); + void SetDisplaySettings(bool accel); u8 Read8(u32 addr); u16 Read16(u32 addr); diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 04ec55e..0ca3cd4 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -156,6 +156,8 @@ u32 NumCommands, CurCommand, ParamCount, TotalParams; bool GeometryEnabled; bool RenderingEnabled; +int Renderer; + u32 DispCnt; u8 AlphaRefVal, AlphaRef; @@ -275,16 +277,16 @@ bool Init() CmdStallQueue = new FIFO(64); - //if (!SoftRenderer::Init()) return false; - if (!GLRenderer::Init()) return false; + Renderer = -1; + // SetRenderer() will be called to set it up later return true; } void DeInit() { - //SoftRenderer::DeInit(); - GLRenderer::DeInit(); + if (Renderer == 0) SoftRenderer::DeInit(); + else GLRenderer::DeInit(); delete CmdFIFO; delete CmdPIPE; @@ -384,8 +386,8 @@ void Reset() FlushAttributes = 0; ResetRenderingState(); - //SoftRenderer::Reset(); - GLRenderer::Reset(); + if (Renderer == 0) SoftRenderer::Reset(); + else GLRenderer::Reset(); } void DoSavestate(Savestate* file) @@ -607,14 +609,24 @@ void SetEnabled(bool geometry, bool rendering) if (!rendering) ResetRenderingState(); } -void SetDisplaySettings(int scale, bool accel) -{ - GLRenderer::SetDisplaySettings(scale, accel); -} -int GetScale() +int SetRenderer(int renderer) { - return GLRenderer::GetScale(); + //if (renderer == Renderer) return renderer; + + //if (Renderer == 0) SoftRenderer::DeInit(); + //else GLRenderer::DeInit(); + + if (renderer == 1) + { + if (!GLRenderer::Init()) + renderer = 0; + } + + if (renderer == 0) SoftRenderer::Init(); + + Renderer = renderer; + return renderer; } @@ -2354,7 +2366,7 @@ void CheckFIFODMA() void VCount144() { - //SoftRenderer::VCount144(); + if (Renderer == 0) SoftRenderer::VCount144(); } @@ -2436,19 +2448,14 @@ void VBlank() void VCount215() { - //SoftRenderer::RenderFrame(); - GLRenderer::RenderFrame(); + if (Renderer == 0) SoftRenderer::RenderFrame(); + else GLRenderer::RenderFrame(); } u32* GetLine(int line) { - //return SoftRenderer::GetLine(line); - return GLRenderer::GetLine(line); -} - -void SetupAccelFrame() -{ - GLRenderer::SetupAccelFrame(); + if (Renderer == 0) return SoftRenderer::GetLine(line); + else return GLRenderer::GetLine(line); } diff --git a/src/GPU3D.h b/src/GPU3D.h index 280b99e..36c6c0f 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -97,8 +97,8 @@ void Reset(); void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); -void SetDisplaySettings(int scale, bool accel); -int GetScale(); + +int SetRenderer(int renderer); void ExecuteCommand(); @@ -129,15 +129,11 @@ bool Init(); void DeInit(); void Reset(); -void SetDisplaySettings(int scale, bool accel); -int GetScale(); - void SetupRenderThread(); void VCount144(); void RenderFrame(); u32* GetLine(int line); -void SetupAccelFrame(); } @@ -148,8 +144,7 @@ bool Init(); void DeInit(); void Reset(); -void SetDisplaySettings(int scale, bool accel); -int GetScale(); +void SetDisplaySettings(int scale, bool antialias); void RenderFrame(); void PrepareCaptureFrame(); diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 0bb7e42..30c77bf 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -95,13 +95,13 @@ GLuint TexMemID; GLuint TexPalMemID; int ScaleFactor; -bool Accelerated; +bool Antialias; int ScreenW, ScreenH; GLuint FramebufferTex[8]; int FrontBuffer; GLuint FramebufferID[4], PixelbufferID; -u32* Framebuffer = NULL; +u32 Framebuffer[256*192]; @@ -176,26 +176,6 @@ bool Init() printf("OpenGL: renderer: %s\n", renderer); printf("OpenGL: version: %s\n", version); - int barg1, barg2; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &barg1); - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &barg2); - printf("max texture: %d\n", barg1); - printf("max comb. texture: %d\n", barg2); - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &barg1); - printf("max tex size: %d\n", barg1); - - glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &barg1); - printf("max arraytex levels: %d\n", barg1); - - /*glGetIntegerv(GL_NUM_EXTENSIONS, &barg1); - printf("extensions: %d\n", barg1); - for (int i = 0; i < barg1; i++) - { - const GLubyte* ext = glGetStringi(GL_EXTENSIONS, i); - printf("- %s\n", ext); - }*/ - glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); @@ -317,6 +297,12 @@ bool Init() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[1], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); + glDrawBuffers(2, fbassign); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[2], 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[6], 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[7], 0); glDrawBuffers(2, fbassign); @@ -324,8 +310,9 @@ bool Init() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); glEnable(GL_BLEND); + // TODO: these are said to require GL 4.0; use the regular ones instead? glBlendFuncSeparatei(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - glBlendEquationSeparatei(0, GL_ADD, GL_MAX); + glBlendEquationSeparatei(0, GL_FUNC_ADD, GL_MAX); glBlendFuncSeparatei(1, GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); glGenBuffers(1, &PixelbufferID); @@ -347,7 +334,7 @@ bool Init() 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_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL); - +printf("init done. %04X\n", glGetError()); return true; } @@ -375,44 +362,55 @@ void DeInit() void Reset() { - // } -void SetDisplaySettings(int scale, bool accel) +void SetDisplaySettings(int scale, bool antialias) { + if (antialias) scale *= 2; + ScaleFactor = scale; - Accelerated = accel; - - // TODO: antialiasing setting - ScreenW = 256 << scale; - ScreenH = 192 << scale; - - 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_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); - 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); - 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); + Antialias = antialias; - glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); + ScreenW = 256 * scale; + ScreenH = 192 * scale; - if (Framebuffer) delete[] Framebuffer; - if (accel) Framebuffer = new u32[256*192]; - else Framebuffer = new u32[ScreenW*ScreenH]; -} + if (!antialias) + { + 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_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 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); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 1, 1, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + } + else + { + glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW/2, ScreenH/2, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW/2, ScreenH/2, 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); + } -int GetScale() -{ - return ScaleFactor; + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); + glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); } @@ -496,10 +494,10 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) while (z > 0xFFFF) { z >>= 1; zshift++; } u32 x, y; - if (ScaleFactor > 0) + if (ScaleFactor > 1) { - x = vtx->HiresPosition[0] >> (4-ScaleFactor); - y = vtx->HiresPosition[1] >> (4-ScaleFactor); + x = (vtx->HiresPosition[0] * ScaleFactor) >> 4; + y = (vtx->HiresPosition[1] * ScaleFactor) >> 4; } else { @@ -829,8 +827,8 @@ void RenderFrame() glViewport(0, 0, ScreenW, ScreenH); - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); - FrontBuffer = FrontBuffer ? 0 : 1; + if (Antialias) glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); + else glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); glDisable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -902,26 +900,15 @@ void RenderFrame() RenderSceneChunk(0, 192); } - if (false) + if (Antialias) { - glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferID[0]); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[1]); + glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferID[2]); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[FrontBuffer]); glBlitFramebuffer(0, 0, ScreenW, ScreenH, 0, 0, ScreenW/2, ScreenH/2, GL_COLOR_BUFFER_BIT, GL_LINEAR); - - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); } - else - { - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); - } - - /*if (!Accelerated) - { - glReadBuffer(GL_COLOR_ATTACHMENT0); - glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glReadPixels(0, 0, 256< 8) Config::GL_ScaleFactor = 8; + + old_renderer = Config::_3DRenderer; + old_gldisplay = Config::ScreenUseGL; + old_threaded3D = Config::Threaded3D; + old_resolution = Config::GL_ScaleFactor; + old_antialias = Config::GL_Antialias; + + uiCheckboxSetChecked(cbGLDisplay, Config::ScreenUseGL); + uiCheckboxSetChecked(cbThreaded3D, Config::Threaded3D); + uiComboboxSetSelected(cbResolution, Config::GL_ScaleFactor-1); + uiCheckboxSetChecked(cbAntialias, Config::GL_Antialias); + uiRadioButtonsSetSelected(rbRenderer, Config::_3DRenderer); + UpdateControls(); uiControlShow(uiControl(win)); } diff --git a/src/libui_sdl/PlatformConfig.cpp b/src/libui_sdl/PlatformConfig.cpp index 065d9c2..f700ecb 100644 --- a/src/libui_sdl/PlatformConfig.cpp +++ b/src/libui_sdl/PlatformConfig.cpp @@ -40,9 +40,8 @@ int ScreenLayout; int ScreenSizing; int ScreenFilter; -int ScreenScale; +int ScreenUseGL; int ScreenRatio; -int ScreenScaleMode; int LimitFPS; @@ -105,9 +104,8 @@ ConfigEntry PlatformConfigFile[] = {"ScreenSizing", 0, &ScreenSizing, 0, NULL, 0}, {"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0}, - {"ScreenScale", 0, &ScreenScale, 0, NULL, 0}, + {"ScreenUseGL", 0, &ScreenUseGL, 1, NULL, 0}, {"ScreenRatio", 0, &ScreenRatio, 0, NULL, 0}, - {"ScreenScaleMode", 0, &ScreenScaleMode, 0, NULL, 0}, {"LimitFPS", 0, &LimitFPS, 1, NULL, 0}, diff --git a/src/libui_sdl/PlatformConfig.h b/src/libui_sdl/PlatformConfig.h index 0cff1d2..013a0a7 100644 --- a/src/libui_sdl/PlatformConfig.h +++ b/src/libui_sdl/PlatformConfig.h @@ -48,9 +48,8 @@ extern int ScreenLayout; extern int ScreenSizing; extern int ScreenFilter; -extern int ScreenScale; +extern int ScreenUseGL; extern int ScreenRatio; -extern int ScreenScaleMode; extern int LimitFPS; diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index b499da7..f0d7b74 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -100,6 +100,9 @@ char PrevSRAMPath[1024]; // for savestate 'undo load' bool SavestateLoaded; +bool Screen_UseGL; +int _3DRenderer; + bool ScreenDrawInited = false; uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; @@ -117,8 +120,7 @@ float GL_ScreenVertices[2 * 3*2 * 4]; // position/texcoord GLuint GL_ScreenTexture; bool GL_ScreenSizeDirty; -int ScreenScale[3]; -int ScreenScaleMode; +int GL_3DScale; int ScreenGap = 0; int ScreenLayout = 0; @@ -161,14 +163,14 @@ void GetSavestateName(int slot, char* filename, int len); -bool GLDrawing_Init() +bool GLScreen_Init() { if (!OpenGL_Init()) return false; if (!OpenGL_BuildShaderProgram(kScreenVS, kScreenFS, GL_ScreenShader, "ScreenShader")) return false; -printf("GL init looking good\n"); + GLuint uni_id; memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig)); @@ -211,11 +213,11 @@ printf("GL init looking good\n"); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1024, 1536, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); GL_ScreenSizeDirty = true; -printf("finished w/ err: %04X\n", glGetError()); + return true; } -void GLDrawing_DeInit() +void GLScreen_DeInit() { glDeleteTextures(1, &GL_ScreenTexture); @@ -225,7 +227,7 @@ void GLDrawing_DeInit() OpenGL_DeleteShaderProgram(GL_ScreenShader); } -void GLDrawing_DrawScreen() +void GLScreen_DrawScreen() { if (GL_ScreenSizeDirty) { @@ -233,8 +235,8 @@ void GLDrawing_DrawScreen() GL_ShaderConfig.uScreenSize[0] = WindowWidth; GL_ShaderConfig.uScreenSize[1] = WindowHeight; - GL_ShaderConfig.u3DScale = 1 << GPU3D::GetScale(); - + GL_ShaderConfig.u3DScale = GL_3DScale; +printf("updating GL scale: %d\n", GL_3DScale); glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO); void* unibuf = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); if (unibuf) memcpy(unibuf, &GL_ShaderConfig, sizeof(GL_ShaderConfig)); @@ -257,8 +259,8 @@ void GLDrawing_DrawScreen() x1 = TopScreenRect.X + TopScreenRect.Width; y1 = TopScreenRect.Y + TopScreenRect.Height; - scwidth = 256;// << ScreenScale[0]; - scheight = 192;// << ScreenScale[0]; + scwidth = 256; + scheight = 192; switch (ScreenRotation) { @@ -303,8 +305,8 @@ void GLDrawing_DrawScreen() x1 = BottomScreenRect.X + BottomScreenRect.Width; y1 = BottomScreenRect.Y + BottomScreenRect.Height; - scwidth = 256;// << ScreenScale[1]; - scheight = 192;// << ScreenScale[1]; + scwidth = 256; + scheight = 192; switch (ScreenRotation) { @@ -376,7 +378,8 @@ void GLDrawing_DrawScreen() GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); glActiveTexture(GL_TEXTURE1); - GPU3D::SetupAccelFrame(); + if (_3DRenderer != 0) + GPU3D::GLRenderer::SetupAccelFrame(); glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); glBindVertexArray(GL_ScreenVertexArrayID); @@ -384,7 +387,89 @@ void GLDrawing_DrawScreen() glFlush(); uiGLSwapBuffers(GLContext); - uiAreaQueueRedrawAll(MainDrawArea); +} + +void ScreenCreateArea(bool opengl) +{ + bool opengl_good = opengl; + if (opengl_good) + { + MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions); + uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); + uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); + uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); + GLContext = uiAreaGetGLContext(MainDrawArea); + if (!GLContext) opengl_good = false; + } + + if (opengl_good) + { + uiGLMakeContextCurrent(GLContext); + if (!GLScreen_Init()) opengl_good = false; + } + + if (opengl_good) + { + //if (_3DRenderer != 0) + { + _3DRenderer = GPU3D::SetRenderer(_3DRenderer); + if (_3DRenderer != 0) + GPU3D::GLRenderer::SetDisplaySettings(Config::GL_ScaleFactor, Config::GL_Antialias); + else if (RunningSomething) + GPU3D::SoftRenderer::SetupRenderThread(); + } + uiGLMakeContextCurrent(NULL); + } + else + { + if (opengl) + { + uiWindowSetChild(MainWindow, NULL); + uiControlDestroy(uiControl(MainDrawArea)); + } + + Screen_UseGL = false; + + MainDrawArea = uiNewArea(&MainDrawAreaHandler); + uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); + uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); + uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); + ScreenDrawInited = false; + } + + uiControlShow(uiControl(MainWindow)); + uiControlSetFocus(uiControl(MainDrawArea)); +} + +void ScreenSetMethod(bool opengl) +{ + int oldstatus = EmuRunning; + EmuRunning = 3; + while (EmuStatus != 3); + + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + if (_3DRenderer != 0) GPU3D::GLRenderer::DeInit(); + else GPU3D::SoftRenderer::DeInit(); + GLScreen_DeInit(); + uiGLMakeContextCurrent(NULL); + } + else + { + if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); + if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); + } + + uiWindowSetChild(MainWindow, NULL); + uiControlDestroy(uiControl(MainDrawArea)); + + Screen_UseGL = Config::ScreenUseGL; + _3DRenderer = Config::_3DRenderer; + + ScreenCreateArea(opengl); + + EmuRunning = oldstatus; } void MicLoadWav(char* name) @@ -642,8 +727,11 @@ void FeedMicInput() int EmuThreadFunc(void* burp) { - uiGLMakeContextCurrent(GLContext); - GLDrawing_Init(); + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + GLScreen_Init(); + } NDS::Init(); @@ -652,13 +740,8 @@ int EmuThreadFunc(void* burp) MainScreenPos[2] = 0; AutoScreenSizing = 0; - // FIXME - ScreenScale[2] = Config::ScreenScale; - ScreenScale[0] = ScreenScale[2]; - ScreenScale[1] = ScreenScale[2]; - - int lastscale[2] = {ScreenScale[0], ScreenScale[1]}; - GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false); + GPU::SetDisplaySettings(_3DRenderer != 0); + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); Touching = false; KeyInputMask = 0xFFF; @@ -773,7 +856,7 @@ int EmuThreadFunc(void* burp) // microphone input FeedMicInput(); - uiGLMakeContextCurrent(GLContext); + if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); // auto screen layout { @@ -804,22 +887,16 @@ int EmuThreadFunc(void* burp) } } - if (ScreenScale[0] != lastscale[0] || - ScreenScale[1] != lastscale[1]) - { - GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false); - ScreenDrawInited = false; - } - // emulate u32 nlines = NDS::RunFrame(); if (EmuRunning == 0) break; - GLDrawing_DrawScreen(); - - //uiAreaQueueRedrawAll(MainDrawArea); - //uiGLSwapBuffers(GLContext); + if (Screen_UseGL) + { + GLScreen_DrawScreen(); + } + uiAreaQueueRedrawAll(MainDrawArea); // framerate limiter based off SDL2_gfx float framerate = (1000.0f * nlines) / (60.0f * 263.0f); @@ -869,13 +946,16 @@ int EmuThreadFunc(void* burp) if (EmuRunning == 2) { - uiGLMakeContextCurrent(GLContext); - - //uiAreaQueueRedrawAll(MainDrawArea); - //uiGLSwapBuffers(GLContext); - GLDrawing_DrawScreen(); + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + GLScreen_DrawScreen(); + } + uiAreaQueueRedrawAll(MainDrawArea); } + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + EmuStatus = EmuRunning; SDL_Delay(100); @@ -889,7 +969,7 @@ int EmuThreadFunc(void* burp) NDS::DeInit(); Platform::LAN_DeInit(); - GLDrawing_DeInit(); + if (Screen_UseGL) GLScreen_DeInit(); return 44203; } @@ -897,22 +977,21 @@ int EmuThreadFunc(void* burp) void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) { - // TODO: recreate bitmap if screen scale changed if (!ScreenDrawInited) { if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); ScreenDrawInited = true; - ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256<Context, 256<Context, 256, 192); + ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192); } if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; if (!GPU::Framebuffer[0][0]) return; - uiRect top = {0, 0, 256< 8) GL_3DScale = 8; MainWindow = uiNewWindow("melonDS " MELONDS_VERSION, w, h, Config::WindowMaximized, 1, 1); uiWindowOnClosing(MainWindow, OnCloseWindow, NULL); @@ -2346,11 +2378,7 @@ int main(int argc, char** argv) MainDrawAreaHandler.Resize = OnAreaResize; ScreenDrawInited = false; - //MainDrawArea = uiNewArea(&MainDrawAreaHandler); - MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions); - uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); - uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); - uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); // TODO: make configurable? + ScreenCreateArea(Screen_UseGL); ScreenRotation = Config::ScreenRotation; ScreenGap = Config::ScreenGap; @@ -2377,15 +2405,6 @@ int main(int argc, char** argv) OnSetScreenRotation(MenuItem_ScreenRot[ScreenRotation], MainWindow, (void*)&kScreenRot[ScreenRotation]); - // TODO: fail gracefully, support older OpenGL, etc - GLContext = uiAreaGetGLContext(MainDrawArea); - uiGLMakeContextCurrent(GLContext); - - void* testor = uiGLGetProcAddress("glUseProgram"); - void* testor2 = uiGLGetProcAddress("glBindFramebuffer"); - printf("OPENGL: %p %p\n", testor, testor2); - uiGLMakeContextCurrent(NULL); - SDL_AudioSpec whatIwant, whatIget; memset(&whatIwant, 0, sizeof(SDL_AudioSpec)); whatIwant.freq = 47340; @@ -2454,8 +2473,6 @@ int main(int argc, char** argv) } } - uiControlShow(uiControl(MainWindow)); - uiControlSetFocus(uiControl(MainDrawArea)); uiMain(); EmuRunning = 0; -- cgit v1.2.3 From 667dee67540482660fddd6ddd9bf7f7f639693aa Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 24 May 2019 02:04:41 +0200 Subject: more code botching it's less shitty tho but still has bugs --- src/GPU3D.cpp | 26 ++- src/GPU3D.h | 9 +- src/GPU3D_OpenGL.cpp | 9 +- src/libui_sdl/DlgVideoSettings.cpp | 17 +- src/libui_sdl/main.cpp | 334 +++++++++++++------------------------ 5 files changed, 164 insertions(+), 231 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 0ca3cd4..115b31f 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -22,6 +22,7 @@ #include "NDS.h" #include "GPU.h" #include "FIFO.h" +#include "Config.h" // 3D engine notes @@ -610,12 +611,9 @@ void SetEnabled(bool geometry, bool rendering) } -int SetRenderer(int renderer) +int InitRenderer(bool hasGL) { - //if (renderer == Renderer) return renderer; - - //if (Renderer == 0) SoftRenderer::DeInit(); - //else GLRenderer::DeInit(); + int renderer = hasGL ? Config::_3DRenderer : 0; if (renderer == 1) { @@ -629,6 +627,24 @@ int SetRenderer(int renderer) return renderer; } +void DeInitRenderer() +{ + if (Renderer == 0) SoftRenderer::DeInit(); + else GLRenderer::DeInit(); +} + +void UpdateRendererConfig() +{ + if (Renderer == 0) + { + SoftRenderer::SetupRenderThread(); + } + else + { + GLRenderer::UpdateDisplaySettings(); + } +} + void MatrixLoadIdentity(s32* m) diff --git a/src/GPU3D.h b/src/GPU3D.h index 36c6c0f..4e7c01a 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -90,6 +90,8 @@ extern u32 RenderNumPolygons; extern u64 Timestamp; +extern int Renderer; + bool Init(); void DeInit(); void Reset(); @@ -98,7 +100,9 @@ void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); -int SetRenderer(int renderer); +int InitRenderer(bool hasGL); +void DeInitRenderer(); +void UpdateRendererConfig(); void ExecuteCommand(); @@ -111,7 +115,6 @@ void VCount144(); void VBlank(); void VCount215(); u32* GetLine(int line); -void SetupAccelFrame(); void WriteToGXFIFO(u32 val); @@ -144,7 +147,7 @@ bool Init(); void DeInit(); void Reset(); -void SetDisplaySettings(int scale, bool antialias); +void UpdateDisplaySettings(); void RenderFrame(); void PrepareCaptureFrame(); diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 30c77bf..cbf5abd 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -20,6 +20,7 @@ #include #include "NDS.h" #include "GPU.h" +#include "Config.h" #include "OpenGLSupport.h" #include "GPU3D_OpenGL_shaders.h" @@ -362,10 +363,14 @@ void DeInit() void Reset() { + UpdateDisplaySettings(); } -void SetDisplaySettings(int scale, bool antialias) +void UpdateDisplaySettings() { + int scale = Config::GL_ScaleFactor; + bool antialias = false; //Config::GL_Antialias; + if (antialias) scale *= 2; ScaleFactor = scale; @@ -950,7 +955,7 @@ u32* GetLine(int line) } void SetupAccelFrame() -{ +{printf("morp %04X\n", glGetError()); glBindTexture(GL_TEXTURE_2D, FramebufferTex[FrontBuffer]); } diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index 3102873..26c0109 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -83,13 +83,14 @@ void OnRendererChanged(uiRadioButtons* rb, void* blarg) printf("RENDERER CHANGE: %d\n", id); Config::_3DRenderer = id; UpdateControls(); - ApplyNewSettings(2); + ApplyNewSettings(3); } void OnGLDisplayChanged(uiCheckbox* cb, void* blarg) { Config::ScreenUseGL = uiCheckboxChecked(cb); ApplyNewSettings(2); + uiControlSetFocus(uiControl(cb)); } void OnThreaded3DChanged(uiCheckbox* cb, void* blarg) @@ -103,21 +104,23 @@ void OnResolutionChanged(uiCombobox* cb, void* blarg) int id = uiComboboxSelected(cb); Config::GL_ScaleFactor = id+1; - ApplyNewSettings(3); + ApplyNewSettings(0); } void OnAntialiasChanged(uiCheckbox* cb, void* blarg) { Config::GL_Antialias = uiCheckboxChecked(cb); - ApplyNewSettings(3); + ApplyNewSettings(0); } void OnCancel(uiButton* btn, void* blarg) { + bool apply0 = false; + if (old_renderer != Config::_3DRenderer) { Config::_3DRenderer = old_renderer; - ApplyNewSettings(2); + ApplyNewSettings(3); } if (old_gldisplay != Config::ScreenUseGL) @@ -129,7 +132,7 @@ void OnCancel(uiButton* btn, void* blarg) if (old_threaded3D != Config::Threaded3D) { Config::Threaded3D = old_threaded3D; - ApplyNewSettings(0); + apply0 = true; } if (old_resolution != Config::GL_ScaleFactor || @@ -137,9 +140,11 @@ void OnCancel(uiButton* btn, void* blarg) { Config::GL_ScaleFactor = old_resolution; Config::GL_Antialias = old_antialias; - ApplyNewSettings(3); + apply0 = true; } + if (apply0) ApplyNewSettings(0); + uiControlDestroy(uiControl(win)); opened = false; } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 1f41bbe..efebc8d 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -104,7 +104,6 @@ char PrevSRAMPath[1024]; // for savestate 'undo load' bool SavestateLoaded; bool Screen_UseGL; -int _3DRenderer; bool ScreenDrawInited = false; uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; @@ -164,6 +163,10 @@ void LoadState(int slot); void UndoStateLoad(); void GetSavestateName(int slot, char* filename, int len); +void CreateMainWindow(bool opengl); +void DestroyMainWindow(); +void RecreateMainWindow(bool opengl); + bool GLScreen_Init() @@ -239,7 +242,7 @@ void GLScreen_DrawScreen() GL_ShaderConfig.uScreenSize[0] = WindowWidth; GL_ShaderConfig.uScreenSize[1] = WindowHeight; GL_ShaderConfig.u3DScale = GL_3DScale; -printf("updating GL scale: %d\n", GL_3DScale); + glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO); void* unibuf = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); if (unibuf) memcpy(unibuf, &GL_ShaderConfig, sizeof(GL_ShaderConfig)); @@ -381,7 +384,7 @@ printf("updating GL scale: %d\n", GL_3DScale); GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); glActiveTexture(GL_TEXTURE1); - if (_3DRenderer != 0) + if (GPU3D::Renderer != 0) GPU3D::GLRenderer::SetupAccelFrame(); glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); @@ -392,89 +395,6 @@ printf("updating GL scale: %d\n", GL_3DScale); uiGLSwapBuffers(GLContext); } -void ScreenCreateArea(bool opengl) -{ - bool opengl_good = opengl; - if (opengl_good) - { - MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions); - uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); - uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); - uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); - GLContext = uiAreaGetGLContext(MainDrawArea); - if (!GLContext) opengl_good = false; - } - - if (opengl_good) - { - uiGLMakeContextCurrent(GLContext); - if (!GLScreen_Init()) opengl_good = false; - } - - if (opengl_good) - { - //if (_3DRenderer != 0) - { - _3DRenderer = GPU3D::SetRenderer(_3DRenderer); - if (_3DRenderer != 0) - GPU3D::GLRenderer::SetDisplaySettings(Config::GL_ScaleFactor, Config::GL_Antialias); - else if (RunningSomething) - GPU3D::SoftRenderer::SetupRenderThread(); - } - uiGLMakeContextCurrent(NULL); - } - else - { - if (opengl) - { - uiWindowSetChild(MainWindow, NULL); - uiControlDestroy(uiControl(MainDrawArea)); - } - - Screen_UseGL = false; - - MainDrawArea = uiNewArea(&MainDrawAreaHandler); - uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); - uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); - uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); - ScreenDrawInited = false; - } - - uiControlShow(uiControl(MainWindow)); - uiControlSetFocus(uiControl(MainDrawArea)); -} - -void ScreenSetMethod(bool opengl) -{ - int oldstatus = EmuRunning; - EmuRunning = 3; - while (EmuStatus != 3); - - if (Screen_UseGL) - { - uiGLMakeContextCurrent(GLContext); - if (_3DRenderer != 0) GPU3D::GLRenderer::DeInit(); - else GPU3D::SoftRenderer::DeInit(); - GLScreen_DeInit(); - uiGLMakeContextCurrent(NULL); - } - else - { - if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); - if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); - } - - uiWindowSetChild(MainWindow, NULL); - uiControlDestroy(uiControl(MainDrawArea)); - - Screen_UseGL = Config::ScreenUseGL; - _3DRenderer = Config::_3DRenderer; - - ScreenCreateArea(opengl); - - EmuRunning = oldstatus; -} - void MicLoadWav(char* name) { SDL_AudioSpec format; @@ -730,12 +650,6 @@ void FeedMicInput() int EmuThreadFunc(void* burp) { - if (Screen_UseGL) - { - uiGLMakeContextCurrent(GLContext); - GLScreen_Init(); - } - NDS::Init(); MainScreenPos[0] = 0; @@ -743,8 +657,18 @@ int EmuThreadFunc(void* burp) MainScreenPos[2] = 0; AutoScreenSizing = 0; - GPU::SetDisplaySettings(_3DRenderer != 0); - if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + GPU3D::InitRenderer(true); + GPU::SetDisplaySettings(GPU3D::Renderer != 0); + uiGLMakeContextCurrent(NULL); + } + else + { + GPU3D::InitRenderer(false); + GPU::SetDisplaySettings(false); + } Touching = false; KeyInputMask = 0xFFF; @@ -895,10 +819,7 @@ int EmuThreadFunc(void* burp) if (EmuRunning == 0) break; - if (Screen_UseGL) - { - GLScreen_DrawScreen(); - } + if (Screen_UseGL) GLScreen_DrawScreen(); uiAreaQueueRedrawAll(MainDrawArea); // framerate limiter based off SDL2_gfx @@ -1731,7 +1652,7 @@ void OnCloseByMenu(uiMenuItem* item, uiWindow* window, void* blarg) EmuRunning = 3; while (EmuStatus != 3); - uiControlDestroy(uiControl(window)); + DestroyMainWindow(); uiQuit(); } @@ -1851,22 +1772,10 @@ void OnOpenHotkeyConfig(uiMenuItem* item, uiWindow* window, void* blarg) { DlgInputConfig::Open(1); } -void zarg(); + void OnOpenVideoSettings(uiMenuItem* item, uiWindow* window, void* blarg) { - //DlgVideoSettings::Open(); - int zerp = EmuRunning; - EmuRunning = 3; - while (EmuStatus != 3); - - int winX, winY; - uiWindowPosition(MainWindow, &winX, &winY); - uiControlDestroy(uiControl(window)); - - zarg(); - uiWindowSetPosition(MainWindow, winX, winY); - - EmuRunning = zerp; + DlgVideoSettings::Open(); } void OnOpenAudioSettings(uiMenuItem* item, uiWindow* window, void* blarg) @@ -2037,23 +1946,18 @@ void OnSetLimitFPS(uiMenuItem* item, uiWindow* window, void* blarg) void ApplyNewSettings(int type) { - if (type == 2) - { - bool usegl = Config::ScreenUseGL || (Config::_3DRenderer != 0); - ScreenSetMethod(usegl); - return; - } - - if (!RunningSomething) return; + if (!RunningSomething && type != 2) return; int prevstatus = EmuRunning; EmuRunning = 3; while (EmuStatus != 3); - if (type == 0) // software renderer thread + if (type == 0) // 3D renderer settings { - if (_3DRenderer == 0) - GPU3D::SoftRenderer::SetupRenderThread(); + GPU3D::UpdateRendererConfig(); + + GL_3DScale = Config::GL_ScaleFactor; // dorp + GL_ScreenSizeDirty = true; } else if (type == 1) // wifi settings { @@ -2066,20 +1970,37 @@ void ApplyNewSettings(int type) Platform::LAN_DeInit(); Platform::LAN_Init(); } - else if (type == 3) // GL renderer settings + else if (type == 2) // video output method { - GL_3DScale = Config::GL_ScaleFactor; - - if (_3DRenderer != 0) + bool usegl = Config::ScreenUseGL || (Config::_3DRenderer != 0); + if (usegl != Screen_UseGL) { - uiGLMakeContextCurrent(GLContext); - printf("%04X\n", glGetError()); - printf("%04X\n", glGetError()); - GPU3D::GLRenderer::SetDisplaySettings(Config::GL_ScaleFactor, Config::GL_Antialias); - uiGLMakeContextCurrent(NULL); - GL_ScreenSizeDirty = true; + Screen_UseGL = usegl; + + if (RunningSomething) + { + if (usegl) uiGLMakeContextCurrent(GLContext); + GPU3D::DeInitRenderer(); + if (usegl) uiGLMakeContextCurrent(NULL); + } + + RecreateMainWindow(usegl); + + if (RunningSomething) + { + if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); + GPU3D::InitRenderer(Screen_UseGL); + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + } } } + else if (type == 3) // 3D renderer + { + if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); + GPU3D::DeInitRenderer(); + GPU3D::InitRenderer(Screen_UseGL); + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + } EmuRunning = prevstatus; } @@ -2251,24 +2172,11 @@ void CreateMainWindowMenu() uiMenuItemOnClicked(MenuItem_LimitFPS, OnSetLimitFPS, NULL); } -void zarg() +void CreateMainWindow(bool opengl) { - int w = Config::WindowWidth; - int h = Config::WindowHeight; - //if (w < 256) w = 256; - //if (h < 384) h = 384; - - WindowWidth = w; - WindowHeight = h; - - Screen_UseGL = Config::ScreenUseGL || (Config::_3DRenderer != 0); - _3DRenderer = Config::_3DRenderer; - - GL_3DScale = Config::GL_ScaleFactor; - if (GL_3DScale < 1) GL_3DScale = 1; - else if (GL_3DScale > 8) GL_3DScale = 8; - - MainWindow = uiNewWindow("melonDS " MELONDS_VERSION, w, h, Config::WindowMaximized, 1, 1); + MainWindow = uiNewWindow("melonDS " MELONDS_VERSION, + WindowWidth, WindowHeight, + Config::WindowMaximized, 1, 1); uiWindowOnClosing(MainWindow, OnCloseWindow, NULL); uiWindowSetDropTarget(MainWindow, 1); @@ -2277,40 +2185,57 @@ void zarg() uiWindowOnGetFocus(MainWindow, OnGetFocus, NULL); uiWindowOnLoseFocus(MainWindow, OnLoseFocus, NULL); - MainDrawAreaHandler.Draw = OnAreaDraw; - MainDrawAreaHandler.MouseEvent = OnAreaMouseEvent; - MainDrawAreaHandler.MouseCrossed = OnAreaMouseCrossed; - MainDrawAreaHandler.DragBroken = OnAreaDragBroken; - MainDrawAreaHandler.KeyEvent = OnAreaKeyEvent; - MainDrawAreaHandler.Resize = OnAreaResize; - ScreenDrawInited = false; - ScreenCreateArea(Screen_UseGL); + bool opengl_good = opengl; - ScreenRotation = Config::ScreenRotation; - ScreenGap = Config::ScreenGap; - ScreenLayout = Config::ScreenLayout; - ScreenSizing = Config::ScreenSizing; + if (!opengl) MainDrawArea = uiNewArea(&MainDrawAreaHandler); + else MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions); -#define SANITIZE(var, min, max) if ((var < min) || (var > max)) var = 0; - SANITIZE(ScreenRotation, 0, 3); - SANITIZE(ScreenLayout, 0, 2); - SANITIZE(ScreenSizing, 0, 3); -#undef SANITIZE + uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); + uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); + uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); - /*uiMenuItemSetChecked(MenuItem_SavestateSRAMReloc, Config::SavestateRelocSRAM?1:0); + uiControlShow(uiControl(MainWindow)); + uiControlSetFocus(uiControl(MainDrawArea)); - uiMenuItemSetChecked(MenuItem_ScreenRot[ScreenRotation], 1); - uiMenuItemSetChecked(MenuItem_ScreenLayout[ScreenLayout], 1); - uiMenuItemSetChecked(MenuItem_ScreenSizing[ScreenSizing], 1); + if (opengl_good) + { + GLContext = uiAreaGetGLContext(MainDrawArea); + if (!GLContext) opengl_good = false; + } + if (opengl_good) + { + uiGLMakeContextCurrent(GLContext); + if (!GLScreen_Init()) opengl_good = false; + uiGLMakeContextCurrent(NULL); + } - for (int i = 0; i < 6; i++) + if (opengl && !opengl_good) { - if (ScreenGap == kScreenGap[i]) - uiMenuItemSetChecked(MenuItem_ScreenGap[i], 1); - }*/ + printf("OpenGL: initialization failed\n"); + RecreateMainWindow(false); + Screen_UseGL = false; + } +} - OnSetScreenRotation(MenuItem_ScreenRot[ScreenRotation], MainWindow, (void*)&kScreenRot[ScreenRotation]); +void DestroyMainWindow() +{ + uiControlDestroy(uiControl(MainWindow)); + + if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); + if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); + + ScreenBitmap[0] = NULL; + ScreenBitmap[1] = NULL; +} + +void RecreateMainWindow(bool opengl) +{ + int winX, winY; + uiWindowPosition(MainWindow, &winX, &winY); + DestroyMainWindow(); + CreateMainWindow(opengl); + uiWindowSetPosition(MainWindow, winX, winY); } @@ -2417,49 +2342,23 @@ int main(int argc, char** argv) CreateMainWindowMenu(); - int w = Config::WindowWidth; - int h = Config::WindowHeight; - //if (w < 256) w = 256; - //if (h < 384) h = 384; + MainDrawAreaHandler.Draw = OnAreaDraw; + MainDrawAreaHandler.MouseEvent = OnAreaMouseEvent; + MainDrawAreaHandler.MouseCrossed = OnAreaMouseCrossed; + MainDrawAreaHandler.DragBroken = OnAreaDragBroken; + MainDrawAreaHandler.KeyEvent = OnAreaKeyEvent; + MainDrawAreaHandler.Resize = OnAreaResize; - WindowWidth = w; - WindowHeight = h; + WindowWidth = Config::WindowWidth; + WindowHeight = Config::WindowHeight; Screen_UseGL = Config::ScreenUseGL || (Config::_3DRenderer != 0); - _3DRenderer = Config::_3DRenderer; GL_3DScale = Config::GL_ScaleFactor; if (GL_3DScale < 1) GL_3DScale = 1; else if (GL_3DScale > 8) GL_3DScale = 8; - MainWindow = uiNewWindow("melonDS " MELONDS_VERSION, w, h, Config::WindowMaximized, 1, 1); - uiWindowOnClosing(MainWindow, OnCloseWindow, NULL); - - uiWindowSetDropTarget(MainWindow, 1); - uiWindowOnDropFile(MainWindow, OnDropFile, NULL); - - uiWindowOnGetFocus(MainWindow, OnGetFocus, NULL); - uiWindowOnLoseFocus(MainWindow, OnLoseFocus, NULL); - - //uiMenuItemDisable(MenuItem_SaveState); - //uiMenuItemDisable(MenuItem_LoadState); - for (int i = 0; i < 9; i++) uiMenuItemDisable(MenuItem_SaveStateSlot[i]); - for (int i = 0; i < 9; i++) uiMenuItemDisable(MenuItem_LoadStateSlot[i]); - uiMenuItemDisable(MenuItem_UndoStateLoad); - - uiMenuItemDisable(MenuItem_Pause); - uiMenuItemDisable(MenuItem_Reset); - uiMenuItemDisable(MenuItem_Stop); - - MainDrawAreaHandler.Draw = OnAreaDraw; - MainDrawAreaHandler.MouseEvent = OnAreaMouseEvent; - MainDrawAreaHandler.MouseCrossed = OnAreaMouseCrossed; - MainDrawAreaHandler.DragBroken = OnAreaDragBroken; - MainDrawAreaHandler.KeyEvent = OnAreaKeyEvent; - MainDrawAreaHandler.Resize = OnAreaResize; - - ScreenDrawInited = false; - ScreenCreateArea(Screen_UseGL); + CreateMainWindow(Screen_UseGL); ScreenRotation = Config::ScreenRotation; ScreenGap = Config::ScreenGap; @@ -2472,6 +2371,14 @@ int main(int argc, char** argv) SANITIZE(ScreenSizing, 0, 3); #undef SANITIZE + for (int i = 0; i < 9; i++) uiMenuItemDisable(MenuItem_SaveStateSlot[i]); + for (int i = 0; i < 9; i++) uiMenuItemDisable(MenuItem_LoadStateSlot[i]); + uiMenuItemDisable(MenuItem_UndoStateLoad); + + uiMenuItemDisable(MenuItem_Pause); + uiMenuItemDisable(MenuItem_Reset); + uiMenuItemDisable(MenuItem_Stop); + uiMenuItemSetChecked(MenuItem_SavestateSRAMReloc, Config::SavestateRelocSRAM?1:0); uiMenuItemSetChecked(MenuItem_ScreenRot[ScreenRotation], 1); @@ -2575,9 +2482,6 @@ int main(int argc, char** argv) Config::Save(); - if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); - if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); - uiUninit(); SDL_Quit(); delete[] EmuDirectory; -- cgit v1.2.3 From 9e2f47f4a0862e05f05cebbc5fae4e322c5b5d9f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 24 May 2019 02:35:25 +0200 Subject: fix more bugs --- src/GPU3D.cpp | 1 + src/GPU3D_OpenGL.cpp | 2 +- src/libui_sdl/main.cpp | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 770c874..98aa6eb 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -624,6 +624,7 @@ int InitRenderer(bool hasGL) if (renderer == 0) SoftRenderer::Init(); Renderer = renderer; + UpdateRendererConfig(); GPU::SetDisplaySettings(Renderer != 0); return renderer; } diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index cbf5abd..ceefbaf 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -955,7 +955,7 @@ u32* GetLine(int line) } void SetupAccelFrame() -{printf("morp %04X\n", glGetError()); +{ glBindTexture(GL_TEXTURE_2D, FramebufferTex[FrontBuffer]); } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index e17827d..c302b7e 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -375,7 +375,7 @@ void GLScreen_DrawScreen() glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); - if (GPU::Framebuffer[frontbuf][1]) + if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) { if (GPU3D::Renderer == 0) { @@ -922,7 +922,7 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) int frontbuf = GPU::FrontBuffer; if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; - if (!GPU::Framebuffer[frontbuf][1]) return; + if (!GPU::Framebuffer[frontbuf][0] || !GPU::Framebuffer[frontbuf][1]) return; uiRect top = {0, 0, 256, 192}; uiRect bot = {0, 0, 256, 192}; -- cgit v1.2.3 From 182e123598ca7ad641df47c0854928dd99f52345 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 01:55:44 +0200 Subject: fix shadow bugs bahaahah --- src/GPU3D_OpenGL.cpp | 302 +++++++++++++++++++++++++++------------------------ src/OpenGLSupport.h | 4 +- 2 files changed, 162 insertions(+), 144 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index ceefbaf..74e736a 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -45,6 +45,7 @@ enum GLuint ClearShaderPlain[3]; GLuint RenderShader[16][3]; +GLuint CurShaderID = -1; struct { @@ -61,6 +62,7 @@ typedef struct { Polygon* PolyData; + u32 NumIndices; u16* Indices; u32 RenderKey; @@ -158,7 +160,9 @@ bool BuildRenderShader(u32 flags, const char* vs, const char* fs) void UseRenderShader(u32 flags) { + if (CurShaderID == flags) return; glUseProgram(RenderShader[flags][2]); + CurShaderID = flags; } void SetupDefaultTexParams(GLuint tex) @@ -311,10 +315,7 @@ bool Init() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); glEnable(GL_BLEND); - // TODO: these are said to require GL 4.0; use the regular ones instead? - glBlendFuncSeparatei(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - glBlendEquationSeparatei(0, GL_FUNC_ADD, GL_MAX); - glBlendFuncSeparatei(1, GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); + glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX); glGenBuffers(1, &PixelbufferID); @@ -335,7 +336,7 @@ bool Init() 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_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL); -printf("init done. %04X\n", glGetError()); + return true; } @@ -486,6 +487,8 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) if (poly->FacingView) vtxattr |= (1<<8); if (poly->WBuffer) vtxattr |= (1<<9); + rp->NumIndices = 0; + // assemble vertices for (int j = 0; j < poly->NumVertices; j++) { @@ -531,6 +534,7 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) *iptr++ = vidx - 1; *iptr++ = vidx; numtriangles++; + rp->NumIndices += 3; } vidx++; @@ -541,14 +545,38 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) NumVertices = vidx; } +void RenderSinglePolygon(int i) +{ + RendererPolygon* rp = &PolygonList[i]; + + glDrawElements(GL_TRIANGLES, rp->NumIndices, GL_UNSIGNED_SHORT, rp->Indices); +} + +int RenderPolygonBatch(int i) +{ + RendererPolygon* rp = &PolygonList[i]; + u32 key = rp->RenderKey; + int numpolys = 0; + u32 numindices = 0; + + for (int iend = i; iend < NumFinalPolys; iend++) + { + RendererPolygon* cur_rp = &PolygonList[iend]; + if (cur_rp->RenderKey != key) break; + + numpolys++; + numindices += cur_rp->NumIndices; + } + + glDrawElements(GL_TRIANGLES, numindices, GL_UNSIGNED_SHORT, rp->Indices); + return numpolys; +} + void RenderSceneChunk(int y, int h) { u32 flags = 0; if (RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer; - u16* iptr; - u32 curkey; - if (h != 192) glScissor(0, y<RenderKey != curkey) - { - u16* endptr = rp->Indices; - u32 num = (u32)(endptr - iptr); - if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); - - iptr = rp->Indices; - curkey = rp->RenderKey; - // zorp - glDepthFunc(GL_LESS); + // zorp + glDepthFunc(GL_LESS); - u32 polyattr = rp->PolyData->Attr; - u32 polyid = (polyattr >> 24) & 0x3F; + u32 polyattr = rp->PolyData->Attr; + u32 polyid = (polyattr >> 24) & 0x3F; - glStencilFunc(GL_ALWAYS, polyid, 0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glStencilMask(0xFF); - } - } + glStencilFunc(GL_ALWAYS, polyid, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0xFF); - { - u16* endptr = &IndexBuffer[NumTriangles*3]; - u32 num = (u32)(endptr - iptr); - if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + i += RenderPolygonBatch(i); } glEnable(GL_BLEND); @@ -602,54 +614,81 @@ void RenderSceneChunk(int y, int h) { glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - if (PolygonList[NumOpaqueFinalPolys].PolyData->IsShadow) printf("!! GLORG!!! %08X\n", PolygonList[NumOpaqueFinalPolys].PolyData->Attr); - - // pass 2: if needed, render translucent pixels that are against background pixels + // pass 2: if needed, render translucent pixels that are against background pixels // when background alpha is zero, those need to be rendered with blending disabled if ((RenderClearAttr1 & 0x001F0000) == 0) { - iptr = PolygonList[NumOpaqueFinalPolys].Indices; - curkey = 0xFFFFFFFF; - glDisable(GL_BLEND); - for (int i = NumOpaqueFinalPolys; i < NumFinalPolys; i++) + for (int i = 0; i < NumFinalPolys; ) { RendererPolygon* rp = &PolygonList[i]; - if (rp->RenderKey != curkey) + + if (rp->PolyData->IsShadowMask) { - u16* endptr = rp->Indices; - u32 num = (u32)(endptr - iptr); - if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + // clear shadow bits in stencil buffer - iptr = rp->Indices; - curkey = rp->RenderKey; + glStencilMask(0x80); + glClear(GL_STENCIL_BUFFER_BIT); + + // draw actual shadow mask - // configure new one + UseRenderShader(flags | RenderFlag_ShadowMask); + + glDisable(GL_BLEND); + glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glDepthMask(GL_FALSE); - // shadows aren't likely to pass against the clear-plane, so - if (rp->PolyData->IsShadow) continue; + glDepthFunc(GL_LESS); + glStencilFunc(GL_EQUAL, 0xFF, 0xFE); + glStencilOp(GL_KEEP, GL_INVERT, GL_KEEP); + glStencilMask(0x01); + i += RenderPolygonBatch(i); + } + else if (rp->PolyData->Translucent) + { // zorp glDepthFunc(GL_LESS); u32 polyattr = rp->PolyData->Attr; u32 polyid = (polyattr >> 24) & 0x3F; - glStencilFunc(GL_EQUAL, 0xFF, 0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); - glStencilMask(~(0x40|polyid)); // heheh + if (rp->PolyData->IsShadow) + { + // shadow against clear-plane will only pass if its polyID matches that of the clear plane + u32 clrpolyid = (RenderClearAttr1 >> 24) & 0x3F; + if (polyid != clrpolyid) { i++; continue; } - if (polyattr & (1<<11)) glDepthMask(GL_TRUE); - else glDepthMask(GL_FALSE); - } - } + glEnable(GL_BLEND); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); - { - u16* endptr = &IndexBuffer[NumTriangles*3]; - u32 num = (u32)(endptr - iptr); - if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + glStencilFunc(GL_EQUAL, 0xFE, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); + glStencilMask(~(0x40|polyid)); // heheh + + if (polyattr & (1<<11)) glDepthMask(GL_TRUE); + else glDepthMask(GL_FALSE); + + i += RenderPolygonBatch(i); + } + else + { + glStencilFunc(GL_EQUAL, 0xFF, 0xFE); + glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); + glStencilMask(~(0x40|polyid)); // heheh + + if (polyattr & (1<<11)) glDepthMask(GL_TRUE); + else glDepthMask(GL_FALSE); + + i += RenderPolygonBatch(i); + } + } + else + i++; } glEnable(GL_BLEND); @@ -658,112 +697,86 @@ void RenderSceneChunk(int y, int h) // pass 3: translucent pixels - iptr = PolygonList[NumOpaqueFinalPolys].Indices; - curkey = 0xFFFFFFFF; - - for (int i = NumOpaqueFinalPolys; i < NumFinalPolys; i++) + for (int i = 0; i < NumFinalPolys; ) { RendererPolygon* rp = &PolygonList[i]; - if (rp->RenderKey != curkey) + + if (rp->PolyData->IsShadowMask) { - u16* endptr = rp->Indices; - u32 num = (u32)(endptr - iptr); - if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + // clear shadow bits in stencil buffer - iptr = rp->Indices; - curkey = rp->RenderKey; + glStencilMask(0x80); + glClear(GL_STENCIL_BUFFER_BIT); - // configure new one + // draw actual shadow mask - if (rp->PolyData->IsShadowMask) - { - // clear shadow bits in stencil buffer + UseRenderShader(flags | RenderFlag_ShadowMask); - glStencilMask(0x80); - glClear(GL_STENCIL_BUFFER_BIT); + glDisable(GL_BLEND); + glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glDepthMask(GL_FALSE); - // draw actual shadow mask + glDepthFunc(GL_LESS); + glStencilFunc(GL_ALWAYS, 0x80, 0x80); + glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); - UseRenderShader(flags | RenderFlag_ShadowMask); + i += RenderPolygonBatch(i); + } + else if (rp->PolyData->Translucent) + { + UseRenderShader(flags | RenderFlag_Trans); + + u32 polyattr = rp->PolyData->Attr; + u32 polyid = (polyattr >> 24) & 0x3F; + + // zorp + glDepthFunc(GL_LESS); + if (rp->PolyData->IsShadow) + { glDisable(GL_BLEND); glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthMask(GL_FALSE); + glStencilFunc(GL_EQUAL, polyid, 0x3F); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glStencilMask(0x80); - glDepthFunc(GL_LESS); - glStencilFunc(GL_ALWAYS, 0x80, 0x80); - glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); - - glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); - glBindVertexArray(VertexArrayID); - } - else - { - UseRenderShader(flags | RenderFlag_Trans); - - u32 polyattr = rp->PolyData->Attr; - u32 polyid = (polyattr >> 24) & 0x3F; + RenderSinglePolygon(i); - // zorp - glDepthFunc(GL_LESS); + glEnable(GL_BLEND); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); - if (rp->PolyData->IsShadow) - { - glDisable(GL_BLEND); - glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glDepthMask(GL_FALSE); - glStencilFunc(GL_EQUAL, polyid, 0x3F); - glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); - glStencilMask(0x80); - - { - u16* _endptr = &IndexBuffer[NumTriangles*3]; - for (int j = i; j < NumFinalPolys; j++) - { - RendererPolygon* rp = &PolygonList[j]; - if (!rp->PolyData->IsShadow) - { - _endptr = rp->Indices; - break; - } - - // berg. - } - u32 num = (u32)(_endptr - iptr); - if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); - } + glStencilFunc(GL_EQUAL, 0xC0|polyid, 0x80); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0x7F); - glEnable(GL_BLEND); - glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + if (polyattr & (1<<11)) glDepthMask(GL_TRUE); + else glDepthMask(GL_FALSE); - glStencilFunc(GL_EQUAL, 0xC0|polyid, 0x80); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glStencilMask(0x7F); - } - else - { - glEnable(GL_BLEND); - glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + RenderSinglePolygon(i); + i++; + } + else + { + glEnable(GL_BLEND); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); - glStencilFunc(GL_NOTEQUAL, 0x40|polyid, 0x7F); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glStencilMask(0x7F); - } + glStencilFunc(GL_NOTEQUAL, 0x40|polyid, 0x7F); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0x7F); if (polyattr & (1<<11)) glDepthMask(GL_TRUE); else glDepthMask(GL_FALSE); + + i += RenderPolygonBatch(i); } } - } - - { - u16* endptr = &IndexBuffer[NumTriangles*3]; - u32 num = (u32)(endptr - iptr); - if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + else + i++; } } @@ -835,9 +848,14 @@ void RenderFrame() if (Antialias) glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); else glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); + if (RenderDispCnt & (1<<3)) + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + else + glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ONE); + glDisable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glColorMaski(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + glColorMaski(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_TRUE); glStencilMask(0xFF); diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 659d682..c922f7c 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -100,8 +100,8 @@ \ func(GLDRAWBUFFERS, glDrawBuffers); \ \ - func(GLBLENDFUNCSEPARATEI, glBlendFuncSeparatei); \ - func(GLBLENDEQUATIONSEPARATEI, glBlendEquationSeparatei); \ + func(GLBLENDFUNCSEPARATE, glBlendFuncSeparate); \ + func(GLBLENDEQUATIONSEPARATE, glBlendEquationSeparate); \ \ func(GLCOLORMASKI, glColorMaski); \ \ -- cgit v1.2.3 From 04f1809dd17b5f7c034bcf394dbe040844c10712 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 02:34:14 +0200 Subject: finish fixing shadows --- src/GPU3D_OpenGL.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 74e736a..264d3b9 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -594,6 +594,8 @@ void RenderSceneChunk(int y, int h) { RendererPolygon* rp = &PolygonList[i]; + if (rp->PolyData->IsShadowMask) { i++; continue; } + // zorp glDepthFunc(GL_LESS); @@ -627,11 +629,6 @@ void RenderSceneChunk(int y, int h) if (rp->PolyData->IsShadowMask) { - // clear shadow bits in stencil buffer - - glStencilMask(0x80); - glClear(GL_STENCIL_BUFFER_BIT); - // draw actual shadow mask UseRenderShader(flags | RenderFlag_ShadowMask); @@ -642,7 +639,7 @@ void RenderSceneChunk(int y, int h) glDepthMask(GL_FALSE); glDepthFunc(GL_LESS); - glStencilFunc(GL_EQUAL, 0xFF, 0xFE); + glStencilFunc(GL_EQUAL, 0xFF, 0xFF); glStencilOp(GL_KEEP, GL_INVERT, GL_KEEP); glStencilMask(0x01); -- cgit v1.2.3 From 7cdeb7fa4e365dd3ef4e505985c9fc9a4c4045ab Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 04:28:00 +0200 Subject: feeble, miserable little attempt at emulating fog --- src/GPU3D_OpenGL.cpp | 110 +++++++++++++++++++++++++++++++++++++++++---- src/GPU3D_OpenGL_shaders.h | 109 ++++++++++++++++++++++++++++++++++++++++---- src/OpenGLSupport.cpp | 4 ++ 3 files changed, 206 insertions(+), 17 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 264d3b9..f8ed773 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -47,12 +47,19 @@ GLuint ClearShaderPlain[3]; GLuint RenderShader[16][3]; GLuint CurShaderID = -1; +GLuint FinalPassShader[3]; + struct { float uScreenSize[2]; u32 uDispCnt; u32 __pad0; float uToonColors[32][4]; + float uEdgeColors[8][4]; + float uFogColor[4]; + float uFogDensity[34][4]; + u32 uFogOffset; + u32 uFogShift; } ShaderConfig; @@ -176,6 +183,8 @@ void SetupDefaultTexParams(GLuint tex) bool Init() { + GLint uni_id; + const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string const GLubyte* version = glGetString(GL_VERSION); // version as a string printf("OpenGL: renderer: %s\n", renderer); @@ -216,6 +225,23 @@ bool Init() kRenderVS_W, kRenderFS_WSM)) return false; + if (!OpenGL_BuildShaderProgram(kFinalPassVS, kFinalPassFS, FinalPassShader, "FinalPassShader")) + return false; + + uni_id = glGetUniformBlockIndex(FinalPassShader[2], "uConfig"); + glUniformBlockBinding(FinalPassShader[2], uni_id, 0); + + glBindAttribLocation(FinalPassShader[2], 0, "vPosition"); + glBindFragDataLocation(FinalPassShader[2], 0, "oColor"); + + glUseProgram(FinalPassShader[2]); + + uni_id = glGetUniformLocation(FinalPassShader[2], "DepthBuffer"); + glUniform1i(uni_id, 0); + uni_id = glGetUniformLocation(FinalPassShader[2], "AttrBuffer"); + glUniform1i(uni_id, 1); + + memset(&ShaderConfig, 0, sizeof(ShaderConfig)); glGenBuffers(1, &ShaderConfigUBO); @@ -277,8 +303,8 @@ bool Init() // attribute buffer // R: opaque polyID (for edgemarking) - // G: opaque polyID (for shadows, suppressed when rendering translucent polygons) - // B: stencil flag + // G: edge flag + // B: fog flag SetupDefaultTexParams(FramebufferTex[5]); SetupDefaultTexParams(FramebufferTex[7]); @@ -447,6 +473,7 @@ void SetupPolygon(RendererPolygon* rp, Polygon* polygon) if (polygon->IsShadow) rp->RenderKey |= 0x20000; else rp->RenderKey |= 0x10000; rp->RenderKey |= (polygon->Attr >> 10) & 0x2; // bit11 - depth write + rp->RenderKey |= (polygon->Attr >> 13) & 0x4; // bit15 - fog rp->RenderKey |= (polygon->Attr & 0x3F000000) >> 16; // polygon ID } else @@ -579,11 +606,13 @@ void RenderSceneChunk(int y, int h) if (h != 192) glScissor(0, y< -1) { - glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - // pass 2: if needed, render translucent pixels that are against background pixels // when background alpha is zero, those need to be rendered with blending disabled @@ -653,6 +680,10 @@ void RenderSceneChunk(int y, int h) u32 polyattr = rp->PolyData->Attr; u32 polyid = (polyattr >> 24) & 0x3F; + GLboolean transfog; + if (!(polyattr & (1<<15))) transfog = fogenable; + else transfog = GL_FALSE; + if (rp->PolyData->IsShadow) { // shadow against clear-plane will only pass if its polyID matches that of the clear plane @@ -661,7 +692,7 @@ void RenderSceneChunk(int y, int h) glEnable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_FALSE, transfog, GL_FALSE); glStencilFunc(GL_EQUAL, 0xFE, 0xFF); glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); @@ -674,6 +705,9 @@ void RenderSceneChunk(int y, int h) } else { + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_FALSE, GL_FALSE, transfog, GL_FALSE); + glStencilFunc(GL_EQUAL, 0xFF, 0xFE); glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); glStencilMask(~(0x40|polyid)); // heheh @@ -727,6 +761,10 @@ void RenderSceneChunk(int y, int h) u32 polyattr = rp->PolyData->Attr; u32 polyid = (polyattr >> 24) & 0x3F; + GLboolean transfog; + if (!(polyattr & (1<<15))) transfog = fogenable; + else transfog = GL_FALSE; + // zorp glDepthFunc(GL_LESS); @@ -744,7 +782,7 @@ void RenderSceneChunk(int y, int h) glEnable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_FALSE, transfog, GL_FALSE); glStencilFunc(GL_EQUAL, 0xC0|polyid, 0x80); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); @@ -760,7 +798,7 @@ void RenderSceneChunk(int y, int h) { glEnable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_FALSE, transfog, GL_FALSE); glStencilFunc(GL_NOTEQUAL, 0x40|polyid, 0x7F); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); @@ -778,11 +816,33 @@ void RenderSceneChunk(int y, int h) } glFlush(); + + if (RenderDispCnt & 0x00A0) // fog/edge enabled + { + glUseProgram(FinalPassShader[2]); + + glDepthFunc(GL_ALWAYS); + glDepthMask(GL_FALSE); + glStencilFunc(GL_ALWAYS, 0, 0); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilMask(0); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); + + glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID); + glBindVertexArray(ClearVertexArrayID); + glDrawArrays(GL_TRIANGLES, 0, 2*3); + } } void RenderFrame() { + CurShaderID = -1; + ShaderConfig.uScreenSize[0] = ScreenW; ShaderConfig.uScreenSize[1] = ScreenH; ShaderConfig.uDispCnt = RenderDispCnt; @@ -799,6 +859,40 @@ void RenderFrame() ShaderConfig.uToonColors[i][2] = (float)b / 31.0; } + for (int i = 0; i < 8; i++) + { + u16 c = RenderEdgeTable[i]; + u32 r = c & 0x1F; + u32 g = (c >> 5) & 0x1F; + u32 b = (c >> 10) & 0x1F; + + ShaderConfig.uEdgeColors[i][0] = (float)r / 31.0; + ShaderConfig.uEdgeColors[i][1] = (float)g / 31.0; + ShaderConfig.uEdgeColors[i][2] = (float)b / 31.0; + } + + { + u32 c = RenderFogColor; + u32 r = c & 0x1F; + u32 g = (c >> 5) & 0x1F; + u32 b = (c >> 10) & 0x1F; + u32 a = (c >> 16) & 0x1F; + + ShaderConfig.uFogColor[0] = (float)r / 31.0; + ShaderConfig.uFogColor[1] = (float)g / 31.0; + ShaderConfig.uFogColor[2] = (float)b / 31.0; + ShaderConfig.uFogColor[3] = (float)a / 31.0; + } + + for (int i = 0; i < 34; i++) + { + u8 d = RenderFogDensityTable[i]; + ShaderConfig.uFogDensity[i][0] = (float)d / 127.0; + } + + ShaderConfig.uFogOffset = RenderFogOffset; + ShaderConfig.uFogShift = RenderFogShift; + glBindBuffer(GL_UNIFORM_BUFFER, ShaderConfigUBO); void* unibuf = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); if (unibuf) memcpy(unibuf, &ShaderConfig, sizeof(ShaderConfig)); diff --git a/src/GPU3D_OpenGL_shaders.h b/src/GPU3D_OpenGL_shaders.h index e436544..0e4c4fe 100644 --- a/src/GPU3D_OpenGL_shaders.h +++ b/src/GPU3D_OpenGL_shaders.h @@ -47,13 +47,94 @@ out uvec3 oAttr; void main() { oColor = vec4(uColor).bgra / 31.0; - oAttr.r = uint(0); - oAttr.g = uOpaquePolyID; - oAttr.b = uint(0); + oAttr.r = uOpaquePolyID; + oAttr.g = uint(0); + oAttr.b = uFogFlag; +} +)"; + + + +const char* kFinalPassVS = kShaderHeader R"( + +in vec2 vPosition; + +void main() +{ + // heh + gl_Position = vec4(vPosition, 0.0, 1.0); +} +)"; + +const char* kFinalPassFS = kShaderHeader R"( + +uniform sampler2D DepthBuffer; +uniform usampler2D AttrBuffer; + +layout(std140) uniform uConfig +{ + vec2 uScreenSize; + int uDispCnt; + vec4 uToonColors[32]; + vec4 uEdgeColors[8]; + vec4 uFogColor; + float uFogDensity[34]; + int uFogOffset; + int uFogShift; +}; + +out vec4 oColor; + +vec4 CalculateFog(float depth) +{ + int idepth = int(depth * 16777216.0); + int densityid, densityfrac; + + if (idepth < uFogOffset) + { + densityid = 0; + densityfrac = 0; + } + else + { + uint udepth = uint(idepth); + udepth -= uint(uFogOffset); + udepth = (udepth >> 2) << uint(uFogShift); + + densityid = int(udepth >> 17); + if (densityid >= 32) + { + densityid = 32; + densityfrac = 0; + } + else + densityfrac = int(udepth & uint(0x1FFFF)); + } + + float density = + ((uFogDensity[densityid] * float(0x20000-densityfrac)) + + (uFogDensity[densityid+1] * float(densityfrac))) / float(0x20000); + + return vec4(uFogColor.bgr,density); + return uFogColor * density; +} + +void main() +{ + ivec2 coord = ivec2(gl_FragCoord.xy); + + vec4 ret = vec4(0,0,0,0); + vec4 depth = texelFetch(DepthBuffer, coord, 0); + ivec4 attr = ivec4(texelFetch(AttrBuffer, coord, 0)); + + if (attr.b != 0) ret = CalculateFog(depth.r); + + oColor = ret; } )"; + const char* kRenderVSCommon = R"( layout(std140) uniform uConfig @@ -61,6 +142,11 @@ layout(std140) uniform uConfig vec2 uScreenSize; int uDispCnt; vec4 uToonColors[32]; + vec4 uEdgeColors[8]; + vec4 uFogColor; + float uFogDensity[34]; + int uFogOffset; + int uFogShift; }; in uvec4 vPosition; @@ -83,6 +169,11 @@ layout(std140) uniform uConfig vec2 uScreenSize; int uDispCnt; vec4 uToonColors[32]; + vec4 uEdgeColors[8]; + vec4 uFogColor; + float uFogDensity[34]; + int uFogOffset; + int uFogShift; }; smooth in vec4 fColor; @@ -530,7 +621,8 @@ void main() if (col.a < 30.5/31) discard; oColor = col; - oAttr.g = uint((fPolygonAttr.x >> 24) & 0x3F); + oAttr.r = uint((fPolygonAttr.x >> 24) & 0x3F); + oAttr.b = uint((fPolygonAttr.x >> 15) & 0x1); } )"; @@ -544,7 +636,8 @@ void main() if (col.a < 30.5/31) discard; oColor = col; - oAttr.g = uint((fPolygonAttr.x >> 24) & 0x3F); + oAttr.r = uint((fPolygonAttr.x >> 24) & 0x3F); + oAttr.b = uint((fPolygonAttr.x >> 15) & 0x1); gl_FragDepth = fZ; } )"; @@ -558,7 +651,7 @@ void main() if (col.a >= 30.5/31) discard; oColor = col; - oAttr.g = uint(0xFF); + oAttr.b = uint(0); } )"; @@ -573,7 +666,7 @@ void main() if (col.a >= 30.5/31) discard; oColor = col; - oAttr.g = uint(0xFF); + oAttr.b = uint(0); gl_FragDepth = fZ; } )"; @@ -583,7 +676,6 @@ const char* kRenderFS_ZSM = R"( void main() { oColor = vec4(0,0,0,1); - oAttr.g = uint(0xFF); } )"; @@ -594,7 +686,6 @@ smooth in float fZ; void main() { oColor = vec4(0,0,0,1); - oAttr.g = uint(0xFF); gl_FragDepth = fZ; } )"; diff --git a/src/OpenGLSupport.cpp b/src/OpenGLSupport.cpp index 81a008b..0204835 100644 --- a/src/OpenGLSupport.cpp +++ b/src/OpenGLSupport.cpp @@ -71,6 +71,10 @@ bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, cons //printf("shader source:\n--\n%s\n--\n", fs); delete[] log; + FILE* logf = fopen("shaderfail.log", "w"); + fwrite(fs, len+1, 1, logf); + fclose(logf); + glDeleteShader(ids[0]); glDeleteShader(ids[1]); -- cgit v1.2.3 From 478ca019da6cbd6fb93908cbc79f821953402bc2 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 13:43:06 +0200 Subject: implement fog correctly also some base work for edgemarking --- src/GPU3D_OpenGL.cpp | 63 ++++++++++++++++++++++++++++++++++++++++------ src/GPU3D_OpenGL_shaders.h | 7 ++---- src/OpenGLSupport.h | 1 + 3 files changed, 58 insertions(+), 13 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index f8ed773..759c404 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -71,6 +71,9 @@ typedef struct u32 NumIndices; u16* Indices; + u32 NumEdgeIndices; + u16* EdgeIndices; + u32 RenderKey; } RendererPolygon; @@ -98,7 +101,7 @@ u32 VertexBuffer[10240 * 7]; u32 NumVertices; GLuint VertexArrayID; -u16 IndexBuffer[2048 * 10]; +u16 IndexBuffer[2048 * 40]; u32 NumTriangles; GLuint TexMemID; @@ -443,6 +446,8 @@ void UpdateDisplaySettings() glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); + + //glLineWidth(scale); } @@ -495,6 +500,7 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) u32 vidx = 0; u16* iptr = &IndexBuffer[0]; + u16* eiptr = &IndexBuffer[2048*30]; u32 numtriangles = 0; for (int i = 0; i < npolys; i++) @@ -503,6 +509,7 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) Polygon* poly = rp->PolyData; rp->Indices = iptr; + rp->NumIndices = 0; u32 vidx_first = vidx; @@ -514,8 +521,6 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) if (poly->FacingView) vtxattr |= (1<<8); if (poly->WBuffer) vtxattr |= (1<<9); - rp->NumIndices = 0; - // assemble vertices for (int j = 0; j < poly->NumVertices; j++) { @@ -566,6 +571,17 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) vidx++; } + + rp->EdgeIndices = eiptr; + rp->NumEdgeIndices = 0; + + for (int j = 1; j < poly->NumVertices; j++) + { + *eiptr++ = vidx_first; + *eiptr++ = vidx_first + 1; + vidx_first++; + rp->NumEdgeIndices += 2; + } } NumTriangles = numtriangles; @@ -599,6 +615,24 @@ int RenderPolygonBatch(int i) return numpolys; } +int RenderPolygonEdges() +{ + RendererPolygon* rp = &PolygonList[0]; + int numpolys = 0; + u32 numindices = 0; + + for (int iend = 0; iend < NumOpaqueFinalPolys; iend++) + { + RendererPolygon* cur_rp = &PolygonList[iend]; + + numpolys++; + numindices += cur_rp->NumEdgeIndices; + } + + glDrawElements(GL_LINES, numindices, GL_UNSIGNED_SHORT, rp->EdgeIndices); + return numpolys; +} + void RenderSceneChunk(int y, int h) { u32 flags = 0; @@ -639,6 +673,11 @@ void RenderSceneChunk(int y, int h) } glEnable(GL_BLEND); + if (RenderDispCnt & (1<<3)) + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + else + glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ONE); + UseRenderShader(flags | RenderFlag_Trans); if (NumOpaqueFinalPolys > -1) @@ -821,6 +860,19 @@ void RenderSceneChunk(int y, int h) { glUseProgram(FinalPassShader[2]); + glEnable(GL_BLEND); + glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA); + + { + u32 c = RenderFogColor; + u32 r = c & 0x1F; + u32 g = (c >> 5) & 0x1F; + u32 b = (c >> 10) & 0x1F; + u32 a = (c >> 16) & 0x1F; + + glBlendColor((float)b/31.0, (float)g/31.0, (float)r/31.0, (float)a/31.0); + } + glDepthFunc(GL_ALWAYS); glDepthMask(GL_FALSE); glStencilFunc(GL_ALWAYS, 0, 0); @@ -939,11 +991,6 @@ void RenderFrame() if (Antialias) glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); else glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); - if (RenderDispCnt & (1<<3)) - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - else - glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ONE); - glDisable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMaski(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); diff --git a/src/GPU3D_OpenGL_shaders.h b/src/GPU3D_OpenGL_shaders.h index 0e4c4fe..a1aa95a 100644 --- a/src/GPU3D_OpenGL_shaders.h +++ b/src/GPU3D_OpenGL_shaders.h @@ -111,12 +111,9 @@ vec4 CalculateFog(float depth) densityfrac = int(udepth & uint(0x1FFFF)); } - float density = - ((uFogDensity[densityid] * float(0x20000-densityfrac)) + - (uFogDensity[densityid+1] * float(densityfrac))) / float(0x20000); + float density = mix(uFogDensity[densityid], uFogDensity[densityid+1], float(densityfrac)/131072.0); - return vec4(uFogColor.bgr,density); - return uFogColor * density; + return vec4(density, density, density, density); } void main() diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index c922f7c..1ae0a35 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -102,6 +102,7 @@ \ func(GLBLENDFUNCSEPARATE, glBlendFuncSeparate); \ func(GLBLENDEQUATIONSEPARATE, glBlendEquationSeparate); \ + func(GLBLENDCOLOR, glBlendColor); \ \ func(GLCOLORMASKI, glColorMaski); \ \ -- cgit v1.2.3 From 8c93a4557419ccdec2598af32e3305bdefbbd23b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 13:45:00 +0200 Subject: also support alpha-only fog --- src/GPU3D_OpenGL.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 759c404..9144792 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -861,7 +861,10 @@ void RenderSceneChunk(int y, int h) glUseProgram(FinalPassShader[2]); glEnable(GL_BLEND); - glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA); + if (RenderDispCnt & (1<<6)) + glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA); + else + glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA); { u32 c = RenderFogColor; -- 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/GPU3D_OpenGL.cpp') 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 ee61b97ec9e8bbe5491ac0aa01b1aa4da1a2ad7a Mon Sep 17 00:00:00 2001 From: StapleButter Date: Thu, 30 May 2019 02:44:49 +0200 Subject: OpenGL renderer: fix for Intel driver (doesn't like RGB8UI framebuffers) --- src/GPU3D_OpenGL.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index c759147..1b35fca 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -209,7 +209,7 @@ bool Init() glBindFragDataLocation(ClearShaderPlain[2], 1, "oAttr"); ClearUniformLoc[0] = glGetUniformLocation(ClearShaderPlain[2], "uColor"); ClearUniformLoc[1] = glGetUniformLocation(ClearShaderPlain[2], "uDepth"); - ClearUniformLoc[2] = glGetUniformLocation(ClearShaderPlain[2], "uOpaquePolyId"); + ClearUniformLoc[2] = glGetUniformLocation(ClearShaderPlain[2], "uOpaquePolyID"); ClearUniformLoc[3] = glGetUniformLocation(ClearShaderPlain[2], "uFogFlag"); memset(RenderShader, 0, sizeof(RenderShader)); @@ -420,7 +420,8 @@ void UpdateDisplaySettings() 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); + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ScreenW, ScreenH, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 1, 1, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); -- cgit v1.2.3 From c49dec1acdf2b90cb53364efa4ed525259c387d9 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Fri, 31 May 2019 03:00:53 +0200 Subject: try to fix fog consecutively to the Intel fix. still not perfect for whatever reason also clean up more code --- src/GPU3D_OpenGL.cpp | 7 +---- src/GPU3D_OpenGL_shaders.h | 26 ++++++++-------- src/libui_sdl/libui/unix/gl.c | 71 +++++++++++++++---------------------------- src/libui_sdl/main.cpp | 15 +++++---- 4 files changed, 46 insertions(+), 73 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 1b35fca..db2617c 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -187,12 +187,7 @@ void SetupDefaultTexParams(GLuint tex) bool Init() { GLint uni_id; - - const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string - const GLubyte* version = glGetString(GL_VERSION); // version as a string - printf("OpenGL: renderer: %s\n", renderer); - printf("OpenGL: version: %s\n", version); - + glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); diff --git a/src/GPU3D_OpenGL_shaders.h b/src/GPU3D_OpenGL_shaders.h index a1aa95a..b12dc61 100644 --- a/src/GPU3D_OpenGL_shaders.h +++ b/src/GPU3D_OpenGL_shaders.h @@ -42,14 +42,14 @@ uniform uint uOpaquePolyID; uniform uint uFogFlag; out vec4 oColor; -out uvec3 oAttr; +out vec3 oAttr; void main() { oColor = vec4(uColor).bgra / 31.0; - oAttr.r = uOpaquePolyID; - oAttr.g = uint(0); - oAttr.b = uFogFlag; + oAttr.r = float(uOpaquePolyID) / 63.0; + oAttr.g = 0; + oAttr.b = float(uFogFlag); } )"; @@ -69,7 +69,7 @@ void main() const char* kFinalPassFS = kShaderHeader R"( uniform sampler2D DepthBuffer; -uniform usampler2D AttrBuffer; +uniform sampler2D AttrBuffer; layout(std140) uniform uConfig { @@ -122,7 +122,7 @@ void main() vec4 ret = vec4(0,0,0,0); vec4 depth = texelFetch(DepthBuffer, coord, 0); - ivec4 attr = ivec4(texelFetch(AttrBuffer, coord, 0)); + vec4 attr = texelFetch(AttrBuffer, coord, 0); if (attr.b != 0) ret = CalculateFog(depth.r); @@ -178,7 +178,7 @@ smooth in vec2 fTexcoord; flat in ivec3 fPolygonAttr; out vec4 oColor; -out uvec3 oAttr; +out vec3 oAttr; int TexcoordWrap(int c, int maxc, int mode) { @@ -618,8 +618,8 @@ void main() if (col.a < 30.5/31) discard; oColor = col; - oAttr.r = uint((fPolygonAttr.x >> 24) & 0x3F); - oAttr.b = uint((fPolygonAttr.x >> 15) & 0x1); + oAttr.r = float((fPolygonAttr.x >> 24) & 0x3F) / 63.0; + oAttr.b = float((fPolygonAttr.x >> 15) & 0x1); } )"; @@ -633,8 +633,8 @@ void main() if (col.a < 30.5/31) discard; oColor = col; - oAttr.r = uint((fPolygonAttr.x >> 24) & 0x3F); - oAttr.b = uint((fPolygonAttr.x >> 15) & 0x1); + oAttr.r = float((fPolygonAttr.x >> 24) & 0x3F) / 63.0; + oAttr.b = float((fPolygonAttr.x >> 15) & 0x1); gl_FragDepth = fZ; } )"; @@ -648,7 +648,7 @@ void main() if (col.a >= 30.5/31) discard; oColor = col; - oAttr.b = uint(0); + oAttr.b = 0; } )"; @@ -663,7 +663,7 @@ void main() if (col.a >= 30.5/31) discard; oColor = col; - oAttr.b = uint(0); + oAttr.b = 0; gl_FragDepth = fZ; } )"; diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c index dbb30fa..0511639 100644 --- a/src/libui_sdl/libui/unix/gl.c +++ b/src/libui_sdl/libui/unix/gl.c @@ -115,67 +115,46 @@ void freeGLContext(uiGLContext* glctx) static void areaAllocRenderbuffer(uiGLContext* glctx) { - _glGenRenderbuffers(4, &glctx->renderbuffer[0][0]);printf("ylarg0 %04X, %d %d\n", glGetError(), glctx->width, glctx->height); - //glGenTextures(2, &glctx->renderbuffer[0]); - _glGenFramebuffers(2, &glctx->framebuffer[0]);printf("ylarg1 %04X\n", glGetError()); - printf("FB %08X created under ctx %p (%p %p)\n", glctx?glctx->framebuffer[0]:0, gdk_gl_context_get_current(), glctx?glctx->gctx:NULL, glctx); - /*glBindTexture(GL_TEXTURE_2D, glctx->renderbuffer[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); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + // TODO: create textures as a fallback if GL_RGB renderbuffer isn't supported? + // they say GL implementations aren't required to support a GL_RGB renderbuffer + // however, a GL_RGBA one would cause gdk_cairo_draw_from_gl() to fall back to glReadPixels() - glBindTexture(GL_TEXTURE_2D, glctx->renderbuffer[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);*/ - - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);printf("ylarg1 %04X\n", glGetError()); - _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError()); - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]);printf("ylarg1 %04X\n", glGetError()); - _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError()); - - _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[0]);printf("ylarg2 %04X\n", glGetError()); - /*_glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glctx->renderbuffer[0], 0); - _glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, glctx->renderbuffer[1], 0);*/ - _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[0][0]);printf("ylarg3 %04X\n", glGetError()); - _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[0][1]);printf("ylarg4 %04X\n", glGetError()); - //printf("ylarg: %08X, %04X, %08X %08X\n", glctx->framebuffer, glGetError(), glctx->renderbuffer[0], glctx->renderbuffer[1]); + _glGenRenderbuffers(4, &glctx->renderbuffer[0][0]); + _glGenFramebuffers(2, &glctx->framebuffer[0]); + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]); + _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale); + //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]); + //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale); - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]);printf("ylarg1 %04X\n", glGetError()); - _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError()); - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]);printf("ylarg1 %04X\n", glGetError()); - _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);printf("ylarg1 %04X\n", glGetError()); + _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[0]); + _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[0][0]); + _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[0][1]); - _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[1]);printf("ylarg2 %04X\n", glGetError()); - /*_glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glctx->renderbuffer[0], 0); - _glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, glctx->renderbuffer[1], 0);*/ - _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[1][0]);printf("ylarg3 %04X\n", glGetError()); - _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1][1]);printf("ylarg4 %04X\n", glGetError()); - //printf("ylarg: %08X, %04X, %08X %08X\n", glctx->framebuffer, glGetError(), glctx->renderbuffer[0], glctx->renderbuffer[1]); + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]); + _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale); + //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]); + //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale); - if(_glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER)); + _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[1]); + _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[1][0]); + _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1][1]); - int alpha_size; - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]); - _glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_ALPHA_SIZE, &alpha_size); - printf("FRAMEBUFFER GOOD. ALPHA SIZE IS %d\n", alpha_size); + //if (_glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + // printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER)); } static void areaRellocRenderbuffer(uiGLContext* glctx) { _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]); _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale); - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]); - _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale); + //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]); + //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale); _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]); _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale); - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]); - _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale); + //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]); + //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale); } void areaPreRedrawGL(uiGLContext* glctx) diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index a686cb4..986a809 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -194,12 +194,11 @@ bool GLScreen_InitShader(GLuint* shader, const char* fs) } bool GLScreen_Init() -{printf("BEGINNING GL SHITO\n"); +{ + // TODO: consider using epoxy? if (!OpenGL_Init()) return false; - printf("GL INIT: %p, %p\n", glGenFramebuffers, glCreateShader); - const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string const GLubyte* version = glGetString(GL_VERSION); // version as a string printf("OpenGL: renderer: %s\n", renderer); @@ -211,7 +210,7 @@ bool GLScreen_Init() return false; memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig)); -printf("morp0\n"); + glGenBuffers(1, &GL_ShaderConfigUBO); glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO); glBufferData(GL_UNIFORM_BUFFER, sizeof(GL_ShaderConfig), &GL_ShaderConfig, GL_STATIC_DRAW); @@ -220,14 +219,14 @@ printf("morp0\n"); glGenBuffers(1, &GL_ScreenVertexBufferID); glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); glBufferData(GL_ARRAY_BUFFER, sizeof(GL_ScreenVertices), NULL, GL_STATIC_DRAW); -printf("morp1\n"); + glGenVertexArrays(1, &GL_ScreenVertexArrayID); glBindVertexArray(GL_ScreenVertexArrayID); glEnableVertexAttribArray(0); // position glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(0)); glEnableVertexAttribArray(1); // texcoord glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(2*4)); -printf("morp2\n"); + glGenTextures(1, &GL_ScreenTexture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); @@ -238,7 +237,7 @@ printf("morp2\n"); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 256*3 + 1, 192*2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); GL_ScreenSizeDirty = true; -printf("morp3\n"); + return true; } @@ -394,7 +393,7 @@ void GLScreen_DrawScreen() glBindFramebuffer(GL_DRAW_FRAMEBUFFER, uiGLGetFramebuffer(GLContext)); - glClearColor(0, 0, 1, 1); + glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); int frontbuf = GPU::FrontBuffer; -- cgit v1.2.3 From f6814e02c02a0ad68af107e7605c08ee47de79f4 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 31 May 2019 21:37:30 +0200 Subject: * add needed libui functions under Windows, even if they don't do a whole lot * fix ass-stupid fog bug --- src/GPU3D_OpenGL.cpp | 5 +---- src/GPU3D_OpenGL_shaders.h | 9 +++++++-- src/libui_sdl/libui/windows/gl.cpp | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index db2617c..95243d1 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -187,7 +187,7 @@ void SetupDefaultTexParams(GLuint tex) bool Init() { GLint uni_id; - + glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); @@ -1043,9 +1043,6 @@ void RenderFrame() { if (RenderPolygonRAM[i]->Degenerate) continue; - // zog. - //if (RenderPolygonRAM[i]->YBottom <= 96 || RenderPolygonRAM[i]->YTop >= 144) continue; - SetupPolygon(&PolygonList[npolys], RenderPolygonRAM[i]); if (firsttrans < 0 && RenderPolygonRAM[i]->Translucent) firsttrans = npolys; diff --git a/src/GPU3D_OpenGL_shaders.h b/src/GPU3D_OpenGL_shaders.h index b12dc61..4c5b82e 100644 --- a/src/GPU3D_OpenGL_shaders.h +++ b/src/GPU3D_OpenGL_shaders.h @@ -42,7 +42,7 @@ uniform uint uOpaquePolyID; uniform uint uFogFlag; out vec4 oColor; -out vec3 oAttr; +out vec4 oAttr; void main() { @@ -50,6 +50,7 @@ void main() oAttr.r = float(uOpaquePolyID) / 63.0; oAttr.g = 0; oAttr.b = float(uFogFlag); + oAttr.a = 1; } )"; @@ -178,7 +179,7 @@ smooth in vec2 fTexcoord; flat in ivec3 fPolygonAttr; out vec4 oColor; -out vec3 oAttr; +out vec4 oAttr; int TexcoordWrap(int c, int maxc, int mode) { @@ -620,6 +621,7 @@ void main() oColor = col; oAttr.r = float((fPolygonAttr.x >> 24) & 0x3F) / 63.0; oAttr.b = float((fPolygonAttr.x >> 15) & 0x1); + oAttr.a = 1; } )"; @@ -635,6 +637,7 @@ void main() oColor = col; oAttr.r = float((fPolygonAttr.x >> 24) & 0x3F) / 63.0; oAttr.b = float((fPolygonAttr.x >> 15) & 0x1); + oAttr.a = 1; gl_FragDepth = fZ; } )"; @@ -649,6 +652,7 @@ void main() oColor = col; oAttr.b = 0; + oAttr.a = 1; } )"; @@ -664,6 +668,7 @@ void main() oColor = col; oAttr.b = 0; + oAttr.a = 1; gl_FragDepth = fZ; } )"; diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp index 1e3732c..c621721 100644 --- a/src/libui_sdl/libui/windows/gl.cpp +++ b/src/libui_sdl/libui/windows/gl.cpp @@ -135,8 +135,27 @@ void *uiGLGetProcAddress(const char* proc) return (void*)wglGetProcAddress(proc); } +void uiGLBegin(uiGLContext* ctx) +{ +} + +void uiGLEnd(uiGLContext* ctx) +{ +} + void uiGLSwapBuffers(uiGLContext* ctx) { if (ctx == NULL) return; SwapBuffers(ctx->dc); } + +int uiGLGetFramebuffer(uiGLContext* ctx) +{ + return 0; +} + +float uiGLGetFramebufferScale(uiGLContext* ctx) +{ + // TODO + return 1; +} -- cgit v1.2.3 From 06e08b053fa6523657aab4074c25a52c65364ad6 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 31 May 2019 02:26:13 +0200 Subject: do binding of VS inputs and FS outputs before linking shader programs, as per OpenGL standard. should fix the rendering issues with strict drivers (AMD, Intel). --- src/GPU3D_OpenGL.cpp | 22 ++++++++++++++++------ src/OpenGLSupport.cpp | 10 +++++++++- src/OpenGLSupport.h | 3 ++- src/libui_sdl/main.cpp | 17 ++++++++++------- 4 files changed, 37 insertions(+), 15 deletions(-) (limited to 'src/GPU3D_OpenGL.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 95243d1..1fd266f 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -148,9 +148,6 @@ bool BuildRenderShader(u32 flags, const char* vs, const char* fs) GLuint prog = RenderShader[flags][2]; - GLint uni_id = glGetUniformBlockIndex(prog, "uConfig"); - glUniformBlockBinding(prog, uni_id, 0); - glBindAttribLocation(prog, 0, "vPosition"); glBindAttribLocation(prog, 1, "vColor"); glBindAttribLocation(prog, 2, "vTexcoord"); @@ -158,6 +155,12 @@ bool BuildRenderShader(u32 flags, const char* vs, const char* fs) glBindFragDataLocation(prog, 0, "oColor"); glBindFragDataLocation(prog, 1, "oAttr"); + if (!OpenGL_LinkShaderProgram(RenderShader[flags])) + return false; + + GLint uni_id = glGetUniformBlockIndex(prog, "uConfig"); + glUniformBlockBinding(prog, uni_id, 0); + glUseProgram(prog); uni_id = glGetUniformLocation(prog, "TexMem"); @@ -202,6 +205,10 @@ bool Init() glBindAttribLocation(ClearShaderPlain[2], 0, "vPosition"); glBindFragDataLocation(ClearShaderPlain[2], 0, "oColor"); glBindFragDataLocation(ClearShaderPlain[2], 1, "oAttr"); + + if (!OpenGL_LinkShaderProgram(ClearShaderPlain)) + return false; + ClearUniformLoc[0] = glGetUniformLocation(ClearShaderPlain[2], "uColor"); ClearUniformLoc[1] = glGetUniformLocation(ClearShaderPlain[2], "uDepth"); ClearUniformLoc[2] = glGetUniformLocation(ClearShaderPlain[2], "uOpaquePolyID"); @@ -226,12 +233,15 @@ bool Init() if (!OpenGL_BuildShaderProgram(kFinalPassVS, kFinalPassFS, FinalPassShader, "FinalPassShader")) return false; - uni_id = glGetUniformBlockIndex(FinalPassShader[2], "uConfig"); - glUniformBlockBinding(FinalPassShader[2], uni_id, 0); - glBindAttribLocation(FinalPassShader[2], 0, "vPosition"); glBindFragDataLocation(FinalPassShader[2], 0, "oColor"); + if (!OpenGL_LinkShaderProgram(FinalPassShader)) + return false; + + uni_id = glGetUniformBlockIndex(FinalPassShader[2], "uConfig"); + glUniformBlockBinding(FinalPassShader[2], uni_id, 0); + glUseProgram(FinalPassShader[2]); uni_id = glGetUniformLocation(FinalPassShader[2], "DepthBuffer"); diff --git a/src/OpenGLSupport.cpp b/src/OpenGLSupport.cpp index 11fd629..59424b4 100644 --- a/src/OpenGLSupport.cpp +++ b/src/OpenGLSupport.cpp @@ -85,6 +85,14 @@ bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, cons ids[2] = glCreateProgram(); glAttachShader(ids[2], ids[0]); glAttachShader(ids[2], ids[1]); + + return true; +} + +bool OpenGL_LinkShaderProgram(GLuint* ids) +{ + int res; + glLinkProgram(ids[2]); glGetProgramiv(ids[2], GL_LINK_STATUS, &res); @@ -94,7 +102,7 @@ bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, cons if (res < 1) res = 1024; char* log = new char[res+1]; glGetProgramInfoLog(ids[2], res+1, NULL, log); - printf("OpenGL: failed to link program %s: %s\n", name, log); + printf("OpenGL: failed to link shader program: %s\n", log); delete[] log; glDeleteShader(ids[0]); diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 31a0dc0..a4d6124 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -49,7 +49,7 @@ #ifndef __WIN32__ -#define DO_PROCLIST_1_3(func) +#define DO_PROCLIST_1_3(func) #else @@ -131,6 +131,7 @@ DO_PROCLIST(DECLPROC_EXT); bool OpenGL_Init(); bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name); +bool OpenGL_LinkShaderProgram(GLuint* ids); void OpenGL_DeleteShaderProgram(GLuint* ids); void OpenGL_UseShaderProgram(GLuint* ids); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 33a35d0..5408586 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -175,6 +175,13 @@ bool GLScreen_InitShader(GLuint* shader, const char* fs) if (!OpenGL_BuildShaderProgram(kScreenVS, fs, shader, "ScreenShader")) return false; + glBindAttribLocation(shader[2], 0, "vPosition"); + glBindAttribLocation(shader[2], 1, "vTexcoord"); + glBindFragDataLocation(shader[2], 0, "oColor"); + + if (!OpenGL_LinkShaderProgram(shader)) + return false; + GLuint uni_id; uni_id = glGetUniformBlockIndex(shader[2], "uConfig"); @@ -186,10 +193,6 @@ bool GLScreen_InitShader(GLuint* shader, const char* fs) 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; } @@ -198,7 +201,7 @@ bool GLScreen_Init() // TODO: consider using epoxy? if (!OpenGL_Init()) return false; - + const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string const GLubyte* version = glGetString(GL_VERSION); // version as a string printf("OpenGL: renderer: %s\n", renderer); @@ -255,7 +258,7 @@ void GLScreen_DeInit() void GLScreen_DrawScreen() { float scale = uiGLGetFramebufferScale(GLContext); - + if (GL_ScreenSizeDirty) { GL_ScreenSizeDirty = false; @@ -2540,7 +2543,7 @@ int main(int argc, char** argv) if (MicDevice) SDL_CloseAudioDevice(MicDevice); if (MicWavBuffer) delete[] MicWavBuffer; - + if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); -- cgit v1.2.3