From 256b8cb69c751f43a7766eafc6f8798eefa3217e Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 15 May 2019 19:49:21 +0200 Subject: botch GL support. --- src/OpenGLSupport.h | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/OpenGLSupport.h (limited to 'src/OpenGLSupport.h') diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h new file mode 100644 index 0000000..10ba1e5 --- /dev/null +++ b/src/OpenGLSupport.h @@ -0,0 +1,112 @@ +/* + Copyright 2016-2019 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef OPENGLSUPPORT_H +#define OPENGLSUPPORT_H + +#include +#include +#include + +#include "Platform.h" + + +// here, have some macro magic +// we at the melonDS company really love macro magic +// also, suggestion to the fine folks who write the OpenGL headers: +// pls make the type names follow the same capitalization as their +// matching function names, so this is more convenient to deal with + +#define DECLPROC(type, name) \ + PFN##type##PROC name ; + +#define DECLPROC_EXT(type, name) \ + extern PFN##type##PROC name ; + +#define LOADPROC(type, name) \ + name = (PFN##type##PROC)Platform::GL_GetProcAddress(#name); \ + if (!name) { printf("OpenGL: " #name " not found\n"); return false; } + + +// if you need more OpenGL functions, add them to the macronator here +// TODO: handle conditionally loading certain functions for different GL versions + +#define DO_PROCLIST(func) \ + func(GLGENFRAMEBUFFERS, glGenFramebuffers); \ + func(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers); \ + func(GLBINDFRAMEBUFFER, glBindFramebuffer); \ + func(GLFRAMEBUFFERTEXTURE, glFramebufferTexture); \ + func(GLBLITFRAMEBUFFER, glBlitFramebuffer); \ + \ + func(GLGENBUFFERS, glGenBuffers); \ + func(GLDELETEBUFFERS, glDeleteBuffers); \ + func(GLBINDBUFFER, glBindBuffer); \ + func(GLMAPBUFFER, glMapBuffer); \ + func(GLMAPBUFFERRANGE, glMapBufferRange); \ + func(GLUNMAPBUFFER, glUnmapBuffer); \ + func(GLBUFFERDATA, glBufferData); \ + func(GLBUFFERSUBDATA, glBufferSubData); \ + func(GLBINDBUFFERBASE, glBindBufferBase); \ + \ + func(GLGENVERTEXARRAYS, glGenVertexArrays); \ + func(GLDELETEVERTEXARRAYS, glDeleteVertexArrays); \ + func(GLBINDVERTEXARRAY, glBindVertexArray); \ + func(GLENABLEVERTEXATTRIBARRAY, glEnableVertexAttribArray); \ + func(GLDISABLEVERTEXATTRIBARRAY, glDisableVertexAttribArray); \ + func(GLVERTEXATTRIBPOINTER, glVertexAttribPointer); \ + func(GLVERTEXATTRIBIPOINTER, glVertexAttribIPointer); \ + \ + func(GLCREATESHADER, glCreateShader); \ + func(GLSHADERSOURCE, glShaderSource); \ + func(GLCOMPILESHADER, glCompileShader); \ + func(GLCREATEPROGRAM, glCreateProgram); \ + func(GLATTACHSHADER, glAttachShader); \ + func(GLLINKPROGRAM, glLinkProgram); \ + func(GLUSEPROGRAM, glUseProgram); \ + func(GLGETSHADERIV, glGetShaderiv); \ + func(GLGETSHADERINFOLOG, glGetShaderInfoLog); \ + func(GLGETPROGRAMIV, glGetProgramiv); \ + func(GLGETPROGRAMINFOLOG, glGetProgramInfoLog); \ + func(GLDELETESHADER, glDeleteShader); \ + func(GLDELETEPROGRAM, glDeleteProgram); \ + \ + func(GLUNIFORM1UI, glUniform1ui); \ + func(GLUNIFORM4UI, glUniform4ui); \ + func(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); \ + \ + func(GLACTIVETEXTURE, glActiveTexture); \ + func(GLBINDIMAGETEXTURE, glBindImageTexture); \ + \ + func(GLDRAWBUFFERS, glDrawBuffers); \ + \ + func(GLBLENDFUNCSEPARATEI, glBlendFuncSeparatei); \ + func(GLBLENDEQUATIONSEPARATEI, glBlendEquationSeparatei); \ + \ + func(GLCOLORMASKI, glColorMaski); \ + \ + func(GLMEMORYBARRIER, glMemoryBarrier); \ + \ + func(GLGETSTRINGI, glGetStringi); \ + + +DO_PROCLIST(DECLPROC_EXT); + + +bool OpenGL_Init(); + +#endif // OPENGLSUPPORT_H -- cgit v1.2.3 From f2725791d8c3b5f00ddc830691ed556b48f2f508 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 16 May 2019 00:30:55 +0200 Subject: preliminary, shitty, code for drawing the main window with OpenGL --- melonDS.cbp | 1 + src/GPU3D_OpenGL43.cpp | 7 +- src/OpenGLSupport.cpp | 85 ++++++++++++++ src/OpenGLSupport.h | 4 + src/libui_sdl/libui/windows/gl.cpp | 2 +- src/libui_sdl/main.cpp | 227 ++++++++++++++++++++++++++++++++++++- src/libui_sdl/main_shaders.h | 72 ++++++++++++ 7 files changed, 392 insertions(+), 6 deletions(-) create mode 100644 src/libui_sdl/main_shaders.h (limited to 'src/OpenGLSupport.h') diff --git a/melonDS.cbp b/melonDS.cbp index 4634513..ff01ebf 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -230,6 +230,7 @@ + diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 3a2a3f1..b3e0856 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -732,7 +732,8 @@ bool ChunkedRendering = false; bool InitGLExtensions() { - if (!OpenGL_Init()) return false; + // TODO move this elsewhere!! + //if (!OpenGL_Init()) return false; return true; } @@ -1385,7 +1386,7 @@ void VCount144() } void RenderFrame() -{ +{return; ShaderConfig.uScreenSize[0] = ScreenW; ShaderConfig.uScreenSize[1] = ScreenH; ShaderConfig.uDispCnt = RenderDispCnt; @@ -1544,7 +1545,7 @@ void RenderFrame() u32* GetLine(int line) { int stride = 256 << (ScaleFactor*2); - +return &Framebuffer[stride * line]; if (!ChunkedRendering) { if (line == 0) diff --git a/src/OpenGLSupport.cpp b/src/OpenGLSupport.cpp index c22fd1c..81a008b 100644 --- a/src/OpenGLSupport.cpp +++ b/src/OpenGLSupport.cpp @@ -28,3 +28,88 @@ bool OpenGL_Init() return true; } + +bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name) +{ + int len; + int res; + + ids[0] = glCreateShader(GL_VERTEX_SHADER); + len = strlen(vs); + glShaderSource(ids[0], 1, &vs, &len); + glCompileShader(ids[0]); + + glGetShaderiv(ids[0], GL_COMPILE_STATUS, &res); + if (res != GL_TRUE) + { + glGetShaderiv(ids[0], GL_INFO_LOG_LENGTH, &res); + if (res < 1) res = 1024; + char* log = new char[res+1]; + glGetShaderInfoLog(ids[0], res+1, NULL, log); + printf("OpenGL: failed to compile vertex shader %s: %s\n", name, log); + printf("shader source:\n--\n%s\n--\n", vs); + delete[] log; + + glDeleteShader(ids[0]); + + return false; + } + + ids[1] = glCreateShader(GL_FRAGMENT_SHADER); + len = strlen(fs); + glShaderSource(ids[1], 1, &fs, &len); + glCompileShader(ids[1]); + + glGetShaderiv(ids[1], GL_COMPILE_STATUS, &res); + if (res != GL_TRUE) + { + glGetShaderiv(ids[1], GL_INFO_LOG_LENGTH, &res); + if (res < 1) res = 1024; + char* log = new char[res+1]; + glGetShaderInfoLog(ids[1], res+1, NULL, log); + printf("OpenGL: failed to compile fragment shader %s: %s\n", name, log); + //printf("shader source:\n--\n%s\n--\n", fs); + delete[] log; + + glDeleteShader(ids[0]); + glDeleteShader(ids[1]); + + return false; + } + + ids[2] = glCreateProgram(); + glAttachShader(ids[2], ids[0]); + glAttachShader(ids[2], ids[1]); + glLinkProgram(ids[2]); + + glGetProgramiv(ids[2], GL_LINK_STATUS, &res); + if (res != GL_TRUE) + { + glGetProgramiv(ids[2], GL_INFO_LOG_LENGTH, &res); + 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); + delete[] log; + + glDeleteShader(ids[0]); + glDeleteShader(ids[1]); + glDeleteProgram(ids[2]); + + return false; + } + + return true; +} + +void OpenGL_DeleteShaderProgram(GLuint* ids) +{ + glDeleteShader(ids[0]); + glDeleteShader(ids[1]); + glDeleteProgram(ids[2]); +} + +void OpenGL_UseShaderProgram(GLuint* ids) +{ + glUseProgram(ids[2]); +} diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 10ba1e5..2cee741 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -109,4 +109,8 @@ DO_PROCLIST(DECLPROC_EXT); bool OpenGL_Init(); +bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name); +void OpenGL_DeleteShaderProgram(GLuint* ids); +void OpenGL_UseShaderProgram(GLuint* ids); + #endif // OPENGLSUPPORT_H diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp index 67eaeda..832a2e5 100644 --- a/src/libui_sdl/libui/windows/gl.cpp +++ b/src/libui_sdl/libui/windows/gl.cpp @@ -39,7 +39,7 @@ uiGLContext* uiGLNewContext(uiControl* c, int vermajor, int verminor) memset(&pfd, 0, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cAlphaBits = 8; diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index b39f493..23e6617 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -24,6 +24,9 @@ #include #include "libui/ui.h" +#include "../OpenGLSupport.h" +#include "main_shaders.h" + #include "../types.h" #include "../version.h" #include "PlatformConfig.h" @@ -97,6 +100,19 @@ bool SavestateLoaded; bool ScreenDrawInited = false; uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; +GLuint GL_ScreenShader[3]; +struct +{ + float uScreenSize[2]; + u32 uFilterMode; + +} GL_ShaderConfig; +GLuint GL_ShaderConfigUBO; +GLuint GL_ScreenVertexArrayID, GL_ScreenVertexBufferID; +float GL_ScreenVertices[2 * 3*2 * 4]; // position/texcoord +GLuint GL_ScreenTexture; +bool GL_ScreenSizeDirty; + int ScreenScale[3]; int ScreenScaleMode; @@ -141,6 +157,204 @@ void GetSavestateName(int slot, char* filename, int len); +bool GLDrawing_Init() +{ + if (!OpenGL_Init()) + return false; + + if (!OpenGL_BuildShaderProgram(kScreenVS, kScreenFS, GL_ScreenShader, "ScreenShader")) + return false; + + memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig)); + + glGenBuffers(1, &GL_ShaderConfigUBO); + glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO); + glBufferData(GL_UNIFORM_BUFFER, sizeof(GL_ShaderConfig), &GL_ShaderConfig, GL_STATIC_DRAW); + glBindBufferBase(GL_UNIFORM_BUFFER, 16, GL_ShaderConfigUBO); + glUniformBlockBinding(GL_ScreenShader[2], 0, 16); + + glGenBuffers(1, &GL_ScreenVertexBufferID); + glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); + glBufferData(GL_ARRAY_BUFFER, sizeof(GL_ScreenVertices), NULL, GL_STATIC_DRAW); + + 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)); + + glGenTextures(1, &GL_ScreenTexture); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); + 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_RGBA8UI, 1024, 1536, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); + + GL_ScreenSizeDirty = true; + + return true; +} + +void GLDrawing_DeInit() +{ + glDeleteTextures(1, &GL_ScreenTexture); + + glDeleteVertexArrays(1, &GL_ScreenVertexArrayID); + glDeleteBuffers(1, &GL_ScreenVertexBufferID); + + OpenGL_DeleteShaderProgram(GL_ScreenShader); +} + +void GLDrawing_DrawScreen() +{ + if (GL_ScreenSizeDirty) + { + GL_ScreenSizeDirty = false; + + GL_ShaderConfig.uScreenSize[0] = WindowWidth; + GL_ShaderConfig.uScreenSize[1] = WindowHeight; + + glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO); + void* unibuf = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); + if (unibuf) memcpy(unibuf, &GL_ShaderConfig, sizeof(GL_ShaderConfig)); + glUnmapBuffer(GL_UNIFORM_BUFFER); + + float scwidth, scheight; + scwidth = 512; + scheight = 384; + + float x0, y0, x1, y1; + float s0, s1, s2, s3; + float t0, t1, t2, t3; + +#define SETVERTEX(i, x, y, s, t) \ + GL_ScreenVertices[4*(i) + 0] = x; \ + GL_ScreenVertices[4*(i) + 1] = y; \ + GL_ScreenVertices[4*(i) + 2] = s; \ + GL_ScreenVertices[4*(i) + 3] = t; + + x0 = TopScreenRect.X; + y0 = TopScreenRect.Y; + x1 = TopScreenRect.X + TopScreenRect.Width; + y1 = TopScreenRect.Y + TopScreenRect.Height; + + switch (ScreenRotation) + { + case 0: + s0 = 0; t0 = 0; + s1 = scwidth; t1 = 0; + s2 = 0; t2 = scheight; + s3 = scwidth; t3 = scheight; + break; + + case 1: + s0 = 0; t0 = scheight; + s1 = 0; t1 = 0; + s2 = scwidth; t2 = scheight; + s3 = scwidth; t3 = 0; + break; + + case 2: + s0 = scwidth; t0 = scheight; + s1 = 0; t1 = scheight; + s2 = scwidth; t2 = 0; + s3 = 0; t3 = 0; + break; + + case 3: + s0 = scwidth; t0 = 0; + s1 = scwidth; t1 = scheight; + s2 = 0; t2 = 0; + s3 = 0; t3 = scheight; + break; + } + + SETVERTEX(0, x0, y0, s0, t0); + SETVERTEX(1, x1, y1, s3, t3); + SETVERTEX(2, x1, y0, s1, t1); + SETVERTEX(3, x0, y0, s0, t0); + SETVERTEX(4, x0, y1, s2, t2); + SETVERTEX(5, x1, y1, s3, t3); + + // TODO: adjust scwidth/scheight + + x0 = BottomScreenRect.X; + y0 = BottomScreenRect.Y; + x1 = BottomScreenRect.X + BottomScreenRect.Width; + y1 = BottomScreenRect.Y + BottomScreenRect.Height; + + switch (ScreenRotation) + { + case 0: + s0 = 0; t0 = 768; + s1 = scwidth; t1 = 768; + s2 = 0; t2 = 768+scheight; + s3 = scwidth; t3 = 768+scheight; + break; + + case 1: + s0 = 0; t0 = 768+scheight; + s1 = 0; t1 = 768; + s2 = scwidth; t2 = 768+scheight; + s3 = scwidth; t3 = 768; + break; + + case 2: + s0 = scwidth; t0 = 768+scheight; + s1 = 0; t1 = 768+scheight; + s2 = scwidth; t2 = 768; + s3 = 0; t3 = 768; + break; + + case 3: + s0 = scwidth; t0 = 768; + s1 = scwidth; t1 = 768+scheight; + s2 = 0; t2 = 768; + s3 = 0; t3 = 768+scheight; + break; + } + + SETVERTEX(6, x0, y0, s0, t0); + SETVERTEX(7, x1, y1, s3, t3); + SETVERTEX(8, x1, y0, s1, t1); + SETVERTEX(9, x0, y0, s0, t0); + SETVERTEX(10, x0, y1, s2, t2); + SETVERTEX(11, x1, y1, s3, t3); + +#undef SETVERTEX + + glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GL_ScreenVertices), GL_ScreenVertices); + } + + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + + glViewport(0, 0, WindowWidth, WindowHeight); + + OpenGL_UseShaderProgram(GL_ScreenShader); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glClearColor(0, 1, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + int frontbuf = GPU::FrontBuffer; + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 512, 384, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 512, 384, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); + + glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); + glBindVertexArray(GL_ScreenVertexArrayID); + glDrawArrays(GL_TRIANGLES, 0, 4*3); + + uiGLSwapBuffers(GLContext); + uiAreaQueueRedrawAll(MainDrawArea); +} + void MicLoadWav(char* name) { SDL_AudioSpec format; @@ -397,6 +611,8 @@ void FeedMicInput() int EmuThreadFunc(void* burp) { uiGLMakeContextCurrent(GLContext); + GLDrawing_Init(); + NDS::Init(); MainScreenPos[0] = 0; @@ -567,7 +783,9 @@ int EmuThreadFunc(void* burp) if (EmuRunning == 0) break; - uiAreaQueueRedrawAll(MainDrawArea); + GLDrawing_DrawScreen(); + + //uiAreaQueueRedrawAll(MainDrawArea); //uiGLSwapBuffers(GLContext); // framerate limiter based off SDL2_gfx @@ -622,6 +840,7 @@ int EmuThreadFunc(void* burp) { //uiAreaQueueRedrawAll(MainDrawArea); //uiGLSwapBuffers(GLContext); + GLDrawing_DrawScreen(); } EmuStatus = EmuRunning; @@ -637,6 +856,8 @@ int EmuThreadFunc(void* burp) NDS::DeInit(); Platform::LAN_DeInit(); + GLDrawing_DeInit(); + return 44203; } @@ -1058,6 +1279,8 @@ void SetupScreenRects(int width, int height) } break; } + + GL_ScreenSizeDirty = true; } void SetMinSize(int w, int h) @@ -2063,7 +2286,7 @@ int main(int argc, char** argv) areahandler.Resize = OnAreaResize; ScreenDrawInited = false; - MainDrawArea = uiNewArea(&areahandler, 0); + MainDrawArea = uiNewArea(&areahandler, 1); uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); // TODO: make configurable? diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h new file mode 100644 index 0000000..dcf79d9 --- /dev/null +++ b/src/libui_sdl/main_shaders.h @@ -0,0 +1,72 @@ +/* + Copyright 2016-2019 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef MAIN_SHADERS_H +#define MAIN_SHADERS_H + +const char* kScreenVS = R"(#version 420 + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uFilterMode; +}; + +layout(location=0) in vec2 vPosition; +layout(location=1) in vec2 vTexcoord; + +smooth out vec2 fTexcoord; + +void main() +{ + vec4 fpos; + fpos.xy = ((vPosition.xy * 2.0) / uScreenSize) - 1.0; + fpos.y *= -1; + fpos.z = 0.0; + fpos.w = 1.0; + + gl_Position = fpos; + fTexcoord = vTexcoord; +} +)"; + +const char* kScreenFS = R"(#version 420 + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uFilterMode; +}; + +layout(binding=0) uniform usampler2D ScreenTex; + +smooth in vec2 fTexcoord; + +layout(location=0) out vec4 oColor; + +void main() +{ + uvec4 pixel = texelFetch(ScreenTex, ivec2(fTexcoord), 0); + + // TODO: filters + + oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0); +} +)"; + +#endif // MAIN_SHADERS_H -- cgit v1.2.3 From 8bf45571754a1469758f83ab8f98f951122c96f8 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 17 May 2019 15:47:40 +0200 Subject: make screen shaders work with OpenGL 3.1 --- src/OpenGLSupport.h | 5 +++++ src/libui_sdl/main.cpp | 14 +++++++++++- src/libui_sdl/main_shaders.h | 53 ++++++++++++++++++++++---------------------- 3 files changed, 44 insertions(+), 28 deletions(-) (limited to 'src/OpenGLSupport.h') diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 2cee741..793205b 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -70,6 +70,8 @@ func(GLDISABLEVERTEXATTRIBARRAY, glDisableVertexAttribArray); \ func(GLVERTEXATTRIBPOINTER, glVertexAttribPointer); \ func(GLVERTEXATTRIBIPOINTER, glVertexAttribIPointer); \ + func(GLBINDATTRIBLOCATION, glBindAttribLocation); \ + func(GLBINDFRAGDATALOCATION, glBindFragDataLocation); \ \ func(GLCREATESHADER, glCreateShader); \ func(GLSHADERSOURCE, glShaderSource); \ @@ -85,9 +87,12 @@ func(GLDELETESHADER, glDeleteShader); \ func(GLDELETEPROGRAM, glDeleteProgram); \ \ + func(GLUNIFORM1I, glUniform1i); \ func(GLUNIFORM1UI, glUniform1ui); \ func(GLUNIFORM4UI, glUniform4ui); \ func(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); \ + func(GLGETUNIFORMLOCATION, glGetUniformLocation); \ + func(GLGETUNIFORMBLOCKINDEX, glGetUniformBlockIndex); \ \ func(GLACTIVETEXTURE, glActiveTexture); \ func(GLBINDIMAGETEXTURE, glBindImageTexture); \ diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 9cdb610..f4a1fdb 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -166,13 +166,21 @@ bool GLDrawing_Init() if (!OpenGL_BuildShaderProgram(kScreenVS, kScreenFS, GL_ScreenShader, "ScreenShader")) return false; + GLuint uni_id; memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig)); glGenBuffers(1, &GL_ShaderConfigUBO); glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO); glBufferData(GL_UNIFORM_BUFFER, sizeof(GL_ShaderConfig), &GL_ShaderConfig, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, 16, GL_ShaderConfigUBO); - glUniformBlockBinding(GL_ScreenShader[2], 0, 16); + uni_id = glGetUniformBlockIndex(GL_ScreenShader[2], "uConfig"); + glUniformBlockBinding(GL_ScreenShader[2], uni_id, 16); + + glUseProgram(GL_ScreenShader[2]); + uni_id = glGetUniformLocation(GL_ScreenShader[2], "ScreenTex"); + glUniform1i(uni_id, 0); + uni_id = glGetUniformLocation(GL_ScreenShader[2], "_3DTex"); + glUniform1i(uni_id, 1); glGenBuffers(1, &GL_ScreenVertexBufferID); glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); @@ -185,6 +193,10 @@ bool GLDrawing_Init() glEnableVertexAttribArray(1); // texcoord glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(2*4)); + glBindAttribLocation(GL_ScreenShader[2], 0, "vPosition"); + glBindAttribLocation(GL_ScreenShader[2], 1, "vTexcoord"); + glBindFragDataLocation(GL_ScreenShader[2], 0, "oColor"); + // TODO: consider reallocating the texture when changing screen sizes glGenTextures(1, &GL_ScreenTexture); glActiveTexture(GL_TEXTURE0); diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h index 85ff794..9ed3cc0 100644 --- a/src/libui_sdl/main_shaders.h +++ b/src/libui_sdl/main_shaders.h @@ -19,17 +19,17 @@ #ifndef MAIN_SHADERS_H #define MAIN_SHADERS_H -const char* kScreenVS = R"(#version 420 +const char* kScreenVS = R"(#version 140 -layout(std140, binding=0) uniform uConfig +layout(std140) uniform uConfig { vec2 uScreenSize; uint u3DScale; uint uFilterMode; }; -layout(location=0) in vec2 vPosition; -layout(location=1) in vec2 vTexcoord; +in vec2 vPosition; +in vec2 vTexcoord; smooth out vec2 fTexcoord; @@ -46,51 +46,51 @@ void main() } )"; -const char* kScreenFS = R"(#version 420 +const char* kScreenFS = R"(#version 140 -layout(std140, binding=0) uniform uConfig +layout(std140) uniform uConfig { vec2 uScreenSize; uint u3DScale; uint uFilterMode; }; -layout(binding=0) uniform usampler2D ScreenTex; -layout(binding=1) uniform sampler2D _3DTex; +uniform usampler2D ScreenTex; +uniform sampler2D _3DTex; smooth in vec2 fTexcoord; -layout(location=0) out vec4 oColor; +out vec4 oColor; void main() { - uvec4 pixel = texelFetch(ScreenTex, ivec2(fTexcoord), 0); + ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); // bit0-13: BLDCNT // bit14-15: DISPCNT display mode // bit16-20: EVA // bit21-25: EVB // bit26-30: EVY - uvec4 ctl = texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0); - uint dispmode = (ctl.g >> 6) & 0x3; + ivec4 ctl = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); + int dispmode = (ctl.g >> 6) & 0x3; if (dispmode == 1) { - uint eva = ctl.b & 0x1F; - uint evb = (ctl.b >> 5) | ((ctl.a & 0x03) << 3); - uint evy = ctl.a >> 2; + int eva = ctl.b & 0x1F; + int evb = (ctl.b >> 5) | ((ctl.a & 0x03) << 3); + int evy = ctl.a >> 2; - uvec4 top = pixel; - uvec4 mid = texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0); - uvec4 bot = texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0); + ivec4 top = pixel; + ivec4 mid = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0)); + ivec4 bot = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0)); - uint winmask = top.b >> 7; + int winmask = top.b >> 7; if ((top.a & 0x40) != 0) { float xpos = top.r + fract(fTexcoord.x); float ypos = mod(fTexcoord.y, 768); - uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra * vec4(63,63,63,31)); if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } @@ -100,7 +100,7 @@ void main() { float xpos = mid.r + fract(fTexcoord.x); float ypos = mod(fTexcoord.y, 768); - uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra * vec4(63,63,63,31)); if (_3dpix.a > 0) { bot = _3dpix; bot.a |= 0x40; } @@ -115,13 +115,13 @@ void main() top.b &= 0x3F; bot.b &= 0x3F; - uint target2; + int target2; if ((bot.a & 0x80) != 0) target2 = 0x10; else if ((bot.a & 0x40) != 0) target2 = 0x01; else target2 = bot.a; bool t2pass = ((ctl.g & target2) != 0); - uint coloreffect = 0; + int coloreffect = 0; if ((top.a & 0x80) != 0 && t2pass) { @@ -150,7 +150,7 @@ void main() if ((ctl.r & top.a) != 0 && winmask != 0) { - uint effect = ctl.r >> 6; + int effect = ctl.r >> 6; if ((effect != 1) || t2pass) coloreffect = effect; } } @@ -167,7 +167,7 @@ void main() else if (coloreffect == 2) { pixel = top; - pixel += ((uvec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; + pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; } else if (coloreffect == 3) { @@ -177,7 +177,7 @@ void main() else { pixel = ((top * eva) + (bot * evb)) >> 5; - if (eva <= 16) pixel += uvec4(1,1,1,0); + if (eva <= 16) pixel += ivec4(1,1,1,0); pixel = min(pixel, 0x3F); } } @@ -188,7 +188,6 @@ void main() // TODO: filters oColor = vec4(vec3(pixel.rgb) / 255.0, 1.0); - //oColor = texelFetch(_3DTex, ivec2(fTexcoord*4), 0).bgra; } )"; -- cgit v1.2.3 From 139c2d24ec253f1688b12b667ce6a090a43bbd57 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 20 May 2019 22:24:11 +0200 Subject: burp --- src/OpenGLSupport.h | 1 + src/libui_sdl/main.cpp | 58 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 11 deletions(-) (limited to 'src/OpenGLSupport.h') diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 793205b..659d682 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -52,6 +52,7 @@ func(GLBINDFRAMEBUFFER, glBindFramebuffer); \ func(GLFRAMEBUFFERTEXTURE, glFramebufferTexture); \ func(GLBLITFRAMEBUFFER, glBlitFramebuffer); \ + func(GLCHECKFRAMEBUFFERSTATUS, glCheckFramebufferStatus); \ \ func(GLGENBUFFERS, glGenBuffers); \ func(GLDELETEBUFFERS, glDeleteBuffers); \ diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 27f0369..c68f323 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -165,7 +165,7 @@ bool GLDrawing_Init() 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)); @@ -208,7 +208,7 @@ bool GLDrawing_Init() 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; } @@ -357,7 +357,7 @@ void GLDrawing_DrawScreen() OpenGL_UseShaderProgram(GL_ScreenShader); glBindFramebuffer(GL_FRAMEBUFFER, 0); - glClearColor(0, 0, 0, 1); + glClearColor(0, 1, 0, 1); glClear(GL_COLOR_BUFFER_BIT); int frontbuf = GPU::FrontBuffer; @@ -689,8 +689,6 @@ int EmuThreadFunc(void* burp) { EmuStatus = 1; - uiGLMakeContextCurrent(GLContext); - SDL_JoystickUpdate(); if (Joystick) @@ -772,6 +770,8 @@ int EmuThreadFunc(void* burp) // microphone input FeedMicInput(); + uiGLMakeContextCurrent(GLContext); + // auto screen layout { MainScreenPos[2] = MainScreenPos[1]; @@ -819,9 +819,7 @@ int EmuThreadFunc(void* burp) //uiGLSwapBuffers(GLContext); // framerate limiter based off SDL2_gfx - float framerate; - if (nlines == 263) framerate = 1000.0f / 60.0f; - else framerate = ((1000.0f * nlines) / 263.0f) / 60.0f; + float framerate = (1000.0f * nlines) / (60.0f * 263.0f); fpslimitcount++; u32 curtick = SDL_GetTicks(); @@ -868,6 +866,8 @@ int EmuThreadFunc(void* burp) if (EmuRunning == 2) { + uiGLMakeContextCurrent(GLContext); + //uiAreaQueueRedrawAll(MainDrawArea); //uiGLSwapBuffers(GLContext); GLDrawing_DrawScreen(); @@ -1792,10 +1792,46 @@ void OnOpenHotkeyConfig(uiMenuItem* item, uiWindow* window, void* blarg) { DlgInputConfig::Open(1); } - +uiAreaHandler eeareahandler; void OnOpenVideoSettings(uiMenuItem* item, uiWindow* window, void* blarg) { - DlgVideoSettings::Open(); + //DlgVideoSettings::Open(); + + int oldstatus = EmuRunning; + EmuRunning = 3; + while (EmuStatus != 3); + + uiGLMakeContextCurrent(GLContext); + GPU3D::GLRenderer::DeInit(); + GLDrawing_DeInit(); + uiGLMakeContextCurrent(NULL); + uiGLFreeContext(GLContext); + + uiWindowSetChild(MainWindow, NULL); + uiControlDestroy(uiControl(MainDrawArea)); + + + eeareahandler.Draw = OnAreaDraw; + eeareahandler.MouseEvent = OnAreaMouseEvent; + eeareahandler.MouseCrossed = OnAreaMouseCrossed; + eeareahandler.DragBroken = OnAreaDragBroken; + eeareahandler.KeyEvent = OnAreaKeyEvent; + eeareahandler.Resize = OnAreaResize; + + MainDrawArea = uiNewArea(&eeareahandler, 1); + uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); + uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); + uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); + //uiControlShow(uiControl(MainDrawArea)); + GLContext = uiGLNewContext(uiControl(MainDrawArea), 3, 1); + + uiGLMakeContextCurrent(GLContext); + GLDrawing_Init(); + GPU3D::GLRenderer::Init(); + GPU3D::GLRenderer::SetDisplaySettings(1, true); + uiGLMakeContextCurrent(NULL); + + EmuRunning = oldstatus; } void OnOpenAudioSettings(uiMenuItem* item, uiWindow* window, void* blarg) @@ -2347,7 +2383,7 @@ int main(int argc, char** argv) OnSetScreenRotation(MenuItem_ScreenRot[ScreenRotation], MainWindow, (void*)&kScreenRot[ScreenRotation]); // TODO: fail gracefully, support older OpenGL, etc - GLContext = uiGLNewContext(uiControl(MainDrawArea), 4, 3); // haw haw haw + GLContext = uiGLNewContext(uiControl(MainDrawArea), 3, 1); // haw haw haw uiGLMakeContextCurrent(GLContext); void* testor = uiGLGetProcAddress("glUseProgram"); -- 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/OpenGLSupport.h') 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 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/OpenGLSupport.h') 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 99dbbb0b0464d91ed07ffd67c0b6ef83bc6a293e Mon Sep 17 00:00:00 2001 From: StapleButter Date: Sat, 25 May 2019 22:23:43 +0200 Subject: gfghfshdf --- src/OpenGLSupport.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/OpenGLSupport.h') diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 1ae0a35..3f21a4c 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -46,7 +46,22 @@ // if you need more OpenGL functions, add them to the macronator here // TODO: handle conditionally loading certain functions for different GL versions +#ifdef GL_VERSION_1_3 + +#define DO_PROCLIST_1_3(func) + +#else + +#define DO_PROCLIST_1_3(func) \ + func(GLACTIVETEXTURE, glActiveTexture); \ + func(GLBLENDCOLOR, glBlendColor); \ + +#endif + + #define DO_PROCLIST(func) \ + DO_PROCLIST_1_3(func) \ + \ func(GLGENFRAMEBUFFERS, glGenFramebuffers); \ func(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers); \ func(GLBINDFRAMEBUFFER, glBindFramebuffer); \ @@ -95,14 +110,12 @@ func(GLGETUNIFORMLOCATION, glGetUniformLocation); \ func(GLGETUNIFORMBLOCKINDEX, glGetUniformBlockIndex); \ \ - func(GLACTIVETEXTURE, glActiveTexture); \ func(GLBINDIMAGETEXTURE, glBindImageTexture); \ \ func(GLDRAWBUFFERS, glDrawBuffers); \ \ func(GLBLENDFUNCSEPARATE, glBlendFuncSeparate); \ func(GLBLENDEQUATIONSEPARATE, glBlendEquationSeparate); \ - func(GLBLENDCOLOR, glBlendColor); \ \ func(GLCOLORMASKI, glColorMaski); \ \ -- cgit v1.2.3 From 891ab9fd3c91042d5097f38107cccfb47511e5e5 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Tue, 28 May 2019 19:48:59 +0200 Subject: Linux: start getting somewhere with the whole OpenGL shito --- CMakeLists.txt | 5 +- src/CMakeLists.txt | 7 +- src/OpenGLSupport.cpp | 1 - src/OpenGLSupport.h | 1 + src/libui_sdl/CMakeLists.txt | 2 +- src/libui_sdl/libui/ui.h | 2 + src/libui_sdl/libui/unix/area.c | 83 ++++++--- src/libui_sdl/libui/unix/gl.c | 391 +++++++++++++++++++++++++++++++++++++++- src/libui_sdl/main.cpp | 46 +++-- 9 files changed, 489 insertions(+), 49 deletions(-) (limited to 'src/OpenGLSupport.h') diff --git a/CMakeLists.txt b/CMakeLists.txt index 9aa96ad..c127af5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,9 +21,12 @@ else() endif() if(ENABLE_LTO) - add_compile_options(-flto) + add_compile_options(-O2 -flto) endif() +add_compile_options(-fno-pic) +add_link_options(-no-pie) + option(BUILD_LIBUI "Build libui frontend" ON) option(BUILD_SDL "Build SDL2 frontend" OFF) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 702edf5..d096c02 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,22 +13,21 @@ add_library(core STATIC GPU.cpp GPU2D.cpp GPU3D.cpp + GPU3D_OpenGL.cpp GPU3D_Soft.cpp NDS.cpp NDSCart.cpp + OpenGLSupport.cpp RTC.cpp Savestate.cpp SPI.cpp SPU.cpp Wifi.cpp WifiAP.cpp - # opengl backend stuff - GPU3D_OpenGL.cpp - OpenGLSupport.cpp ) if (WIN32) target_link_libraries(core ole32 comctl32 ws2_32 opengl32) else() - target_link_libraries(core OpenGL) + target_link_libraries(core GL) endif() diff --git a/src/OpenGLSupport.cpp b/src/OpenGLSupport.cpp index bb9e180..11fd629 100644 --- a/src/OpenGLSupport.cpp +++ b/src/OpenGLSupport.cpp @@ -18,7 +18,6 @@ #include "OpenGLSupport.h" -#include DO_PROCLIST(DECLPROC); diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 3f21a4c..239ae95 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -20,6 +20,7 @@ #define OPENGLSUPPORT_H #include +#include #include #include diff --git a/src/libui_sdl/CMakeLists.txt b/src/libui_sdl/CMakeLists.txt index 0b7545b..61e0981 100644 --- a/src/libui_sdl/CMakeLists.txt +++ b/src/libui_sdl/CMakeLists.txt @@ -47,7 +47,7 @@ if (UNIX) --generate-header "${CMAKE_SOURCE_DIR}/melon_grc.xml") if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - target_link_libraries(melonDS dl) + target_link_libraries(melonDS dl X11) endif () target_sources(melonDS PUBLIC melon_grc.c) diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h index d2e9960..0c89d90 100644 --- a/src/libui_sdl/libui/ui.h +++ b/src/libui_sdl/libui/ui.h @@ -615,6 +615,8 @@ _UI_EXTERN uiGLContext *uiAreaGetGLContext(uiArea* a); _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx); _UI_EXTERN unsigned int uiGLGetVersion(uiGLContext* ctx); _UI_EXTERN void *uiGLGetProcAddress(const char* proc); +_UI_EXTERN int uiGLGetFramebuffer(uiGLContext* ctx); +_UI_EXTERN float uiGLGetFramebufferScale(uiGLContext* ctx); _UI_EXTERN void uiGLSwapBuffers(uiGLContext* ctx); diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c index e518ae5..bf92ddf 100644 --- a/src/libui_sdl/libui/unix/area.c +++ b/src/libui_sdl/libui/unix/area.c @@ -28,6 +28,8 @@ struct areaWidgetClass { GtkDrawingAreaClass parent_class; }; +typedef struct uiGLContext uiGLContext; + struct uiArea { uiUnixControl c; GtkWidget *widget; // either swidget or areaWidget depending on whether it is scrolling @@ -41,7 +43,8 @@ struct uiArea { GtkGLArea *glArea; areaWidget *area; - GdkGLContext *glContext; + gboolean opengl; + uiGLContext *glContext; int bgR, bgG, bgB; @@ -125,6 +128,8 @@ static void loadAreaSize(uiArea *a, double *width, double *height) } } +void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx); + static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) { areaWidget *aw = areaWidget(w); @@ -136,21 +141,28 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) loadAreaSize(a, &(dp.AreaWidth), &(dp.AreaHeight)); - cairo_clip_extents(cr, &clipX0, &clipY0, &clipX1, &clipY1); - dp.ClipX = clipX0; - dp.ClipY = clipY0; - dp.ClipWidth = clipX1 - clipX0; - dp.ClipHeight = clipY1 - clipY0; - - if (a->bgR != -1) + if (!a->opengl) + { + cairo_clip_extents(cr, &clipX0, &clipY0, &clipX1, &clipY1); + dp.ClipX = clipX0; + dp.ClipY = clipY0; + dp.ClipWidth = clipX1 - clipX0; + dp.ClipHeight = clipY1 - clipY0; + + if (a->bgR != -1) + { + cairo_set_source_rgb(cr, a->bgR/255.0, a->bgG/255.0, a->bgB/255.0); + cairo_paint(cr); + } + + // no need to save or restore the graphics state to reset transformations; GTK+ does that for us + (*(a->ah->Draw))(a->ah, a, &dp); + } + else { - cairo_set_source_rgb(cr, a->bgR/255.0, a->bgG/255.0, a->bgB/255.0); - cairo_paint(cr); + areaDrawGL(w, &dp, cr, a->glContext); } - // no need to save or restore the graphics state to reset transformations; GTK+ does that for us - (*(a->ah->Draw))(a->ah, a, &dp); - freeContext(dp.Context); return FALSE; } @@ -714,11 +726,12 @@ void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge) uiArea *uiNewArea(uiAreaHandler *ah) { uiArea *a; - +printf("create regular area\n"); uiUnixNewControl(uiArea, a); a->ah = ah; a->scrolling = FALSE; + a->opengl = FALSE; a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType, "libui-area", a, @@ -733,35 +746,54 @@ uiArea *uiNewArea(uiAreaHandler *ah) return a; } +uiGLContext* FARTOMATIC(int major, int minor); +void databotte(GtkWidget* gla, uiGLContext* ctx); +void majoricc(GtkWidget* widget, gpointer data) +{ + printf("ACTUALLY CREATE CONTEXT\n"); + + uiArea* a = (uiArea*)data; + uiGLContext* ctx = a->glContext; + + databotte(a->widget, ctx); +} + uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions) { uiArea *a; - +printf("create glarea\n"); uiUnixNewControl(uiArea, a); a->ah = ah; a->scrolling = FALSE; + a->opengl = TRUE; - GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new(); - GdkGLContext* ctx = NULL; - + //GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new(); + uiGLContext* ctx = NULL; +printf("create sdfsf\n"); for (int i = 0; req_versions[i] && !ctx; i++) { int major = uiGLVerMajor(req_versions[i]); int minor = uiGLVerMinor(req_versions[i]); - gtk_gl_area_set_required_version(gla, major, minor); - ctx = createGLContext(gla, major, minor); + //gtk_gl_area_set_required_version(gla, major, minor); + //ctx = createGLContext(gla, major, minor); + ctx = FARTOMATIC(major, minor); } - +printf("create jfghjjgh: %p\n", ctx); a->glContext = ctx; - a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType, "libui-area", - a, NULL)); - a->glArea = gla; + //a->areaWidget = GTK_WIDGET(gla); + //a->glArea = gla; + a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType, + "libui-area", a, + NULL)); a->area = areaWidget(a->areaWidget); a->widget = a->areaWidget; + + g_signal_connect(a->widget, "realize", G_CALLBACK(majoricc), a); uiAreaSetBackgroundColor(a, -1, -1, -1); - + //printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla))); +printf("create qssssq\n"); return a; } @@ -781,6 +813,7 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height) a->scrolling = TRUE; a->scrollWidth = width; a->scrollHeight = height; + a->opengl = FALSE; a->swidget = gtk_scrolled_window_new(NULL, NULL); a->scontainer = GTK_CONTAINER(a->swidget); diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c index da41437..3504d3a 100644 --- a/src/libui_sdl/libui/unix/gl.c +++ b/src/libui_sdl/libui/unix/gl.c @@ -1,6 +1,12 @@ // 26 may 2019 #include "uipriv_unix.h" +#include +#include +#include + +extern GThread* gtkthread; + /* *(melonDS:17013): Gtk-CRITICAL **: 00:28:09.095: gtk_gl_area_set_required_version: assertion 'GTK_IS_GL_AREA (area)' failed @@ -9,32 +15,409 @@ struct uiGLContext { GtkGLArea *gla; + GtkWidget* widget; + GdkWindow* window; GdkGLContext *gctx; + + Display* xdisp; + GLXPixmap glxpm; + GLXContext glxctx; int vermaj, vermin; + + int width, height; + int scale; + GLuint renderbuffer[2]; + GLuint framebuffer; }; +static PFNGLGENRENDERBUFFERSPROC _glGenRenderbuffers; +static PFNGLDELETERENDERBUFFERSPROC _glDeleteRenderbuffers; +static PFNGLBINDRENDERBUFFERPROC _glBindRenderbuffer; +static PFNGLRENDERBUFFERSTORAGEPROC _glRenderbufferStorage; +static PFNGLGETRENDERBUFFERPARAMETERIVPROC _glGetRenderbufferParameteriv; + +static PFNGLGENRENDERBUFFERSPROC _glGenFramebuffers; +static PFNGLDELETERENDERBUFFERSPROC _glDeleteFramebuffers; +static PFNGLBINDRENDERBUFFERPROC _glBindFramebuffer; +static PFNGLFRAMEBUFFERTEXTUREPROC _glFramebufferTexture; +static PFNGLFRAMEBUFFERRENDERBUFFERPROC _glFramebufferRenderbuffer; +static PFNGLCHECKFRAMEBUFFERSTATUSPROC _glCheckFramebufferStatus; + +static int _procsLoaded = 0; + +static void _loadGLProcs() +{ + if (_procsLoaded) return; + + _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)uiGLGetProcAddress("glGenRenderbuffers"); + _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)uiGLGetProcAddress("glDeleteRenderbuffers"); + _glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)uiGLGetProcAddress("glBindRenderbuffer"); + _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)uiGLGetProcAddress("glRenderbufferStorage"); + _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)uiGLGetProcAddress("glGetRenderbufferParameteriv"); + + _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)uiGLGetProcAddress("glGenFramebuffers"); + _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)uiGLGetProcAddress("glDeleteFramebuffers"); + _glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)uiGLGetProcAddress("glBindFramebuffer"); + _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)uiGLGetProcAddress("glFramebufferTexture"); + _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)uiGLGetProcAddress("glFramebufferRenderbuffer"); + _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)uiGLGetProcAddress("glCheckFramebufferStatus"); + + _procsLoaded = 1; +} + +Display* derp; + uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min) { - uiGLContext *ret = uiAlloc(sizeof(uiGLContext), "uiGLContext"); + printf("barp\n"); + uiGLContext *ret = uiNew(uiGLContext);//uiAlloc(sizeof(uiGLContext), "uiGLContext"); + + // herp + ret->gla = gla; + ret->gctx = NULL; + //while (!ret->gctx) + /*{ + gtk_widget_realize(GTK_WIDGET(gla)); + printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla))); ret->gla = gla; ret->gctx = gtk_gl_area_get_context(gla); + printf("context: %p\n", ret->gctx); + }*/ + + + + /* + GtkAllocation allocation; + GdkWindow *window; + Display *display; + int id; + + window = gtk_widget_get_window(widget); + display = gdk_x11_display_get_xdisplay(gdk_window_get_display(window)); + id = gdk_x11_window_get_xid(window); + + if (glXMakeCurrent(display, id, context) == TRUE) {*/ + + + /*GdkWindow* window; + Display* disp; + + window = gtk_widget_get_window(GTK_WIDGET(gla)); + display = */ + + + ret->vermaj = maj; ret->vermin = min; return ret; } +static void areaAllocRenderbuffer(uiGLContext* glctx); + +void databotte(GtkWidget* widget, uiGLContext* ctx) +{ + /*printf("is area realized: %d\n", gtk_widget_get_realized(GTK_WIDGET(gla))); + ctx->gctx = gtk_gl_area_get_context(gla); + printf("context: %p\n", ctx->gctx);*/ + + printf("DATABOTTE\n"); + + GdkWindow* gdkwin = gtk_widget_get_window(widget); + printf("window=%p\n", gdkwin); + + GError* err = NULL; + GdkGLContext* glctx = gdk_window_create_gl_context(gdkwin, &err); + if (err != NULL) + { + printf("CONTEXT SHAT ITSELF\n"); + return; + } + + gdk_gl_context_set_use_es(glctx, FALSE); + gdk_gl_context_set_required_version(glctx, 3, 2); + + gdk_gl_context_realize(glctx, &err); + if (err != NULL) + { + printf("CONTEXT REALIZE SHAT ITSELF\n"); + return; + } + + GtkAllocation allocation; + gtk_widget_get_allocation(widget, &allocation); + int window_scale = gdk_window_get_scale_factor(gdkwin); + ctx->width = allocation.width; + ctx->height = allocation.height; + ctx->scale = window_scale; + + gdk_gl_context_make_current(glctx); + _loadGLProcs(); + areaAllocRenderbuffer(ctx); + + ctx->widget = widget; + ctx->window = gdkwin; + ctx->gctx = glctx; +} + +static void areaAllocRenderbuffer(uiGLContext* glctx) +{ + _glGenRenderbuffers(2, &glctx->renderbuffer[0]);printf("ylarg0 %04X, %d %d\n", glGetError(), glctx->width, glctx->height); + //glGenTextures(2, &glctx->renderbuffer[0]); + _glGenFramebuffers(1, &glctx->framebuffer);printf("ylarg1 %04X\n", glGetError()); + printf("FB %08X created under ctx %p (%p %p)\n", glctx?glctx->framebuffer: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); + + 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]);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]);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);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]);printf("ylarg3 %04X\n", glGetError()); + _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1]);printf("ylarg4 %04X\n", glGetError()); + //printf("ylarg: %08X, %04X, %08X %08X\n", glctx->framebuffer, glGetError(), glctx->renderbuffer[0], glctx->renderbuffer[1]); + + if(_glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + int alpha_size; + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0]); + _glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_ALPHA_SIZE, &alpha_size); + printf("FRAMEBUFFER GOOD. ALPHA SIZE IS %d\n", alpha_size); +} + +static void areaRellocRenderbuffer(uiGLContext* glctx) +{ + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0]); + _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale); + _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1]); + _glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale); +} + +void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx) +{ + int window_scale = gdk_window_get_scale_factor(glctx->window); + + if (glctx->width != dp->AreaWidth || glctx->height != dp->AreaHeight || glctx->scale != window_scale) + { + glctx->width = dp->AreaWidth; + glctx->height = dp->AreaHeight; + glctx->scale = window_scale; + areaRellocRenderbuffer(glctx); + } + + gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), + glctx->renderbuffer[0], GL_RENDERBUFFER, + 1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale); +} + +uiGLContext* FARTOMATIC(int major, int minor) +{ + uiGLContext *_ret = uiNew(uiGLContext); + _ret->vermaj = major; + _ret->vermin = minor; + _ret->width = -1; + _ret->height = -1; + _ret->renderbuffer[0] = 0; + _ret->renderbuffer[1] = 0; + _ret->framebuffer = 0; + + return _ret; + + Display* disp; + XVisualInfo* vizir; + GLXFBConfig *cfg; + Pixmap pm; + GLXPixmap glxpm; + GLXContext ctx; + + disp = XOpenDisplay(NULL); + derp = disp; + + int kaa, baa; + glXQueryVersion(disp, &kaa, &baa); + printf("GL VERSION: %d.%d\n", kaa, baa); + + const int sbAttrib[] = { GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + None }; + const int dbAttrib[] = { GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + None }; + + int scrnum = DefaultScreen( disp ); + Window root = RootWindow( disp, scrnum ); + + vizir = glXChooseVisual( disp, scrnum, (int *) sbAttrib ); + if (!vizir) { + vizir = glXChooseVisual( disp, scrnum, (int *) dbAttrib ); + if (!vizir) { + printf("Error: couldn't get an RGB visual\n"); + return NULL; + } + } + + const int fb_attr[] = { + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, + GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, + GLX_DOUBLEBUFFER, True, + GLX_X_RENDERABLE, True, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_ALPHA_SIZE, 8, + GLX_DEPTH_SIZE, 24, + GLX_STENCIL_SIZE, 8, + None + }; + int configs; + cfg = glXChooseFBConfig(disp, scrnum, (int *)&fb_attr, &configs); + + if (!cfg) + { + printf("NO GOOD FBCONFIG\n"); + return NULL; + } + + /*ctx = glXCreateContext( disp, vizir, NULL, True ); + if (!ctx) + { + printf("Error: glXCreateContext failed\n"); + return NULL; + }*/ + + PFNGLXCREATECONTEXTATTRIBSARBPROC createctx; + createctx = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB("glXCreateContextAttribsARB"); + if (!createctx) + { + printf("bad shito\n"); + return NULL; + } + + const int ctx_attr[] = + { + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + GLX_CONTEXT_MAJOR_VERSION_ARB, 3,//major, + GLX_CONTEXT_MINOR_VERSION_ARB, 2,//minor, + None + }; + + ctx = glXCreateContextAttribsARB(disp, cfg[0], 0, True, ctx_attr); + if (!ctx) + { + printf("FAILED TO CREATE FANCYPANTS GL CONTEXT\n"); + return NULL; + } + + //printf("CONTEXT GOOD. Direct rendering: %s\n", glXIsDirect(disp, ctx) ? "Yes" : "No"); + + printf("blorp: %d\n", vizir->depth); + pm = XCreatePixmap(disp, root, 256, 384, vizir->depth); + if (!pm) printf("PIXMAP SHAT ITSELF\n"); + else printf("PIXMAP GOOD\n"); + + glxpm = glXCreateGLXPixmap(disp, vizir, pm); + if (!glxpm) printf("GLXPIXMAP SHAT ITSELF\n"); + else printf("GLXPIXMAP GOOD\n"); + + uiGLContext *ret = uiNew(uiGLContext); + printf("CREATE CTX: %p, %p\n", ret, g_thread_self()); + ret->xdisp = disp; + ret->glxpm = glxpm; + ret->glxctx = ctx; + + return ret; +} + +int uiGLGetFramebuffer(uiGLContext* ctx) +{ + return ctx->framebuffer; +} + +float uiGLGetFramebufferScale(uiGLContext* ctx) +{ + return (float)ctx->scale; +} + void uiGLSwapBuffers(uiGLContext* ctx) { if (!ctx) return; - gtk_gl_area_attach_buffers(ctx->gla); + //gtk_gl_area_attach_buffers(ctx->gla); +} + +static volatile int _ctxset_done; + +gboolean _threadsafe_ctxset(gpointer data) +{ + uiGLContext* ctx = (uiGLContext*)data; + gtk_gl_area_make_current(ctx->gla); + _ctxset_done = 1; + return FALSE; } void uiGLMakeContextCurrent(uiGLContext* ctx) { - if (!ctx) return; - gtk_gl_area_make_current(ctx->gla); + //if (!ctx) return; + /*if (g_thread_self() != gtkthread) + { + _ctxset_done = 0; + g_idle_add(_threadsafe_ctxset, ctx); + while (!_ctxset_done); + } + else*/ + //gtk_gl_area_make_current(ctx->gla); + /*printf("MAKE CONTEXT CURRENT %p, %p\n", ctx, g_thread_self()); + if (!ctx) + { + // BLERUGEHZFZF + glXMakeCurrent(derp, None, NULL); + return; + } + Bool ret = True; + if (glXGetCurrentContext() != ctx->glxctx) + {printf("DZJSKFLD\n"); + ret = glXMakeCurrent(ctx->xdisp, ctx->glxpm, ctx->glxctx); + //glXMakeContextCurrent(ctx->xdisp, ctx->glxpm, ctx->glxpm, ctx->glxctx); + } + printf("WE MAED IT CURRENT: %d\n", ret);*/ + + printf("[%p] MAKE CONTEXT CURRENT %p, %p\n", g_thread_self(), ctx, ctx?ctx->gctx:NULL); + if (!ctx) + { + gdk_gl_context_clear_current(); + return; + } + //gtk_gl_area_make_current(ctx->gla); + gdk_gl_context_make_current(ctx->gctx); + GdkGLContext* burp = gdk_gl_context_get_current(); + //gtk_gl_area_attach_buffers(ctx->gla); + //printf("burp = %p / %p\n", burp, ctx->gctx); } void *uiGLGetProcAddress(const char* proc) { +printf("get: %s - ", proc); +void* a = dlsym(NULL, proc); +void* b = glXGetProcAddress(proc); +void* c = glXGetProcAddressARB(proc); +printf("%p / %p / %p\n", a, b, c); +return c; // this *will* break for older systems that don't have libglvnd! // TODO: use a real solution return dlsym(NULL /* RTLD_DEFAULT */, proc); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 0c7aacd..e2686f9 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -194,9 +194,16 @@ bool GLScreen_InitShader(GLuint* shader, const char* fs) } bool GLScreen_Init() -{ +{printf("BEGINNING GL SHITO\n"); 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); + printf("OpenGL: version: %s\n", version); if (!GLScreen_InitShader(GL_ScreenShader, kScreenFS)) return false; @@ -204,7 +211,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); @@ -213,14 +220,14 @@ bool GLScreen_Init() 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); @@ -231,7 +238,7 @@ bool GLScreen_Init() 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; } @@ -248,6 +255,8 @@ void GLScreen_DeInit() void GLScreen_DrawScreen() { + float scale = uiGLGetFramebufferScale(GLContext); + if (GL_ScreenSizeDirty) { GL_ScreenSizeDirty = false; @@ -370,23 +379,26 @@ void GLScreen_DrawScreen() glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GL_ScreenVertices), GL_ScreenVertices); } - + printf("rarp4 %04X\n", glGetError()); glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +printf("rarp2 %04X\n", glGetError()); - glViewport(0, 0, WindowWidth, WindowHeight); + glViewport(0, 0, WindowWidth*scale, WindowHeight*scale); + printf("draw screen: viewport=%d/%d\n", WindowWidth, WindowHeight); if (GPU3D::Renderer == 0) OpenGL_UseShaderProgram(GL_ScreenShader); else OpenGL_UseShaderProgram(GL_ScreenShaderAccel); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glClearColor(0, 0, 0, 1); +printf("rarp3 %04X\n", glGetError()); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, uiGLGetFramebuffer(GLContext)); + printf("rarp8 %04X\n", glGetError()); + glClearColor(0, 0, 1, 1); glClear(GL_COLOR_BUFFER_BIT); - +printf("rarp5 %04X\n", glGetError()); int frontbuf = GPU::FrontBuffer; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); @@ -412,15 +424,21 @@ void GLScreen_DrawScreen() glActiveTexture(GL_TEXTURE1); if (GPU3D::Renderer != 0) GPU3D::GLRenderer::SetupAccelFrame(); - +printf("rarp6 %04X\n", glGetError()); glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); glBindVertexArray(GL_ScreenVertexArrayID); glDrawArrays(GL_TRIANGLES, 0, 4*3); - +printf("rarp7 %04X\n", glGetError()); glFlush(); uiGLSwapBuffers(GLContext); } +void norp(void* data) +{ + uiGLMakeContextCurrent(GLContext); + GLScreen_DrawScreen(); +} + void MicLoadWav(char* name) { SDL_AudioSpec format; @@ -901,6 +919,8 @@ int EmuThreadFunc(void* burp) { uiGLMakeContextCurrent(GLContext); GLScreen_DrawScreen(); + //uiGLMakeContextCurrent(NULL); + //uiQueueMain(norp, NULL); } uiAreaQueueRedrawAll(MainDrawArea); } -- cgit v1.2.3 From 65ccf2a71762433b0674b2b42e5a70f90d9e2c5a Mon Sep 17 00:00:00 2001 From: StapleButter Date: Fri, 31 May 2019 19:29:48 +0200 Subject: blarg --- src/OpenGLSupport.h | 2 +- src/libui_sdl/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/OpenGLSupport.h') diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 239ae95..31a0dc0 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -47,7 +47,7 @@ // if you need more OpenGL functions, add them to the macronator here // TODO: handle conditionally loading certain functions for different GL versions -#ifdef GL_VERSION_1_3 +#ifndef __WIN32__ #define DO_PROCLIST_1_3(func) diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index c351a04..33a35d0 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -427,7 +427,7 @@ void GLScreen_DrawScreen() glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); glBindVertexArray(GL_ScreenVertexArrayID); glDrawArrays(GL_TRIANGLES, 0, 4*3); - } + } glFlush(); uiGLSwapBuffers(GLContext); -- 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/OpenGLSupport.h') 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 From 43e3e53afc4a8777592333717cfc4f4b304051eb Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 2 Jun 2019 21:45:36 +0200 Subject: fix some shito --- src/OpenGLSupport.h | 2 -- src/libui_sdl/OSD.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src/OpenGLSupport.h') diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index a4d6124..6130c8e 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -120,8 +120,6 @@ \ func(GLCOLORMASKI, glColorMaski); \ \ - func(GLMEMORYBARRIER, glMemoryBarrier); \ - \ func(GLGETSTRINGI, glGetStringi); \ diff --git a/src/libui_sdl/OSD.cpp b/src/libui_sdl/OSD.cpp index 7e8c8f7..bce14c1 100644 --- a/src/libui_sdl/OSD.cpp +++ b/src/libui_sdl/OSD.cpp @@ -20,7 +20,7 @@ #include #include #include -#include "types.h" +#include "../types.h" #include "OSD.h" #include "libui/ui.h" -- cgit v1.2.3 From 2b3ca2089f7420bb938c6bdda67ed0f8c04e51d5 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 3 Jun 2019 16:45:55 +0200 Subject: take the OSD shito somewhere --- src/OpenGLSupport.h | 1 + src/libui_sdl/OSD.cpp | 136 +++++++++++++++++++++++++++++++------------ src/libui_sdl/main.cpp | 45 ++++++++++++-- src/libui_sdl/main_shaders.h | 51 +++++++++++++++- 4 files changed, 190 insertions(+), 43 deletions(-) (limited to 'src/OpenGLSupport.h') diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 6130c8e..fbc100c 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -106,6 +106,7 @@ \ func(GLUNIFORM1I, glUniform1i); \ func(GLUNIFORM1UI, glUniform1ui); \ + func(GLUNIFORM2I, glUniform2i); \ func(GLUNIFORM4UI, glUniform4ui); \ func(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); \ func(GLGETUNIFORMLOCATION, glGetUniformLocation); \ diff --git a/src/libui_sdl/OSD.cpp b/src/libui_sdl/OSD.cpp index a13ff44..851f9c5 100644 --- a/src/libui_sdl/OSD.cpp +++ b/src/libui_sdl/OSD.cpp @@ -35,7 +35,7 @@ namespace OSD const u32 kOSDMargin = 6; -typedef struct +struct Item { Uint32 Timestamp; char Text[256]; @@ -50,13 +50,45 @@ typedef struct bool GLTextureLoaded; GLuint GLTexture; -} Item; +}; -std::deque ItemQueue; +std::deque ItemQueue; + +GLint uOSDPos, uOSDSize; +GLuint OSDVertexArray; +GLuint OSDVertexBuffer; + +volatile bool Rendering; bool Init(bool opengl) { + if (opengl) + { + GLuint prog; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&prog); + uOSDPos = glGetUniformLocation(prog, "uOSDPos"); + uOSDSize = glGetUniformLocation(prog, "uOSDSize"); + + float vertices[6*2] = + { + 0, 0, + 1, 1, + 1, 0, + 0, 0, + 0, 1, + 1, 1 + }; + + glGenBuffers(1, &OSDVertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, OSDVertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glGenVertexArrays(1, &OSDVertexArray); + glBindVertexArray(OSDVertexArray); + glEnableVertexAttribArray(0); // position + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0)); + } + return true; } @@ -64,15 +96,13 @@ void DeInit(bool opengl) { for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) { - Item* item = *it; - - if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap); - if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture); - if (item->Bitmap) delete[] item->Bitmap; + Item& item = *it; - delete item; + if (item.DrawBitmapLoaded && item.DrawBitmap) uiDrawFreeBitmap(item.DrawBitmap); + if (item.GLTextureLoaded && opengl) glDeleteTextures(1, &item.GLTexture); + if (item.Bitmap) delete[] item.Bitmap; - ItemQueue.erase(it); + it = ItemQueue.erase(it); } } @@ -276,15 +306,17 @@ void RenderText(u32 color, const char* text, Item* item) void AddMessage(u32 color, const char* text) { - Item* item = new Item; + while (Rendering); + + Item item; - item->Timestamp = SDL_GetTicks(); - strncpy(item->Text, text, 255); item->Text[255] = '\0'; - item->Color = color; - item->Bitmap = NULL; + item.Timestamp = SDL_GetTicks(); + strncpy(item.Text, text, 255); item.Text[255] = '\0'; + item.Color = color; + item.Bitmap = NULL; - item->DrawBitmapLoaded = false; - item->GLTextureLoaded = false; + item.DrawBitmapLoaded = false; + item.GLTextureLoaded = false; ItemQueue.push_back(item); } @@ -293,7 +325,7 @@ void WindowResized(bool opengl) { /*for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) { - Item* item = *it; + Item& item = *it; if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap); //if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture); @@ -309,53 +341,83 @@ void WindowResized(bool opengl) void Update(bool opengl, uiAreaDrawParams* params) { + Rendering = true; + Uint32 tick_now = SDL_GetTicks(); Uint32 tick_min = tick_now - 2500; u32 y = kOSDMargin; + if (opengl) + { + glBindBuffer(GL_ARRAY_BUFFER, OSDVertexBuffer); + glBindVertexArray(OSDVertexArray); + + glActiveTexture(GL_TEXTURE0); + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) { - Item* item = *it; + Item& item = *it; - if (item->Timestamp < tick_min) + if (item.Timestamp < tick_min) { - if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap); - if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture); - if (item->Bitmap) delete[] item->Bitmap; - - delete item; + if (item.DrawBitmapLoaded && item.DrawBitmap) uiDrawFreeBitmap(item.DrawBitmap); + if (item.GLTextureLoaded && opengl) glDeleteTextures(1, &item.GLTexture); + if (item.Bitmap) delete[] item.Bitmap; - ItemQueue.erase(it); + it = ItemQueue.erase(it); continue; } - if (!item->Bitmap) + if (!item.Bitmap) { - RenderText(item->Color, item->Text, item); + RenderText(item.Color, item.Text, &item); } if (opengl) { - // + if (!item.GLTextureLoaded) + { + glGenTextures(1, &item.GLTexture); + glBindTexture(GL_TEXTURE_2D, item.GLTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, item.Width, item.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, item.Bitmap); + + item.GLTextureLoaded = true; + } + + glBindTexture(GL_TEXTURE_2D, item.GLTexture); + glUniform2i(uOSDPos, kOSDMargin, y); + glUniform2i(uOSDSize, item.Width, item.Height); + glDrawArrays(GL_TRIANGLES, 0, 2*3); } else { - if (!item->DrawBitmapLoaded) + if (!item.DrawBitmapLoaded) { - item->DrawBitmap = uiDrawNewBitmap(params->Context, item->Width, item->Height, 1); - uiDrawBitmapUpdate(item->DrawBitmap, item->Bitmap); - item->DrawBitmapLoaded = true; + item.DrawBitmap = uiDrawNewBitmap(params->Context, item.Width, item.Height, 1); + uiDrawBitmapUpdate(item.DrawBitmap, item.Bitmap); + + item.DrawBitmapLoaded = true; } - uiRect rc_src = {0, 0, item->Width, item->Height}; - uiRect rc_dst = {kOSDMargin, y, item->Width, item->Height}; + uiRect rc_src = {0, 0, item.Width, item.Height}; + uiRect rc_dst = {kOSDMargin, y, item.Width, item.Height}; - uiDrawBitmapDraw(params->Context, item->DrawBitmap, &rc_src, &rc_dst, 0); + uiDrawBitmapDraw(params->Context, item.DrawBitmap, &rc_src, &rc_dst, 0); } - y += item->Height; + y += item.Height; it++; } + + Rendering = false; } } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 5407403..073c8ac 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -112,6 +112,7 @@ uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; GLuint GL_ScreenShader[3]; GLuint GL_ScreenShaderAccel[3]; +GLuint GL_ScreenShaderOSD[3]; struct { float uScreenSize[2]; @@ -198,6 +199,29 @@ bool GLScreen_InitShader(GLuint* shader, const char* fs) return true; } +bool GLScreen_InitOSDShader(GLuint* shader) +{ + if (!OpenGL_BuildShaderProgram(kScreenVS_OSD, kScreenFS_OSD, shader, "ScreenShaderOSD")) + return false; + + glBindAttribLocation(shader[2], 0, "vPosition"); + glBindFragDataLocation(shader[2], 0, "oColor"); + + if (!OpenGL_LinkShaderProgram(shader)) + return false; + + GLuint uni_id; + + uni_id = glGetUniformBlockIndex(shader[2], "uConfig"); + glUniformBlockBinding(shader[2], uni_id, 16); + + glUseProgram(shader[2]); + uni_id = glGetUniformLocation(shader[2], "OSDTex"); + glUniform1i(uni_id, 0); + + return true; +} + bool GLScreen_Init() { // TODO: consider using epoxy? @@ -213,6 +237,8 @@ bool GLScreen_Init() return false; if (!GLScreen_InitShader(GL_ScreenShaderAccel, kScreenFS_Accel)) return false; + if (!GLScreen_InitOSDShader(GL_ScreenShaderOSD)) + return false; memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig)); @@ -255,6 +281,7 @@ void GLScreen_DeInit() OpenGL_DeleteShaderProgram(GL_ScreenShader); OpenGL_DeleteShaderProgram(GL_ScreenShaderAccel); + OpenGL_DeleteShaderProgram(GL_ScreenShaderOSD); } void GLScreen_DrawScreen() @@ -396,7 +423,7 @@ void GLScreen_DrawScreen() else OpenGL_UseShaderProgram(GL_ScreenShaderAccel); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, uiGLGetFramebuffer(GLContext)); + glBindFramebuffer(GL_FRAMEBUFFER, uiGLGetFramebuffer(GLContext)); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); @@ -434,6 +461,7 @@ void GLScreen_DrawScreen() glDrawArrays(GL_TRIANGLES, 0, 4*3); } + OpenGL_UseShaderProgram(GL_ScreenShaderOSD); OSD::Update(true, NULL); glFlush(); @@ -947,19 +975,21 @@ int EmuThreadFunc(void* burp) if (joybuttons) delete[] joybuttons; + if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); + NDS::DeInit(); Platform::LAN_DeInit(); if (Screen_UseGL) { - uiGLMakeContextCurrent(GLContext); OSD::DeInit(true); GLScreen_DeInit(); - uiGLMakeContextCurrent(NULL); } else OSD::DeInit(false); + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + return 44203; } @@ -1128,7 +1158,7 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt) MicCommand |= 1; if (evt->Scancode == 0x57) // F11 - OSD::AddMessage(0, "OSD test"); + OSD::AddMessage(0x00FFFF, "OSD test"); //NDS::debug(0); } @@ -2302,6 +2332,11 @@ void CreateMainWindow(bool opengl) { uiGLMakeContextCurrent(GLContext); if (!GLScreen_Init()) opengl_good = false; + if (opengl_good) + { + OpenGL_UseShaderProgram(GL_ScreenShaderOSD); + OSD::Init(true); + } uiGLMakeContextCurrent(NULL); } @@ -2312,7 +2347,7 @@ void CreateMainWindow(bool opengl) Screen_UseGL = false; } - OSD::Init(opengl); + if (!opengl) OSD::Init(false); } void DestroyMainWindow() diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h index f03931c..6504520 100644 --- a/src/libui_sdl/main_shaders.h +++ b/src/libui_sdl/main_shaders.h @@ -36,7 +36,7 @@ smooth out vec2 fTexcoord; void main() { vec4 fpos; - fpos.xy = ((vPosition.xy * 2.0) / uScreenSize) - 1.0; + fpos.xy = ((vPosition * 2.0) / uScreenSize) - 1.0; fpos.y *= -1; fpos.z = 0.0; fpos.w = 1.0; @@ -198,4 +198,53 @@ void main() } )"; + +const char* kScreenVS_OSD = R"(#version 140 + +layout(std140) uniform uConfig +{ + vec2 uScreenSize; + uint u3DScale; + uint uFilterMode; +}; + +uniform ivec2 uOSDPos; +uniform ivec2 uOSDSize; + +in vec2 vPosition; + +smooth out vec2 fTexcoord; + +void main() +{ + vec4 fpos; + + vec2 osdpos = (vPosition * vec2(uOSDSize)); + fTexcoord = osdpos; + osdpos += uOSDPos; + + fpos.xy = ((osdpos * 2.0) / uScreenSize) - 1.0; + fpos.y *= -1; + fpos.z = 0.0; + fpos.w = 1.0; + + gl_Position = fpos; +} +)"; + +const char* kScreenFS_OSD = R"(#version 140 + +uniform sampler2D OSDTex; + +smooth in vec2 fTexcoord; + +out vec4 oColor; + +void main() +{ + vec4 pixel = texelFetch(OSDTex, ivec2(fTexcoord), 0); + oColor = pixel.bgra; +} +)"; + #endif // MAIN_SHADERS_H -- cgit v1.2.3