From 75f8cbf953093bc539af67c77d18263767bb3474 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 31 Mar 2019 21:15:45 +0200 Subject: draft API for OpenGL shito in libui --- src/ARM.cpp | 14 +++++++++++++- src/GPU.cpp | 4 ++-- src/NDS.cpp | 2 +- src/libui_sdl/libui/ui.h | 11 +++++++++++ 4 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ARM.cpp b/src/ARM.cpp index f1bed5f..69755ff 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -159,7 +159,7 @@ void ARM::SetupCodeMem(u32 addr) //NDS::ARM7GetMemRegion(addr, false, &CodeMem); } } - +extern u64 vbltime; void ARMv5::JumpTo(u32 addr, bool restorecpsr) { if (restorecpsr) @@ -180,6 +180,16 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr) if (R[15]==0x0204BE5E) printf("recvfrom() ret:%d errno:%d %08X\n", R[0], NDS::ARM9Read32(0x217F398), addr); if (R[15]==0x0205038A) printf("sgrecvfrom() ret:%d errno:%d %08X\n", R[0], NDS::ARM9Read32(0x217F398), addr); if (addr==0x02050379 || addr==0x0205036D) printf("morp %08X->%08X, %d\n", R[15], addr, R[7]);*/ + /*if (addr==0x020B5F14) printf("VRAM UNMAP %02X %08X\n", R[0], R[15]); + if (addr==0x020B5FAC) printf("VRAM MAP %2X %08X\n", R[0], R[15]); + if (addr==0x0209F860) printf("VRAM BLORP %02X %08X\n", R[0], R[15]); + if (addr==0x02005A34) printf("VAZAVAZORP %08X. VCOUNT=%d\n", R[15], NDS::ARM9Read16(0x04000006)); + if (addr==0x0209FBEC) printf("COUILLON. %08X %08X\n", R[0], R[1]); + if (addr==0x02004AA8) printf("ANEBATE 1 %d\n", NDS::ARM9Read16(0x04000006)); + if (addr==0x020058C8) printf("ANEBATE 2 %d\n", NDS::ARM9Read16(0x04000006)); + if (addr==0x02005398) printf("ANEBATE 3 %d %d\n", NDS::ARM9Read16(0x04000006), (u32)(NDS::ARM9Timestamp-vbltime)); + if (addr==0x02005A5C) printf("PLAFORP %d\n", NDS::ARM9Read16(0x04000006)); + if (addr==0x209FBDC) printf("ROLOLORP\n");*/ u32 oldregion = R[15] >> 24; u32 newregion = addr >> 24; @@ -508,6 +518,8 @@ void ARMv5::Execute() } else AddCycles_C(); + + //if (R[15]>=0x02005A5C && R[15]<=0x02005A84) printf("NORP %08X %d\n", R[15]-8, NDS::ARM9Read16(0x04000006)); } // TODO optimize this shit!!! diff --git a/src/GPU.cpp b/src/GPU.cpp index 14e562e..ad39007 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -20,7 +20,7 @@ #include #include "NDS.h" #include "GPU.h" - +u64 vbltime; namespace GPU { @@ -811,7 +811,7 @@ void StartScanline(u32 line) else { if (VCount == 192) - { + {//printf("- VBLANK -\n");vbltime=NDS::ARM9Timestamp; // VBlank DispStat[0] |= (1<<0); DispStat[1] |= (1<<0); diff --git a/src/NDS.cpp b/src/NDS.cpp index ae71ad6..a814dfd 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -1532,7 +1532,7 @@ void debug(u32 param) // printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]); FILE* - shit = fopen("debug/lmnts.bin", "wb"); + shit = fopen("debug/card.bin", "wb"); for (u32 i = 0x02000000; i < 0x02400000; i+=4) { u32 val = ARM7Read32(i); diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h index b100c08..a81aa70 100644 --- a/src/libui_sdl/libui/ui.h +++ b/src/libui_sdl/libui/ui.h @@ -599,6 +599,17 @@ _UI_EXTERN void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, int startChar _UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout); + +// OpenGL support +// TODO for later: allow using OpenGL inside a uiWindow or uiArea + +typedef struct uiGLContext uiGLContext; + +_UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c); +_UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx); +_UI_EXTERN void *uiGLGetProcAddress(const char* proc); + + _UI_ENUM(uiModifiers) { uiModifierCtrl = 1 << 0, uiModifierAlt = 1 << 1, -- cgit v1.2.3 From b48fe5909bd9314c271f1cb729c9aa79d88a26f3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 31 Mar 2019 21:54:14 +0200 Subject: * add some GL base to libui (only for Windows for now) * make the Codeblocks project a bit less braindead (don't repeat libraries for each build target) --- CMakeLists.txt | 2 ++ melonDS.cbp | 1 + src/libui_sdl/libui/ui.h | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index 8abe112..a333766 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,6 +138,7 @@ elseif (WIN32) src/libui_sdl/libui/windows/fontbutton.cpp src/libui_sdl/libui/windows/fontdialog.cpp src/libui_sdl/libui/windows/form.cpp + src/libui_sdl/libui/windows/gl.cpp src/libui_sdl/libui/windows/graphemes.cpp src/libui_sdl/libui/windows/grid.cpp src/libui_sdl/libui/windows/group.cpp @@ -172,6 +173,7 @@ elseif (WIN32) LINK_LIBRARIES("usp10") LINK_LIBRARIES("ws2_32") LINK_LIBRARIES("uxtheme") + LINK_LIBRARIES("opengl32") endif (UNIX) find_package(SDL2 REQUIRED) diff --git a/melonDS.cbp b/melonDS.cbp index fc5f8df..9f105fc 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -222,6 +222,7 @@ + diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h index a81aa70..381b85b 100644 --- a/src/libui_sdl/libui/ui.h +++ b/src/libui_sdl/libui/ui.h @@ -601,11 +601,11 @@ _UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayou // OpenGL support -// TODO for later: allow using OpenGL inside a uiWindow or uiArea typedef struct uiGLContext uiGLContext; _UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c); +_UI_EXTERN void uiGLFreeContext(uiGLContext* ctx); _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx); _UI_EXTERN void *uiGLGetProcAddress(const char* proc); -- cgit v1.2.3 From f1628b98de5dcef702ca57ee363407d715d5b36e Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 31 Mar 2019 21:54:42 +0200 Subject: adding that file might be good, too --- src/libui_sdl/libui/windows/gl.cpp | 66 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/libui_sdl/libui/windows/gl.cpp (limited to 'src') diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp new file mode 100644 index 0000000..fe21ae4 --- /dev/null +++ b/src/libui_sdl/libui/windows/gl.cpp @@ -0,0 +1,66 @@ +// 31 march 2019 +#include "uipriv_windows.hpp" + +struct uiGLContext +{ + uiControl* c; + + HWND hwnd; + HDC dc; + HGLRC rc; +}; + + +uiGLContext* uiGLNewContext(uiControl* c) +{ + uiGLContext* ctx; + + ctx = uiNew(uiGLContext); + + ctx->c = c; + if (c) + { + ctx->hwnd = (HWND)c->Handle(c); // welp + } + else + { + // windowless context + ctx->hwnd = GetDesktopWindow(); + } + + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cAlphaBits = 8; + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; + pfd.iLayerType = PFD_MAIN_PLANE; + + ctx->dc = GetDC(ctx->hwnd); + + int pixelformat = ChoosePixelFormat(ctx->dc, &pfd); + SetPixelFormat(ctx->dc, pixelformat, &pfd); + + ctx->rc = wglCreateContext(ctx->dc); +} + +void uiGLFreeContext(uiGLContext* ctx) +{ + wglDeleteContext(ctx->rc); + ReleaseDC(ctx->hwnd, ctx->dc); + uiFree(ctx); +} + +void uiGLMakeContextCurrent(uiGLContext* ctx) +{ + wglMakeCurrent(ctx->dc, ctx->rc); +} + +void *uiGLGetProcAddress(const char* proc) +{ + return (void*)wglGetProcAddress(proc); +} -- cgit v1.2.3 From f8751bd1fb83e85e2eb4e91b9c4b032ef0c18cdd Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 1 Apr 2019 02:51:31 +0200 Subject: first attempt at things (also fix softrenderer reset) --- melonDS.cbp | 68 ++++++------------ src/GPU3D.cpp | 20 ++++-- src/GPU3D.h | 14 ++++ src/GPU3D_OpenGL43.cpp | 138 +++++++++++++++++++++++++++++++++++++ src/GPU3D_Soft.cpp | 6 +- src/Platform.h | 2 + src/libui_sdl/Platform.cpp | 7 ++ src/libui_sdl/libui/ui.h | 2 +- src/libui_sdl/libui/windows/gl.cpp | 69 ++++++++++++++++++- src/libui_sdl/main.cpp | 11 +++ 10 files changed, 275 insertions(+), 62 deletions(-) create mode 100644 src/GPU3D_OpenGL43.cpp (limited to 'src') diff --git a/melonDS.cbp b/melonDS.cbp index 9f105fc..0ba8653 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -19,22 +19,6 @@ - - - - - - - - - - - - - - - - @@ -51,22 +35,6 @@ - - - - - - - - - - - - - - - - @@ -82,22 +50,6 @@ - - - - - - - - - - - - - - - - @@ -107,6 +59,25 @@ + + + + + + + + + + + + + + + + + + + @@ -135,6 +106,7 @@ + diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 802c9cd..b4211f0 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -275,14 +275,16 @@ bool Init() CmdStallQueue = new FIFO(64); - if (!SoftRenderer::Init()) return false; + //if (!SoftRenderer::Init()) return false; + if (!GLRenderer43::Init()) return false; return true; } void DeInit() { - SoftRenderer::DeInit(); + //SoftRenderer::DeInit(); + GLRenderer43::DeInit(); delete CmdFIFO; delete CmdPIPE; @@ -382,7 +384,8 @@ void Reset() FlushAttributes = 0; ResetRenderingState(); - SoftRenderer::Reset(); + //SoftRenderer::Reset(); + GLRenderer43::Reset(); } void DoSavestate(Savestate* file) @@ -2331,7 +2334,7 @@ void CheckFIFODMA() void VCount144() { - SoftRenderer::VCount144(); + //SoftRenderer::VCount144(); } @@ -2413,17 +2416,20 @@ void VBlank() void VCount215() { - SoftRenderer::RenderFrame(); + //SoftRenderer::RenderFrame(); + GLRenderer43::RenderFrame(); } void RequestLine(int line) { - return SoftRenderer::RequestLine(line); + //return SoftRenderer::RequestLine(line); + return GLRenderer43::RequestLine(line); } u32* GetLine(int line) { - return SoftRenderer::GetLine(line); + //return SoftRenderer::GetLine(line); + return GLRenderer43::GetLine(line); } diff --git a/src/GPU3D.h b/src/GPU3D.h index 279494a..f300da8 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -132,6 +132,20 @@ u32* GetLine(int line); } +namespace GLRenderer43 +{ + +bool Init(); +void DeInit(); +void Reset(); + +void VCount144(); +void RenderFrame(); +void RequestLine(int line); +u32* GetLine(int line); + +} + } #endif diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp new file mode 100644 index 0000000..acb1436 --- /dev/null +++ b/src/GPU3D_OpenGL43.cpp @@ -0,0 +1,138 @@ +/* + 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 +#include +#include "NDS.h" +#include "GPU.h" +#include "Platform.h" + +namespace GPU3D +{ +namespace GLRenderer43 +{ + +PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; +PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; +PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; + + +GLuint FramebufferID; +u8 Framebuffer[256*192*4]; +u8 CurLine[256*4]; + + +bool InitGLExtensions() +{ +#define LOADPROC(type, name) \ + name = (PFN##type##PROC)Platform::GL_GetProcAddress(#name); \ + if (!name) return false; + + LOADPROC(GLGENFRAMEBUFFERS, glGenFramebuffers); + LOADPROC(GLBINDFRAMEBUFFER, glBindFramebuffer); + LOADPROC(GLFRAMEBUFFERTEXTURE, glFramebufferTexture); + +#undef LOADPROC + return true; +} + +bool Init() +{ + if (!InitGLExtensions()) return false; + + u8* test_tex = new u8[256*192*4]; + u8* ptr = test_tex; + for (int y = 0; y < 192; y++) + { + for (int x = 0; x < 256; x++) + { + if ((x & 0x10) ^ (y & 0x10)) + { + *ptr++ = 0x00; + *ptr++ = 0x00; + *ptr++ = 0x3F; + *ptr++ = 0x1F; + } + else + { + *ptr++ = 0; + *ptr++ = y>>2; + *ptr++ = 0x3F; + *ptr++ = 0x1F; + } + } + } + + glGenFramebuffers(1, &FramebufferID); + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); + + GLuint frametex; + glGenTextures(1, &frametex); + glBindTexture(GL_TEXTURE_2D, frametex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_BYTE, test_tex); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, frametex, 0); + + return true; +} + +void DeInit() +{ + // +} + +void Reset() +{ + // +} + + +void VCount144() +{ +} + +void RenderFrame() +{ + // +} + +void RequestLine(int line) +{ + // +} + +u32* GetLine(int line) +{ + if (line == 0) + { + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glReadPixels(0, 0, 256, 192, GL_RGBA, GL_UNSIGNED_BYTE, Framebuffer); + } + + return (u32*)&Framebuffer[256*4 * line]; +} + +} +} diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp index 29b46e1..8d18a35 100644 --- a/src/GPU3D_Soft.cpp +++ b/src/GPU3D_Soft.cpp @@ -129,9 +129,9 @@ void DeInit() void Reset() { - memset(ColorBuffer, 0, 256*192 * 4); - memset(DepthBuffer, 0, 256*192 * 4); - memset(AttrBuffer, 0, 256*192 * 4); + memset(ColorBuffer, 0, BufferSize * 2 * 4); + memset(DepthBuffer, 0, BufferSize * 2 * 4); + memset(AttrBuffer, 0, BufferSize * 2 * 4); PrevIsShadowMask = false; diff --git a/src/Platform.h b/src/Platform.h index df3335b..ca6971e 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -68,6 +68,8 @@ void Semaphore_Reset(void* sema); void Semaphore_Wait(void* sema); void Semaphore_Post(void* sema); +void* GL_GetProcAddress(const char* proc); + // local multiplayer comm interface // packet type: DS-style TX header (12 bytes) + original 802.11 frame bool MP_Init(); diff --git a/src/libui_sdl/Platform.cpp b/src/libui_sdl/Platform.cpp index 6ebe8c3..e3035b3 100644 --- a/src/libui_sdl/Platform.cpp +++ b/src/libui_sdl/Platform.cpp @@ -24,6 +24,7 @@ #include "PlatformConfig.h" #include "LAN_Socket.h" #include "LAN_PCap.h" +#include "libui/ui.h" #include #ifdef __WIN32__ @@ -302,6 +303,12 @@ void Semaphore_Post(void* sema) } +void* GL_GetProcAddress(const char* proc) +{ + return uiGLGetProcAddress(proc); +} + + bool MP_Init() { int opt_true = 1; diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h index 381b85b..dd1c786 100644 --- a/src/libui_sdl/libui/ui.h +++ b/src/libui_sdl/libui/ui.h @@ -604,7 +604,7 @@ _UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayou typedef struct uiGLContext uiGLContext; -_UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c); +_UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c, int vermajor, int verminor); _UI_EXTERN void uiGLFreeContext(uiGLContext* ctx); _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx); _UI_EXTERN void *uiGLGetProcAddress(const char* proc); diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp index fe21ae4..eb7d33d 100644 --- a/src/libui_sdl/libui/windows/gl.cpp +++ b/src/libui_sdl/libui/windows/gl.cpp @@ -1,6 +1,9 @@ // 31 march 2019 #include "uipriv_windows.hpp" +#include +#include + struct uiGLContext { uiControl* c; @@ -11,9 +14,10 @@ struct uiGLContext }; -uiGLContext* uiGLNewContext(uiControl* c) +uiGLContext* uiGLNewContext(uiControl* c, int vermajor, int verminor) { uiGLContext* ctx; + BOOL res; ctx = uiNew(uiGLContext); @@ -25,7 +29,10 @@ uiGLContext* uiGLNewContext(uiControl* c) else { // windowless context - ctx->hwnd = GetDesktopWindow(); + //ctx->hwnd = GetDesktopWindow(); + // nope. + uiFree(ctx); + return NULL; } PIXELFORMATDESCRIPTOR pfd; @@ -41,15 +48,71 @@ uiGLContext* uiGLNewContext(uiControl* c) pfd.iLayerType = PFD_MAIN_PLANE; ctx->dc = GetDC(ctx->hwnd); + if (!ctx->dc) + { + uiFree(ctx); + return NULL; + } int pixelformat = ChoosePixelFormat(ctx->dc, &pfd); - SetPixelFormat(ctx->dc, pixelformat, &pfd); + res = SetPixelFormat(ctx->dc, pixelformat, &pfd); + if (!res) + { + ReleaseDC(ctx->hwnd, ctx->dc); + uiFree(ctx); + return NULL; + } ctx->rc = wglCreateContext(ctx->dc); + if (!ctx->rc) + { + ReleaseDC(ctx->hwnd, ctx->dc); + uiFree(ctx); + return NULL; + } + + wglMakeCurrent(ctx->dc, ctx->rc); + + if (vermajor >= 3) + { + HGLRC (*wglCreateContextAttribsARB)(HDC,HGLRC,const int*); + HGLRC rc_better = NULL; + + wglCreateContextAttribsARB = (HGLRC(*)(HDC,HGLRC,const int*))wglGetProcAddress("wglCreateContextAttribsARB"); + if (wglCreateContextAttribsARB) + { + int attribs[15]; + int i = 0; + + attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; + attribs[i++] = vermajor; + attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; + attribs[i++] = verminor; + + attribs[i] = 0; + rc_better = wglCreateContextAttribsARB(ctx->dc, NULL, attribs); + } + + wglMakeCurrent(NULL, NULL); + wglDeleteContext(ctx->rc); + + if (!rc_better) + { + ReleaseDC(ctx->hwnd, ctx->dc); + uiFree(ctx); + return NULL; + } + + ctx->rc = rc_better; + wglMakeCurrent(ctx->dc, ctx->rc); + } + + return ctx; } void uiGLFreeContext(uiGLContext* ctx) { + wglMakeCurrent(NULL, NULL); wglDeleteContext(ctx->rc); ReleaseDC(ctx->hwnd, ctx->dc); uiFree(ctx); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 566b346..d892912 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -392,6 +392,14 @@ void FeedMicInput() int EmuThreadFunc(void* burp) { + // TODO: fail gracefully, support older OpenGL, etc + uiGLContext* glctx = uiGLNewContext(uiControl(MainDrawArea), 4, 3); // haw haw haw + uiGLMakeContextCurrent(glctx); + + void* testor = uiGLGetProcAddress("glUseProgram"); + void* testor2 = uiGLGetProcAddress("glBindFramebuffer"); + printf("OPENGL: %p %p\n", testor, testor2); + NDS::Init(); MainScreenPos[0] = 0; @@ -616,6 +624,8 @@ int EmuThreadFunc(void* burp) NDS::DeInit(); Platform::LAN_DeInit(); + uiGLFreeContext(glctx); + return 44203; } @@ -1652,6 +1662,7 @@ void ApplyNewSettings(int type) if (type == 0) // general emu settings { + // TODO!! REMOVE ME GPU3D::SoftRenderer::SetupRenderThread(); } else if (type == 1) // wifi settings -- cgit v1.2.3 From 8bc4ca3fc8231c8836b0b0ff8cbeeb3855a719e1 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 1 Apr 2019 04:20:43 +0200 Subject: fasterer framebuffer read --- src/GPU3D_OpenGL43.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index acb1436..3641ff3 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -30,12 +30,21 @@ namespace GPU3D namespace GLRenderer43 { -PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; -PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; -PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; +PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; +PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; +PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; +PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; +PFNGLGENBUFFERSPROC glGenBuffers; +PFNGLDELETEBUFFERSPROC glDeleteBuffers; +PFNGLBINDBUFFERPROC glBindBuffer; +PFNGLMAPBUFFERPROC glMapBuffer; +PFNGLMAPBUFFERRANGEPROC glMapBufferRange; +PFNGLUNMAPBUFFERPROC glUnmapBuffer; +PFNGLBUFFERDATAPROC glBufferData; -GLuint FramebufferID; + +GLuint FramebufferID, PixelbufferID; u8 Framebuffer[256*192*4]; u8 CurLine[256*4]; @@ -47,9 +56,18 @@ bool InitGLExtensions() if (!name) return false; LOADPROC(GLGENFRAMEBUFFERS, glGenFramebuffers); + LOADPROC(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers); LOADPROC(GLBINDFRAMEBUFFER, glBindFramebuffer); LOADPROC(GLFRAMEBUFFERTEXTURE, glFramebufferTexture); + LOADPROC(GLGENBUFFERS, glGenBuffers); + LOADPROC(GLDELETEBUFFERS, glDeleteBuffers); + LOADPROC(GLBINDBUFFER, glBindBuffer); + LOADPROC(GLMAPBUFFER, glMapBuffer); + LOADPROC(GLMAPBUFFERRANGE, glMapBufferRange); + LOADPROC(GLUNMAPBUFFER, glUnmapBuffer); + LOADPROC(GLBUFFERDATA, glBufferData); + #undef LOADPROC return true; } @@ -66,16 +84,16 @@ bool Init() { if ((x & 0x10) ^ (y & 0x10)) { - *ptr++ = 0x00; - *ptr++ = 0x00; *ptr++ = 0x3F; + *ptr++ = 0x00; + *ptr++ = 0; *ptr++ = 0x1F; } else { - *ptr++ = 0; - *ptr++ = y>>2; *ptr++ = 0x3F; + *ptr++ = y>>2; + *ptr++ = 0; *ptr++ = 0x1F; } } @@ -94,6 +112,10 @@ bool Init() glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_BYTE, test_tex); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, frametex, 0); + glGenBuffers(1, &PixelbufferID); + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); + glBufferData(GL_PIXEL_PACK_BUFFER, 256*48*4, NULL, GL_DYNAMIC_READ); + return true; } @@ -114,7 +136,13 @@ void VCount144() void RenderFrame() { - // + // render shit here + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); + glReadBuffer(GL_COLOR_ATTACHMENT0); + //glReadPixels(0, 0, 256, 48, GL_RGBA, GL_UNSIGNED_BYTE, Framebuffer); + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); + glReadPixels(0, 0, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); } void RequestLine(int line) @@ -126,9 +154,37 @@ u32* GetLine(int line) { if (line == 0) { - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); + /*glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); glReadBuffer(GL_COLOR_ATTACHMENT0); - glReadPixels(0, 0, 256, 192, GL_RGBA, GL_UNSIGNED_BYTE, Framebuffer); + glReadPixels(0, 0, 256, 192, GL_RGBA, GL_UNSIGNED_BYTE, Framebuffer);*/ + + u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (data) memcpy(&Framebuffer[4*256*0], data, 4*256*48); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + + glReadPixels(0, 48, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + } + else if (line == 48) + { + u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (data) memcpy(&Framebuffer[4*256*48], data, 4*256*48); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + + glReadPixels(0, 96, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + } + else if (line == 96) + { + u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (data) memcpy(&Framebuffer[4*256*96], data, 4*256*48); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + + glReadPixels(0, 144, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + } + else if (line == 144) + { + u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (data) memcpy(&Framebuffer[4*256*144], data, 4*256*48); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); } return (u32*)&Framebuffer[256*4 * line]; -- cgit v1.2.3 From 2d0d501d1ffe972dcc0a8879b95aaed9328650c7 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 1 Apr 2019 04:22:03 +0200 Subject: probs better this way (ultimately RequestLine should be axed) --- src/GPU3D_OpenGL43.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 3641ff3..58539fa 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -146,18 +146,9 @@ void RenderFrame() } void RequestLine(int line) -{ - // -} - -u32* GetLine(int line) { if (line == 0) { - /*glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); - glReadBuffer(GL_COLOR_ATTACHMENT0); - glReadPixels(0, 0, 256, 192, GL_RGBA, GL_UNSIGNED_BYTE, Framebuffer);*/ - u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); if (data) memcpy(&Framebuffer[4*256*0], data, 4*256*48); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); @@ -186,7 +177,10 @@ u32* GetLine(int line) if (data) memcpy(&Framebuffer[4*256*144], data, 4*256*48); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); } +} +u32* GetLine(int line) +{ return (u32*)&Framebuffer[256*4 * line]; } -- cgit v1.2.3 From 1f13d9ce80c0cd5e94ba883ff6bb30c95d48a48a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 1 Apr 2019 04:50:48 +0200 Subject: * move GL init to main thread * fix potential bug causing the screen bitmap to be created twice --- src/GPU3D_OpenGL43.cpp | 2 +- src/libui_sdl/libui/windows/alloc.cpp | 2 +- src/libui_sdl/libui/windows/gl.cpp | 9 ++++++++- src/libui_sdl/main.cpp | 29 +++++++++++++++++------------ 4 files changed, 27 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 58539fa..ea8bbd7 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -53,7 +53,7 @@ bool InitGLExtensions() { #define LOADPROC(type, name) \ name = (PFN##type##PROC)Platform::GL_GetProcAddress(#name); \ - if (!name) return false; + if (!name) { printf("OpenGL: " #name " not found\n"); return false; } LOADPROC(GLGENFRAMEBUFFERS, glGenFramebuffers); LOADPROC(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers); diff --git a/src/libui_sdl/libui/windows/alloc.cpp b/src/libui_sdl/libui/windows/alloc.cpp index cf6bd2e..e29d60e 100644 --- a/src/libui_sdl/libui/windows/alloc.cpp +++ b/src/libui_sdl/libui/windows/alloc.cpp @@ -32,7 +32,7 @@ void *uiAlloc(size_t size, const char *type) { byteArray *out; - out = new byteArray(size, 0); + out = new byteArray(size, 0);//printf("alloc %s at %08X\n", type, rawBytes(out)); heap[rawBytes(out)] = out; types[out] = type; return rawBytes(out); diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp index eb7d33d..beccb79 100644 --- a/src/libui_sdl/libui/windows/gl.cpp +++ b/src/libui_sdl/libui/windows/gl.cpp @@ -120,7 +120,14 @@ void uiGLFreeContext(uiGLContext* ctx) void uiGLMakeContextCurrent(uiGLContext* ctx) { - wglMakeCurrent(ctx->dc, ctx->rc); + if (ctx == NULL) + { + wglMakeCurrent(NULL, NULL); + return; + } + + if (wglGetCurrentContext() == ctx->rc) return; + int res = wglMakeCurrent(ctx->dc, ctx->rc); } void *uiGLGetProcAddress(const char* proc) diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index d892912..2705560 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -60,6 +60,7 @@ char* EmuDirectory; uiWindow* MainWindow; uiArea* MainDrawArea; +uiGLContext* GLContext; int WindowWidth, WindowHeight; @@ -392,14 +393,7 @@ void FeedMicInput() int EmuThreadFunc(void* burp) { - // TODO: fail gracefully, support older OpenGL, etc - uiGLContext* glctx = uiGLNewContext(uiControl(MainDrawArea), 4, 3); // haw haw haw - uiGLMakeContextCurrent(glctx); - - void* testor = uiGLGetProcAddress("glUseProgram"); - void* testor2 = uiGLGetProcAddress("glBindFramebuffer"); - printf("OPENGL: %p %p\n", testor, testor2); - + uiGLMakeContextCurrent(GLContext); NDS::Init(); MainScreenPos[0] = 0; @@ -407,7 +401,6 @@ int EmuThreadFunc(void* burp) MainScreenPos[2] = 0; AutoScreenSizing = 0; - ScreenDrawInited = false; Touching = false; KeyInputMask = 0xFFF; HotkeyMask = 0; @@ -440,6 +433,8 @@ int EmuThreadFunc(void* burp) { EmuStatus = 1; + uiGLMakeContextCurrent(GLContext); + SDL_JoystickUpdate(); if (Joystick) @@ -624,8 +619,6 @@ int EmuThreadFunc(void* burp) NDS::DeInit(); Platform::LAN_DeInit(); - uiGLFreeContext(glctx); - return 44203; } @@ -634,8 +627,8 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) { if (!ScreenDrawInited) { - ScreenBitmap = uiDrawNewBitmap(params->Context, 256, 384); ScreenDrawInited = true; + ScreenBitmap = uiDrawNewBitmap(params->Context, 256, 384); } if (!ScreenBitmap) return; @@ -1981,6 +1974,7 @@ int main(int argc, char** argv) areahandler.KeyEvent = OnAreaKeyEvent; areahandler.Resize = OnAreaResize; + ScreenDrawInited = false; MainDrawArea = uiNewArea(&areahandler); uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); @@ -2011,6 +2005,15 @@ 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 + 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; @@ -2092,6 +2095,8 @@ int main(int argc, char** argv) if (MicWavBuffer) delete[] MicWavBuffer; + uiGLFreeContext(GLContext); + Config::ScreenRotation = ScreenRotation; Config::ScreenGap = ScreenGap; Config::ScreenLayout = ScreenLayout; -- cgit v1.2.3 From 4bf75a8d8ee1a5adae7dd1deb571ef943d874ce7 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 1 Apr 2019 04:52:03 +0200 Subject: glörg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libui_sdl/libui/windows/alloc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libui_sdl/libui/windows/alloc.cpp b/src/libui_sdl/libui/windows/alloc.cpp index e29d60e..cf6bd2e 100644 --- a/src/libui_sdl/libui/windows/alloc.cpp +++ b/src/libui_sdl/libui/windows/alloc.cpp @@ -32,7 +32,7 @@ void *uiAlloc(size_t size, const char *type) { byteArray *out; - out = new byteArray(size, 0);//printf("alloc %s at %08X\n", type, rawBytes(out)); + out = new byteArray(size, 0); heap[rawBytes(out)] = out; types[out] = type; return rawBytes(out); -- cgit v1.2.3 From 00341bbae5a0344fece4fdffb586bfdfb716959b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 1 Apr 2019 04:58:21 +0200 Subject: actually, seems faster to read it all at once?? --- src/GPU3D_OpenGL43.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index ea8bbd7..2e15cfa 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -114,7 +114,8 @@ bool Init() glGenBuffers(1, &PixelbufferID); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glBufferData(GL_PIXEL_PACK_BUFFER, 256*48*4, NULL, GL_DYNAMIC_READ); + //glBufferData(GL_PIXEL_PACK_BUFFER, 256*48*4, NULL, GL_DYNAMIC_READ); + glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); return true; } @@ -142,7 +143,8 @@ void RenderFrame() glReadBuffer(GL_COLOR_ATTACHMENT0); //glReadPixels(0, 0, 256, 48, GL_RGBA, GL_UNSIGNED_BYTE, Framebuffer); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glReadPixels(0, 0, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + //glReadPixels(0, 0, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + glReadPixels(0, 0, 256, 192, GL_BGRA, GL_UNSIGNED_BYTE, NULL); } void RequestLine(int line) @@ -150,12 +152,13 @@ void RequestLine(int line) if (line == 0) { u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (data) memcpy(&Framebuffer[4*256*0], data, 4*256*48); + //if (data) memcpy(&Framebuffer[4*256*0], data, 4*256*48); + if (data) memcpy(&Framebuffer[4*256*0], data, 4*256*192); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - glReadPixels(0, 48, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + //glReadPixels(0, 48, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); } - else if (line == 48) + /*else if (line == 48) { u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); if (data) memcpy(&Framebuffer[4*256*48], data, 4*256*48); @@ -176,7 +179,7 @@ void RequestLine(int line) u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); if (data) memcpy(&Framebuffer[4*256*144], data, 4*256*48); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - } + }*/ } u32* GetLine(int line) -- cgit v1.2.3 From 32c75e20a6f030bb4ac9e5bb68f2f6febbde7f24 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 9 Apr 2019 23:23:24 +0200 Subject: here, have shader shit --- src/GPU3D_OpenGL43.cpp | 133 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 2e15cfa..32d652b 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -43,6 +43,44 @@ PFNGLMAPBUFFERRANGEPROC glMapBufferRange; PFNGLUNMAPBUFFERPROC glUnmapBuffer; PFNGLBUFFERDATAPROC glBufferData; +PFNGLCREATESHADERPROC glCreateShader; +PFNGLSHADERSOURCEPROC glShaderSource; +PFNGLCOMPILESHADERPROC glCompileShader; +PFNGLCREATEPROGRAMPROC glCreateProgram; +PFNGLATTACHSHADERPROC glAttachShader; +PFNGLLINKPROGRAMPROC glLinkProgram; +PFNGLUSEPROGRAMPROC glUseProgram; +PFNGLGETSHADERIVPROC glGetShaderiv; +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; +PFNGLGETPROGRAMIVPROC glGetProgramiv; +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; +PFNGLDELETESHADERPROC glDeleteShader; +PFNGLDELETEPROGRAMPROC glDeleteProgram; + + +const char* kRenderVS = R"(#version 400 + +in vec4 vPosition; + +void main() +{ + // burp + gl_Position = vPosition; +} +)"; + +const char* kRenderFS = R"(#version 400 + +out vec4 oColor; + +void main() +{ + oColor = vec4(0,1,1,1); +} +)"; + + +GLuint RenderShader[3]; GLuint FramebufferID, PixelbufferID; u8 Framebuffer[256*192*4]; @@ -68,14 +106,109 @@ bool InitGLExtensions() LOADPROC(GLUNMAPBUFFER, glUnmapBuffer); LOADPROC(GLBUFFERDATA, glBufferData); + LOADPROC(GLCREATESHADER, glCreateShader); + LOADPROC(GLSHADERSOURCE, glShaderSource); + LOADPROC(GLCOMPILESHADER, glCompileShader); + LOADPROC(GLCREATEPROGRAM, glCreateProgram); + LOADPROC(GLATTACHSHADER, glAttachShader); + LOADPROC(GLLINKPROGRAM, glLinkProgram); + LOADPROC(GLUSEPROGRAM, glUseProgram); + LOADPROC(GLGETSHADERIV, glGetShaderiv); + LOADPROC(GLGETSHADERINFOLOG, glGetShaderInfoLog); + LOADPROC(GLGETPROGRAMIV, glGetProgramiv); + LOADPROC(GLGETPROGRAMINFOLOG, glGetProgramInfoLog); + LOADPROC(GLDELETESHADER, glDeleteShader); + LOADPROC(GLDELETEPROGRAM, glDeleteProgram); + #undef LOADPROC return true; } +bool 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); + delete[] log; + + glDeleteShader(ids[0]); + + return false; + } + + ids[1] = glCreateShader(GL_FRAGMENT_SHADER); + len = strlen(vs); + 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); + 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; +} + bool Init() { if (!InitGLExtensions()) 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); + printf("OpenGL: version: %s\n", version); + + + if (!BuildShaderProgram(kRenderVS, kRenderFS, RenderShader, "RenderShader")) + return false; + + u8* test_tex = new u8[256*192*4]; u8* ptr = test_tex; for (int y = 0; y < 192; y++) -- cgit v1.2.3 From ccc9608ad249829a70d34295d7626aec10237798 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 10 Apr 2019 22:49:06 +0200 Subject: it renders shit!! albeit in monochrome and with fucky clipping for some reason --- src/GPU3D_OpenGL43.cpp | 152 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 148 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 32d652b..c618837 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -42,6 +42,14 @@ PFNGLMAPBUFFERPROC glMapBuffer; PFNGLMAPBUFFERRANGEPROC glMapBufferRange; PFNGLUNMAPBUFFERPROC glUnmapBuffer; PFNGLBUFFERDATAPROC glBufferData; +PFNGLBUFFERSUBDATAPROC glBufferSubData; + +PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; +PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; +PFNGLBINDVERTEXARRAYPROC glBindVertexArray; +PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; +PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; PFNGLCREATESHADERPROC glCreateShader; PFNGLSHADERSOURCEPROC glShaderSource; @@ -60,12 +68,18 @@ PFNGLDELETEPROGRAMPROC glDeleteProgram; const char* kRenderVS = R"(#version 400 -in vec4 vPosition; +layout(location=0) in uvec4 vPosition; void main() { // burp - gl_Position = vPosition; + vec4 fpos; + fpos.x = ((float(vPosition.x) / 256.0) * 2.0) - 1.0; + fpos.y = ((float(vPosition.y) / 192.0) * 2.0) - 1.0; + fpos.z = 0.0; + fpos.w = 1.0; + + gl_Position = fpos; } )"; @@ -75,13 +89,33 @@ out vec4 oColor; void main() { - oColor = vec4(0,1,1,1); + oColor = vec4(0, 63.0/255.0, 63.0/255.0, 31.0/255.0); } )"; GLuint RenderShader[3]; +// 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 FramebufferID, PixelbufferID; u8 Framebuffer[256*192*4]; u8 CurLine[256*4]; @@ -105,6 +139,14 @@ bool InitGLExtensions() LOADPROC(GLMAPBUFFERRANGE, glMapBufferRange); LOADPROC(GLUNMAPBUFFER, glUnmapBuffer); LOADPROC(GLBUFFERDATA, glBufferData); + LOADPROC(GLBUFFERSUBDATA, glBufferSubData); + + LOADPROC(GLGENVERTEXARRAYS, glGenVertexArrays); + LOADPROC(GLDELETEVERTEXARRAYS, glDeleteVertexArrays); + LOADPROC(GLBINDVERTEXARRAY, glBindVertexArray); + LOADPROC(GLENABLEVERTEXATTRIBARRAY, glEnableVertexAttribArray); + LOADPROC(GLVERTEXATTRIBPOINTER, glVertexAttribPointer); + LOADPROC(GLVERTEXATTRIBIPOINTER, glVertexAttribIPointer); LOADPROC(GLCREATESHADER, glCreateShader); LOADPROC(GLSHADERSOURCE, glShaderSource); @@ -150,7 +192,7 @@ bool BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* } ids[1] = glCreateShader(GL_FRAGMENT_SHADER); - len = strlen(vs); + len = strlen(fs); glShaderSource(ids[1], 1, &fs, &len); glCompileShader(ids[1]); @@ -205,10 +247,31 @@ bool Init() printf("OpenGL: version: %s\n", version); + // TODO: make configurable (hires, etc) + glViewport(0, 0, 256, 192); + glDepthRange(0, 1); + + if (!BuildShaderProgram(kRenderVS, kRenderFS, RenderShader, "RenderShader")) return false; + 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_UNSIGNED_SHORT, 7*4, (void*)(3*4)); + glEnableVertexAttribArray(3); // attrib + glVertexAttribIPointer(3, 3, GL_UNSIGNED_INT, 7*4, (void*)(4*4)); + + u8* test_tex = new u8[256*192*4]; u8* ptr = test_tex; for (int y = 0; y < 192; y++) @@ -264,13 +327,94 @@ void Reset() } +void BuildPolygons(Polygon** polygons, int npolys) +{ + u32* vptr = &VertexBuffer[0]; + u32 vidx = 0; + + u16* iptr = &IndexBuffer[0]; + u32 numtriangles = 0; + + for (int i = 0; i < npolys; i++) + { + Polygon* poly = polygons[i]; + if (poly->Degenerate) continue; + + 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++; } + + // TODO hires-upgraded positions? + *vptr++ = vtx->FinalPosition[0] | (vtx->FinalPosition[1] << 16); + *vptr++ = z | (w << 16); + + *vptr++ = (vtx->FinalColor[0] >> 1) | + ((vtx->FinalColor[1] >> 1) << 8) | + ((vtx->FinalColor[2] >> 1) << 16) | + (alpha << 24); + + *vptr++ = vtx->TexCoords[0] | (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 VCount144() { } void RenderFrame() { + // TODO: proper clear color!! + glClearColor(0, 0, 0, 31.0/255.0); + glClear(GL_COLOR_BUFFER_BIT); + // render shit here + glUseProgram(RenderShader[2]); + + BuildPolygons(&RenderPolygonRAM[0], RenderNumPolygons); + glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); + glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); + + glBindVertexArray(VertexArrayID); + glDrawElements(GL_TRIANGLES, NumTriangles, GL_UNSIGNED_SHORT, IndexBuffer); + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); glReadBuffer(GL_COLOR_ATTACHMENT0); -- cgit v1.2.3 From 210a5b583e2ce332f95e95e5ca183c1f92557068 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 10 Apr 2019 23:25:01 +0200 Subject: make it actually work without asploding half the geometry also, fix colors --- src/GPU3D_OpenGL43.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index c618837..b4a07d3 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -74,11 +74,13 @@ void main() { // burp vec4 fpos; - fpos.x = ((float(vPosition.x) / 256.0) * 2.0) - 1.0; - fpos.y = ((float(vPosition.y) / 192.0) * 2.0) - 1.0; - fpos.z = 0.0; + fpos.x = ((float(vPosition.x) * 2.0) / 256.0) - 1.0; + fpos.y = ((float(vPosition.y) * 2.0) / 192.0) - 1.0; + fpos.z = 0.5; fpos.w = 1.0; + //if (fpos.y < 0.0) fpos.y = -fpos.y; + gl_Position = fpos; } )"; @@ -89,7 +91,9 @@ out vec4 oColor; void main() { - oColor = vec4(0, 63.0/255.0, 63.0/255.0, 31.0/255.0); + vec4 finalcolor = vec4(0, 63.0/255.0, 63.0/255.0, 31.0/255.0); + + oColor = finalcolor.bgra; } )"; @@ -365,7 +369,7 @@ void BuildPolygons(Polygon** polygons, int npolys) // TODO hires-upgraded positions? *vptr++ = vtx->FinalPosition[0] | (vtx->FinalPosition[1] << 16); *vptr++ = z | (w << 16); - +//printf("vertex %d (%d): %08X\n", j, vidx, vptr[-2]); *vptr++ = (vtx->FinalColor[0] >> 1) | ((vtx->FinalColor[1] >> 1) << 8) | ((vtx->FinalColor[2] >> 1) << 16) | @@ -384,6 +388,8 @@ void BuildPolygons(Polygon** polygons, int npolys) *iptr++ = vidx - 1; *iptr++ = vidx; numtriangles++; + + //printf("BUILDZORZ TRIANGLE: %d,%d,%d\n", vidx_first, vidx-1, vidx); } vidx++; @@ -413,7 +419,7 @@ void RenderFrame() glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); glBindVertexArray(VertexArrayID); - glDrawElements(GL_TRIANGLES, NumTriangles, GL_UNSIGNED_SHORT, IndexBuffer); + glDrawElements(GL_TRIANGLES, NumTriangles*3, GL_UNSIGNED_SHORT, IndexBuffer); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); -- cgit v1.2.3 From 38885185759271ffaabcc24cad8b9c4614ee3b00 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 10 Apr 2019 23:47:58 +0200 Subject: here, have vertex colors --- src/GPU3D_OpenGL43.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index b4a07d3..aab8e01 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -69,6 +69,9 @@ PFNGLDELETEPROGRAMPROC glDeleteProgram; const char* kRenderVS = R"(#version 400 layout(location=0) in uvec4 vPosition; +layout(location=1) in uvec4 vColor; + +smooth out vec4 fColor; void main() { @@ -79,7 +82,7 @@ void main() fpos.z = 0.5; fpos.w = 1.0; - //if (fpos.y < 0.0) fpos.y = -fpos.y; + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); gl_Position = fpos; } @@ -87,13 +90,18 @@ void main() const char* kRenderFS = R"(#version 400 +smooth in vec4 fColor; + out vec4 oColor; void main() { - vec4 finalcolor = vec4(0, 63.0/255.0, 63.0/255.0, 31.0/255.0); + vec4 finalcolor; + + finalcolor.rgb = fColor.rgb; + finalcolor.a = 1.0; - oColor = finalcolor.bgra; + oColor = finalcolor.bgra * vec4(63.0/255.0, 63.0/255.0, 63.0/255.0, 31.0/255.0); } )"; -- cgit v1.2.3 From 15b7903170c9883ba5c7347ef8ab68893433864f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 10 Apr 2019 23:55:34 +0200 Subject: now with perspective correction! --- src/GPU3D_OpenGL43.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index aab8e01..f924758 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -80,7 +80,8 @@ void main() fpos.x = ((float(vPosition.x) * 2.0) / 256.0) - 1.0; fpos.y = ((float(vPosition.y) * 2.0) / 192.0) - 1.0; fpos.z = 0.5; - fpos.w = 1.0; + fpos.w = float(vPosition.w) / 65535.0f; + fpos.xyz *= fpos.w; fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); -- cgit v1.2.3 From 448806fada854f381db1057a2403bafa889eeb10 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 24 Apr 2019 22:38:50 +0200 Subject: weak little attempt at a zbuffer. still bad for wbuffering because of course it is --- src/GPU3D_OpenGL43.cpp | 119 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index f924758..0837f56 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -49,7 +49,7 @@ PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; PFNGLBINDVERTEXARRAYPROC glBindVertexArray; PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; +PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; PFNGLCREATESHADERPROC glCreateShader; PFNGLSHADERSOURCEPROC glShaderSource; @@ -65,21 +65,29 @@ PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLDELETESHADERPROC glDeleteShader; PFNGLDELETEPROGRAMPROC glDeleteProgram; +PFNGLBINDIMAGETEXTUREPROC glBindImageTexture; -const char* kRenderVS = R"(#version 400 +PFNGLGETSTRINGIPROC glGetStringi; + + +const char* kRenderVS = R"(#version 420 layout(location=0) in uvec4 vPosition; layout(location=1) in uvec4 vColor; +layout(location=2) in uvec2 vTexcoord; +layout(location=3) in uvec3 vPolygonAttr; smooth out vec4 fColor; void main() { - // burp + uint attr = vPolygonAttr.x; + uint zshift = (attr >> 16) & 0x1F; + vec4 fpos; fpos.x = ((float(vPosition.x) * 2.0) / 256.0) - 1.0; fpos.y = ((float(vPosition.y) * 2.0) / 192.0) - 1.0; - fpos.z = 0.5; + fpos.z = float(vPosition.z << zshift) / 16777216.0; fpos.w = float(vPosition.w) / 65535.0f; fpos.xyz *= fpos.w; @@ -89,7 +97,7 @@ void main() } )"; -const char* kRenderFS = R"(#version 400 +const char* kRenderFS = R"(#version 420 smooth in vec4 fColor; @@ -129,10 +137,13 @@ GLuint VertexArrayID; u16 IndexBuffer[2048 * 10]; u32 NumTriangles; +GLuint FramebufferTex[2]; GLuint FramebufferID, PixelbufferID; u8 Framebuffer[256*192*4]; u8 CurLine[256*4]; +GLuint AuxBufferID; + bool InitGLExtensions() { @@ -175,6 +186,10 @@ bool InitGLExtensions() LOADPROC(GLDELETESHADER, glDeleteShader); LOADPROC(GLDELETEPROGRAM, glDeleteProgram); + LOADPROC(GLBINDIMAGETEXTURE, glBindImageTexture); + + LOADPROC(GLGETSTRINGI, glGetStringi); + #undef LOADPROC return true; } @@ -259,10 +274,28 @@ 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_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); + }*/ + // TODO: make configurable (hires, etc) glViewport(0, 0, 256, 192); glDepthRange(0, 1); + glClearDepth(1.0); if (!BuildShaderProgram(kRenderVS, kRenderFS, RenderShader, "RenderShader")) @@ -285,53 +318,46 @@ bool Init() glVertexAttribIPointer(3, 3, GL_UNSIGNED_INT, 7*4, (void*)(4*4)); - u8* test_tex = new u8[256*192*4]; - u8* ptr = test_tex; - for (int y = 0; y < 192; y++) - { - for (int x = 0; x < 256; x++) - { - if ((x & 0x10) ^ (y & 0x10)) - { - *ptr++ = 0x3F; - *ptr++ = 0x00; - *ptr++ = 0; - *ptr++ = 0x1F; - } - else - { - *ptr++ = 0x3F; - *ptr++ = y>>2; - *ptr++ = 0; - *ptr++ = 0x1F; - } - } - } - glGenFramebuffers(1, &FramebufferID); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); - GLuint frametex; - glGenTextures(1, &frametex); - glBindTexture(GL_TEXTURE_2D, frametex); + glGenTextures(1, &FramebufferTex[0]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_BYTE, test_tex); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, frametex, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); + + glGenTextures(1, &FramebufferTex[1]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 256, 192, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); // welp + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, FramebufferTex[1], 0); glGenBuffers(1, &PixelbufferID); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); //glBufferData(GL_PIXEL_PACK_BUFFER, 256*48*4, NULL, GL_DYNAMIC_READ); glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); + glGenTextures(1, &AuxBufferID); + glBindTexture(GL_TEXTURE_2D, AuxBufferID); + 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_RG32UI, 256, 192, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, NULL); + return true; } void DeInit() { - // + // TODO CLEAN UP SHIT!!!! } void Reset() @@ -378,7 +404,7 @@ void BuildPolygons(Polygon** polygons, int npolys) // TODO hires-upgraded positions? *vptr++ = vtx->FinalPosition[0] | (vtx->FinalPosition[1] << 16); *vptr++ = z | (w << 16); -//printf("vertex %d (%d): %08X\n", j, vidx, vptr[-2]); + *vptr++ = (vtx->FinalColor[0] >> 1) | ((vtx->FinalColor[1] >> 1) << 8) | ((vtx->FinalColor[2] >> 1) << 16) | @@ -397,8 +423,6 @@ void BuildPolygons(Polygon** polygons, int npolys) *iptr++ = vidx - 1; *iptr++ = vidx; numtriangles++; - - //printf("BUILDZORZ TRIANGLE: %d,%d,%d\n", vidx_first, vidx-1, vidx); } vidx++; @@ -418,11 +442,30 @@ void RenderFrame() { // TODO: proper clear color!! glClearColor(0, 0, 0, 31.0/255.0); - glClear(GL_COLOR_BUFFER_BIT); + glClearDepth(1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + { + u32* dorp = new u32[256*192*2]; + for (int i = 0; i < 256*192; i++) + { + dorp[i*2+0] = 0xFFFFFF; + dorp[i*2+1] = 0; + } + glBindTexture(GL_TEXTURE_2D, AuxBufferID); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RG_INTEGER, GL_UNSIGNED_INT, dorp); + delete[] dorp; + } // render shit here glUseProgram(RenderShader[2]); + glBindTexture(GL_TEXTURE_2D, AuxBufferID); + glBindImageTexture(0, AuxBufferID, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32UI); + + // zorp + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + BuildPolygons(&RenderPolygonRAM[0], RenderNumPolygons); glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); -- cgit v1.2.3 From 6febd79f83c0a69f4af8e6345cf0725a1d07e59b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 25 Apr 2019 13:32:15 +0200 Subject: finally get wbuffering covered. --- src/GPU3D_OpenGL43.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 133 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 0837f56..ccb8698 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -70,7 +70,24 @@ PFNGLBINDIMAGETEXTUREPROC glBindImageTexture; PFNGLGETSTRINGIPROC glGetStringi; -const char* kRenderVS = R"(#version 420 +const char* kShaderHeader = "#version 420"; + + +const char* kRenderVSCommon = R"( + +// common shit goes here +)"; + +const char* kRenderFSCommon = R"( + +vec4 FinalColor(vec4 col) +{ + return col.bgra * vec4(63.0/255.0, 63.0/255.0, 63.0/255.0, 31.0/255.0); +} +)"; + + +const char* kRenderVS_Z = R"( layout(location=0) in uvec4 vPosition; layout(location=1) in uvec4 vColor; @@ -88,7 +105,7 @@ void main() fpos.x = ((float(vPosition.x) * 2.0) / 256.0) - 1.0; fpos.y = ((float(vPosition.y) * 2.0) / 192.0) - 1.0; fpos.z = float(vPosition.z << zshift) / 16777216.0; - fpos.w = float(vPosition.w) / 65535.0f; + fpos.w = float(vPosition.w) / 65536.0f; fpos.xyz *= fpos.w; fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); @@ -97,7 +114,36 @@ void main() } )"; -const char* kRenderFS = R"(#version 420 +const char* kRenderVS_W = R"( + +layout(location=0) in uvec4 vPosition; +layout(location=1) in uvec4 vColor; +layout(location=2) in uvec2 vTexcoord; +layout(location=3) in uvec3 vPolygonAttr; + +smooth out float fZ; +smooth out vec4 fColor; + +void main() +{ + uint attr = vPolygonAttr.x; + uint zshift = (attr >> 16) & 0x1F; + + vec4 fpos; + fpos.x = ((float(vPosition.x) * 2.0) / 256.0) - 1.0; + fpos.y = ((float(vPosition.y) * 2.0) / 192.0) - 1.0; + fZ = float(vPosition.z << zshift) / 16777216.0; + fpos.w = float(vPosition.w) / 65536.0f; + fpos.xy *= fpos.w; + + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + + gl_Position = fpos; +} +)"; + + +const char* kRenderFS_Z = R"( smooth in vec4 fColor; @@ -110,12 +156,38 @@ void main() finalcolor.rgb = fColor.rgb; finalcolor.a = 1.0; - oColor = finalcolor.bgra * vec4(63.0/255.0, 63.0/255.0, 63.0/255.0, 31.0/255.0); + oColor = FinalColor(finalcolor); } )"; +const char* kRenderFS_W = R"( -GLuint RenderShader[3]; +smooth in float fZ; +smooth in vec4 fColor; + +out vec4 oColor; + +void main() +{ + vec4 finalcolor; + + finalcolor.rgb = fColor.rgb; + finalcolor.a = 1.0; + + oColor = FinalColor(finalcolor); + + gl_FragDepth = fZ; +} +)"; + + +enum +{ + RenderFlag_WBuffer = 0x01, +}; + + +GLuint RenderShader[16][3]; // vertex buffer // * XYZW: 4x16bit @@ -127,7 +199,7 @@ GLuint RenderShader[3]; // * bit4-7, 11, 14-15, 24-29: POLYGON_ATTR // * bit16-20: Z shift // * bit8: front-facing (?) -// * bit9: W-buffering +// * bit9: W-buffering (?) GLuint VertexBufferID; u32 VertexBuffer[10240 * 7]; @@ -265,6 +337,40 @@ bool BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* return true; } +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 = BuildShaderProgram(vsbuf, fsbuf, RenderShader[flags], shadername); + + delete[] vsbuf; + delete[] fsbuf; + + return ret; +} + +void UseRenderShader(u32 flags) +{ + glUseProgram(RenderShader[flags][2]); +} + bool Init() { if (!InitGLExtensions()) return false; @@ -298,8 +404,10 @@ bool Init() glClearDepth(1.0); - if (!BuildShaderProgram(kRenderVS, kRenderFS, RenderShader, "RenderShader")) - return false; + //if (!BuildShaderProgram(kRenderVS, kRenderFS, RenderShader, "RenderShader")) + // return false; + if (!BuildRenderShader(0, kRenderVS_Z, kRenderFS_Z)) return false; + if (!BuildRenderShader(RenderFlag_WBuffer, kRenderVS_W, kRenderFS_W)) return false; glGenBuffers(1, &VertexBufferID); @@ -456,22 +564,27 @@ void RenderFrame() delete[] dorp; } - // render shit here - glUseProgram(RenderShader[2]); + if (RenderNumPolygons) + { + // render shit here + u32 flags = 0; + if (RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer; + UseRenderShader(flags); - glBindTexture(GL_TEXTURE_2D, AuxBufferID); - glBindImageTexture(0, AuxBufferID, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32UI); + glBindTexture(GL_TEXTURE_2D, AuxBufferID); + glBindImageTexture(0, AuxBufferID, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32UI); - // zorp - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); + // zorp + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); - BuildPolygons(&RenderPolygonRAM[0], RenderNumPolygons); - glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); - glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); + BuildPolygons(&RenderPolygonRAM[0], RenderNumPolygons); + glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); + glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); - glBindVertexArray(VertexArrayID); - glDrawElements(GL_TRIANGLES, NumTriangles*3, GL_UNSIGNED_SHORT, IndexBuffer); + glBindVertexArray(VertexArrayID); + glDrawElements(GL_TRIANGLES, NumTriangles*3, GL_UNSIGNED_SHORT, IndexBuffer); + } glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); -- cgit v1.2.3 From 2a63ba40d7c20719c5a09f1eb061a3fa80d7889e Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 29 Apr 2019 04:19:56 +0200 Subject: support 256-color textures. but ass-batteringly shitty. --- src/GPU3D_OpenGL43.cpp | 208 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 158 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index ccb8698..121d8e8 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -65,6 +65,7 @@ PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLDELETESHADERPROC glDeleteShader; PFNGLDELETEPROGRAMPROC glDeleteProgram; +PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLBINDIMAGETEXTUREPROC glBindImageTexture; PFNGLGETSTRINGIPROC glGetStringi; @@ -75,13 +76,64 @@ const char* kShaderHeader = "#version 420"; const char* kRenderVSCommon = R"( -// common shit goes here +layout(location=0) in uvec4 vPosition; +layout(location=1) in uvec4 vColor; +layout(location=2) in ivec2 vTexcoord; +layout(location=3) in uvec3 vPolygonAttr; + +smooth out vec4 fColor; +smooth out vec2 fTexcoord; +flat out uvec3 fPolygonAttr; )"; const char* kRenderFSCommon = R"( -vec4 FinalColor(vec4 col) +layout(binding=0) uniform usampler2D TexMem; +layout(binding=1) uniform sampler2D TexPalMem; + +smooth in vec4 fColor; +smooth in vec2 fTexcoord; +flat in uvec3 fPolygonAttr; + +out vec4 oColor; + +vec4 TextureLookup() +{ + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + + int vramaddr = int(attr & 0xFFFF) << 3; + ivec2 st = ivec2(fTexcoord); + + st.x &= (tw-1); + st.y &= (th-1); + + uint type = (attr >> 26) & 0x7; + if (type == 4) + { + vramaddr += ((st.y * tw) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + + paladdr = (paladdr << 3) + pixel.r; + vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + + return vec4(color.rgb, 1); + } + + return vec4(0,0,1,1); +} + +vec4 FinalColor() { + vec4 col; + vec4 vcol = vec4(fColor.rgb,1.0); + vec4 tcol = TextureLookup(); + + col = vcol * tcol; + return col.bgra * vec4(63.0/255.0, 63.0/255.0, 63.0/255.0, 31.0/255.0); } )"; @@ -89,13 +141,6 @@ vec4 FinalColor(vec4 col) const char* kRenderVS_Z = R"( -layout(location=0) in uvec4 vPosition; -layout(location=1) in uvec4 vColor; -layout(location=2) in uvec2 vTexcoord; -layout(location=3) in uvec3 vPolygonAttr; - -smooth out vec4 fColor; - void main() { uint attr = vPolygonAttr.x; @@ -109,6 +154,8 @@ void main() fpos.xyz *= fpos.w; fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; gl_Position = fpos; } @@ -116,13 +163,7 @@ void main() const char* kRenderVS_W = R"( -layout(location=0) in uvec4 vPosition; -layout(location=1) in uvec4 vColor; -layout(location=2) in uvec2 vTexcoord; -layout(location=3) in uvec3 vPolygonAttr; - smooth out float fZ; -smooth out vec4 fColor; void main() { @@ -137,6 +178,8 @@ void main() fpos.xy *= fpos.w; fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; gl_Position = fpos; } @@ -145,36 +188,19 @@ void main() const char* kRenderFS_Z = R"( -smooth in vec4 fColor; - -out vec4 oColor; - void main() { - vec4 finalcolor; - - finalcolor.rgb = fColor.rgb; - finalcolor.a = 1.0; - - oColor = FinalColor(finalcolor); + oColor = FinalColor(); } )"; const char* kRenderFS_W = R"( smooth in float fZ; -smooth in vec4 fColor; - -out vec4 oColor; void main() { - vec4 finalcolor; - - finalcolor.rgb = fColor.rgb; - finalcolor.a = 1.0; - - oColor = FinalColor(finalcolor); + oColor = FinalColor(); gl_FragDepth = fZ; } @@ -209,6 +235,9 @@ GLuint VertexArrayID; u16 IndexBuffer[2048 * 10]; u32 NumTriangles; +GLuint TexMemID; +GLuint TexPalMemID; + GLuint FramebufferTex[2]; GLuint FramebufferID, PixelbufferID; u8 Framebuffer[256*192*4]; @@ -258,6 +287,7 @@ bool InitGLExtensions() LOADPROC(GLDELETESHADER, glDeleteShader); LOADPROC(GLDELETEPROGRAM, glDeleteProgram); + LOADPROC(GLACTIVETEXTURE, glActiveTexture); LOADPROC(GLBINDIMAGETEXTURE, glBindImageTexture); LOADPROC(GLGETSTRINGI, glGetStringi); @@ -284,6 +314,7 @@ bool BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* 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]); @@ -304,6 +335,7 @@ bool BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* 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]); @@ -386,6 +418,9 @@ bool Init() 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); @@ -421,7 +456,7 @@ bool Init() glEnableVertexAttribArray(1); // color glVertexAttribIPointer(1, 4, GL_UNSIGNED_BYTE, 7*4, (void*)(2*4)); glEnableVertexAttribArray(2); // texcoords - glVertexAttribIPointer(2, 2, GL_UNSIGNED_SHORT, 7*4, (void*)(3*4)); + glVertexAttribIPointer(2, 2, GL_SHORT, 7*4, (void*)(3*4)); glEnableVertexAttribArray(3); // attrib glVertexAttribIPointer(3, 3, GL_UNSIGNED_INT, 7*4, (void*)(4*4)); @@ -452,13 +487,23 @@ bool Init() //glBufferData(GL_PIXEL_PACK_BUFFER, 256*48*4, NULL, GL_DYNAMIC_READ); glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); - glGenTextures(1, &AuxBufferID); - glBindTexture(GL_TEXTURE_2D, AuxBufferID); + 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_RG32UI, 256, 192, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, NULL); + 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; } @@ -473,7 +518,7 @@ void Reset() // } - +//u64 texpool1[1024]; u32 texpool2[1024]; void BuildPolygons(Polygon** polygons, int npolys) { u32* vptr = &VertexBuffer[0]; @@ -482,11 +527,40 @@ void BuildPolygons(Polygon** polygons, int npolys) u16* iptr = &IndexBuffer[0]; u32 numtriangles = 0; + /*memset(texpool1, 0, 1024*8); + memset(texpool2, 0, 1024*4); + u32 texcount1 = 0, texcount2 = 0; + + u32 texsizecnt[64]; + memset(texsizecnt, 0, 64*4);*/ + for (int i = 0; i < npolys; i++) { Polygon* poly = polygons[i]; if (poly->Degenerate) continue; + /*u32 tid1 = -1, tid2 = -1; + for (int k = 0; k < 1024; k++) + { + if (texpool1[k] == ((u64)poly->TexParam | ((u64)poly->TexPalette << 32))) + { + tid1 = k; + } + if (texpool2[k] == poly->TexParam) + { + tid2 = k; + } + } + if (tid1 == -1) + { + texpool1[texcount1++] = ((u64)poly->TexParam | ((u64)poly->TexPalette << 32)); + } + if (tid2 == -1) + { + texpool2[texcount2++] = poly->TexParam; + texsizecnt[(poly->TexParam >> 20) & 0x3F]++; + }*/ + u32 vidx_first = vidx; u32 polyattr = poly->Attr; @@ -539,6 +613,17 @@ void BuildPolygons(Polygon** polygons, int npolys) NumTriangles = numtriangles; NumVertices = vidx; + /*printf("polygons done: %d | textures by attr+pal: %d | textures by attr: %d\n", RenderNumPolygons, texcount1, texcount2); + printf("texture sizes: "); + for (int s = 0; s < 64; s++) + { + u32 n = texsizecnt[s]; + if (!n) continue; + int sizes = 8 << (s & 0x7); + int sizet = 8 << (s >> 3); + printf("%dx%d: %d, ", sizes, sizet, n); + } + printf("\n");*/ } @@ -552,18 +637,41 @@ void RenderFrame() glClearColor(0, 0, 0, 31.0/255.0); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // SUCKY!!!!!!!!!!!!!!!!!! + // TODO: detect when VRAM blocks are modified! + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, TexMemID); + for (int i = 0; i < 4; i++) { - u32* dorp = new u32[256*192*2]; - for (int i = 0; i < 256*192; i++) - { - dorp[i*2+0] = 0xFFFFFF; - dorp[i*2+1] = 0; - } - glBindTexture(GL_TEXTURE_2D, AuxBufferID); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RG_INTEGER, GL_UNSIGNED_INT, dorp); - delete[] dorp; + 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); + } + + //glActiveTexture(GL_TEXTURE0); + if (RenderNumPolygons) { // render shit here @@ -571,8 +679,8 @@ void RenderFrame() if (RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer; UseRenderShader(flags); - glBindTexture(GL_TEXTURE_2D, AuxBufferID); - glBindImageTexture(0, AuxBufferID, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32UI); + //glBindTexture(GL_TEXTURE_2D, AuxBufferID); + //glBindImageTexture(0, AuxBufferID, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32UI); // zorp glEnable(GL_DEPTH_TEST); -- cgit v1.2.3 From eb9cfd12d4e85f224df8954cdeca79a20a604045 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 29 Apr 2019 13:05:15 +0200 Subject: * add type5 textures * fix texture distortion. I knew it was something stupid like that. --- src/GPU3D_OpenGL43.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 121d8e8..02c20b9 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -122,6 +122,80 @@ vec4 TextureLookup() return vec4(color.rgb, 1); } + else if (type == 5) + { + vramaddr += ((st.y & 0x3FC) * (tw>>2)) + (st.x & 0x3FC) + (st.y & 0x3); + uvec4 p = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; + + int slot1addr = 0x20000 + ((vramaddr & 0x1FFFC) >> 1); + if (vramaddr >= 0x40000) slot1addr += 0x10000; + + uint palinfo; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo = p.r; + slot1addr++; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo |= (p.r << 8); + + paladdr = (paladdr << 3) + ((palinfo & 0x3FFF) << 1); + palinfo >>= 14; + + if (val == 0) + { + vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 1) + { + paladdr++; + vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 2) + { + if (palinfo == 1) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + paladdr++; + vec4 color1 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + paladdr++; + vec4 color1 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); + } + else + { + paladdr += 2; + vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + return vec4(color.rgb, 1.0); + } + } + else + { + if (palinfo == 2) + { + paladdr += 3; + vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + paladdr++; + vec4 color1 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); + } + else + { + return vec4(0.0); + } + } + } return vec4(0,0,1,1); } @@ -592,7 +666,7 @@ void BuildPolygons(Polygon** polygons, int npolys) ((vtx->FinalColor[2] >> 1) << 16) | (alpha << 24); - *vptr++ = vtx->TexCoords[0] | (vtx->TexCoords[1] << 16); + *vptr++ = (u16)vtx->TexCoords[0] | ((u16)vtx->TexCoords[1] << 16); *vptr++ = vtxattr | (zshift << 16); *vptr++ = poly->TexParam; -- cgit v1.2.3 From e7be82430b183bbdc424dbb0858fa5ee4056a8de Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 29 Apr 2019 18:24:36 +0200 Subject: texcoord wrap modes --- src/GPU3D_OpenGL43.cpp | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 02c20b9..4292638 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -108,8 +108,35 @@ vec4 TextureLookup() int vramaddr = int(attr & 0xFFFF) << 3; ivec2 st = ivec2(fTexcoord); - st.x &= (tw-1); - st.y &= (th-1); + if ((attr & (1<<16)) != 0) + { + if ((attr & (1<<18)) != 0) + { + if ((st.x & tw) != 0) + st.x = (tw-1) - (st.x & (tw-1)); + else + st.x = (st.x & (tw-1)); + } + else + st.x &= (tw-1); + } + else + st.x = clamp(st.x, 0, tw-1); + + if ((attr & (1<<17)) != 0) + { + if ((attr & (1<<19)) != 0) + { + if ((st.y & th) != 0) + st.y = (th-1) - (st.y & (th-1)); + else + st.y = (st.y & (th-1)); + } + else + st.y &= (th-1); + } + else + st.y = clamp(st.y, 0, th-1); uint type = (attr >> 26) & 0x7; if (type == 4) -- cgit v1.2.3 From 41e7af8412440941f8da9ca86b2089d91815e2fb Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 29 Apr 2019 18:47:32 +0200 Subject: add remaining texture types --- src/GPU3D_OpenGL43.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 4292638..964216a 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -102,6 +102,10 @@ vec4 TextureLookup() uint attr = fPolygonAttr.y; uint paladdr = fPolygonAttr.z; + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + int tw = 8 << int((attr >> 20) & 0x7); int th = 8 << int((attr >> 23) & 0x7); @@ -139,7 +143,45 @@ vec4 TextureLookup() st.y = clamp(st.y, 0, th-1); uint type = (attr >> 26) & 0x7; - if (type == 4) + if (type == 1) + { + vramaddr += ((st.y * tw) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + + pixel.a = (pixel.r & 0xE0); + pixel.a = (pixel.a >> 3) + (pixel.a >> 6); + pixel.r &= 0x1F; + + paladdr = (paladdr << 3) + pixel.r; + vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); + } + else if (type == 2) + { + vramaddr += ((st.y * tw) + st.x) >> 2; + uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + pixel.r >>= (2 * (st.x & 3)); + pixel.r &= 0x03; + + paladdr = (paladdr << 2) + pixel.r; + vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + + return vec4(color.rgb, step(1,pixel.r)*alpha0); + } + else if (type == 3) + { + vramaddr += ((st.y * tw) + st.x) >> 1; + uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + if ((st.x & 1) != 0) pixel.r >>= 4; + else pixel.r &= 0x0F; + + paladdr = (paladdr << 3) + pixel.r; + vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + + return vec4(color.rgb, step(1,pixel.r)*alpha0); + } + else if (type == 4) { vramaddr += ((st.y * tw) + st.x); uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); @@ -147,7 +189,7 @@ vec4 TextureLookup() paladdr = (paladdr << 3) + pixel.r; vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4(color.rgb, 1); + return vec4(color.rgb, step(1,pixel.r)*alpha0); } else if (type == 5) { @@ -223,17 +265,53 @@ vec4 TextureLookup() } } } + else if (type == 6) + { + vramaddr += ((st.y * tw) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + + pixel.a = (pixel.r & 0xF8) >> 3; + pixel.r &= 0x07; + + paladdr = (paladdr << 3) + pixel.r; + vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4(0,0,1,1); + return vec4(color.rgb, float(pixel.a)/31.0); + } + else + { + vramaddr += ((st.y * tw) + st.x) << 1; + uvec4 pixelL = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + vramaddr++; + uvec4 pixelH = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + + vec4 color; + color.r = float(pixelL.r & 0x1F) / 31.0; + color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; + color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; + color.a = float(pixelH.r >> 7); + + return color; + } } vec4 FinalColor() { vec4 col; vec4 vcol = vec4(fColor.rgb,1.0); - vec4 tcol = TextureLookup(); - col = vcol * tcol; + // TODO: also check DISPCNT + if (((fPolygonAttr.y >> 26) & 0x7) == 0) + { + // no texture + col = vcol; + } + else + { + vec4 tcol = TextureLookup(); + + col = vcol * tcol; + } return col.bgra * vec4(63.0/255.0, 63.0/255.0, 63.0/255.0, 31.0/255.0); } -- cgit v1.2.3 From ffa0ddd94c6c3887de574214872e3185ea027e99 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 29 Apr 2019 18:52:23 +0200 Subject: fix the alpha0 shit --- src/GPU3D_OpenGL43.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 964216a..21a77c1 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -167,7 +167,7 @@ vec4 TextureLookup() paladdr = (paladdr << 2) + pixel.r; vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4(color.rgb, step(1,pixel.r)*alpha0); + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); } else if (type == 3) { @@ -179,7 +179,7 @@ vec4 TextureLookup() paladdr = (paladdr << 3) + pixel.r; vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4(color.rgb, step(1,pixel.r)*alpha0); + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); } else if (type == 4) { @@ -189,7 +189,7 @@ vec4 TextureLookup() paladdr = (paladdr << 3) + pixel.r; vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4(color.rgb, step(1,pixel.r)*alpha0); + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); } else if (type == 5) { -- cgit v1.2.3 From 88bc76545504a8284f6810d996c2a0d9706e6915 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 29 Apr 2019 19:13:20 +0200 Subject: don't lose half the zbuffer range --- src/GPU3D_OpenGL43.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 21a77c1..0197546 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -328,7 +328,7 @@ void main() vec4 fpos; fpos.x = ((float(vPosition.x) * 2.0) / 256.0) - 1.0; fpos.y = ((float(vPosition.y) * 2.0) / 192.0) - 1.0; - fpos.z = float(vPosition.z << zshift) / 16777216.0; + fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; fpos.w = float(vPosition.w) / 65536.0f; fpos.xyz *= fpos.w; -- cgit v1.2.3 From 8c2b4b4813bc163ca8add5baaa5f692b85d347f6 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 1 May 2019 23:35:48 +0200 Subject: very evil shit --- src/GPU3D_OpenGL43.cpp | 158 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 103 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 0197546..b28afff 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -365,22 +365,52 @@ void main() )"; -const char* kRenderFS_Z = R"( +const char* kRenderFS_ZO = R"( void main() { - oColor = FinalColor(); + vec4 col = FinalColor(); + if (col.a < 31.0/255.0) discard; + + oColor = col; } )"; -const char* kRenderFS_W = R"( +const char* kRenderFS_WO = R"( smooth in float fZ; void main() { - oColor = FinalColor(); + vec4 col = FinalColor(); + if (col.a < 31.0/255.0) discard; + oColor = col; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZT = R"( + +void main() +{ + vec4 col = FinalColor(); + if (col.a > 30.0/255.0) discard; + + oColor = col; +} +)"; + +const char* kRenderFS_WT = R"( + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a > 30.0/255.0) discard; + + oColor = col; gl_FragDepth = fZ; } )"; @@ -389,11 +419,23 @@ void main() enum { RenderFlag_WBuffer = 0x01, + RenderFlag_Trans = 0x02, }; GLuint RenderShader[16][3]; +typedef struct +{ + Polygon* PolyData; + + u16* Indices; + u32 RenderKey; + +} RendererPolygon; + +RendererPolygon PolygonList[2048]; + // vertex buffer // * XYZW: 4x16bit // * RGBA: 4x8bit @@ -422,8 +464,6 @@ GLuint FramebufferID, PixelbufferID; u8 Framebuffer[256*192*4]; u8 CurLine[256*4]; -GLuint AuxBufferID; - bool InitGLExtensions() { @@ -620,8 +660,14 @@ bool Init() //if (!BuildShaderProgram(kRenderVS, kRenderFS, RenderShader, "RenderShader")) // return false; - if (!BuildRenderShader(0, kRenderVS_Z, kRenderFS_Z)) return false; - if (!BuildRenderShader(RenderFlag_WBuffer, kRenderVS_W, kRenderFS_W)) return false; + 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; glGenBuffers(1, &VertexBufferID); @@ -697,8 +743,43 @@ void Reset() // } -//u64 texpool1[1024]; u32 texpool2[1024]; -void BuildPolygons(Polygon** polygons, int npolys) + +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) + { + 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; + } + } +} + +void BuildPolygons(RendererPolygon* polygons, int npolys) { u32* vptr = &VertexBuffer[0]; u32 vidx = 0; @@ -706,39 +787,12 @@ void BuildPolygons(Polygon** polygons, int npolys) u16* iptr = &IndexBuffer[0]; u32 numtriangles = 0; - /*memset(texpool1, 0, 1024*8); - memset(texpool2, 0, 1024*4); - u32 texcount1 = 0, texcount2 = 0; - - u32 texsizecnt[64]; - memset(texsizecnt, 0, 64*4);*/ - for (int i = 0; i < npolys; i++) { - Polygon* poly = polygons[i]; - if (poly->Degenerate) continue; + RendererPolygon* rp = &polygons[i]; + Polygon* poly = rp->PolyData; - /*u32 tid1 = -1, tid2 = -1; - for (int k = 0; k < 1024; k++) - { - if (texpool1[k] == ((u64)poly->TexParam | ((u64)poly->TexPalette << 32))) - { - tid1 = k; - } - if (texpool2[k] == poly->TexParam) - { - tid2 = k; - } - } - if (tid1 == -1) - { - texpool1[texcount1++] = ((u64)poly->TexParam | ((u64)poly->TexPalette << 32)); - } - if (tid2 == -1) - { - texpool2[texcount2++] = poly->TexParam; - texsizecnt[(poly->TexParam >> 20) & 0x3F]++; - }*/ + rp->Indices = iptr; u32 vidx_first = vidx; @@ -792,17 +846,6 @@ void BuildPolygons(Polygon** polygons, int npolys) NumTriangles = numtriangles; NumVertices = vidx; - /*printf("polygons done: %d | textures by attr+pal: %d | textures by attr: %d\n", RenderNumPolygons, texcount1, texcount2); - printf("texture sizes: "); - for (int s = 0; s < 64; s++) - { - u32 n = texsizecnt[s]; - if (!n) continue; - int sizes = 8 << (s & 0x7); - int sizet = 8 << (s >> 3); - printf("%dx%d: %d, ", sizes, sizet, n); - } - printf("\n");*/ } @@ -856,16 +899,21 @@ void RenderFrame() // render shit here u32 flags = 0; if (RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer; - UseRenderShader(flags); - //glBindTexture(GL_TEXTURE_2D, AuxBufferID); - //glBindImageTexture(0, AuxBufferID, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32UI); + int npolys = 0; + for (int i = 0; i < RenderNumPolygons; i++) + { + if (RenderPolygonRAM[i]->Degenerate) continue; + SetupPolygon(&PolygonList[npolys++], RenderPolygonRAM[i]); + } + + UseRenderShader(flags); // zorp glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); - BuildPolygons(&RenderPolygonRAM[0], RenderNumPolygons); + BuildPolygons(&PolygonList[0], npolys); glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); -- cgit v1.2.3 From 4a776f5d5b8a91bb83348941673ebbddb630aa7f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 2 May 2019 02:28:31 +0200 Subject: half-proper screen clear. still missing bitmap mode, but atleast you can play NSMB without being in the dark. --- src/GPU3D_OpenGL43.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 103 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index b28afff..9ad078c 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -48,6 +48,7 @@ PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; PFNGLBINDVERTEXARRAYPROC glBindVertexArray; PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; @@ -64,6 +65,8 @@ PFNGLGETPROGRAMIVPROC glGetProgramiv; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLDELETESHADERPROC glDeleteShader; PFNGLDELETEPROGRAMPROC glDeleteProgram; +PFNGLUNIFORM1UIPROC glUniform1ui; +PFNGLUNIFORM4UIPROC glUniform4ui; PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLBINDIMAGETEXTUREPROC glBindImageTexture; @@ -71,7 +74,33 @@ PFNGLBINDIMAGETEXTUREPROC glBindImageTexture; PFNGLGETSTRINGIPROC glGetStringi; -const char* kShaderHeader = "#version 420"; +#define kShaderHeader "#version 430" + + +const char* kClearVS = kShaderHeader R"( + +layout(location=0) in vec2 vPosition; + +layout(location=1) uniform uint uDepth; + +void main() +{ + float fdepth = (float(uDepth) / 8388608.0) - 1.0; + gl_Position = vec4(vPosition, fdepth, 1.0); +} +)"; + +const char* kClearFS = kShaderHeader R"( + +layout(location=0) uniform uvec4 uColor; + +out vec4 oColor; + +void main() +{ + oColor = vec4(uColor).bgra / 255.0; +} +)"; const char* kRenderVSCommon = R"( @@ -423,6 +452,8 @@ enum }; +GLuint ClearShaderPlain[3]; + GLuint RenderShader[16][3]; typedef struct @@ -436,6 +467,8 @@ typedef struct RendererPolygon PolygonList[2048]; +GLuint ClearVertexBufferID, ClearVertexArrayID; + // vertex buffer // * XYZW: 4x16bit // * RGBA: 4x8bit @@ -459,7 +492,7 @@ u32 NumTriangles; GLuint TexMemID; GLuint TexPalMemID; -GLuint FramebufferTex[2]; +GLuint FramebufferTex[3]; GLuint FramebufferID, PixelbufferID; u8 Framebuffer[256*192*4]; u8 CurLine[256*4]; @@ -489,6 +522,7 @@ bool InitGLExtensions() LOADPROC(GLDELETEVERTEXARRAYS, glDeleteVertexArrays); LOADPROC(GLBINDVERTEXARRAY, glBindVertexArray); LOADPROC(GLENABLEVERTEXATTRIBARRAY, glEnableVertexAttribArray); + LOADPROC(GLDISABLEVERTEXATTRIBARRAY, glDisableVertexAttribArray); LOADPROC(GLVERTEXATTRIBPOINTER, glVertexAttribPointer); LOADPROC(GLVERTEXATTRIBIPOINTER, glVertexAttribIPointer); @@ -505,6 +539,8 @@ bool InitGLExtensions() LOADPROC(GLGETPROGRAMINFOLOG, glGetProgramInfoLog); LOADPROC(GLDELETESHADER, glDeleteShader); LOADPROC(GLDELETEPROGRAM, glDeleteProgram); + LOADPROC(GLUNIFORM1UI, glUniform1ui); + LOADPROC(GLUNIFORM4UI, glUniform4ui); LOADPROC(GLACTIVETEXTURE, glActiveTexture); LOADPROC(GLBINDIMAGETEXTURE, glBindImageTexture); @@ -651,6 +687,8 @@ bool Init() printf("- %s\n", ext); }*/ + glEnable(GL_DEPTH_TEST); + // TODO: make configurable (hires, etc) glViewport(0, 0, 256, 192); @@ -658,8 +696,9 @@ bool Init() glClearDepth(1.0); - //if (!BuildShaderProgram(kRenderVS, kRenderFS, RenderShader, "RenderShader")) - // return false; + if (!BuildShaderProgram(kClearVS, kClearFS, ClearShaderPlain, "ClearShader")) + return false; + if (!BuildRenderShader(0, kRenderVS_Z, kRenderFS_ZO)) return false; if (!BuildRenderShader(RenderFlag_WBuffer, @@ -670,6 +709,27 @@ bool Init() kRenderVS_W, kRenderFS_WT)) return false; + 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); @@ -707,6 +767,15 @@ bool Init() glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 256, 192, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); // welp glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, FramebufferTex[1], 0); + glGenTextures(1, &FramebufferTex[2]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_STENCIL_INDEX, 256, 192, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, NULL); + glFramebufferTexture(GL_FRAMEBUFFER, GL_STENCIL_INDEX, FramebufferTex[2], 0); + glGenBuffers(1, &PixelbufferID); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); //glBufferData(GL_PIXEL_PACK_BUFFER, 256*48*4, NULL, GL_DYNAMIC_READ); @@ -855,11 +924,6 @@ void VCount144() void RenderFrame() { - // TODO: proper clear color!! - glClearColor(0, 0, 0, 31.0/255.0); - glClearDepth(1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - // SUCKY!!!!!!!!!!!!!!!!!! // TODO: detect when VRAM blocks are modified! glActiveTexture(GL_TEXTURE0); @@ -892,7 +956,30 @@ void RenderFrame() glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i*8, 1024, 8, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, vram); } - //glActiveTexture(GL_TEXTURE0); + // clear buffers + // TODO: clear bitmap + { + glUseProgram(ClearShaderPlain[2]); + glDepthFunc(GL_ALWAYS); + glDepthMask(GL_TRUE); + + u32 r = RenderClearAttr1 & 0x1F; + u32 g = (RenderClearAttr1 >> 5) & 0x1F; + u32 b = (RenderClearAttr1 >> 10) & 0x1F; + u32 a = (RenderClearAttr1 >> 16) & 0x1F; + u32 z = ((RenderClearAttr2 & 0x7FFF) * 0x200) + 0x1FF; + + if (r) r = r*2 + 1; + if (g) g = g*2 + 1; + if (b) b = b*2 + 1; + + glUniform4ui(0, r, g, b, a); + glUniform1ui(1, z); + + glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID); + glBindVertexArray(ClearVertexArrayID); + glDrawArrays(GL_TRIANGLES, 0, 2*3); + } if (RenderNumPolygons) { @@ -907,16 +994,17 @@ void RenderFrame() SetupPolygon(&PolygonList[npolys++], RenderPolygonRAM[i]); } + BuildPolygons(&PolygonList[0], npolys); + glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); + glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); + + // pass 1: opaque pixels + UseRenderShader(flags); // zorp - glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); - BuildPolygons(&PolygonList[0], npolys); - glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); - glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); - glBindVertexArray(VertexArrayID); glDrawElements(GL_TRIANGLES, NumTriangles*3, GL_UNSIGNED_SHORT, IndexBuffer); } -- cgit v1.2.3 From 1e29e1242d2920427a1d0e95e5b43200c795cd89 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 2 May 2019 04:16:48 +0200 Subject: beginning work on transparency support. floats suck. depth/stencil textures suck. the world sucks. burn it down. r e v o l u t i o n in the meantime getting this shit working wouldn't be too bad tho. --- src/GPU3D_OpenGL43.cpp | 130 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 118 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 9ad078c..2d7a757 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -98,7 +98,7 @@ out vec4 oColor; void main() { - oColor = vec4(uColor).bgra / 255.0; + oColor = vec4(uColor).bgra / 31.0; } )"; @@ -327,7 +327,7 @@ vec4 TextureLookup() vec4 FinalColor() { vec4 col; - vec4 vcol = vec4(fColor.rgb,1.0); + vec4 vcol = fColor; // TODO: also check DISPCNT if (((fPolygonAttr.y >> 26) & 0x7) == 0) @@ -342,7 +342,7 @@ vec4 FinalColor() col = vcol * tcol; } - return col.bgra * vec4(63.0/255.0, 63.0/255.0, 63.0/255.0, 31.0/255.0); + return col.bgra; } )"; @@ -399,7 +399,7 @@ const char* kRenderFS_ZO = R"( void main() { vec4 col = FinalColor(); - if (col.a < 31.0/255.0) discard; + if (col.a < 30.5/31) discard; oColor = col; } @@ -412,7 +412,7 @@ smooth in float fZ; void main() { vec4 col = FinalColor(); - if (col.a < 31.0/255.0) discard; + if (col.a < 30.5/31) discard; oColor = col; gl_FragDepth = fZ; @@ -424,7 +424,8 @@ const char* kRenderFS_ZT = R"( void main() { vec4 col = FinalColor(); - if (col.a > 30.0/255.0) discard; + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; oColor = col; } @@ -437,7 +438,8 @@ smooth in float fZ; void main() { vec4 col = FinalColor(); - if (col.a > 30.0/255.0) discard; + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; oColor = col; gl_FragDepth = fZ; @@ -688,6 +690,10 @@ bool Init() }*/ glEnable(GL_DEPTH_TEST); + glEnable(GL_STENCIL_TEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // TODO: make configurable (hires, etc) @@ -758,7 +764,7 @@ bool Init() glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); - glGenTextures(1, &FramebufferTex[1]); + /*glGenTextures(1, &FramebufferTex[1]); glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -774,7 +780,16 @@ 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_STENCIL_INDEX, 256, 192, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, NULL); - glFramebufferTexture(GL_FRAMEBUFFER, GL_STENCIL_INDEX, FramebufferTex[2], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, FramebufferTex[2], 0);*/ + + glGenTextures(1, &FramebufferTex[1]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 192, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); printf("%04X\n", glGetError()); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[1], 0);printf("%04X\n", glGetError()); glGenBuffers(1, &PixelbufferID); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); @@ -956,8 +971,12 @@ void RenderFrame() glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i*8, 1024, 8, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, vram); } + glDisable(GL_BLEND); + // 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); @@ -969,9 +988,20 @@ void RenderFrame() u32 a = (RenderClearAttr1 >> 16) & 0x1F; u32 z = ((RenderClearAttr2 & 0x7FFF) * 0x200) + 0x1FF; - if (r) r = r*2 + 1; + if (a == 0) + { + glStencilFunc(GL_ALWAYS, 0x80, 0xFF); + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + } + else + { + glStencilFunc(GL_ALWAYS, 0, 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; + if (b) b = b*2 + 1;*/ glUniform4ui(0, r, g, b, a); glUniform1ui(1, z); @@ -988,10 +1018,16 @@ void RenderFrame() 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; - SetupPolygon(&PolygonList[npolys++], RenderPolygonRAM[i]); + + SetupPolygon(&PolygonList[npolys], RenderPolygonRAM[i]); + if (firsttrans < 0 && RenderPolygonRAM[i]->Translucent) + firsttrans = npolys; + + npolys++; } BuildPolygons(&PolygonList[0], npolys); @@ -1005,8 +1041,69 @@ void RenderFrame() // zorp glDepthFunc(GL_LESS); + glStencilFunc(GL_ALWAYS, 0, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glBindVertexArray(VertexArrayID); glDrawElements(GL_TRIANGLES, NumTriangles*3, GL_UNSIGNED_SHORT, IndexBuffer); + + // pass 2: if needed, render translucent pixels that are against background pixels + + glEnable(GL_BLEND); + UseRenderShader(flags | RenderFlag_Trans); + + u16* iptr; + u32 curkey; + + /*if ((RenderClearAttr1 & 0x001F0000) == 0) + { + glStencilFunc(GL_EQUAL, 0x80, 0x80); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + + // + }*/ + + // pass 3: translucent pixels + + if (firsttrans > -1) + { + iptr = PolygonList[firsttrans].Indices; + curkey = 0xFFFFFFFF; + + for (int i = firsttrans; i < npolys; 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 + + // zorp + glDepthFunc(GL_LESS); + + u32 polyattr = rp->PolyData->Attr; + u32 polyid = (polyattr >> 24) & 0x3F; + + glStencilFunc(GL_NOTEQUAL, 0x40|polyid, 0x7F); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + 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); + } + } } @@ -1051,6 +1148,15 @@ void RequestLine(int line) if (data) memcpy(&Framebuffer[4*256*144], data, 4*256*48); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); }*/ + + u32* ptr = (u32*)&Framebuffer[256*4 * line]; + for (int i = 0; i < 256; i++) + { + u32 rgb = *ptr & 0x00FCFCFC; + u32 a = *ptr & 0xF8000000; + + *ptr++ = (rgb >> 2) | (a >> 3); + } } u32* GetLine(int line) -- cgit v1.2.3 From 3d7708732088bbe0be9fc469a14875bf993497e1 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 2 May 2019 13:44:54 +0200 Subject: betterer transparency support --- src/GPU3D_OpenGL43.cpp | 203 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 165 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 2d7a757..7e5a8d6 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -71,9 +71,17 @@ PFNGLUNIFORM4UIPROC glUniform4ui; PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLBINDIMAGETEXTUREPROC glBindImageTexture; +PFNGLDRAWBUFFERSPROC glDrawBuffers; + +PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei; +PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei; + PFNGLGETSTRINGIPROC glGetStringi; +// GL version requirements +// * explicit uniform location: 4.3 (or extension) + #define kShaderHeader "#version 430" @@ -93,12 +101,17 @@ void main() const char* kClearFS = kShaderHeader R"( layout(location=0) uniform uvec4 uColor; +layout(location=2) uniform uint uOpaquePolyID; +layout(location=3) uniform uint uFogFlag; -out vec4 oColor; +layout(location=0) out vec4 oColor; +layout(location=1) out uvec2 oAttr; void main() { oColor = vec4(uColor).bgra / 31.0; + oAttr.r = uOpaquePolyID; + oAttr.g = uFogFlag; } )"; @@ -124,7 +137,8 @@ smooth in vec4 fColor; smooth in vec2 fTexcoord; flat in uvec3 fPolygonAttr; -out vec4 oColor; +layout(location=0) out vec4 oColor; +layout(location=1) out uvec2 oAttr; vec4 TextureLookup() { @@ -446,11 +460,31 @@ void main() } )"; +const char* kRenderFS_ZS = R"( + +void main() +{ + oColor = vec4(0,0,0,1); +} +)"; + +const char* kRenderFS_WS = R"( + +smooth in float fZ; + +void main() +{ + oColor = vec4(0,0,0,1); + gl_FragDepth = fZ; +} +)"; + enum { - RenderFlag_WBuffer = 0x01, - RenderFlag_Trans = 0x02, + RenderFlag_WBuffer = 0x01, + RenderFlag_Trans = 0x02, + RenderFlag_ShadowMask = 0x04, }; @@ -547,6 +581,11 @@ bool InitGLExtensions() LOADPROC(GLACTIVETEXTURE, glActiveTexture); LOADPROC(GLBINDIMAGETEXTURE, glBindImageTexture); + LOADPROC(GLDRAWBUFFERS, glDrawBuffers); + + LOADPROC(GLBLENDFUNCSEPARATEI, glBlendFuncSeparatei); + LOADPROC(GLBLENDEQUATIONSEPARATEI, glBlendEquationSeparatei); + LOADPROC(GLGETSTRINGI, glGetStringi); #undef LOADPROC @@ -692,9 +731,6 @@ bool Init() glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - // TODO: make configurable (hires, etc) glViewport(0, 0, 256, 192); @@ -713,6 +749,10 @@ bool Init() 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_ZS)) return false; + if (!BuildRenderShader(RenderFlag_ShadowMask | RenderFlag_WBuffer, + kRenderVS_W, kRenderFS_WS)) return false; float clearvtx[6*2] = @@ -788,8 +828,25 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 192, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); printf("%04X\n", glGetError()); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[1], 0);printf("%04X\n", glGetError()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 192, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[1], 0); + + glGenTextures(1, &FramebufferTex[2]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8UI, 256, 192, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, NULL); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[2], 0); + + GLenum fbassign[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; + glDrawBuffers(2, fbassign); + + 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); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); @@ -985,19 +1042,13 @@ void RenderFrame() 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; - if (a == 0) - { - glStencilFunc(GL_ALWAYS, 0x80, 0xFF); - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - } - else - { - glStencilFunc(GL_ALWAYS, 0, 0xFF); - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - } + glStencilFunc(GL_ALWAYS, 0, 0xFF); + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); /*if (r) r = r*2 + 1; if (g) g = g*2 + 1; @@ -1005,6 +1056,8 @@ void RenderFrame() glUniform4ui(0, r, g, b, a); glUniform1ui(1, z); + glUniform1ui(2, polyid); + glUniform1ui(3, fog); glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID); glBindVertexArray(ClearVertexArrayID); @@ -1041,34 +1094,79 @@ void RenderFrame() // zorp glDepthFunc(GL_LESS); - glStencilFunc(GL_ALWAYS, 0, 0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glStencilFunc(GL_ALWAYS, 0xFF, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glBindVertexArray(VertexArrayID); glDrawElements(GL_TRIANGLES, NumTriangles*3, GL_UNSIGNED_SHORT, IndexBuffer); - // pass 2: if needed, render translucent pixels that are against background pixels glEnable(GL_BLEND); UseRenderShader(flags | RenderFlag_Trans); u16* iptr; u32 curkey; + bool lastwasshadow; - /*if ((RenderClearAttr1 & 0x001F0000) == 0) + if (firsttrans > -1) { - glStencilFunc(GL_EQUAL, 0x80, 0x80); - glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + // 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[firsttrans].Indices; + curkey = 0xFFFFFFFF; - // pass 3: translucent pixels + glDisable(GL_BLEND); + + for (int i = firsttrans; i < npolys; 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, 0, 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 - if (firsttrans > -1) - { iptr = PolygonList[firsttrans].Indices; curkey = 0xFFFFFFFF; + lastwasshadow = false; for (int i = firsttrans; i < npolys; i++) { @@ -1084,17 +1182,46 @@ void RenderFrame() // configure new one - // zorp - glDepthFunc(GL_LESS); + if (rp->PolyData->IsShadowMask) + { + if (!lastwasshadow) + { + glDisable(GL_BLEND); + UseRenderShader(flags | RenderFlag_ShadowMask); + + //glStencilFunc(GL_ALWAYS, 0x80, 0x80); + //glStencilOp(GL_REPLACE, GL_REPLACE, GL_KEEP); + + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glDepthMask(GL_FALSE); + + lastwasshadow = true; + } + } + else + { + if (lastwasshadow) + { + glEnable(GL_BLEND); + UseRenderShader(flags | RenderFlag_Trans); + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + lastwasshadow = false; + } + + // 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_NOTEQUAL, 0x40|polyid, 0x7F); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilFunc(GL_NOTEQUAL, 0x40|polyid, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - if (polyattr & (1<<11)) glDepthMask(GL_TRUE); - else glDepthMask(GL_FALSE); + if (polyattr & (1<<11)) glDepthMask(GL_TRUE); + else glDepthMask(GL_FALSE); + } } } -- cgit v1.2.3 From dc68842db46e48529d951554661e1909ad7b54f7 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 3 May 2019 18:55:45 +0200 Subject: some work on shadows. (still need to check opaquePolyID) --- src/GPU3D_OpenGL43.cpp | 127 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 115 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 7e5a8d6..5ef9c5f 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -76,6 +76,10 @@ PFNGLDRAWBUFFERSPROC glDrawBuffers; PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei; PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei; +PFNGLCOLORMASKIPROC glColorMaski; + +PFNGLMEMORYBARRIERPROC glMemoryBarrier; + PFNGLGETSTRINGIPROC glGetStringi; @@ -111,7 +115,7 @@ void main() { oColor = vec4(uColor).bgra / 31.0; oAttr.r = uOpaquePolyID; - oAttr.g = uFogFlag; + oAttr.g = 0; } )"; @@ -416,6 +420,7 @@ void main() if (col.a < 30.5/31) discard; oColor = col; + oAttr.r = (fPolygonAttr.x >> 24) & 0x3F; } )"; @@ -429,6 +434,7 @@ void main() if (col.a < 30.5/31) discard; oColor = col; + oAttr.r = (fPolygonAttr.x >> 24) & 0x3F; gl_FragDepth = fZ; } )"; @@ -460,21 +466,62 @@ void main() } )"; -const char* kRenderFS_ZS = R"( +const char* kRenderFS_ZSM = R"( void main() { oColor = vec4(0,0,0,1); + oAttr.g = 1; } )"; -const char* kRenderFS_WS = R"( +const char* kRenderFS_WSM = R"( smooth in float fZ; void main() { oColor = vec4(0,0,0,1); + oAttr.g = 1; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZS = R"( + +layout(binding=2) uniform usampler2D iAttrTex; +//layout(origin_upper_left) in vec4 gl_FragCoord; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); + if (iAttr.y != 1) discard; + + oColor = col; +} +)"; + +const char* kRenderFS_WS = R"( + +layout(binding=2) uniform usampler2D iAttrTex; +//layout(origin_upper_left) in vec4 gl_FragCoord; + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); + if (iAttr.y != 1) discard; + + oColor = col; gl_FragDepth = fZ; } )"; @@ -485,6 +532,7 @@ enum RenderFlag_WBuffer = 0x01, RenderFlag_Trans = 0x02, RenderFlag_ShadowMask = 0x04, + RenderFlag_Shadow = 0x08, }; @@ -586,6 +634,10 @@ bool InitGLExtensions() LOADPROC(GLBLENDFUNCSEPARATEI, glBlendFuncSeparatei); LOADPROC(GLBLENDEQUATIONSEPARATEI, glBlendEquationSeparatei); + LOADPROC(GLCOLORMASKI, glColorMaski); + + LOADPROC(GLMEMORYBARRIER, glMemoryBarrier); + LOADPROC(GLGETSTRINGI, glGetStringi); #undef LOADPROC @@ -750,8 +802,12 @@ bool Init() if (!BuildRenderShader(RenderFlag_Trans | RenderFlag_WBuffer, kRenderVS_W, kRenderFS_WT)) return false; if (!BuildRenderShader(RenderFlag_ShadowMask, - kRenderVS_Z, kRenderFS_ZS)) return false; + kRenderVS_Z, kRenderFS_ZSM)) return false; if (!BuildRenderShader(RenderFlag_ShadowMask | RenderFlag_WBuffer, + kRenderVS_W, kRenderFS_WSM)) return false; + if (!BuildRenderShader(RenderFlag_Shadow, + kRenderVS_Z, kRenderFS_ZS)) return false; + if (!BuildRenderShader(RenderFlag_Shadow | RenderFlag_WBuffer, kRenderVS_W, kRenderFS_WS)) return false; @@ -871,6 +927,9 @@ bool Init() 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); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); // opaque polyID / shadow bits + return true; } @@ -909,6 +968,8 @@ void SetupPolygon(RendererPolygon* rp, Polygon* polygon) { 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 } @@ -918,6 +979,10 @@ void SetupPolygon(RendererPolygon* rp, Polygon* polygon) rp->RenderKey |= 0x2; } } + else + { + rp->RenderKey |= 0x30000; + } } void BuildPolygons(RendererPolygon* polygons, int npolys) @@ -1029,6 +1094,8 @@ void RenderFrame() } glDisable(GL_BLEND); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_TRUE, GL_TRUE, GL_FALSE, GL_FALSE); // clear buffers // TODO: clear bitmap @@ -1064,6 +1131,8 @@ void RenderFrame() glDrawArrays(GL_TRIANGLES, 0, 2*3); } + glColorMaski(1, GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); + if (RenderNumPolygons) { // render shit here @@ -1106,10 +1175,12 @@ void RenderFrame() u16* iptr; u32 curkey; - bool lastwasshadow; - + bool lastwasshadow;bool darp; +//printf("morp %08X\n", RenderClearAttr1); if (firsttrans > -1) { + glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); +if (PolygonList[firsttrans].PolyData->IsShadow) printf("!! GLORG!!! %08X\n", PolygonList[firsttrans].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 @@ -1166,11 +1237,12 @@ void RenderFrame() iptr = PolygonList[firsttrans].Indices; curkey = 0xFFFFFFFF; - lastwasshadow = false; + lastwasshadow = false; darp = false; for (int i = firsttrans; i < npolys; i++) { RendererPolygon* rp = &PolygonList[i]; + //printf("PASS 3 POLYGON %i: ATTR %08X (%d) | KEY %08X\n", i, rp->PolyData->Attr, (rp->PolyData->Attr>>4)&0x3, rp->RenderKey); if (rp->RenderKey != curkey) { u16* endptr = rp->Indices; @@ -1184,28 +1256,57 @@ void RenderFrame() if (rp->PolyData->IsShadowMask) { - if (!lastwasshadow) + //printf("beginning shadowmask batch: %d, %d\n", lastwasshadow, darp); + /*if (!lastwasshadow) { + //glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); + glDisable(GL_BLEND); UseRenderShader(flags | RenderFlag_ShadowMask); + // shadow bits are set where the depth test fails + // sure enough, if GL_LESS fails, the opposite function would pass + glDepthFunc(GL_GEQUAL); + //glStencilFunc(GL_ALWAYS, 0x80, 0x80); //glStencilOp(GL_REPLACE, GL_REPLACE, GL_KEEP); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); glDepthMask(GL_FALSE); lastwasshadow = true; - } + }*/ + + glDisable(GL_BLEND); + UseRenderShader(flags | RenderFlag_ShadowMask); + + glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + glDepthMask(GL_FALSE); + glDepthFunc(GL_GEQUAL); + glStencilFunc(GL_ALWAYS,0,0); + glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); + lastwasshadow=true; + + darp = false; } else { + if (rp->PolyData->IsShadow) glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); + //if (rp->PolyData->IsShadow) printf("beginning shadow batch: %d, %d\n", lastwasshadow, darp); + + if (rp->PolyData->IsShadow) + UseRenderShader(flags | RenderFlag_Shadow); + else + UseRenderShader(flags | RenderFlag_Trans); + if (lastwasshadow) { glEnable(GL_BLEND); - UseRenderShader(flags | RenderFlag_Trans); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); lastwasshadow = false; } @@ -1221,6 +1322,8 @@ void RenderFrame() if (polyattr & (1<<11)) glDepthMask(GL_TRUE); else glDepthMask(GL_FALSE); + + darp = rp->PolyData->IsShadow; } } } -- cgit v1.2.3 From 83331bc7e59f483701285bcaf65dec8df80dda36 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 3 May 2019 19:28:15 +0200 Subject: lay base for hi-res rendering IT'S A PILE OF HACKS --- src/GPU.cpp | 32 ++++++++++++++++++++++++-------- src/GPU.h | 4 +++- src/GPU2D.cpp | 13 ++++++++++++- src/libui_sdl/main.cpp | 30 +++++++++++++++++++++++------- 4 files changed, 62 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/GPU.cpp b/src/GPU.cpp index ad39007..f272129 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -71,7 +71,9 @@ u32 VRAMMap_TexPal[8]; u32 VRAMMap_ARM7[2]; -u32 Framebuffer[256*192*2]; +u32* Framebuffer; +int FBScale; +int FBScreenStride; GPU2D* GPU2D_A; GPU2D* GPU2D_B; @@ -83,6 +85,9 @@ bool Init() GPU2D_B = new GPU2D(1); if (!GPU3D::Init()) return false; + //SetFramebufferScale(1); + SetFramebufferScale(2); + return true; } @@ -91,6 +96,8 @@ void DeInit() delete GPU2D_A; delete GPU2D_B; GPU3D::DeInit(); + + if (Framebuffer) delete[] Framebuffer; } void Reset() @@ -147,13 +154,13 @@ void Reset() GPU2D_B->Reset(); GPU3D::Reset(); - GPU2D_A->SetFramebuffer(&Framebuffer[256*192]); - GPU2D_B->SetFramebuffer(&Framebuffer[256*0]); + GPU2D_A->SetFramebuffer(&Framebuffer[FBScreenStride]); + GPU2D_B->SetFramebuffer(&Framebuffer[0]); } void Stop() { - memset(Framebuffer, 0, 256*192*2*4); + memset(Framebuffer, 0, FBScreenStride*2*sizeof(u32)); } void DoSavestate(Savestate* file) @@ -208,6 +215,15 @@ void DoSavestate(Savestate* file) GPU3D::DoSavestate(file); } +void SetFramebufferScale(int scale) +{ + FBScale = scale; + FBScreenStride = (256*scale) * (192*scale); + + if (Framebuffer) delete[] Framebuffer; + Framebuffer = new u32[FBScreenStride * 2]; +} + // VRAM mapping notes // @@ -668,13 +684,13 @@ void SetPowerCnt(u32 val) if (val & (1<<15)) { - GPU2D_A->SetFramebuffer(&Framebuffer[256*0]); - GPU2D_B->SetFramebuffer(&Framebuffer[256*192]); + GPU2D_A->SetFramebuffer(&Framebuffer[0]); + GPU2D_B->SetFramebuffer(&Framebuffer[FBScreenStride]); } else { - GPU2D_A->SetFramebuffer(&Framebuffer[256*192]); - GPU2D_B->SetFramebuffer(&Framebuffer[256*0]); + GPU2D_A->SetFramebuffer(&Framebuffer[FBScreenStride]); + GPU2D_B->SetFramebuffer(&Framebuffer[0]); } } diff --git a/src/GPU.h b/src/GPU.h index 50e5f55..a430a32 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -61,7 +61,7 @@ extern u32 VRAMMap_Texture[4]; extern u32 VRAMMap_TexPal[8]; extern u32 VRAMMap_ARM7[2]; -extern u32 Framebuffer[256*192*2]; +extern u32* Framebuffer; extern GPU2D* GPU2D_A; extern GPU2D* GPU2D_B; @@ -74,6 +74,8 @@ void Stop(); void DoSavestate(Savestate* file); +void SetFramebufferScale(int scale); + void MapVRAM_AB(u32 bank, u8 cnt); void MapVRAM_CD(u32 bank, u8 cnt); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index b120cd8..cc428ce 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -551,7 +551,7 @@ void GPU2D::Write32(u32 addr, u32 val) void GPU2D::DrawScanline(u32 line) { - u32* dst = &Framebuffer[256*line]; + u32* dst = &Framebuffer[256*4*line]; u32 mode1gfx[256]; // request each 3D scanline in advance @@ -725,6 +725,17 @@ void GPU2D::DrawScanline(u32 line) dst[i] = c | ((c & 0x00C0C0C0) >> 6) | 0xFF000000; } + + // hax + for (int i = 255; i >= 0; i--) + { + u32 c = dst[i]; + + dst[i*2] = c; + dst[i*2+1] = c; + dst[i*2+512] = c; + dst[i*2+513] = c; + } } void GPU2D::VBlank() diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 2705560..cc4e15d 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -95,7 +95,9 @@ bool SavestateLoaded; bool ScreenDrawInited = false; uiDrawBitmap* ScreenBitmap = NULL; -u32 ScreenBuffer[256*384]; +u32* ScreenBuffer; + +int ScreenScale; int ScreenGap = 0; int ScreenLayout = 0; @@ -396,6 +398,8 @@ int EmuThreadFunc(void* burp) uiGLMakeContextCurrent(GLContext); NDS::Init(); + ScreenBuffer = new u32[(256*ScreenScale) * (384*ScreenScale)]; + MainScreenPos[0] = 0; MainScreenPos[1] = 0; MainScreenPos[2] = 0; @@ -550,7 +554,7 @@ int EmuThreadFunc(void* burp) } } - memcpy(ScreenBuffer, GPU::Framebuffer, 256*384*4); + memcpy(ScreenBuffer, GPU::Framebuffer, (256*ScreenScale)*(384*ScreenScale)*4); uiAreaQueueRedrawAll(MainDrawArea); // framerate limiter based off SDL2_gfx @@ -616,6 +620,8 @@ int EmuThreadFunc(void* burp) if (joybuttons) delete[] joybuttons; + delete[] ScreenBuffer; + NDS::DeInit(); Platform::LAN_DeInit(); @@ -625,16 +631,17 @@ int EmuThreadFunc(void* burp) void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) { + // TODO: recreate bitmap if screen scale changed if (!ScreenDrawInited) { ScreenDrawInited = true; - ScreenBitmap = uiDrawNewBitmap(params->Context, 256, 384); + ScreenBitmap = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); } if (!ScreenBitmap) return; - uiRect top = {0, 0, 256, 192}; - uiRect bot = {0, 192, 256, 192}; + uiRect top = {0, 0, 256*ScreenScale, 192*ScreenScale}; + uiRect bot = {0, 192*ScreenScale, 256*ScreenScale, 192*ScreenScale}; uiDrawBitmapUpdate(ScreenBitmap, ScreenBuffer); @@ -817,6 +824,9 @@ void SetupScreenRects(int width, int height) screenH = 192; } + screenW *= ScreenScale; + screenH *= ScreenScale; + uiRect *topscreen, *bottomscreen; if (ScreenRotation == 1 || ScreenRotation == 2) { @@ -1010,6 +1020,9 @@ void SetMinSize(int w, int h) int cw, ch; uiWindowContentSize(MainWindow, &cw, &ch); + w *= ScreenScale; + h *= ScreenScale; + uiControlSetMinSize(uiControl(MainDrawArea), w, h); if ((cw < w) || (ch < h)) { @@ -1535,8 +1548,8 @@ void OnSetScreenSize(uiMenuItem* item, uiWindow* window, void* param) int factor = *(int*)param; bool isHori = (ScreenRotation == 1 || ScreenRotation == 3); - int w = 256*factor; - int h = 192*factor; + int w = 256*factor * ScreenScale; + int h = 192*factor * ScreenScale; if (ScreenLayout == 0) // natural { @@ -1947,6 +1960,9 @@ int main(int argc, char** argv) WindowWidth = w; WindowHeight = h; + //ScreenScale = 1; + ScreenScale = 2; // HAW HAW HAW + MainWindow = uiNewWindow("melonDS " MELONDS_VERSION, w, h, Config::WindowMaximized, 1, 1); uiWindowOnClosing(MainWindow, OnCloseWindow, NULL); -- cgit v1.2.3 From 587d432677de5309724b3389d937e8a5bcece9a5 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 7 May 2019 21:19:33 +0200 Subject: don't do OBJ window if it isn't enabled (oops) --- src/GPU2D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index cc428ce..7f19833 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -1019,7 +1019,7 @@ void GPU2D::CalculateWindowMask(u32 line, u8* mask) for (u32 i = 0; i < 256; i++) mask[i] = WinCnt[2]; // window outside - if (DispCnt & ((1<<15)|(1<<12))) + if ((DispCnt & (1<<15)) && (DispCnt & (1<<12))) { // OBJ window DrawSpritesWindow(line, mask); -- cgit v1.2.3 From fb4f972cad62d0c84b563b6b53e313b6cf2c9029 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 8 May 2019 01:58:34 +0200 Subject: hires hax. somewhat functional --- src/GPU2D.cpp | 366 ++++++++++++++++++++++++++++--------------------- src/GPU2D.h | 22 ++- src/GPU3D.cpp | 6 - src/GPU3D.h | 3 - src/GPU3D_OpenGL43.cpp | 59 +++----- src/GPU3D_Soft.cpp | 5 +- 6 files changed, 248 insertions(+), 213 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 7f19833..d057a40 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -549,17 +549,81 @@ void GPU2D::Write32(u32 addr, u32 val) } +u32 GPU2D::ColorBlend4(u32 val1, u32 val2, u32 eva, u32 evb) +{ + u32 r = (((val1 & 0x00003F) * eva) + ((val2 & 0x00003F) * evb)) >> 4; + u32 g = ((((val1 & 0x003F00) * eva) + ((val2 & 0x003F00) * evb)) >> 4) & 0x007F00; + u32 b = ((((val1 & 0x3F0000) * eva) + ((val2 & 0x3F0000) * evb)) >> 4) & 0x7F0000; + + if (r > 0x00003F) r = 0x00003F; + if (g > 0x003F00) g = 0x003F00; + if (b > 0x3F0000) b = 0x3F0000; + + return r | g | b; +} + +u32 GPU2D::ColorBlend5(u32 val1, u32 val2) +{ + u32 eva = ((val1 >> 24) & 0x1F) + 1; + u32 evb = 32 - eva; + + u32 r = (((val1 & 0x00003F) * eva) + ((val2 & 0x00003F) * evb)) >> 5; + u32 g = ((((val1 & 0x003F00) * eva) + ((val2 & 0x003F00) * evb)) >> 5) & 0x007F00; + u32 b = ((((val1 & 0x3F0000) * eva) + ((val2 & 0x3F0000) * evb)) >> 5) & 0x7F0000; + + if (eva <= 16) + { + r += 0x000001; + g += 0x000100; + b += 0x010000; + } + + if (r > 0x00003F) r = 0x00003F; + if (g > 0x003F00) g = 0x003F00; + if (b > 0x3F0000) b = 0x3F0000; + + return r | g | b; +} + +u32 GPU2D::ColorBrightnessUp(u32 val, u32 factor) +{ + u32 r = val & 0x00003F; + u32 g = val & 0x003F00; + u32 b = val & 0x3F0000; + + r += (((0x00003F - r) * factor) >> 4); + g += ((((0x003F00 - g) * factor) >> 4) & 0x003F00); + b += ((((0x3F0000 - b) * factor) >> 4) & 0x3F0000); + + return r | g | b; +} + +u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) +{ + u32 r = val & 0x00003F; + u32 g = val & 0x003F00; + u32 b = val & 0x3F0000; + + r -= ((r * factor) >> 4); + g -= (((g * factor) >> 4) & 0x003F00); + b -= (((b * factor) >> 4) & 0x3F0000); + + return r | g | b; +} + + void GPU2D::DrawScanline(u32 line) { u32* dst = &Framebuffer[256*4*line]; - u32 mode1gfx[256]; + u32 mode1gfx[1024]; + u32* _3dgfx; - // request each 3D scanline in advance - // this is required for the threaded mode of the software renderer - // (alternately we could call GetLine() once and store the result somewhere) - if (Num == 0) - GPU3D::RequestLine(line); + // HAX + LineScale = 2; + LineStride = 1024; + DrawPixel = DrawPixel_2x; + int _3dline = line; line = GPU::VCount; bool forceblank = false; @@ -586,21 +650,23 @@ void GPU2D::DrawScanline(u32 line) u32 dispmode = DispCnt >> 16; dispmode &= (Num ? 0x1 : 0x3); + _3dgfx = GPU3D::GetLine(_3dline); + // always render regular graphics - DrawScanline_Mode1(line, mode1gfx); + DrawScanline_Mode1(line, mode1gfx, _3dgfx); switch (dispmode) { case 0: // screen off { - for (int i = 0; i < 256; i++) + for (int i = 0; i < LineStride; i++) dst[i] = 0xFF3F3F3F; } break; case 1: // regular display { - for (int i = 0; i < 256; i++) + for (int i = 0; i < LineStride; i++) dst[i] = mode1gfx[i]; } break; @@ -620,12 +686,19 @@ void GPU2D::DrawScanline(u32 line) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - dst[i] = r | (g << 8) | (b << 16); + int d = i*LineScale; + dst[d] = r | (g << 8) | (b << 16); + if (LineScale >= 2) + { + dst[d+1] = dst[d]; + dst[d+512] = dst[d]; + dst[d+513] = dst[d]; + } } } else { - for (int i = 0; i < 256; i++) + for (int i = 0; i < LineStride; i++) { dst[i] = 0; } @@ -642,7 +715,14 @@ void GPU2D::DrawScanline(u32 line) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - dst[i] = r | (g << 8) | (b << 16); + int d = i*LineScale; + dst[d] = r | (g << 8) | (b << 16); + if (LineScale >= 2) + { + dst[d+1] = dst[d]; + dst[d+512] = dst[d]; + dst[d+513] = dst[d]; + } } } break; @@ -661,7 +741,7 @@ void GPU2D::DrawScanline(u32 line) } if (line < capheight) - DoCapture(line, capwidth, mode1gfx); + DoCapture(line, capwidth, mode1gfx, _3dgfx); } // master brightness @@ -673,19 +753,9 @@ void GPU2D::DrawScanline(u32 line) u32 factor = MasterBrightness & 0x1F; if (factor > 16) factor = 16; - for (int i = 0; i < 256; i++) + for (int i = 0; i < LineStride; i++) { - u32 val = dst[i]; - - u32 r = val & 0x00003F; - u32 g = val & 0x003F00; - u32 b = val & 0x3F0000; - - r += (((0x00003F - r) * factor) >> 4); - g += ((((0x003F00 - g) * factor) >> 4) & 0x003F00); - b += ((((0x3F0000 - b) * factor) >> 4) & 0x3F0000); - - dst[i] = r | g | b; + dst[i] = ColorBrightnessUp(dst[i], factor); } } else if ((MasterBrightness >> 14) == 2) @@ -694,19 +764,9 @@ void GPU2D::DrawScanline(u32 line) u32 factor = MasterBrightness & 0x1F; if (factor > 16) factor = 16; - for (int i = 0; i < 256; i++) + for (int i = 0; i < LineStride; i++) { - u32 val = dst[i]; - - u32 r = val & 0x00003F; - u32 g = val & 0x003F00; - u32 b = val & 0x3F0000; - - r -= ((r * factor) >> 4); - g -= (((g * factor) >> 4) & 0x003F00); - b -= (((b * factor) >> 4) & 0x3F0000); - - dst[i] = r | g | b; + dst[i] = ColorBrightnessDown(dst[i], factor); } } } @@ -714,7 +774,7 @@ void GPU2D::DrawScanline(u32 line) // convert to 32-bit BGRA // note: 32-bit RGBA would be more straightforward, but // BGRA seems to be more compatible (Direct2D soft, cairo...) - for (int i = 0; i < 256; i++) + for (int i = 0; i < LineStride; i++) { u32 c = dst[i]; @@ -725,17 +785,6 @@ void GPU2D::DrawScanline(u32 line) dst[i] = c | ((c & 0x00C0C0C0) >> 6) | 0xFF000000; } - - // hax - for (int i = 255; i >= 0; i--) - { - u32 c = dst[i]; - - dst[i*2] = c; - dst[i*2+1] = c; - dst[i*2+512] = c; - dst[i*2+513] = c; - } } void GPU2D::VBlank() @@ -761,7 +810,7 @@ void GPU2D::VBlankEnd() } -void GPU2D::DoCapture(u32 line, u32 width, u32* src) +void GPU2D::DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx) { u32 dstvram = (CaptureCnt >> 16) & 0x3; @@ -774,7 +823,7 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src) u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width); if (CaptureCnt & (1<<24)) - src = (u32*)GPU3D::GetLine(line); + src = _3dgfx; u16* srcB = NULL; u32 srcBaddr = line * 256; @@ -803,7 +852,7 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src) { for (u32 i = 0; i < width; i++) { - u32 val = src[i]; + u32 val = src[i * LineScale]; // TODO: check what happens when alpha=0 @@ -854,7 +903,7 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src) { for (u32 i = 0; i < width; i++) { - u32 val = src[i]; + u32 val = src[i * LineScale]; // TODO: check what happens when alpha=0 @@ -888,7 +937,7 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src) { for (u32 i = 0; i < width; i++) { - u32 val = src[i]; + u32 val = src[i * LineScale]; // TODO: check what happens when alpha=0 @@ -1058,7 +1107,7 @@ void GPU2D::CalculateWindowMask(u32 line, u8* mask) template -void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst) +void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx) { for (int i = 3; i >= 0; i--) { @@ -1098,7 +1147,7 @@ void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst) if (DispCnt & 0x0100) { if ((!Num) && (DispCnt & 0x8)) - DrawBG_3D(line, dst); + DrawBG_3D(line, dst, _3dgfx); else DrawBG_Text(line, dst, 0); } @@ -1108,7 +1157,7 @@ void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst) } } -void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst) +void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx) { if (Num) { @@ -1130,7 +1179,7 @@ void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst if (DispCnt & 0x0100) { if (DispCnt & 0x8) - DrawBG_3D(line, dst); + DrawBG_3D(line, dst, _3dgfx); } } if ((DispCnt & 0x1000) && nsprites) @@ -1138,10 +1187,10 @@ void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst } } -void GPU2D::DrawScanline_Mode1(u32 line, u32* dst) +void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) { - u32 linebuf[256*2 + 64]; - u8* windowmask = (u8*)&linebuf[256*2]; + u32 linebuf[1024*2 + 64]; + u8* windowmask = (u8*)&linebuf[1024*2]; u32 backdrop; if (Num) backdrop = *(u16*)&GPU::Palette[0x400]; @@ -1154,7 +1203,7 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst) backdrop = r | (g << 8) | (b << 16) | 0x20000000; - for (int i = 0; i < 256; i++) + for (int i = 0; i < LineStride; i++) linebuf[i] = backdrop; } @@ -1171,13 +1220,13 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst) // TODO: what happens in mode 7? mode 6 on the sub engine? switch (DispCnt & 0x7) { - case 0: DrawScanlineBGMode<0>(line, nsprites, spritebuf, linebuf); break; - case 1: DrawScanlineBGMode<1>(line, nsprites, spritebuf, linebuf); break; - case 2: DrawScanlineBGMode<2>(line, nsprites, spritebuf, linebuf); break; - case 3: DrawScanlineBGMode<3>(line, nsprites, spritebuf, linebuf); break; - case 4: DrawScanlineBGMode<4>(line, nsprites, spritebuf, linebuf); break; - case 5: DrawScanlineBGMode<5>(line, nsprites, spritebuf, linebuf); break; - case 6: DrawScanlineBGMode6(line, nsprites, spritebuf, linebuf); break; + case 0: DrawScanlineBGMode<0>(line, nsprites, spritebuf, linebuf, _3dgfx); break; + case 1: DrawScanlineBGMode<1>(line, nsprites, spritebuf, linebuf, _3dgfx); break; + case 2: DrawScanlineBGMode<2>(line, nsprites, spritebuf, linebuf, _3dgfx); break; + case 3: DrawScanlineBGMode<3>(line, nsprites, spritebuf, linebuf, _3dgfx); break; + case 4: DrawScanlineBGMode<4>(line, nsprites, spritebuf, linebuf, _3dgfx); break; + case 5: DrawScanlineBGMode<5>(line, nsprites, spritebuf, linebuf, _3dgfx); break; + case 6: DrawScanlineBGMode6(line, nsprites, spritebuf, linebuf, _3dgfx); break; } // color special effects @@ -1185,10 +1234,10 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst) u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - for (int i = 0; i < 256; i++) + for (int i = 0; i < LineStride; i++) { u32 val1 = linebuf[i]; - u32 val2 = linebuf[256+i]; + u32 val2 = linebuf[1024+i]; u32 coloreffect, eva, evb; @@ -1221,26 +1270,7 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst) { // 3D layer blending - eva = (flag1 & 0x1F) + 1; - evb = 32 - eva; - - u32 r = (((val1 & 0x00003F) * eva) + ((val2 & 0x00003F) * evb)) >> 5; - u32 g = ((((val1 & 0x003F00) * eva) + ((val2 & 0x003F00) * evb)) >> 5) & 0x007F00; - u32 b = ((((val1 & 0x3F0000) * eva) + ((val2 & 0x3F0000) * evb)) >> 5) & 0x7F0000; - - if (eva <= 16) - { - r += 0x000001; - g += 0x000100; - b += 0x010000; - } - - if (r > 0x00003F) r = 0x00003F; - if (g > 0x003F00) g = 0x003F00; - if (b > 0x3F0000) b = 0x3F0000; - - dst[i] = r | g | b | 0xFF000000; - + dst[i] = ColorBlend5(val1, val2); continue; } else @@ -1272,45 +1302,15 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst) break; case 1: - { - u32 r = (((val1 & 0x00003F) * eva) + ((val2 & 0x00003F) * evb)) >> 4; - u32 g = ((((val1 & 0x003F00) * eva) + ((val2 & 0x003F00) * evb)) >> 4) & 0x007F00; - u32 b = ((((val1 & 0x3F0000) * eva) + ((val2 & 0x3F0000) * evb)) >> 4) & 0x7F0000; - - if (r > 0x00003F) r = 0x00003F; - if (g > 0x003F00) g = 0x003F00; - if (b > 0x3F0000) b = 0x3F0000; - - dst[i] = r | g | b | 0xFF000000; - } + dst[i] = ColorBlend4(val1, val2, eva, evb); break; case 2: - { - u32 r = val1 & 0x00003F; - u32 g = val1 & 0x003F00; - u32 b = val1 & 0x3F0000; - - r += ((0x00003F - r) * EVY) >> 4; - g += (((0x003F00 - g) * EVY) >> 4) & 0x003F00; - b += (((0x3F0000 - b) * EVY) >> 4) & 0x3F0000; - - dst[i] = r | g | b | 0xFF000000; - } + dst[i] = ColorBrightnessUp(val1, EVY); break; case 3: - { - u32 r = val1 & 0x00003F; - u32 g = val1 & 0x003F00; - u32 b = val1 & 0x3F0000; - - r -= (r * EVY) >> 4; - g -= ((g * EVY) >> 4) & 0x003F00; - b -= ((b * EVY) >> 4) & 0x3F0000; - - dst[i] = r | g | b | 0xFF000000; - } + dst[i] = ColorBrightnessDown(val1, EVY); break; } } @@ -1333,20 +1333,35 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst) } -void GPU2D::DrawPixel(u32* dst, u16 color, u32 flag) +void GPU2D::DrawPixel_1x(u32* dst, u16 color, u32 flag) { u8 r = (color & 0x001F) << 1; u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - *(dst+256) = *dst; + *(dst+1024) = *dst; *dst = r | (g << 8) | (b << 16) | flag; } -void GPU2D::DrawBG_3D(u32 line, u32* dst) +void GPU2D::DrawPixel_2x(u32* dst, u16 color, u32 flag) { - u32* src = GPU3D::GetLine(line); - u8* windowmask = (u8*)&dst[256*2]; + u8 r = (color & 0x001F) << 1; + u8 g = (color & 0x03E0) >> 4; + u8 b = (color & 0x7C00) >> 9; + + u64 val = r | (g << 8) | (b << 16) | flag; + val |= (val << 32); + + *(u64*)(dst+1024) = *(u64*)dst; + *(u64*)(dst+1536) = *(u64*)(dst+512); + + *(u64*)dst = val; + *(u64*)(dst+512) = val; +} + +void GPU2D::DrawBG_3D(u32 line, u32* dst, u32* src) +{ + u8* windowmask = (u8*)&dst[1024*2]; u16 xoff = BGXPos[0]; int i = 0; @@ -1362,22 +1377,65 @@ void GPU2D::DrawBG_3D(u32 line, u32* dst) iend -= (xoff & 0xFF); } - for (; i < iend; i++) + if (LineScale == 1) + { + for (; i < iend; i++) + { + u32 c = src[xoff]; + xoff++; + + if ((c >> 24) == 0) continue; + if (!(windowmask[i] & 0x01)) continue; + + dst[i+1024] = dst[i]; + dst[i] = c | 0x40000000; + } + } + else if (LineScale == 2) { - u32 c = src[xoff]; - xoff++; + for (; i < iend; i++) + { + int is = i * 2; + int xs = xoff * 2; + u32 c; + + xoff++; + if (!(windowmask[i] & 0x01)) continue; + + c = src[xs]; + if ((c >> 24) != 0) + { + dst[is+1024] = dst[is]; + dst[is] = c | 0x40000000; + } + + c = src[xs+1]; is++; + if ((c >> 24) != 0) + { + dst[is+1024] = dst[is]; + dst[is] = c | 0x40000000; + } - if ((c >> 24) == 0) continue; - if (!(windowmask[i] & 0x01)) continue; + c = src[xs+512]; is += 511; + if ((c >> 24) != 0) + { + dst[is+1024] = dst[is]; + dst[is] = c | 0x40000000; + } - dst[i+256] = dst[i]; - dst[i] = c | 0x40000000; + c = src[xs+513]; is++; + if ((c >> 24) != 0) + { + dst[is+1024] = dst[is]; + dst[is] = c | 0x40000000; + } + } } } void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum) { - u8* windowmask = (u8*)&dst[256*2]; + u8* windowmask = (u8*)&dst[1024*2]; u16 bgcnt = BGCnt[bgnum]; u32 xmos = 0, xmossize = 0; @@ -1474,7 +1532,7 @@ void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum) xmos--; if (color) - DrawPixel(&dst[i], curpal[color], 0x01000000< 0) { if (color) - DrawPixel(&dst[i], pal[color], 0x01000000<(tilesetaddr + (curtile << 6) + (tileyoff << 3) + tilexoff); if (color) - DrawPixel(&dst[i], pal[color], 0x01000000< 0) { if (color & 0x8000) - DrawPixel(&dst[i], color, 0x01000000<(tilemapaddr + (((((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)) << 1)); if (color & 0x8000) - DrawPixel(&dst[i], color, 0x01000000< 0) { if (color) - DrawPixel(&dst[i], pal[color], 0x01000000<(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)); if (color) - DrawPixel(&dst[i], pal[color], 0x01000000< 0) { if (color) - DrawPixel(&dst[i], curpal[color], 0x01000000<(tilesetaddr + ((curtile & 0x03FF) << 6) + (tileyoff << 3) + tilexoff); if (color) - DrawPixel(&dst[i], curpal[color], 0x01000000< 0) { if (color) - DrawPixel(&dst[i], pal[color], 0x01000000<<2); + DrawPixel(&dst[i*LineScale], pal[color], 0x01000000<<2); xmos--; } @@ -1914,7 +1972,7 @@ void GPU2D::DrawBG_Large(u32 line, u32* dst) // BG is always BG2 color = GPU::ReadVRAM_BG(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)); if (color) - DrawPixel(&dst[i], pal[color], 0x01000000<<2); + DrawPixel(&dst[i*LineScale], pal[color], 0x01000000<<2); } } @@ -1928,13 +1986,13 @@ void GPU2D::DrawBG_Large(u32 line, u32* dst) // BG is always BG2 void GPU2D::InterleaveSprites(u32* buf, u32 prio, u32* dst) { - u8* windowmask = (u8*)&dst[256*2]; + u8* windowmask = (u8*)&dst[1024*2]; for (u32 i = 0; i < 256; i++) { if (((buf[i] & 0xF8000) == prio) && (windowmask[i] & 0x10)) { - DrawPixel(&dst[i], buf[i] & 0x7FFF, buf[i] & 0xFF000000); + DrawPixel(&dst[i*LineScale], buf[i] & 0x7FFF, buf[i] & 0xFF000000); } } } diff --git a/src/GPU2D.h b/src/GPU2D.h index d7c4e3f..7ffe798 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -68,6 +68,9 @@ private: bool Enabled; u32* Framebuffer; + u32 LineStride; + u32 LineScale; + u16 DispFIFO[16]; u32 DispFIFOReadPtr; u32 DispFIFOWritePtr; @@ -114,13 +117,20 @@ private: u32 BGExtPalStatus[4]; u32 OBJExtPalStatus; - template void DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst); - void DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst); - void DrawScanline_Mode1(u32 line, u32* dst); + u32 ColorBlend4(u32 val1, u32 val2, u32 eva, u32 evb); + u32 ColorBlend5(u32 val1, u32 val2); + u32 ColorBrightnessUp(u32 val, u32 factor); + u32 ColorBrightnessDown(u32 val, u32 factor); + + template void DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx); + void DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx); + void DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx); - void DrawPixel(u32* dst, u16 color, u32 flag); + static void DrawPixel_1x(u32* dst, u16 color, u32 flag); + static void DrawPixel_2x(u32* dst, u16 color, u32 flag); + void (*DrawPixel)(u32* dst, u16 color, u32 flag); - void DrawBG_3D(u32 line, u32* dst); + void DrawBG_3D(u32 line, u32* dst, u32* src); void DrawBG_Text(u32 line, u32* dst, u32 bgnum); void DrawBG_Affine(u32 line, u32* dst, u32 bgnum); void DrawBG_Extended(u32 line, u32* dst, u32 bgnum); @@ -132,7 +142,7 @@ private: template void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos, u32* dst); template void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* dst); - void DoCapture(u32 line, u32 width, u32* src); + void DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx); void CalculateWindowMask(u32 line, u8* mask); }; diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index b4211f0..68b9c7f 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -2420,12 +2420,6 @@ void VCount215() GLRenderer43::RenderFrame(); } -void RequestLine(int line) -{ - //return SoftRenderer::RequestLine(line); - return GLRenderer43::RequestLine(line); -} - u32* GetLine(int line) { //return SoftRenderer::GetLine(line); diff --git a/src/GPU3D.h b/src/GPU3D.h index f300da8..ecc23de 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -104,7 +104,6 @@ void CheckFIFODMA(); void VCount144(); void VBlank(); void VCount215(); -void RequestLine(int line); u32* GetLine(int line); void WriteToGXFIFO(u32 val); @@ -127,7 +126,6 @@ void SetupRenderThread(); void VCount144(); void RenderFrame(); -void RequestLine(int line); u32* GetLine(int line); } @@ -141,7 +139,6 @@ void Reset(); void VCount144(); void RenderFrame(); -void RequestLine(int line); u32* GetLine(int line); } diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 5ef9c5f..50ff4c6 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -364,7 +364,7 @@ vec4 FinalColor() } )"; - +// TODO!!! NOT HARDCODE SCREEN SIZE!!!!!!! const char* kRenderVS_Z = R"( void main() @@ -373,8 +373,8 @@ void main() uint zshift = (attr >> 16) & 0x1F; vec4 fpos; - fpos.x = ((float(vPosition.x) * 2.0) / 256.0) - 1.0; - fpos.y = ((float(vPosition.y) * 2.0) / 192.0) - 1.0; + fpos.x = ((float(vPosition.x) * 2.0) / 512.0) - 1.0; + fpos.y = ((float(vPosition.y) * 2.0) / 384.0) - 1.0; fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; fpos.w = float(vPosition.w) / 65536.0f; fpos.xyz *= fpos.w; @@ -397,8 +397,8 @@ void main() uint zshift = (attr >> 16) & 0x1F; vec4 fpos; - fpos.x = ((float(vPosition.x) * 2.0) / 256.0) - 1.0; - fpos.y = ((float(vPosition.y) * 2.0) / 192.0) - 1.0; + fpos.x = ((float(vPosition.x) * 2.0) / 512.0) - 1.0; + fpos.y = ((float(vPosition.y) * 2.0) / 384.0) - 1.0; fZ = float(vPosition.z << zshift) / 16777216.0; fpos.w = float(vPosition.w) / 65536.0f; fpos.xy *= fpos.w; @@ -578,8 +578,7 @@ GLuint TexPalMemID; GLuint FramebufferTex[3]; GLuint FramebufferID, PixelbufferID; -u8 Framebuffer[256*192*4]; -u8 CurLine[256*4]; +u8 Framebuffer[512*384*4]; bool InitGLExtensions() @@ -785,7 +784,7 @@ bool Init() // TODO: make configurable (hires, etc) - glViewport(0, 0, 256, 192); + glViewport(0, 0, 512, 384); glDepthRange(0, 1); glClearDepth(1.0); @@ -857,34 +856,16 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 384, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); - /*glGenTextures(1, &FramebufferTex[1]); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 256, 192, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); // welp - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, FramebufferTex[1], 0); - - glGenTextures(1, &FramebufferTex[2]); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_STENCIL_INDEX, 256, 192, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, NULL); - glFramebufferTexture(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, FramebufferTex[2], 0);*/ - glGenTextures(1, &FramebufferTex[1]); glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 192, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 512, 384, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[1], 0); glGenTextures(1, &FramebufferTex[2]); @@ -893,7 +874,7 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8UI, 256, 192, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8UI, 512, 384, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[2], 0); GLenum fbassign[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; @@ -907,7 +888,7 @@ bool Init() glGenBuffers(1, &PixelbufferID); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); //glBufferData(GL_PIXEL_PACK_BUFFER, 256*48*4, NULL, GL_DYNAMIC_READ); - glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); + glBufferData(GL_PIXEL_PACK_BUFFER, 512*384*4, NULL, GL_DYNAMIC_READ); glActiveTexture(GL_TEXTURE0); glGenTextures(1, &TexMemID); @@ -1023,7 +1004,8 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) while (z > 0xFFFF) { z >>= 1; zshift++; } // TODO hires-upgraded positions? - *vptr++ = vtx->FinalPosition[0] | (vtx->FinalPosition[1] << 16); + //*vptr++ = vtx->FinalPosition[0] | (vtx->FinalPosition[1] << 16); + *vptr++ = (vtx->FinalPosition[0] << 1) | (vtx->FinalPosition[1] << 17); *vptr++ = z | (w << 16); *vptr++ = (vtx->FinalColor[0] >> 1) | @@ -1342,16 +1324,16 @@ if (PolygonList[firsttrans].PolyData->IsShadow) printf("!! GLORG!!! %08X\n", Pol //glReadPixels(0, 0, 256, 48, GL_RGBA, GL_UNSIGNED_BYTE, Framebuffer); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); //glReadPixels(0, 0, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); - glReadPixels(0, 0, 256, 192, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + glReadPixels(0, 0, 512, 384, GL_BGRA, GL_UNSIGNED_BYTE, NULL); } -void RequestLine(int line) +u32* GetLine(int line) { if (line == 0) { u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); //if (data) memcpy(&Framebuffer[4*256*0], data, 4*256*48); - if (data) memcpy(&Framebuffer[4*256*0], data, 4*256*192); + if (data) memcpy(&Framebuffer[4*256*0], data, 4*512*384); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); //glReadPixels(0, 48, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); @@ -1379,19 +1361,16 @@ void RequestLine(int line) glUnmapBuffer(GL_PIXEL_PACK_BUFFER); }*/ - u32* ptr = (u32*)&Framebuffer[256*4 * line]; - for (int i = 0; i < 256; i++) + u32* ptr = (u32*)&Framebuffer[512*2*4 * line]; + for (int i = 0; i < 1024; i++) { u32 rgb = *ptr & 0x00FCFCFC; u32 a = *ptr & 0xF8000000; *ptr++ = (rgb >> 2) | (a >> 3); } -} -u32* GetLine(int line) -{ - return (u32*)&Framebuffer[256*4 * line]; + return (u32*)&Framebuffer[512*2*4 * line]; } } diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp index 8d18a35..932b5d4 100644 --- a/src/GPU3D_Soft.cpp +++ b/src/GPU3D_Soft.cpp @@ -2106,17 +2106,14 @@ void RenderThreadFunc() } } -void RequestLine(int line) +u32* GetLine(int line) { if (RenderThreadRunning) { if (line < 192) Platform::Semaphore_Wait(Sema_ScanlineCount); } -} -u32* GetLine(int line) -{ return &ColorBuffer[(line * ScanlineWidth) + FirstPixelOffset]; } -- cgit v1.2.3 From f1d1a9b82818c3981c29266c202a3fe89099ad6f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 8 May 2019 03:24:22 +0200 Subject: temp fix for color effects --- src/GPU2D.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index d057a40..ed47fd3 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -642,7 +642,7 @@ void GPU2D::DrawScanline(u32 line) if (forceblank) { - for (int i = 0; i < 256; i++) + for (int i = 0; i < LineStride; i++) dst[i] = 0xFFFFFFFF; return; } @@ -1236,6 +1236,8 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) for (int i = 0; i < LineStride; i++) { + int j = (i & 0x1FF) >> 1; // FIXME!!!!!! + u32 val1 = linebuf[i]; u32 val2 = linebuf[1024+i]; @@ -1278,7 +1280,7 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) if (flag1 & 0x80) flag1 = 0x10; else if (flag1 & 0x40) flag1 = 0x01; - if ((BlendCnt & flag1) && (windowmask[i] & 0x20)) + if ((BlendCnt & flag1) && (windowmask[j] & 0x20)) { if ((bldcnteffect == 1) && (BlendCnt & target2)) { -- cgit v1.2.3 From 8efc8623ad9ba91c3a3b5121259f9554f3265d0b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 10 May 2019 01:52:05 +0200 Subject: do not hardcode GL screen size all over the place --- src/GPU3D_OpenGL43.cpp | 64 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 50ff4c6..ef03bef 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -43,6 +43,7 @@ PFNGLMAPBUFFERRANGEPROC glMapBufferRange; PFNGLUNMAPBUFFERPROC glUnmapBuffer; PFNGLBUFFERDATAPROC glBufferData; PFNGLBUFFERSUBDATAPROC glBufferSubData; +PFNGLBINDBUFFERBASEPROC glBindBufferBase; PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; @@ -65,8 +66,10 @@ PFNGLGETPROGRAMIVPROC glGetProgramiv; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLDELETESHADERPROC glDeleteShader; PFNGLDELETEPROGRAMPROC glDeleteProgram; + PFNGLUNIFORM1UIPROC glUniform1ui; PFNGLUNIFORM4UIPROC glUniform4ui; +PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding; PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLBINDIMAGETEXTUREPROC glBindImageTexture; @@ -85,6 +88,11 @@ PFNGLGETSTRINGIPROC glGetStringi; // GL version requirements // * explicit uniform location: 4.3 (or extension) +// * texelFetch: 3.0 (GLSL 1.30) (3.2/1.50 for MS) +// * UBO: 3.1 +// * glMemoryBarrier: 4.2 + +// TODO: consider other way to handle uniforms (UBO?) #define kShaderHeader "#version 430" @@ -127,6 +135,11 @@ layout(location=1) in uvec4 vColor; layout(location=2) in ivec2 vTexcoord; layout(location=3) in uvec3 vPolygonAttr; +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; +}; + smooth out vec4 fColor; smooth out vec2 fTexcoord; flat out uvec3 fPolygonAttr; @@ -364,7 +377,7 @@ vec4 FinalColor() } )"; -// TODO!!! NOT HARDCODE SCREEN SIZE!!!!!!! + const char* kRenderVS_Z = R"( void main() @@ -373,8 +386,7 @@ void main() uint zshift = (attr >> 16) & 0x1F; vec4 fpos; - fpos.x = ((float(vPosition.x) * 2.0) / 512.0) - 1.0; - fpos.y = ((float(vPosition.y) * 2.0) / 384.0) - 1.0; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; fpos.w = float(vPosition.w) / 65536.0f; fpos.xyz *= fpos.w; @@ -397,8 +409,7 @@ void main() uint zshift = (attr >> 16) & 0x1F; vec4 fpos; - fpos.x = ((float(vPosition.x) * 2.0) / 512.0) - 1.0; - fpos.y = ((float(vPosition.y) * 2.0) / 384.0) - 1.0; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; fZ = float(vPosition.z << zshift) / 16777216.0; fpos.w = float(vPosition.w) / 65536.0f; fpos.xy *= fpos.w; @@ -540,6 +551,14 @@ GLuint ClearShaderPlain[3]; GLuint RenderShader[16][3]; +struct +{ + float uScreenSize[2]; + +} ShaderConfig; + +GLuint ShaderConfigUBO; + typedef struct { Polygon* PolyData; @@ -600,6 +619,7 @@ bool InitGLExtensions() LOADPROC(GLUNMAPBUFFER, glUnmapBuffer); LOADPROC(GLBUFFERDATA, glBufferData); LOADPROC(GLBUFFERSUBDATA, glBufferSubData); + LOADPROC(GLBINDBUFFERBASE, glBindBufferBase); LOADPROC(GLGENVERTEXARRAYS, glGenVertexArrays); LOADPROC(GLDELETEVERTEXARRAYS, glDeleteVertexArrays); @@ -622,8 +642,10 @@ bool InitGLExtensions() LOADPROC(GLGETPROGRAMINFOLOG, glGetProgramInfoLog); LOADPROC(GLDELETESHADER, glDeleteShader); LOADPROC(GLDELETEPROGRAM, glDeleteProgram); + LOADPROC(GLUNIFORM1UI, glUniform1ui); LOADPROC(GLUNIFORM4UI, glUniform4ui); + LOADPROC(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); LOADPROC(GLACTIVETEXTURE, glActiveTexture); LOADPROC(GLBINDIMAGETEXTURE, glBindImageTexture); @@ -784,7 +806,11 @@ bool Init() // TODO: make configurable (hires, etc) - glViewport(0, 0, 512, 384); + int screenW = 512; + int screenH = 384; + + + glViewport(0, 0, screenW, screenH); glDepthRange(0, 1); glClearDepth(1.0); @@ -792,6 +818,8 @@ bool Init() if (!BuildShaderProgram(kClearVS, kClearFS, ClearShaderPlain, "ClearShader")) return false; + memset(RenderShader, 0, sizeof(RenderShader)); + if (!BuildRenderShader(0, kRenderVS_Z, kRenderFS_ZO)) return false; if (!BuildRenderShader(RenderFlag_WBuffer, @@ -810,6 +838,21 @@ bool Init() kRenderVS_W, kRenderFS_WS)) return false; + ShaderConfig.uScreenSize[0] = screenW; + ShaderConfig.uScreenSize[1] = screenH; + + glGenBuffers(1, &ShaderConfigUBO); + glBindBuffer(GL_UNIFORM_BUFFER, ShaderConfigUBO); + glBufferData(GL_UNIFORM_BUFFER, sizeof(ShaderConfig), &ShaderConfig, GL_STATIC_DRAW); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, ShaderConfigUBO); + + for (int i = 0; i < 16; i++) + { + if (!RenderShader[i][2]) continue; + glUniformBlockBinding(RenderShader[i][2], 0, 0); + } + + float clearvtx[6*2] = { -1.0, -1.0, @@ -856,7 +899,7 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 384, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screenW, screenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); glGenTextures(1, &FramebufferTex[1]); @@ -865,7 +908,7 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 512, 384, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, screenW, screenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[1], 0); glGenTextures(1, &FramebufferTex[2]); @@ -874,7 +917,7 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8UI, 512, 384, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8UI, screenW, screenH, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[2], 0); GLenum fbassign[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; @@ -887,8 +930,7 @@ bool Init() glGenBuffers(1, &PixelbufferID); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - //glBufferData(GL_PIXEL_PACK_BUFFER, 256*48*4, NULL, GL_DYNAMIC_READ); - glBufferData(GL_PIXEL_PACK_BUFFER, 512*384*4, NULL, GL_DYNAMIC_READ); + glBufferData(GL_PIXEL_PACK_BUFFER, screenW*screenH*4, NULL, GL_DYNAMIC_READ); glActiveTexture(GL_TEXTURE0); glGenTextures(1, &TexMemID); -- cgit v1.2.3 From 92d67a17de4a16948cef2889b103b7c28bbf16c7 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 10 May 2019 02:28:26 +0200 Subject: (disabled) proof-of-concept antialiasing --- src/GPU3D_OpenGL43.cpp | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index ef03bef..d28053c 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -34,6 +34,7 @@ PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; +PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; PFNGLGENBUFFERSPROC glGenBuffers; PFNGLDELETEBUFFERSPROC glDeleteBuffers; @@ -595,8 +596,8 @@ u32 NumTriangles; GLuint TexMemID; GLuint TexPalMemID; -GLuint FramebufferTex[3]; -GLuint FramebufferID, PixelbufferID; +GLuint FramebufferTex[4]; +GLuint FramebufferID[2], PixelbufferID; u8 Framebuffer[512*384*4]; @@ -610,6 +611,7 @@ bool InitGLExtensions() LOADPROC(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers); LOADPROC(GLBINDFRAMEBUFFER, glBindFramebuffer); LOADPROC(GLFRAMEBUFFERTEXTURE, glFramebufferTexture); + LOADPROC(GLBLITFRAMEBUFFER, glBlitFramebuffer); LOADPROC(GLGENBUFFERS, glGenBuffers); LOADPROC(GLDELETEBUFFERS, glDeleteBuffers); @@ -806,6 +808,7 @@ bool Init() // TODO: make configurable (hires, etc) + // set those to 2x the final resolution for antialiased rendering int screenW = 512; int screenH = 384; @@ -890,8 +893,8 @@ bool Init() glVertexAttribIPointer(3, 3, GL_UNSIGNED_INT, 7*4, (void*)(4*4)); - glGenFramebuffers(1, &FramebufferID); - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); + glGenFramebuffers(2, &FramebufferID[0]); + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); glGenTextures(1, &FramebufferTex[0]); glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); @@ -920,6 +923,18 @@ bool Init() glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8UI, screenW, screenH, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[2], 0); + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); + glGenTextures(1, &FramebufferTex[3]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screenW/2, screenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[3], 0); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); + GLenum fbassign[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; glDrawBuffers(2, fbassign); @@ -1048,6 +1063,7 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) // TODO hires-upgraded positions? //*vptr++ = vtx->FinalPosition[0] | (vtx->FinalPosition[1] << 16); *vptr++ = (vtx->FinalPosition[0] << 1) | (vtx->FinalPosition[1] << 17); + //*vptr++ = (vtx->FinalPosition[0] << 2) | (vtx->FinalPosition[1] << 18); *vptr++ = z | (w << 16); *vptr++ = (vtx->FinalColor[0] >> 1) | @@ -1117,6 +1133,7 @@ void RenderFrame() glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i*8, 1024, 8, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, vram); } + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); glDisable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMaski(1, GL_TRUE, GL_TRUE, GL_FALSE, GL_FALSE); @@ -1361,7 +1378,19 @@ if (PolygonList[firsttrans].PolyData->IsShadow) printf("!! GLORG!!! %08X\n", Pol } - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID); + if (false) + { + glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferID[0]); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[1]); + glBlitFramebuffer(0, 0, 1024, 768, 0, 0, 512, 384, GL_COLOR_BUFFER_BIT, GL_LINEAR); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); + } + else + { + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); + } + glReadBuffer(GL_COLOR_ATTACHMENT0); //glReadPixels(0, 0, 256, 48, GL_RGBA, GL_UNSIGNED_BYTE, Framebuffer); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); -- cgit v1.2.3 From 13b0d13e23ca175ac66ab2a6c9d32809723797cb Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 10 May 2019 15:59:46 +0200 Subject: move code around --- src/GPU3D_OpenGL43.cpp | 385 ++++++++++++++++++++++++++----------------------- 1 file changed, 205 insertions(+), 180 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index d28053c..9e772e9 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -24,7 +24,7 @@ #include "NDS.h" #include "GPU.h" #include "Platform.h" - +extern "C" u32 SDL_GetTicks(); namespace GPU3D { namespace GLRenderer43 @@ -570,6 +570,7 @@ typedef struct } RendererPolygon; RendererPolygon PolygonList[2048]; +int NumFinalPolys, NumOpaqueFinalPolys; GLuint ClearVertexBufferID, ClearVertexArrayID; @@ -1094,6 +1095,195 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) NumVertices = vidx; } +void RenderSceneChunk(int y, int h) +{ + u32 flags = 0; + if (RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer; + + if (h != 192) glScissor(0, y*2, 256*2, h*2); + + // pass 1: opaque pixels + + UseRenderShader(flags); + + // zorp + glDepthFunc(GL_LESS); + + glStencilFunc(GL_ALWAYS, 0xFF, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + glBindVertexArray(VertexArrayID); + glDrawElements(GL_TRIANGLES, NumTriangles*3, GL_UNSIGNED_SHORT, IndexBuffer); + + + glEnable(GL_BLEND); + UseRenderShader(flags | RenderFlag_Trans); + + u16* iptr; + u32 curkey; + bool lastwasshadow;bool darp; +//printf("morp %08X\n", RenderClearAttr1); + 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, 0, 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; + lastwasshadow = false; darp = false; + + for (int i = NumOpaqueFinalPolys; i < NumFinalPolys; i++) + { + RendererPolygon* rp = &PolygonList[i]; + //printf("PASS 3 POLYGON %i: ATTR %08X (%d) | KEY %08X\n", i, rp->PolyData->Attr, (rp->PolyData->Attr>>4)&0x3, rp->RenderKey); + 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) + { + //printf("beginning shadowmask batch: %d, %d\n", lastwasshadow, darp); + /*if (!lastwasshadow) + { + //glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); + + glDisable(GL_BLEND); + UseRenderShader(flags | RenderFlag_ShadowMask); + + // shadow bits are set where the depth test fails + // sure enough, if GL_LESS fails, the opposite function would pass + glDepthFunc(GL_GEQUAL); + + //glStencilFunc(GL_ALWAYS, 0x80, 0x80); + //glStencilOp(GL_REPLACE, GL_REPLACE, GL_KEEP); + + glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + glDepthMask(GL_FALSE); + + lastwasshadow = true; + }*/ + + glDisable(GL_BLEND); + UseRenderShader(flags | RenderFlag_ShadowMask); + + glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + glDepthMask(GL_FALSE); + glDepthFunc(GL_GEQUAL); + glStencilFunc(GL_ALWAYS,0,0); + glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); + lastwasshadow=true; + + darp = false; + } + else + { + if (rp->PolyData->IsShadow) glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); + //if (rp->PolyData->IsShadow) printf("beginning shadow batch: %d, %d\n", lastwasshadow, darp); + + if (rp->PolyData->IsShadow) + UseRenderShader(flags | RenderFlag_Shadow); + else + UseRenderShader(flags | RenderFlag_Trans); + + if (lastwasshadow) + { + glEnable(GL_BLEND); + + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + lastwasshadow = false; + } + + // zorp + glDepthFunc(GL_LESS); + + u32 polyattr = rp->PolyData->Attr; + u32 polyid = (polyattr >> 24) & 0x3F; + + glStencilFunc(GL_NOTEQUAL, 0x40|polyid, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + if (polyattr & (1<<11)) glDepthMask(GL_TRUE); + else glDepthMask(GL_FALSE); + + darp = rp->PolyData->IsShadow; + } + } + } + + { + u16* endptr = &IndexBuffer[NumTriangles*3]; + u32 num = (u32)(endptr - iptr); + if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); + } + } + + glFlush(); +} + void VCount144() { @@ -1132,6 +1322,12 @@ void RenderFrame() glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i*8, 1024, 8, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, vram); } +//u32 _start = SDL_GetTicks(); + //glEnable(GL_SCISSOR_TEST); + //for (int sy=0; sy<384; sy+=96) + // { + //glScissor(0, sy, 512, 96); + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); glDisable(GL_BLEND); @@ -1186,197 +1382,26 @@ 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; npolys++; } + NumFinalPolys = npolys; + NumOpaqueFinalPolys = firsttrans; BuildPolygons(&PolygonList[0], npolys); glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); - // pass 1: opaque pixels - - UseRenderShader(flags); - - // zorp - glDepthFunc(GL_LESS); - - glStencilFunc(GL_ALWAYS, 0xFF, 0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - glBindVertexArray(VertexArrayID); - glDrawElements(GL_TRIANGLES, NumTriangles*3, GL_UNSIGNED_SHORT, IndexBuffer); - - - glEnable(GL_BLEND); - UseRenderShader(flags | RenderFlag_Trans); - - u16* iptr; - u32 curkey; - bool lastwasshadow;bool darp; -//printf("morp %08X\n", RenderClearAttr1); - if (firsttrans > -1) - { - glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); -if (PolygonList[firsttrans].PolyData->IsShadow) printf("!! GLORG!!! %08X\n", PolygonList[firsttrans].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[firsttrans].Indices; - curkey = 0xFFFFFFFF; - - glDisable(GL_BLEND); - - for (int i = firsttrans; i < npolys; 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, 0, 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[firsttrans].Indices; - curkey = 0xFFFFFFFF; - lastwasshadow = false; darp = false; - - for (int i = firsttrans; i < npolys; i++) - { - RendererPolygon* rp = &PolygonList[i]; - //printf("PASS 3 POLYGON %i: ATTR %08X (%d) | KEY %08X\n", i, rp->PolyData->Attr, (rp->PolyData->Attr>>4)&0x3, rp->RenderKey); - 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) - { - //printf("beginning shadowmask batch: %d, %d\n", lastwasshadow, darp); - /*if (!lastwasshadow) - { - //glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); - - glDisable(GL_BLEND); - UseRenderShader(flags | RenderFlag_ShadowMask); - - // shadow bits are set where the depth test fails - // sure enough, if GL_LESS fails, the opposite function would pass - glDepthFunc(GL_GEQUAL); - - //glStencilFunc(GL_ALWAYS, 0x80, 0x80); - //glStencilOp(GL_REPLACE, GL_REPLACE, GL_KEEP); - - glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); - glDepthMask(GL_FALSE); - - lastwasshadow = true; - }*/ - - glDisable(GL_BLEND); - UseRenderShader(flags | RenderFlag_ShadowMask); - - glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); - glDepthMask(GL_FALSE); - glDepthFunc(GL_GEQUAL); - glStencilFunc(GL_ALWAYS,0,0); - glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); - lastwasshadow=true; - - darp = false; - } - else - { - if (rp->PolyData->IsShadow) glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); - //if (rp->PolyData->IsShadow) printf("beginning shadow batch: %d, %d\n", lastwasshadow, darp); - - if (rp->PolyData->IsShadow) - UseRenderShader(flags | RenderFlag_Shadow); - else - UseRenderShader(flags | RenderFlag_Trans); - - if (lastwasshadow) - { - glEnable(GL_BLEND); - - glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - lastwasshadow = false; - } - - // zorp - glDepthFunc(GL_LESS); - - u32 polyattr = rp->PolyData->Attr; - u32 polyid = (polyattr >> 24) & 0x3F; - - glStencilFunc(GL_NOTEQUAL, 0x40|polyid, 0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - if (polyattr & (1<<11)) glDepthMask(GL_TRUE); - else glDepthMask(GL_FALSE); - - darp = rp->PolyData->IsShadow; - } - } - } - - { - u16* endptr = &IndexBuffer[NumTriangles*3]; - u32 num = (u32)(endptr - iptr); - if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); - } - } + RenderSceneChunk(0, 192); } - + //} +//glFinish();u32 _end=SDL_GetTicks(); printf("render time: %d\n", _end-_start);s if (false) { -- cgit v1.2.3 From b74587a4823ee2977b04ecbd475fcdf0d8711738 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 10 May 2019 16:30:20 +0200 Subject: * optional path for chunked rendering (might be faster, but not always) * fix bugs --- src/GPU2D.cpp | 3 +- src/GPU3D_OpenGL43.cpp | 93 +++++++++++++++++++++++++++++++------------------- src/libui_sdl/main.cpp | 2 +- 3 files changed, 60 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index ed47fd3..f725de5 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -650,7 +650,8 @@ void GPU2D::DrawScanline(u32 line) u32 dispmode = DispCnt >> 16; dispmode &= (Num ? 0x1 : 0x3); - _3dgfx = GPU3D::GetLine(_3dline); + if (Num == 0) + _3dgfx = GPU3D::GetLine(_3dline); // always render regular graphics DrawScanline_Mode1(line, mode1gfx, _3dgfx); diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 9e772e9..91a0179 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -601,6 +601,8 @@ GLuint FramebufferTex[4]; GLuint FramebufferID[2], PixelbufferID; u8 Framebuffer[512*384*4]; +bool ChunkedRendering = false; + bool InitGLExtensions() { @@ -1108,6 +1110,7 @@ void RenderSceneChunk(int y, int h) // zorp glDepthFunc(GL_LESS); + glDepthMask(GL_TRUE); glStencilFunc(GL_ALWAYS, 0xFF, 0xFF); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); @@ -1322,12 +1325,8 @@ void RenderFrame() glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i*8, 1024, 8, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, vram); } -//u32 _start = SDL_GetTicks(); - //glEnable(GL_SCISSOR_TEST); - //for (int sy=0; sy<384; sy+=96) - // { - //glScissor(0, sy, 512, 96); + glDisable(GL_SCISSOR_TEST); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); glDisable(GL_BLEND); @@ -1398,10 +1397,16 @@ void RenderFrame() glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); - RenderSceneChunk(0, 192); + if (!ChunkedRendering) + { + RenderSceneChunk(0, 192); + } + else + { + glEnable(GL_SCISSOR_TEST); + RenderSceneChunk(0, 48); + } } - //} -//glFinish();u32 _end=SDL_GetTicks(); printf("render time: %d\n", _end-_start);s if (false) { @@ -1417,45 +1422,61 @@ void RenderFrame() } glReadBuffer(GL_COLOR_ATTACHMENT0); - //glReadPixels(0, 0, 256, 48, GL_RGBA, GL_UNSIGNED_BYTE, Framebuffer); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - //glReadPixels(0, 0, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); - glReadPixels(0, 0, 512, 384, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + + if (!ChunkedRendering) + glReadPixels(0, 0, 256*2, 192*2, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + else + glReadPixels(0, 0, 256*2, 48*2, GL_BGRA, GL_UNSIGNED_BYTE, NULL); } u32* GetLine(int line) { - if (line == 0) + if (!ChunkedRendering) { - u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - //if (data) memcpy(&Framebuffer[4*256*0], data, 4*256*48); - if (data) memcpy(&Framebuffer[4*256*0], data, 4*512*384); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - - //glReadPixels(0, 48, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + if (line == 0) + { + u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (data) memcpy(&Framebuffer[4*1024*0], data, 4*1024*192); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + } } - /*else if (line == 48) + else { - u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (data) memcpy(&Framebuffer[4*256*48], data, 4*256*48); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + if (line == 0) + { + u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (data) memcpy(&Framebuffer[4*1024*0], data, 4*1024*48); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - glReadPixels(0, 96, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); - } - else if (line == 96) - { - u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (data) memcpy(&Framebuffer[4*256*96], data, 4*256*48); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + if (RenderNumPolygons) RenderSceneChunk(48, 48); + glReadPixels(0, 48*2, 256*2, 48*2, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + } + else if (line == 48) + { + u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (data) memcpy(&Framebuffer[4*1024*48], data, 4*1024*48); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + + if (RenderNumPolygons) RenderSceneChunk(96, 48); + glReadPixels(0, 96*2, 256*2, 48*2, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + } + else if (line == 96) + { + u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (data) memcpy(&Framebuffer[4*1024*96], data, 4*1024*48); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - glReadPixels(0, 144, 256, 48, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + if (RenderNumPolygons) RenderSceneChunk(144, 48); + glReadPixels(0, 144*2, 256*2, 48*2, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + } + else if (line == 144) + { + u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (data) memcpy(&Framebuffer[4*1024*144], data, 4*1024*48); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + } } - else if (line == 144) - { - u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (data) memcpy(&Framebuffer[4*256*144], data, 4*256*48); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - }*/ u32* ptr = (u32*)&Framebuffer[512*2*4 * line]; for (int i = 0; i < 1024; i++) diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index cc4e15d..f77f836 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -643,7 +643,7 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) uiRect top = {0, 0, 256*ScreenScale, 192*ScreenScale}; uiRect bot = {0, 192*ScreenScale, 256*ScreenScale, 192*ScreenScale}; - uiDrawBitmapUpdate(ScreenBitmap, ScreenBuffer); + if (ScreenBuffer) uiDrawBitmapUpdate(ScreenBitmap, ScreenBuffer); uiDrawSave(params->Context); uiDrawTransform(params->Context, &TopScreenTrans); -- cgit v1.2.3 From 492d2cfa692bf0747828f528430136268929affb Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 10 May 2019 17:49:13 +0200 Subject: implement texture blending/shading modes --- src/GPU3D_OpenGL43.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 91a0179..f48eb1f 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -131,16 +131,18 @@ void main() const char* kRenderVSCommon = R"( -layout(location=0) in uvec4 vPosition; -layout(location=1) in uvec4 vColor; -layout(location=2) in ivec2 vTexcoord; -layout(location=3) in uvec3 vPolygonAttr; - layout(std140, binding=0) uniform uConfig { vec2 uScreenSize; + uint uDispCnt; + vec4 uToonColors[32]; }; +layout(location=0) in uvec4 vPosition; +layout(location=1) in uvec4 vColor; +layout(location=2) in ivec2 vTexcoord; +layout(location=3) in uvec3 vPolygonAttr; + smooth out vec4 fColor; smooth out vec2 fTexcoord; flat out uvec3 fPolygonAttr; @@ -151,6 +153,13 @@ const char* kRenderFSCommon = R"( layout(binding=0) uniform usampler2D TexMem; layout(binding=1) uniform sampler2D TexPalMem; +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uDispCnt; + vec4 uToonColors[32]; +}; + smooth in vec4 fColor; smooth in vec2 fTexcoord; flat in uvec3 fPolygonAttr; @@ -360,9 +369,24 @@ vec4 FinalColor() { vec4 col; vec4 vcol = fColor; + uint blendmode = (fPolygonAttr.x >> 4) & 0x3; - // TODO: also check DISPCNT - if (((fPolygonAttr.y >> 26) & 0x7) == 0) + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) == 0) + { + // toon + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + vcol.rgb = tooncolor; + } + else + { + // highlight + vcol.rgb = vcol.rrr; + } + } + + if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0)) { // no texture col = vcol; @@ -371,7 +395,26 @@ vec4 FinalColor() { vec4 tcol = TextureLookup(); - col = vcol * tcol; + if ((blendmode & 1) != 0) + { + // decal + col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a)); + col.a = vcol.a; + } + else + { + // modulate + col = vcol * tcol; + } + } + + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) != 0) + { + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + col.rgb = min(col.rgb + tooncolor, 1.0); + } } return col.bgra; @@ -555,6 +598,9 @@ GLuint RenderShader[16][3]; struct { float uScreenSize[2]; + u32 uDispCnt; + u32 __pad0; + float uToonColors[32][4]; } ShaderConfig; @@ -709,7 +755,7 @@ bool BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* 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); + //printf("shader source:\n--\n%s\n--\n", fs); delete[] log; glDeleteShader(ids[0]); @@ -1294,6 +1340,25 @@ void VCount144() void RenderFrame() { + 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); -- cgit v1.2.3 From 7a2504a3a432f16c009794ae4ec311d2ab5743e7 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 10 May 2019 18:22:34 +0200 Subject: fix derpy bug --- src/GPU2D.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index f725de5..aaaddab 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -559,7 +559,7 @@ u32 GPU2D::ColorBlend4(u32 val1, u32 val2, u32 eva, u32 evb) if (g > 0x003F00) g = 0x003F00; if (b > 0x3F0000) b = 0x3F0000; - return r | g | b; + return r | g | b | 0xFF000000; } u32 GPU2D::ColorBlend5(u32 val1, u32 val2) @@ -582,7 +582,7 @@ u32 GPU2D::ColorBlend5(u32 val1, u32 val2) if (g > 0x003F00) g = 0x003F00; if (b > 0x3F0000) b = 0x3F0000; - return r | g | b; + return r | g | b | 0xFF000000; } u32 GPU2D::ColorBrightnessUp(u32 val, u32 factor) @@ -595,7 +595,7 @@ u32 GPU2D::ColorBrightnessUp(u32 val, u32 factor) g += ((((0x003F00 - g) * factor) >> 4) & 0x003F00); b += ((((0x3F0000 - b) * factor) >> 4) & 0x3F0000); - return r | g | b; + return r | g | b | 0xFF000000; } u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) @@ -608,7 +608,7 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) g -= (((g * factor) >> 4) & 0x003F00); b -= (((b * factor) >> 4) & 0x3F0000); - return r | g | b; + return r | g | b | 0xFF000000; } -- cgit v1.2.3 From 44e1593e1f82a3ecc627925353a2ae608d36d62d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 10 May 2019 22:22:17 +0200 Subject: some optimization to the 2D pipeline --- src/GPU2D.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index aaaddab..fc36557 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -567,6 +567,8 @@ u32 GPU2D::ColorBlend5(u32 val1, u32 val2) u32 eva = ((val1 >> 24) & 0x1F) + 1; u32 evb = 32 - eva; + if (eva == 32) return val1; + u32 r = (((val1 & 0x00003F) * eva) + ((val2 & 0x00003F) * evb)) >> 5; u32 g = ((((val1 & 0x003F00) * eva) + ((val2 & 0x003F00) * evb)) >> 5) & 0x007F00; u32 b = ((((val1 & 0x3F0000) * eva) + ((val2 & 0x3F0000) * evb)) >> 5) & 0x7F0000; @@ -587,28 +589,24 @@ u32 GPU2D::ColorBlend5(u32 val1, u32 val2) u32 GPU2D::ColorBrightnessUp(u32 val, u32 factor) { - u32 r = val & 0x00003F; + u32 rb = val & 0x3F003F; u32 g = val & 0x003F00; - u32 b = val & 0x3F0000; - r += (((0x00003F - r) * factor) >> 4); + rb += ((((0x3F003F - rb) * factor) >> 4) & 0x3F003F); g += ((((0x003F00 - g) * factor) >> 4) & 0x003F00); - b += ((((0x3F0000 - b) * factor) >> 4) & 0x3F0000); - return r | g | b | 0xFF000000; + return rb | g | 0xFF000000; } u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) { - u32 r = val & 0x00003F; + u32 rb = val & 0x3F003F; u32 g = val & 0x003F00; - u32 b = val & 0x3F0000; - r -= ((r * factor) >> 4); + rb -= (((rb * factor) >> 4) & 0x3F003F); g -= (((g * factor) >> 4) & 0x003F00); - b -= (((b * factor) >> 4) & 0x3F0000); - return r | g | b | 0xFF000000; + return rb | g | 0xFF000000; } @@ -667,8 +665,8 @@ void GPU2D::DrawScanline(u32 line) case 1: // regular display { - for (int i = 0; i < LineStride; i++) - dst[i] = mode1gfx[i]; + for (int i = 0; i < LineStride; i+=2) + *(u64*)&dst[i] = *(u64*)&mode1gfx[i]; } break; @@ -1193,7 +1191,7 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) u32 linebuf[1024*2 + 64]; u8* windowmask = (u8*)&linebuf[1024*2]; - u32 backdrop; + u64 backdrop; if (Num) backdrop = *(u16*)&GPU::Palette[0x400]; else backdrop = *(u16*)&GPU::Palette[0]; @@ -1203,9 +1201,10 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) u8 b = (backdrop & 0x7C00) >> 9; backdrop = r | (g << 8) | (b << 16) | 0x20000000; + backdrop |= (backdrop << 32); - for (int i = 0; i < LineStride; i++) - linebuf[i] = backdrop; + for (int i = 0; i < LineStride; i+=2) + *(u64*)&linebuf[i] = backdrop; } if (DispCnt & 0xE000) -- cgit v1.2.3 From 858c0eecb91f8f15e8347b9fbad806961d0d8534 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 11 May 2019 01:46:38 +0200 Subject: scale screen gap also moar optimization... --- src/GPU2D.cpp | 12 ++++++------ src/libui_sdl/main.cpp | 13 ++++++++----- 2 files changed, 14 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index fc36557..505468d 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -773,16 +773,16 @@ void GPU2D::DrawScanline(u32 line) // convert to 32-bit BGRA // note: 32-bit RGBA would be more straightforward, but // BGRA seems to be more compatible (Direct2D soft, cairo...) - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < LineStride; i+=2) { - u32 c = dst[i]; + u64 c = *(u64*)&dst[i]; - u32 r = c << 18; - u32 g = (c << 2) & 0xFC00; - u32 b = (c >> 14) & 0xFC; + u64 r = (c << 18) & 0xFC000000FC0000; + u64 g = (c << 2) & 0xFC000000FC00; + u64 b = (c >> 14) & 0xFC000000FC; c = r | g | b; - dst[i] = c | ((c & 0x00C0C0C0) >> 6) | 0xFF000000; + *(u64*)&dst[i] = c | ((c & 0x00C0C0C000C0C0C0) >> 6) | 0xFF000000FF000000; } } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index f77f836..b3fce3f 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -812,7 +812,7 @@ void SetupScreenRects(int width, int height) else sizemode = ScreenSizing; - int screenW, screenH; + int screenW, screenH, gap; if (sideways) { screenW = 192; @@ -824,8 +824,11 @@ void SetupScreenRects(int width, int height) screenH = 192; } + gap = ScreenGap; + screenW *= ScreenScale; screenH *= ScreenScale; + gap *= ScreenScale; uiRect *topscreen, *bottomscreen; if (ScreenRotation == 1 || ScreenRotation == 2) @@ -846,7 +849,7 @@ void SetupScreenRects(int width, int height) int heightreq; int startX = 0; - width -= ScreenGap; + width -= gap; if (sizemode == 0) // even { @@ -884,7 +887,7 @@ void SetupScreenRects(int width, int height) topscreen->X = startX; topscreen->Y = ((height - heightreq) / 2) + (heightreq - topscreen->Height); - bottomscreen->X = topscreen->X + topscreen->Width + ScreenGap; + bottomscreen->X = topscreen->X + topscreen->Width + gap; if (sizemode == 1) { @@ -905,7 +908,7 @@ void SetupScreenRects(int width, int height) int widthreq; int startY = 0; - height -= ScreenGap; + height -= gap; if (sizemode == 0) // even { @@ -943,7 +946,7 @@ void SetupScreenRects(int width, int height) topscreen->Y = startY; topscreen->X = (width - topscreen->Width) / 2; - bottomscreen->Y = topscreen->Y + topscreen->Height + ScreenGap; + bottomscreen->Y = topscreen->Y + topscreen->Height + gap; if (sizemode == 1) { -- cgit v1.2.3 From 5c9df6a4e5dc507a1498a79ea30c3dea279e94bf Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 11 May 2019 15:01:54 +0200 Subject: attempt to take shadow support a bit further. --- src/GPU3D_OpenGL43.cpp | 56 +++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index f48eb1f..cc099f2 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -24,7 +24,7 @@ #include "NDS.h" #include "GPU.h" #include "Platform.h" -extern "C" u32 SDL_GetTicks(); + namespace GPU3D { namespace GLRenderer43 @@ -82,7 +82,7 @@ PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei; PFNGLCOLORMASKIPROC glColorMaski; -PFNGLMEMORYBARRIERPROC glMemoryBarrier; +PFNGLMEMORYBARRIERPROC glMemoryBarrier; PFNGLGETSTRINGIPROC glGetStringi; @@ -118,13 +118,14 @@ layout(location=2) uniform uint uOpaquePolyID; layout(location=3) uniform uint uFogFlag; layout(location=0) out vec4 oColor; -layout(location=1) out uvec2 oAttr; +layout(location=1) out uvec3 oAttr; void main() { oColor = vec4(uColor).bgra / 31.0; - oAttr.r = uOpaquePolyID; - oAttr.g = 0; + oAttr.r = 0; + oAttr.g = uOpaquePolyID; + oAttr.b = 0; } )"; @@ -165,7 +166,7 @@ smooth in vec2 fTexcoord; flat in uvec3 fPolygonAttr; layout(location=0) out vec4 oColor; -layout(location=1) out uvec2 oAttr; +layout(location=1) out uvec3 oAttr; vec4 TextureLookup() { @@ -475,7 +476,7 @@ void main() if (col.a < 30.5/31) discard; oColor = col; - oAttr.r = (fPolygonAttr.x >> 24) & 0x3F; + oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; } )"; @@ -489,7 +490,7 @@ void main() if (col.a < 30.5/31) discard; oColor = col; - oAttr.r = (fPolygonAttr.x >> 24) & 0x3F; + oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; gl_FragDepth = fZ; } )"; @@ -503,6 +504,7 @@ void main() if (col.a >= 30.5/31) discard; oColor = col; + oAttr.g = 0xFF; } )"; @@ -517,6 +519,7 @@ void main() if (col.a >= 30.5/31) discard; oColor = col; + oAttr.g = 0xFF; gl_FragDepth = fZ; } )"; @@ -526,7 +529,8 @@ const char* kRenderFS_ZSM = R"( void main() { oColor = vec4(0,0,0,1); - oAttr.g = 1; + oAttr.g = 0xFF; + oAttr.b = 1; } )"; @@ -537,7 +541,8 @@ smooth in float fZ; void main() { oColor = vec4(0,0,0,1); - oAttr.g = 1; + oAttr.g = 0xFF; + oAttr.b = 1; gl_FragDepth = fZ; } )"; @@ -554,7 +559,8 @@ void main() if (col.a >= 30.5/31) discard; uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.y != 1) discard; + if (iAttr.b != 1) discard; + if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; oColor = col; } @@ -574,7 +580,8 @@ void main() if (col.a >= 30.5/31) discard; uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.y != 1) discard; + if (iAttr.b != 1) discard; + if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; oColor = col; gl_FragDepth = fZ; @@ -945,7 +952,8 @@ bool Init() glGenFramebuffers(2, &FramebufferID[0]); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); - glGenTextures(1, &FramebufferTex[0]); + // color buffer + glGenTextures(4, &FramebufferTex[0]); glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -954,7 +962,7 @@ bool Init() glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screenW, screenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); - glGenTextures(1, &FramebufferTex[1]); + // depth/stencil buffer glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -963,17 +971,20 @@ bool Init() glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, screenW, screenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[1], 0); - glGenTextures(1, &FramebufferTex[2]); + // attribute buffer + // R: opaque polyID (for edgemarking) + // G: opaque polyID (for shadows, suppressed when rendering translucent polygons) + // B: stencil flag glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); 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_RG8UI, screenW, screenH, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, screenW, screenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[2], 0); + // downscale framebuffer, for antialiased mode glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); - glGenTextures(1, &FramebufferTex[3]); glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -1154,7 +1165,8 @@ void RenderSceneChunk(int y, int h) UseRenderShader(flags); - // zorp + glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + glDepthFunc(GL_LESS); glDepthMask(GL_TRUE); @@ -1277,7 +1289,7 @@ if (PolygonList[NumOpaqueFinalPolys].PolyData->IsShadow) printf("!! GLORG!!! %08 UseRenderShader(flags | RenderFlag_ShadowMask); glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE); glDepthMask(GL_FALSE); glDepthFunc(GL_GEQUAL); glStencilFunc(GL_ALWAYS,0,0); @@ -1301,7 +1313,7 @@ if (PolygonList[NumOpaqueFinalPolys].PolyData->IsShadow) printf("!! GLORG!!! %08 glEnable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); lastwasshadow = false; } @@ -1396,7 +1408,7 @@ void RenderFrame() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); glDisable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glColorMaski(1, GL_TRUE, GL_TRUE, GL_FALSE, GL_FALSE); + glColorMaski(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); // clear buffers // TODO: clear bitmap @@ -1432,8 +1444,6 @@ void RenderFrame() glDrawArrays(GL_TRIANGLES, 0, 2*3); } - glColorMaski(1, GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); - if (RenderNumPolygons) { // render shit here -- cgit v1.2.3 From 53b22629173b9147231e1305ea9701377344b172 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 11 May 2019 15:14:59 +0200 Subject: calculate hi-res vertex positions. reduces shaking of polygons when rendering at a higher res. --- src/GPU3D.cpp | 10 ++++++++++ src/GPU3D.h | 4 ++++ src/GPU3D_OpenGL43.cpp | 6 +++++- 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 68b9c7f..3be8ee1 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -1194,6 +1194,16 @@ void SubmitPolygon() vtx->FinalPosition[0] = posX & 0x1FF; vtx->FinalPosition[1] = posY & 0xFF; + // hi-res positions + if (w != 0) + { + posX = ((((s64)(vtx->Position[0] + w) * Viewport[4]) << 4) / (((s64)w) << 1)) + (Viewport[0] << 4); + posY = ((((s64)(-vtx->Position[1] + w) * Viewport[5]) << 4) / (((s64)w) << 1)) + (Viewport[3] << 4); + + vtx->HiresPosition[0] = posX & 0x1FFF; + vtx->HiresPosition[1] = posY & 0xFFF; + } + vtx->FinalColor[0] = vtx->Color[0] >> 12; if (vtx->FinalColor[0]) vtx->FinalColor[0] = ((vtx->FinalColor[0] << 4) + 0xF); vtx->FinalColor[1] = vtx->Color[1] >> 12; diff --git a/src/GPU3D.h b/src/GPU3D.h index ecc23de..53712ad 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -39,6 +39,10 @@ typedef struct s32 FinalPosition[2]; s32 FinalColor[3]; + // hi-res position (4-bit fractional part) + // TODO maybe: hi-res color? (that survives clipping) + s32 HiresPosition[2]; + } Vertex; typedef struct diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index cc099f2..1e4f9d7 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -1120,9 +1120,13 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) u32 zshift = 0; while (z > 0xFFFF) { z >>= 1; zshift++; } + u32 x = vtx->HiresPosition[0] >> 3; + u32 y = vtx->HiresPosition[1] >> 3; + *vptr++ = x | (y << 16); + // TODO hires-upgraded positions? //*vptr++ = vtx->FinalPosition[0] | (vtx->FinalPosition[1] << 16); - *vptr++ = (vtx->FinalPosition[0] << 1) | (vtx->FinalPosition[1] << 17); + //*vptr++ = (vtx->FinalPosition[0] << 1) | (vtx->FinalPosition[1] << 17); //*vptr++ = (vtx->FinalPosition[0] << 2) | (vtx->FinalPosition[1] << 18); *vptr++ = z | (w << 16); -- cgit v1.2.3 From b730bb890207d206505c338178fd49d244cd554d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 11 May 2019 15:36:42 +0200 Subject: welp --- melonDS.cbp | 2 + src/libui_sdl/DlgVideoSettings.cpp | 150 +++++++++++++++++++++++++++++++++++++ src/libui_sdl/DlgVideoSettings.h | 29 +++++++ src/libui_sdl/main.cpp | 8 ++ 4 files changed, 189 insertions(+) create mode 100644 src/libui_sdl/DlgVideoSettings.cpp create mode 100644 src/libui_sdl/DlgVideoSettings.h (limited to 'src') diff --git a/melonDS.cbp b/melonDS.cbp index 0ba8653..b396861 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -131,6 +131,8 @@ + + diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp new file mode 100644 index 0000000..f27a80b --- /dev/null +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -0,0 +1,150 @@ +/* + 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 + +#include "libui/ui.h" + +#include "../types.h" +#include "PlatformConfig.h" + +#include "DlgVideoSettings.h" + + +// + + +namespace DlgVideoSettings +{ + +bool opened; +uiWindow* win; + +// + + +int OnCloseWindow(uiWindow* window, void* blarg) +{ + opened = false; + return 1; +} + +// + +void OnCancel(uiButton* btn, void* blarg) +{ + // restore old settings here + + uiControlDestroy(uiControl(win)); + opened = false; +} + +void OnOk(uiButton* btn, void* blarg) +{ + // set config entries here + + Config::Save(); + + uiControlDestroy(uiControl(win)); + opened = false; +} + +void Open() +{ + if (opened) + { + uiControlSetFocus(uiControl(win)); + return; + } + + opened = true; + win = uiNewWindow("Video settings - melonDS", 400, 100, 0, 0, 0); + uiWindowSetMargined(win, 1); + uiWindowOnClosing(win, OnCloseWindow, NULL); + + uiBox* top = uiNewVerticalBox(); + uiWindowSetChild(win, uiControl(top)); + uiBoxSetPadded(top, 1); + + /*{ + uiGroup* grp = uiNewGroup("Audio output"); + uiBoxAppend(top, uiControl(grp), 0); + uiGroupSetMargined(grp, 1); + + uiBox* in_ctrl = uiNewVerticalBox(); + uiGroupSetChild(grp, uiControl(in_ctrl)); + + uiLabel* label_vol = uiNewLabel("Volume:"); + uiBoxAppend(in_ctrl, uiControl(label_vol), 0); + + slVolume = uiNewSlider(0, 256); + uiSliderOnChanged(slVolume, OnVolumeChanged, NULL); + uiBoxAppend(in_ctrl, uiControl(slVolume), 0); + } + + { + uiGroup* grp = uiNewGroup("Microphone input"); + uiBoxAppend(top, uiControl(grp), 0); + uiGroupSetMargined(grp, 1); + + uiBox* in_ctrl = uiNewVerticalBox(); + uiGroupSetChild(grp, uiControl(in_ctrl)); + + rbMicInputType = uiNewRadioButtons(); + uiRadioButtonsAppend(rbMicInputType, "None"); + uiRadioButtonsAppend(rbMicInputType, "Microphone"); + uiRadioButtonsAppend(rbMicInputType, "White noise"); + uiRadioButtonsAppend(rbMicInputType, "WAV file:"); + uiBoxAppend(in_ctrl, uiControl(rbMicInputType), 0); + + uiBox* path_box = uiNewHorizontalBox(); + uiBoxAppend(in_ctrl, uiControl(path_box), 0); + + txMicWavPath = uiNewEntry(); + uiBoxAppend(path_box, uiControl(txMicWavPath), 1); + + uiButton* path_browse = uiNewButton("..."); + uiButtonOnClicked(path_browse, OnMicWavBrowse, NULL); + uiBoxAppend(path_box, uiControl(path_browse), 0); + }*/ + + { + uiBox* in_ctrl = uiNewHorizontalBox(); + uiBoxSetPadded(in_ctrl, 1); + uiBoxAppend(top, uiControl(in_ctrl), 0); + + uiLabel* dummy = uiNewLabel(""); + uiBoxAppend(in_ctrl, uiControl(dummy), 1); + + uiButton* btncancel = uiNewButton("Cancel"); + uiButtonOnClicked(btncancel, OnCancel, NULL); + uiBoxAppend(in_ctrl, uiControl(btncancel), 0); + + uiButton* btnok = uiNewButton("Ok"); + uiButtonOnClicked(btnok, OnOk, NULL); + uiBoxAppend(in_ctrl, uiControl(btnok), 0); + } + + // + + uiControlShow(uiControl(win)); +} + +} diff --git a/src/libui_sdl/DlgVideoSettings.h b/src/libui_sdl/DlgVideoSettings.h new file mode 100644 index 0000000..cd3d1b1 --- /dev/null +++ b/src/libui_sdl/DlgVideoSettings.h @@ -0,0 +1,29 @@ +/* + 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 DLGVIDEOSETTINGS_H +#define DLGVIDEOSETTINGS_H + +namespace DlgVideoSettings +{ + +void Open(); + +} + +#endif // DLGVIDEOSETTINGS_H diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index b3fce3f..a8a5ceb 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -30,6 +30,7 @@ #include "DlgEmuSettings.h" #include "DlgInputConfig.h" +#include "DlgVideoSettings.h" #include "DlgAudioSettings.h" #include "DlgWifiSettings.h" @@ -1502,6 +1503,11 @@ void OnOpenHotkeyConfig(uiMenuItem* item, uiWindow* window, void* blarg) DlgInputConfig::Open(1); } +void OnOpenVideoSettings(uiMenuItem* item, uiWindow* window, void* blarg) +{ + DlgVideoSettings::Open(); +} + void OnOpenAudioSettings(uiMenuItem* item, uiWindow* window, void* blarg) { DlgAudioSettings::Open(); @@ -1865,6 +1871,8 @@ int main(int argc, char** argv) uiMenuItemOnClicked(menuitem, OnOpenInputConfig, NULL); menuitem = uiMenuAppendItem(menu, "Hotkey config"); uiMenuItemOnClicked(menuitem, OnOpenHotkeyConfig, NULL); + menuitem = uiMenuAppendItem(menu, "Video settings"); + uiMenuItemOnClicked(menuitem, OnOpenVideoSettings, NULL); menuitem = uiMenuAppendItem(menu, "Audio settings"); uiMenuItemOnClicked(menuitem, OnOpenAudioSettings, NULL); menuitem = uiMenuAppendItem(menu, "Wifi settings"); -- cgit v1.2.3 From 39080be9b747795d8699b8f803a7f7888b0144ff Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 11 May 2019 16:12:57 +0200 Subject: draft video settings dialog with the envisioned features --- src/libui_sdl/DlgVideoSettings.cpp | 89 ++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index f27a80b..ed33cb5 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -83,47 +83,88 @@ void Open() uiWindowSetChild(win, uiControl(top)); uiBoxSetPadded(top, 1); - /*{ - uiGroup* grp = uiNewGroup("Audio output"); - uiBoxAppend(top, uiControl(grp), 0); + uiBox* splitter = uiNewHorizontalBox(); + uiBoxAppend(top, uiControl(splitter), 0); + uiBoxSetPadded(splitter, 1); + + uiBox* left = uiNewVerticalBox(); + uiBoxAppend(splitter, uiControl(left), 1); + uiBoxSetPadded(left, 1); + uiBox* right = uiNewVerticalBox(); + uiBoxAppend(splitter, uiControl(right), 1); + uiBoxSetPadded(right, 1); + + { + uiGroup* grp = uiNewGroup("3D renderer"); + uiBoxAppend(left, uiControl(grp), 0); uiGroupSetMargined(grp, 1); uiBox* in_ctrl = uiNewVerticalBox(); uiGroupSetChild(grp, uiControl(in_ctrl)); - uiLabel* label_vol = uiNewLabel("Volume:"); - uiBoxAppend(in_ctrl, uiControl(label_vol), 0); + uiRadioButtons* rbRenderer = uiNewRadioButtons(); + uiRadioButtonsAppend(rbRenderer, "Software"); + uiRadioButtonsAppend(rbRenderer, "OpenGL"); + uiBoxAppend(in_ctrl, uiControl(rbRenderer), 0); + } - slVolume = uiNewSlider(0, 256); - uiSliderOnChanged(slVolume, OnVolumeChanged, NULL); - uiBoxAppend(in_ctrl, uiControl(slVolume), 0); + { + uiGroup* grp = uiNewGroup("Software renderer"); + uiBoxAppend(left, uiControl(grp), 0); + uiGroupSetMargined(grp, 1); + + uiBox* in_ctrl = uiNewVerticalBox(); + uiGroupSetChild(grp, uiControl(in_ctrl)); + + uiCheckbox* cbThreaded3D = uiNewCheckbox("Threaded"); + uiBoxAppend(in_ctrl, uiControl(cbThreaded3D), 0); } { - uiGroup* grp = uiNewGroup("Microphone input"); - uiBoxAppend(top, uiControl(grp), 0); + uiGroup* grp = uiNewGroup("OpenGL renderer"); + uiBoxAppend(left, uiControl(grp), 0); uiGroupSetMargined(grp, 1); uiBox* in_ctrl = uiNewVerticalBox(); uiGroupSetChild(grp, uiControl(in_ctrl)); - rbMicInputType = uiNewRadioButtons(); - uiRadioButtonsAppend(rbMicInputType, "None"); - uiRadioButtonsAppend(rbMicInputType, "Microphone"); - uiRadioButtonsAppend(rbMicInputType, "White noise"); - uiRadioButtonsAppend(rbMicInputType, "WAV file:"); - uiBoxAppend(in_ctrl, uiControl(rbMicInputType), 0); + uiCheckbox* cbAntialias = uiNewCheckbox("Antialiasing"); + uiBoxAppend(in_ctrl, uiControl(cbAntialias), 0); + } - uiBox* path_box = uiNewHorizontalBox(); - uiBoxAppend(in_ctrl, uiControl(path_box), 0); + { + uiGroup* grp = uiNewGroup("Display settings"); + uiBoxAppend(right, uiControl(grp), 0); + uiGroupSetMargined(grp, 1); + + uiBox* in_ctrl = uiNewVerticalBox(); + uiGroupSetChild(grp, uiControl(in_ctrl)); - txMicWavPath = uiNewEntry(); - uiBoxAppend(path_box, uiControl(txMicWavPath), 1); + uiLabel* lbl = uiNewLabel("Resolution:"); + uiBoxAppend(in_ctrl, uiControl(lbl), 0); - uiButton* path_browse = uiNewButton("..."); - uiButtonOnClicked(path_browse, OnMicWavBrowse, NULL); - uiBoxAppend(path_box, uiControl(path_browse), 0); - }*/ + uiRadioButtons* rbResolution = uiNewRadioButtons(); + uiRadioButtonsAppend(rbResolution, "1x"); + uiRadioButtonsAppend(rbResolution, "2x"); + uiRadioButtonsAppend(rbResolution, "4x"); + uiBoxAppend(in_ctrl, uiControl(rbResolution), 0); + + uiCheckbox* cbWidescreen = uiNewCheckbox("Stretch to 16:9"); + uiBoxAppend(in_ctrl, uiControl(cbWidescreen), 0); + + lbl = uiNewLabel(""); + uiBoxAppend(in_ctrl, uiControl(lbl), 0); + + lbl = uiNewLabel("Apply upscaling to:"); + uiBoxAppend(in_ctrl, uiControl(lbl), 0); + + uiRadioButtons* rbApplyScalingTo = uiNewRadioButtons(); + uiRadioButtonsAppend(rbApplyScalingTo, "Both screens"); + uiRadioButtonsAppend(rbApplyScalingTo, "Emphasized screen"); + uiRadioButtonsAppend(rbApplyScalingTo, "Top screen"); + uiRadioButtonsAppend(rbApplyScalingTo, "Bottom screen"); + uiBoxAppend(in_ctrl, uiControl(rbApplyScalingTo), 0); + } { uiBox* in_ctrl = uiNewHorizontalBox(); -- cgit v1.2.3 From 939a37638995a2f4504400c7b365aacf66536473 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 04:40:44 +0200 Subject: add relevant config entries --- src/Config.cpp | 6 ++++++ src/Config.h | 3 +++ src/libui_sdl/PlatformConfig.cpp | 8 ++++++++ src/libui_sdl/PlatformConfig.h | 4 ++++ 4 files changed, 21 insertions(+) (limited to 'src') diff --git a/src/Config.cpp b/src/Config.cpp index 4182dba..aca3d4f 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -28,12 +28,18 @@ namespace Config const char* kConfigFile = "melonDS.ini"; +int _3DRenderer; int Threaded3D; +int GL_Antialias; + ConfigEntry ConfigFile[] = { + {"3DRenderer", 0, &_3DRenderer, 1, NULL, 0}, {"Threaded3D", 0, &Threaded3D, 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 25d1ee2..8dc97d5 100644 --- a/src/Config.h +++ b/src/Config.h @@ -40,8 +40,11 @@ bool HasConfigFile(const char* fileName); void Load(); void Save(); +extern int _3DRenderer; extern int Threaded3D; +extern int GL_Antialias; + } #endif // CONFIG_H diff --git a/src/libui_sdl/PlatformConfig.cpp b/src/libui_sdl/PlatformConfig.cpp index 2daf746..065d9c2 100644 --- a/src/libui_sdl/PlatformConfig.cpp +++ b/src/libui_sdl/PlatformConfig.cpp @@ -40,6 +40,10 @@ int ScreenLayout; int ScreenSizing; int ScreenFilter; +int ScreenScale; +int ScreenRatio; +int ScreenScaleMode; + int LimitFPS; int DirectBoot; @@ -101,6 +105,10 @@ ConfigEntry PlatformConfigFile[] = {"ScreenSizing", 0, &ScreenSizing, 0, NULL, 0}, {"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0}, + {"ScreenScale", 0, &ScreenScale, 0, NULL, 0}, + {"ScreenRatio", 0, &ScreenRatio, 0, NULL, 0}, + {"ScreenScaleMode", 0, &ScreenScaleMode, 0, NULL, 0}, + {"LimitFPS", 0, &LimitFPS, 1, NULL, 0}, {"DirectBoot", 0, &DirectBoot, 1, NULL, 0}, diff --git a/src/libui_sdl/PlatformConfig.h b/src/libui_sdl/PlatformConfig.h index ed31e18..0cff1d2 100644 --- a/src/libui_sdl/PlatformConfig.h +++ b/src/libui_sdl/PlatformConfig.h @@ -48,6 +48,10 @@ extern int ScreenLayout; extern int ScreenSizing; extern int ScreenFilter; +extern int ScreenScale; +extern int ScreenRatio; +extern int ScreenScaleMode; + extern int LimitFPS; extern int DirectBoot; -- cgit v1.2.3 From c88981b5892ed3faf7cd19302c398debe27d94ed Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 15:01:40 +0200 Subject: split framebuffer. setup doublebuffering inside GPU.cpp. avoid copying a whole framebuffer every frame. better performance at higher res. --- src/GPU.cpp | 94 ++++++++++++++++++++++++++++---------- src/GPU.h | 5 +- src/libui_sdl/DlgVideoSettings.cpp | 2 +- src/libui_sdl/main.cpp | 27 +++++++---- 4 files changed, 91 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/GPU.cpp b/src/GPU.cpp index f272129..636c430 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -71,9 +71,9 @@ u32 VRAMMap_TexPal[8]; u32 VRAMMap_ARM7[2]; -u32* Framebuffer; -int FBScale; -int FBScreenStride; +int FrontBuffer; +u32* Framebuffer[2][2]; +int FBScale[2]; GPU2D* GPU2D_A; GPU2D* GPU2D_B; @@ -85,8 +85,12 @@ bool Init() GPU2D_B = new GPU2D(1); if (!GPU3D::Init()) return false; + FrontBuffer = 0; + Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL; + Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL; + FBScale[0] = -1; FBScale[1] = -1; //SetFramebufferScale(1); - SetFramebufferScale(2); + SetFramebufferScale(1, 1); return true; } @@ -97,7 +101,10 @@ void DeInit() delete GPU2D_B; GPU3D::DeInit(); - if (Framebuffer) delete[] Framebuffer; + if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; + if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; + if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; + if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; } void Reset() @@ -145,22 +152,32 @@ void Reset() VRAMMap_ARM7[0] = 0; VRAMMap_ARM7[1] = 0; - for (int i = 0; i < 256*192*2; i++) + for (int i = 0; i < (256*192)<<(FBScale[0]*2); i++) { - Framebuffer[i] = 0xFFFFFFFF; + Framebuffer[0][0][i] = 0xFFFFFFFF; + Framebuffer[1][0][i] = 0xFFFFFFFF; + } + for (int i = 0; i < (256*192)<<(FBScale[1]*2); i++) + { + Framebuffer[0][1][i] = 0xFFFFFFFF; + Framebuffer[1][1][i] = 0xFFFFFFFF; } GPU2D_A->Reset(); GPU2D_B->Reset(); GPU3D::Reset(); - GPU2D_A->SetFramebuffer(&Framebuffer[FBScreenStride]); - GPU2D_B->SetFramebuffer(&Framebuffer[0]); + int backbuf = FrontBuffer ? 0 : 1; + GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); + GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); } void Stop() { - memset(Framebuffer, 0, FBScreenStride*2*sizeof(u32)); + memset(Framebuffer[0][0], 0, (256*192)<<(FBScale[0]*2)); + memset(Framebuffer[0][1], 0, (256*192)<<(FBScale[1]*2)); + memset(Framebuffer[1][0], 0, (256*192)<<(FBScale[0]*2)); + memset(Framebuffer[1][1], 0, (256*192)<<(FBScale[1]*2)); } void DoSavestate(Savestate* file) @@ -215,13 +232,46 @@ void DoSavestate(Savestate* file) GPU3D::DoSavestate(file); } -void SetFramebufferScale(int scale) +void AssignFramebuffers() +{ + int backbuf = FrontBuffer ? 0 : 1; + if (NDS::PowerControl9 & (1<<15)) + { + GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]); + GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]); + } + else + { + GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); + GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); + } +} + +void SetFramebufferScale(int top, int bottom) { - FBScale = scale; - FBScreenStride = (256*scale) * (192*scale); + if (top != FBScale[0]) + { + FBScale[0] = top; - if (Framebuffer) delete[] Framebuffer; - Framebuffer = new u32[FBScreenStride * 2]; + int fbsize = (256 * 192) << (FBScale[0] * 2); + if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; + if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; + Framebuffer[0][0] = new u32[fbsize]; + Framebuffer[1][0] = new u32[fbsize]; + } + + if (bottom != FBScale[1]) + { + FBScale[1] = bottom; + + int fbsize = (256 * 192) << (FBScale[1] * 2); + if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; + if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; + Framebuffer[0][1] = new u32[fbsize]; + Framebuffer[1][1] = new u32[fbsize]; + } + + AssignFramebuffers(); } @@ -682,16 +732,7 @@ void SetPowerCnt(u32 val) GPU2D_B->SetEnabled(val & (1<<9)); GPU3D::SetEnabled(val & (1<<3), val & (1<<2)); - if (val & (1<<15)) - { - GPU2D_A->SetFramebuffer(&Framebuffer[0]); - GPU2D_B->SetFramebuffer(&Framebuffer[FBScreenStride]); - } - else - { - GPU2D_A->SetFramebuffer(&Framebuffer[FBScreenStride]); - GPU2D_B->SetFramebuffer(&Framebuffer[0]); - } + AssignFramebuffers(); } @@ -762,6 +803,9 @@ void StartHBlank(u32 line) void FinishFrame(u32 lines) { + FrontBuffer = FrontBuffer ? 0 : 1; + AssignFramebuffers(); + TotalScanlines = lines; } diff --git a/src/GPU.h b/src/GPU.h index a430a32..2e47fc4 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -61,7 +61,8 @@ extern u32 VRAMMap_Texture[4]; extern u32 VRAMMap_TexPal[8]; extern u32 VRAMMap_ARM7[2]; -extern u32* Framebuffer; +extern int FrontBuffer; +extern u32* Framebuffer[2][2]; extern GPU2D* GPU2D_A; extern GPU2D* GPU2D_B; @@ -74,7 +75,7 @@ void Stop(); void DoSavestate(Savestate* file); -void SetFramebufferScale(int scale); +void SetFramebufferScale(int top, int bottom); void MapVRAM_AB(u32 bank, u8 cnt); diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index ed33cb5..b6544ed 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -160,7 +160,7 @@ void Open() uiRadioButtons* rbApplyScalingTo = uiNewRadioButtons(); uiRadioButtonsAppend(rbApplyScalingTo, "Both screens"); - uiRadioButtonsAppend(rbApplyScalingTo, "Emphasized screen"); + uiRadioButtonsAppend(rbApplyScalingTo, "Emphasized screen (see 'Screen sizing')"); uiRadioButtonsAppend(rbApplyScalingTo, "Top screen"); uiRadioButtonsAppend(rbApplyScalingTo, "Bottom screen"); uiBoxAppend(in_ctrl, uiControl(rbApplyScalingTo), 0); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index a8a5ceb..c8454ed 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -95,7 +95,8 @@ char PrevSRAMPath[1024]; // for savestate 'undo load' bool SavestateLoaded; bool ScreenDrawInited = false; -uiDrawBitmap* ScreenBitmap = NULL; +uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; +SDL_mutex* ScreenMutex; u32* ScreenBuffer; int ScreenScale; @@ -555,7 +556,7 @@ int EmuThreadFunc(void* burp) } } - memcpy(ScreenBuffer, GPU::Framebuffer, (256*ScreenScale)*(384*ScreenScale)*4); + //memcpy(ScreenBuffer, GPU::Framebuffer, (256*ScreenScale)*(384*ScreenScale)*4); uiAreaQueueRedrawAll(MainDrawArea); // framerate limiter based off SDL2_gfx @@ -636,24 +637,27 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) if (!ScreenDrawInited) { ScreenDrawInited = true; - ScreenBitmap = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); + ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); + ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); } - if (!ScreenBitmap) return; + if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; uiRect top = {0, 0, 256*ScreenScale, 192*ScreenScale}; - uiRect bot = {0, 192*ScreenScale, 256*ScreenScale, 192*ScreenScale}; + uiRect bot = {0, 0, 256*ScreenScale, 192*ScreenScale}; - if (ScreenBuffer) uiDrawBitmapUpdate(ScreenBitmap, ScreenBuffer); + int frontbuf = GPU::FrontBuffer; + uiDrawBitmapUpdate(ScreenBitmap[0], GPU::Framebuffer[frontbuf][0]); + uiDrawBitmapUpdate(ScreenBitmap[1], GPU::Framebuffer[frontbuf][1]); uiDrawSave(params->Context); uiDrawTransform(params->Context, &TopScreenTrans); - uiDrawBitmapDraw(params->Context, ScreenBitmap, &top, &TopScreenRect, Config::ScreenFilter==1); + uiDrawBitmapDraw(params->Context, ScreenBitmap[0], &top, &TopScreenRect, Config::ScreenFilter==1); uiDrawRestore(params->Context); uiDrawSave(params->Context); uiDrawTransform(params->Context, &BottomScreenTrans); - uiDrawBitmapDraw(params->Context, ScreenBitmap, &bot, &BottomScreenRect, Config::ScreenFilter==1); + uiDrawBitmapDraw(params->Context, ScreenBitmap[1], &bot, &BottomScreenRect, Config::ScreenFilter==1); uiDrawRestore(params->Context); } @@ -1993,6 +1997,8 @@ int main(int argc, char** argv) uiMenuItemDisable(MenuItem_Reset); uiMenuItemDisable(MenuItem_Stop); + ScreenMutex = SDL_CreateMutex(); + uiAreaHandler areahandler; areahandler.Draw = OnAreaDraw; areahandler.MouseEvent = OnAreaMouseEvent; @@ -2131,7 +2137,10 @@ int main(int argc, char** argv) Config::Save(); - if (ScreenBitmap) uiDrawFreeBitmap(ScreenBitmap); + SDL_DestroyMutex(ScreenMutex); + + if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); + if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); uiUninit(); SDL_Quit(); -- cgit v1.2.3 From 2a0bc4e700d99de3e532eb3952081757f9e874df Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 15:45:58 +0200 Subject: make GPU2D somewhat more flexible. change LineScale to be log2. --- src/GPU2D.cpp | 302 ++++++++++++++++++++++++------------------------- src/GPU2D.h | 37 +++--- src/libui_sdl/main.cpp | 4 +- 3 files changed, 170 insertions(+), 173 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 505468d..0ddc5fb 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -613,15 +613,13 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { u32* dst = &Framebuffer[256*4*line]; - u32 mode1gfx[1024]; - u32* _3dgfx; // HAX - LineScale = 2; + LineScale = 1; LineStride = 1024; DrawPixel = DrawPixel_2x; - int _3dline = line; + int n3dline = line; line = GPU::VCount; bool forceblank = false; @@ -649,10 +647,10 @@ void GPU2D::DrawScanline(u32 line) dispmode &= (Num ? 0x1 : 0x3); if (Num == 0) - _3dgfx = GPU3D::GetLine(_3dline); + _3DLine = GPU3D::GetLine(n3dline); // always render regular graphics - DrawScanline_Mode1(line, mode1gfx, _3dgfx); + DrawScanline_Mode1(line); switch (dispmode) { @@ -666,7 +664,7 @@ void GPU2D::DrawScanline(u32 line) case 1: // regular display { for (int i = 0; i < LineStride; i+=2) - *(u64*)&dst[i] = *(u64*)&mode1gfx[i]; + *(u64*)&dst[i] = *(u64*)&BGOBJLine[i]; } break; @@ -685,9 +683,9 @@ void GPU2D::DrawScanline(u32 line) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - int d = i*LineScale; + int d = i << LineScale; dst[d] = r | (g << 8) | (b << 16); - if (LineScale >= 2) + if (LineScale == 1) { dst[d+1] = dst[d]; dst[d+512] = dst[d]; @@ -714,9 +712,9 @@ void GPU2D::DrawScanline(u32 line) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - int d = i*LineScale; + int d = i << LineScale; dst[d] = r | (g << 8) | (b << 16); - if (LineScale >= 2) + if (LineScale == 1) { dst[d+1] = dst[d]; dst[d+512] = dst[d]; @@ -740,7 +738,7 @@ void GPU2D::DrawScanline(u32 line) } if (line < capheight) - DoCapture(line, capwidth, mode1gfx, _3dgfx); + DoCapture(line, capwidth); } // master brightness @@ -809,7 +807,7 @@ void GPU2D::VBlankEnd() } -void GPU2D::DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx) +void GPU2D::DoCapture(u32 line, u32 width) { u32 dstvram = (CaptureCnt >> 16) & 0x3; @@ -821,8 +819,11 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx) u16* dst = (u16*)GPU::VRAM[dstvram]; u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width); + u32* srcA; if (CaptureCnt & (1<<24)) - src = _3dgfx; + srcA = _3DLine; + else + srcA = BGOBJLine; u16* srcB = NULL; u32 srcBaddr = line * 256; @@ -851,7 +852,7 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx) { for (u32 i = 0; i < width; i++) { - u32 val = src[i * LineScale]; + u32 val = srcA[i << LineScale]; // TODO: check what happens when alpha=0 @@ -902,7 +903,7 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx) { for (u32 i = 0; i < width; i++) { - u32 val = src[i * LineScale]; + u32 val = srcA[i << LineScale]; // TODO: check what happens when alpha=0 @@ -936,7 +937,7 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx) { for (u32 i = 0; i < width; i++) { - u32 val = src[i * LineScale]; + u32 val = srcA[i << LineScale]; // TODO: check what happens when alpha=0 @@ -1062,15 +1063,15 @@ void GPU2D::CheckWindows(u32 line) else if (line == Win1Coords[2]) Win1Active |= 0x1; } -void GPU2D::CalculateWindowMask(u32 line, u8* mask) +void GPU2D::CalculateWindowMask(u32 line) { for (u32 i = 0; i < 256; i++) - mask[i] = WinCnt[2]; // window outside + WindowMask[i] = WinCnt[2]; // window outside if ((DispCnt & (1<<15)) && (DispCnt & (1<<12))) { // OBJ window - DrawSpritesWindow(line, mask); + DrawSpritesWindow(line); } if (DispCnt & (1<<14)) @@ -1084,7 +1085,7 @@ void GPU2D::CalculateWindowMask(u32 line, u8* mask) if (i == x2) Win1Active &= ~0x2; else if (i == x1) Win1Active |= 0x2; - if (Win1Active == 0x3) mask[i] = WinCnt[1]; + if (Win1Active == 0x3) WindowMask[i] = WinCnt[1]; } } @@ -1099,14 +1100,14 @@ void GPU2D::CalculateWindowMask(u32 line, u8* mask) if (i == x2) Win0Active &= ~0x2; else if (i == x1) Win0Active |= 0x2; - if (Win0Active == 0x3) mask[i] = WinCnt[0]; + if (Win0Active == 0x3) WindowMask[i] = WinCnt[0]; } } } template -void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx) +void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites) { for (int i = 3; i >= 0; i--) { @@ -1115,11 +1116,11 @@ void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, if (DispCnt & 0x0800) { if (bgmode >= 3) - DrawBG_Extended(line, dst, 3); + DrawBG_Extended(line, 3); else if (bgmode >= 1) - DrawBG_Affine(line, dst, 3); + DrawBG_Affine(line, 3); else - DrawBG_Text(line, dst, 3); + DrawBG_Text(line, 3); } } if ((BGCnt[2] & 0x3) == i) @@ -1127,18 +1128,18 @@ void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, if (DispCnt & 0x0400) { if (bgmode == 5) - DrawBG_Extended(line, dst, 2); + DrawBG_Extended(line, 2); else if (bgmode == 4 || bgmode == 2) - DrawBG_Affine(line, dst, 2); + DrawBG_Affine(line, 2); else - DrawBG_Text(line, dst, 2); + DrawBG_Text(line, 2); } } if ((BGCnt[1] & 0x3) == i) { if (DispCnt & 0x0200) { - DrawBG_Text(line, dst, 1); + DrawBG_Text(line, 1); } } if ((BGCnt[0] & 0x3) == i) @@ -1146,17 +1147,17 @@ void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, if (DispCnt & 0x0100) { if ((!Num) && (DispCnt & 0x8)) - DrawBG_3D(line, dst, _3dgfx); + DrawBG_3D(); else - DrawBG_Text(line, dst, 0); + DrawBG_Text(line, 0); } } if ((DispCnt & 0x1000) && nsprites) - InterleaveSprites(spritebuf, 0x8000 | (i<<16), dst); + InterleaveSprites(0x8000 | (i<<16)); } } -void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx) +void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites) { if (Num) { @@ -1170,7 +1171,7 @@ void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst { if (DispCnt & 0x0400) { - DrawBG_Large(line, dst); + DrawBG_Large(line); } } if ((BGCnt[0] & 0x3) == i) @@ -1178,19 +1179,16 @@ void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst if (DispCnt & 0x0100) { if (DispCnt & 0x8) - DrawBG_3D(line, dst, _3dgfx); + DrawBG_3D(); } } if ((DispCnt & 0x1000) && nsprites) - InterleaveSprites(spritebuf, 0x8000 | (i<<16), dst); + InterleaveSprites(0x8000 | (i<<16)); } } -void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) +void GPU2D::DrawScanline_Mode1(u32 line) { - u32 linebuf[1024*2 + 64]; - u8* windowmask = (u8*)&linebuf[1024*2]; - u64 backdrop; if (Num) backdrop = *(u16*)&GPU::Palette[0x400]; else backdrop = *(u16*)&GPU::Palette[0]; @@ -1204,29 +1202,29 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) backdrop |= (backdrop << 32); for (int i = 0; i < LineStride; i+=2) - *(u64*)&linebuf[i] = backdrop; + *(u64*)&BGOBJLine[i] = backdrop; } if (DispCnt & 0xE000) - CalculateWindowMask(line, windowmask); + CalculateWindowMask(line); else - memset(windowmask, 0xFF, 256); + memset(WindowMask, 0xFF, 256); // prerender sprites - u32 spritebuf[256]; u32 nsprites = 0; - memset(spritebuf, 0, 256*4); - if (DispCnt & 0x1000) nsprites = DrawSprites(line, spritebuf); + u32 nsprites = 0; + memset(OBJLine, 0, 256*4); + if (DispCnt & 0x1000) nsprites = DrawSprites(line); // TODO: what happens in mode 7? mode 6 on the sub engine? switch (DispCnt & 0x7) { - case 0: DrawScanlineBGMode<0>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 1: DrawScanlineBGMode<1>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 2: DrawScanlineBGMode<2>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 3: DrawScanlineBGMode<3>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 4: DrawScanlineBGMode<4>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 5: DrawScanlineBGMode<5>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 6: DrawScanlineBGMode6(line, nsprites, spritebuf, linebuf, _3dgfx); break; + case 0: DrawScanlineBGMode<0>(line, nsprites); break; + case 1: DrawScanlineBGMode<1>(line, nsprites); break; + case 2: DrawScanlineBGMode<2>(line, nsprites); break; + case 3: DrawScanlineBGMode<3>(line, nsprites); break; + case 4: DrawScanlineBGMode<4>(line, nsprites); break; + case 5: DrawScanlineBGMode<5>(line, nsprites); break; + case 6: DrawScanlineBGMode6(line, nsprites); break; } // color special effects @@ -1236,10 +1234,10 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) for (int i = 0; i < LineStride; i++) { - int j = (i & 0x1FF) >> 1; // FIXME!!!!!! + int j = (i >> LineScale) & 0xFF; - u32 val1 = linebuf[i]; - u32 val2 = linebuf[1024+i]; + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[4096+i]; u32 coloreffect, eva, evb; @@ -1272,7 +1270,7 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) { // 3D layer blending - dst[i] = ColorBlend5(val1, val2); + BGOBJLine[i] = ColorBlend5(val1, val2); continue; } else @@ -1280,7 +1278,7 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) if (flag1 & 0x80) flag1 = 0x10; else if (flag1 & 0x40) flag1 = 0x01; - if ((BlendCnt & flag1) && (windowmask[j] & 0x20)) + if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) { if ((bldcnteffect == 1) && (BlendCnt & target2)) { @@ -1300,19 +1298,19 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) switch (coloreffect) { case 0: - dst[i] = val1; + BGOBJLine[i] = val1; break; case 1: - dst[i] = ColorBlend4(val1, val2, eva, evb); + BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); break; case 2: - dst[i] = ColorBrightnessUp(val1, EVY); + BGOBJLine[i] = ColorBrightnessUp(val1, EVY); break; case 3: - dst[i] = ColorBrightnessDown(val1, EVY); + BGOBJLine[i] = ColorBrightnessDown(val1, EVY); break; } } @@ -1341,7 +1339,7 @@ void GPU2D::DrawPixel_1x(u32* dst, u16 color, u32 flag) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - *(dst+1024) = *dst; + *(dst+4096) = *dst; *dst = r | (g << 8) | (b << 16) | flag; } @@ -1354,17 +1352,15 @@ void GPU2D::DrawPixel_2x(u32* dst, u16 color, u32 flag) u64 val = r | (g << 8) | (b << 16) | flag; val |= (val << 32); - *(u64*)(dst+1024) = *(u64*)dst; - *(u64*)(dst+1536) = *(u64*)(dst+512); + *(u64*)(dst+4096) = *(u64*)dst; + *(u64*)(dst+4096+512) = *(u64*)(dst+512); *(u64*)dst = val; *(u64*)(dst+512) = val; } -void GPU2D::DrawBG_3D(u32 line, u32* dst, u32* src) +void GPU2D::DrawBG_3D() { - u8* windowmask = (u8*)&dst[1024*2]; - u16 xoff = BGXPos[0]; int i = 0; int iend = 256; @@ -1383,61 +1379,60 @@ void GPU2D::DrawBG_3D(u32 line, u32* dst, u32* src) { for (; i < iend; i++) { - u32 c = src[xoff]; - xoff++; - - if ((c >> 24) == 0) continue; - if (!(windowmask[i] & 0x01)) continue; - - dst[i+1024] = dst[i]; - dst[i] = c | 0x40000000; - } - } - else if (LineScale == 2) - { - for (; i < iend; i++) - { - int is = i * 2; - int xs = xoff * 2; + int is = i << 1; + int xs = xoff << 1; u32 c; xoff++; - if (!(windowmask[i] & 0x01)) continue; + if (!(WindowMask[i] & 0x01)) continue; - c = src[xs]; + c = _3DLine[xs]; if ((c >> 24) != 0) { - dst[is+1024] = dst[is]; - dst[is] = c | 0x40000000; + BGOBJLine[is+4096] = BGOBJLine[is]; + BGOBJLine[is] = c | 0x40000000; } - c = src[xs+1]; is++; + c = _3DLine[xs+1]; is++; if ((c >> 24) != 0) { - dst[is+1024] = dst[is]; - dst[is] = c | 0x40000000; + BGOBJLine[is+4096] = BGOBJLine[is]; + BGOBJLine[is] = c | 0x40000000; } - c = src[xs+512]; is += 511; + c = _3DLine[xs+512]; is += 511; if ((c >> 24) != 0) { - dst[is+1024] = dst[is]; - dst[is] = c | 0x40000000; + BGOBJLine[is+4096] = BGOBJLine[is]; + BGOBJLine[is] = c | 0x40000000; } - c = src[xs+513]; is++; + c = _3DLine[xs+513]; is++; if ((c >> 24) != 0) { - dst[is+1024] = dst[is]; - dst[is] = c | 0x40000000; + BGOBJLine[is+4096] = BGOBJLine[is]; + BGOBJLine[is] = c | 0x40000000; } } } + else + { + for (; i < iend; i++) + { + u32 c = _3DLine[xoff]; + xoff++; + + if ((c >> 24) == 0) continue; + if (!(WindowMask[i] & 0x01)) continue; + + BGOBJLine[i+4096] = BGOBJLine[i]; + BGOBJLine[i] = c | 0x40000000; + } + } } -void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum) +void GPU2D::DrawBG_Text(u32 line, u32 bgnum) { - u8* windowmask = (u8*)&dst[1024*2]; u16 bgcnt = BGCnt[bgnum]; u32 xmos = 0, xmossize = 0; @@ -1522,7 +1517,7 @@ void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum) } // draw pixel - if (windowmask[i] & (1< 0) { if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000<(tilesetaddr + (curtile << 6) + (tileyoff << 3) + tilexoff); if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000< 0) { if (color & 0x8000) - DrawPixel(&dst[i*LineScale], color, 0x01000000<(tilemapaddr + (((((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)) << 1)); if (color & 0x8000) - DrawPixel(&dst[i*LineScale], color, 0x01000000< 0) { if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000<(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)); if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000< 0) { if (color) - DrawPixel(&dst[i*LineScale], curpal[color], 0x01000000<(tilesetaddr + ((curtile & 0x03FF) << 6) + (tileyoff << 3) + tilexoff); if (color) - DrawPixel(&dst[i*LineScale], curpal[color], 0x01000000< 0) { if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000<<2); + DrawPixel(&BGOBJLine[i<(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)); if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000<<2); + DrawPixel(&BGOBJLine[i<> 9) & 0x1F; - DrawSprite_Rotscale(attrib, &oam[(rotparamgroup*16) + 3], boundwidth, boundheight, width, height, xpos, ypos, dst); + DrawSprite_Rotscale(attrib, &oam[(rotparamgroup*16) + 3], boundwidth, boundheight, width, height, xpos, ypos); nsprites++; } else @@ -2082,7 +2072,7 @@ u32 GPU2D::DrawSprites(u32 line, u32* dst) if (attrib[1] & 0x2000) ypos = height-1 - ypos; - DrawSprite_Normal(attrib, width, xpos, ypos, dst); + DrawSprite_Normal(attrib, width, xpos, ypos); nsprites++; } } @@ -2091,7 +2081,7 @@ u32 GPU2D::DrawSprites(u32 line, u32* dst) return nsprites; } -void GPU2D::DrawSpritesWindow(u32 line, u8* dst) +void GPU2D::DrawSpritesWindow(u32 line) { u16* oam = (u16*)&GPU::OAM[Num ? 0x400 : 0]; @@ -2142,7 +2132,7 @@ void GPU2D::DrawSpritesWindow(u32 line, u8* dst) u32 rotparamgroup = (attrib[1] >> 9) & 0x1F; - DrawSprite_Rotscale(attrib, &oam[(rotparamgroup*16) + 3], boundwidth, boundheight, width, height, xpos, ypos, (u32*)dst); + DrawSprite_Rotscale(attrib, &oam[(rotparamgroup*16) + 3], boundwidth, boundheight, width, height, xpos, ypos); } else { @@ -2166,13 +2156,13 @@ void GPU2D::DrawSpritesWindow(u32 line, u8* dst) if (attrib[1] & 0x2000) ypos = height-1 - ypos; - DrawSprite_Normal(attrib, width, xpos, ypos, (u32*)dst); + DrawSprite_Normal(attrib, width, xpos, ypos); } } } template -void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos, u32* dst) +void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos) { u32 prio = ((attrib[2] & 0x0C00) << 6) | 0x8000; u32 tilenum = attrib[2] & 0x03FF; @@ -2274,8 +2264,8 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 if (color & 0x8000) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = color | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = color | prio; } } else @@ -2338,8 +2328,8 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } } else @@ -2396,8 +2386,8 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } } else @@ -2416,7 +2406,7 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 } template -void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* dst) +void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos) { u32 prio = ((attrib[2] & 0x0C00) << 6) | 0x8000; u32 tilenum = attrib[2] & 0x03FF; @@ -2510,8 +2500,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color & 0x8000) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = color | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = color | prio; } xoff++; @@ -2537,8 +2527,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color & 0x8000) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = color | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = color | prio; } xoff++; @@ -2597,8 +2587,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } xoff++; @@ -2626,8 +2616,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } xoff++; @@ -2675,8 +2665,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } xoff++; @@ -2709,8 +2699,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } xoff++; diff --git a/src/GPU2D.h b/src/GPU2D.h index 7ffe798..bc50e1a 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -31,6 +31,7 @@ public: void SetEnabled(bool enable) { Enabled = enable; } void SetFramebuffer(u32* buf); + void SetScale(int scale); u8 Read8(u32 addr); u16 Read16(u32 addr); @@ -71,6 +72,12 @@ private: u32 LineStride; u32 LineScale; + u32 BGOBJLine[1024*4 * 2]; + u32* _3DLine; + + u8 WindowMask[256]; + u32 OBJLine[256]; + u16 DispFIFO[16]; u32 DispFIFOReadPtr; u32 DispFIFOWritePtr; @@ -122,29 +129,29 @@ private: u32 ColorBrightnessUp(u32 val, u32 factor); u32 ColorBrightnessDown(u32 val, u32 factor); - template void DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx); - void DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx); - void DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx); + template void DrawScanlineBGMode(u32 line, u32 nsprites); + void DrawScanlineBGMode6(u32 line, u32 nsprites); + void DrawScanline_Mode1(u32 line); static void DrawPixel_1x(u32* dst, u16 color, u32 flag); static void DrawPixel_2x(u32* dst, u16 color, u32 flag); void (*DrawPixel)(u32* dst, u16 color, u32 flag); - void DrawBG_3D(u32 line, u32* dst, u32* src); - void DrawBG_Text(u32 line, u32* dst, u32 bgnum); - void DrawBG_Affine(u32 line, u32* dst, u32 bgnum); - void DrawBG_Extended(u32 line, u32* dst, u32 bgnum); - void DrawBG_Large(u32 line, u32* dst); + void DrawBG_3D(); + void DrawBG_Text(u32 line, u32 bgnum); + void DrawBG_Affine(u32 line, u32 bgnum); + void DrawBG_Extended(u32 line, u32 bgnum); + void DrawBG_Large(u32 line); - void InterleaveSprites(u32* buf, u32 prio, u32* dst); - u32 DrawSprites(u32 line, u32* dst); - void DrawSpritesWindow(u32 line, u8* dst); - template void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos, u32* dst); - template void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* dst); + void InterleaveSprites(u32 prio); + u32 DrawSprites(u32 line); + void DrawSpritesWindow(u32 line); + template void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos); + template void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos); - void DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx); + void DoCapture(u32 line, u32 width); - void CalculateWindowMask(u32 line, u8* mask); + void CalculateWindowMask(u32 line); }; #endif diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index c8454ed..ab7ed33 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -637,8 +637,8 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) if (!ScreenDrawInited) { ScreenDrawInited = true; - ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); - ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); + ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 192*ScreenScale); + ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 192*ScreenScale); } if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; -- cgit v1.2.3 From a32c5c99bbfc46f8284f8903e9a9ec506d4ac5f3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 15:58:12 +0200 Subject: finish de-hardcoding it. also, code 4x variant (not that I guarantee it to be fast, but hey, it's here) --- src/GPU2D.cpp | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/GPU2D.h | 1 + 2 files changed, 108 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 0ddc5fb..521d86a 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -82,6 +82,7 @@ GPU2D::GPU2D(u32 num) { Num = num; + SetScale(0); } GPU2D::~GPU2D() @@ -215,6 +216,16 @@ void GPU2D::SetFramebuffer(u32* buf) Framebuffer = buf; } +void GPU2D::SetScale(int scale) +{ + LineScale = scale; + LineStride = 256 << (scale*2); + + if (scale == 1) DrawPixel = DrawPixel_2x; + else if (scale == 2) DrawPixel = DrawPixel_4x; + else DrawPixel = DrawPixel_1x; +} + u8 GPU2D::Read8(u32 addr) { @@ -612,12 +623,7 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - u32* dst = &Framebuffer[256*4*line]; - - // HAX - LineScale = 1; - LineStride = 1024; - DrawPixel = DrawPixel_2x; + u32* dst = &Framebuffer[LineStride * line]; int n3dline = line; line = GPU::VCount; @@ -691,6 +697,24 @@ void GPU2D::DrawScanline(u32 line) dst[d+512] = dst[d]; dst[d+513] = dst[d]; } + else if (LineScale == 2) + { + dst[d+1] = dst[d]; + dst[d+2] = dst[d]; + dst[d+3] = dst[d]; + dst[d+1024] = dst[d]; + dst[d+1024+1] = dst[d]; + dst[d+1024+2] = dst[d]; + dst[d+1024+3] = dst[d]; + dst[d+2048] = dst[d]; + dst[d+2048+1] = dst[d]; + dst[d+2048+2] = dst[d]; + dst[d+2048+3] = dst[d]; + dst[d+3072] = dst[d]; + dst[d+3072+1] = dst[d]; + dst[d+3072+2] = dst[d]; + dst[d+3072+3] = dst[d]; + } } } else @@ -720,6 +744,24 @@ void GPU2D::DrawScanline(u32 line) dst[d+512] = dst[d]; dst[d+513] = dst[d]; } + else if (LineScale == 2) + { + dst[d+1] = dst[d]; + dst[d+2] = dst[d]; + dst[d+3] = dst[d]; + dst[d+1024] = dst[d]; + dst[d+1024+1] = dst[d]; + dst[d+1024+2] = dst[d]; + dst[d+1024+3] = dst[d]; + dst[d+2048] = dst[d]; + dst[d+2048+1] = dst[d]; + dst[d+2048+2] = dst[d]; + dst[d+2048+3] = dst[d]; + dst[d+3072] = dst[d]; + dst[d+3072+1] = dst[d]; + dst[d+3072+2] = dst[d]; + dst[d+3072+3] = dst[d]; + } } } break; @@ -1359,6 +1401,34 @@ void GPU2D::DrawPixel_2x(u32* dst, u16 color, u32 flag) *(u64*)(dst+512) = val; } +void GPU2D::DrawPixel_4x(u32* dst, u16 color, u32 flag) +{ + u8 r = (color & 0x001F) << 1; + u8 g = (color & 0x03E0) >> 4; + u8 b = (color & 0x7C00) >> 9; + + u64 val = r | (g << 8) | (b << 16) | flag; + val |= (val << 32); + + *(u64*)(dst+4096) = *(u64*)dst; + *(u64*)(dst+4096+2) = *(u64*)(dst+2); + *(u64*)(dst+4096+1024) = *(u64*)(dst+1024); + *(u64*)(dst+4096+1024+2) = *(u64*)(dst+1024+2); + *(u64*)(dst+4096+2048) = *(u64*)(dst+2048); + *(u64*)(dst+4096+2048+2) = *(u64*)(dst+2048+2); + *(u64*)(dst+4096+3072) = *(u64*)(dst+3072); + *(u64*)(dst+4096+3072+2) = *(u64*)(dst+3072+2); + + *(u64*)dst = val; + *(u64*)(dst+2) = val; + *(u64*)(dst+1024) = val; + *(u64*)(dst+1024+2) = val; + *(u64*)(dst+2048) = val; + *(u64*)(dst+2048+2) = val; + *(u64*)(dst+3072) = val; + *(u64*)(dst+3072+2) = val; +} + void GPU2D::DrawBG_3D() { u16 xoff = BGXPos[0]; @@ -1415,6 +1485,37 @@ void GPU2D::DrawBG_3D() } } } + else if (LineScale == 2) + { + for (; i < iend; i++) + { + int is = i << 1; + int xs = xoff << 1; + u32 c; + + xoff++; + if (!(WindowMask[i] & 0x01)) continue; + + for (int by = 0; by < 4; by++) + { + for (int bx = 0; bx < 4; bx++) + { + c = _3DLine[xs]; + if ((c >> 24) != 0) + { + BGOBJLine[is+4096] = BGOBJLine[is]; + BGOBJLine[is] = c | 0x40000000; + } + + is++; + xs++; + } + + is += 1021; + xs += 1021; + } + } + } else { for (; i < iend; i++) diff --git a/src/GPU2D.h b/src/GPU2D.h index bc50e1a..aca1f7e 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -135,6 +135,7 @@ private: static void DrawPixel_1x(u32* dst, u16 color, u32 flag); static void DrawPixel_2x(u32* dst, u16 color, u32 flag); + static void DrawPixel_4x(u32* dst, u16 color, u32 flag); void (*DrawPixel)(u32* dst, u16 color, u32 flag); void DrawBG_3D(); -- cgit v1.2.3 From 0a464c504de43bbcd4a0bedf982e8f0e16cf0f32 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 16:32:53 +0200 Subject: de-hardcode the GL renderer. init framebuffer to black. fix bugs. --- src/GPU.cpp | 33 +++++++++++++++- src/GPU3D.cpp | 5 +++ src/GPU3D.h | 5 +++ src/GPU3D_OpenGL43.cpp | 104 ++++++++++++++++++++++++++++++------------------- src/GPU3D_Soft.cpp | 5 +++ src/libui_sdl/main.cpp | 1 + 6 files changed, 111 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/GPU.cpp b/src/GPU.cpp index 636c430..a904a90 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -92,6 +92,11 @@ bool Init() //SetFramebufferScale(1); SetFramebufferScale(1, 1); + memset(Framebuffer[0][0], 0, (256*192)<<(FBScale[0]*2)); + memset(Framebuffer[0][1], 0, (256*192)<<(FBScale[1]*2)); + memset(Framebuffer[1][0], 0, (256*192)<<(FBScale[0]*2)); + memset(Framebuffer[1][1], 0, (256*192)<<(FBScale[1]*2)); + return true; } @@ -258,6 +263,19 @@ void SetFramebufferScale(int top, int bottom) if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; Framebuffer[0][0] = new u32[fbsize]; Framebuffer[1][0] = new u32[fbsize]; + + int backbuf = FrontBuffer ? 0 : 1; + if (NDS::PowerControl9 & (1<<15)) + { + GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]); + GPU2D_A->SetScale(FBScale[0]); + GPU3D::SetScale(FBScale[0]); + } + else + { + GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); + GPU2D_B->SetScale(FBScale[0]); + } } if (bottom != FBScale[1]) @@ -269,9 +287,20 @@ void SetFramebufferScale(int top, int bottom) if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; Framebuffer[0][1] = new u32[fbsize]; Framebuffer[1][1] = new u32[fbsize]; - } - AssignFramebuffers(); + int backbuf = FrontBuffer ? 0 : 1; + if (NDS::PowerControl9 & (1<<15)) + { + GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]); + GPU2D_B->SetScale(FBScale[1]); + } + else + { + GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); + GPU2D_A->SetScale(FBScale[1]); + GPU3D::SetScale(FBScale[1]); + } + } } diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 3be8ee1..8c0588d 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -607,6 +607,11 @@ void SetEnabled(bool geometry, bool rendering) if (!rendering) ResetRenderingState(); } +void SetScale(int scale) +{ + GLRenderer43::SetScale(scale); +} + void MatrixLoadIdentity(s32* m) diff --git a/src/GPU3D.h b/src/GPU3D.h index 53712ad..68bc696 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -97,6 +97,7 @@ void Reset(); void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); +void SetScale(int scale); void ExecuteCommand(); @@ -126,6 +127,8 @@ bool Init(); void DeInit(); void Reset(); +void SetScale(int scale); + void SetupRenderThread(); void VCount144(); @@ -141,6 +144,8 @@ bool Init(); void DeInit(); void Reset(); +void SetScale(int scale); + void VCount144(); void RenderFrame(); u32* GetLine(int line); diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 1e4f9d7..3bd8932 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -650,9 +650,12 @@ u32 NumTriangles; GLuint TexMemID; GLuint TexPalMemID; +int ScaleFactor; +int ScreenW, ScreenH; + GLuint FramebufferTex[4]; GLuint FramebufferID[2], PixelbufferID; -u8 Framebuffer[512*384*4]; +u32* Framebuffer = NULL; bool ChunkedRendering = false; @@ -863,13 +866,6 @@ bool Init() glEnable(GL_STENCIL_TEST); - // TODO: make configurable (hires, etc) - // set those to 2x the final resolution for antialiased rendering - int screenW = 512; - int screenH = 384; - - - glViewport(0, 0, screenW, screenH); glDepthRange(0, 1); glClearDepth(1.0); @@ -897,8 +893,7 @@ bool Init() kRenderVS_W, kRenderFS_WS)) return false; - ShaderConfig.uScreenSize[0] = screenW; - ShaderConfig.uScreenSize[1] = screenH; + memset(&ShaderConfig, 0, sizeof(ShaderConfig)); glGenBuffers(1, &ShaderConfigUBO); glBindBuffer(GL_UNIFORM_BUFFER, ShaderConfigUBO); @@ -959,7 +954,6 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screenW, screenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); // depth/stencil buffer @@ -968,7 +962,6 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, screenW, screenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[1], 0); // attribute buffer @@ -980,7 +973,6 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, screenW, screenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[2], 0); // downscale framebuffer, for antialiased mode @@ -990,7 +982,6 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screenW/2, screenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[3], 0); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); @@ -1004,8 +995,6 @@ bool Init() glBlendFuncSeparatei(1, GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); glGenBuffers(1, &PixelbufferID); - glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glBufferData(GL_PIXEL_PACK_BUFFER, screenW*screenH*4, NULL, GL_DYNAMIC_READ); glActiveTexture(GL_TEXTURE0); glGenTextures(1, &TexMemID); @@ -1041,6 +1030,32 @@ void Reset() // } +void SetScale(int scale) +{ + ScaleFactor = scale; + + // TODO: antialiasing setting + ScreenW = 256 << scale; + ScreenH = 192 << scale; + + glViewport(0, 0, ScreenW, ScreenH); + + glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); + glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); + + if (Framebuffer) delete[] Framebuffer; + Framebuffer = new u32[ScreenW*ScreenH]; +} + void SetupPolygon(RendererPolygon* rp, Polygon* polygon) { @@ -1120,14 +1135,19 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) u32 zshift = 0; while (z > 0xFFFF) { z >>= 1; zshift++; } - u32 x = vtx->HiresPosition[0] >> 3; - u32 y = vtx->HiresPosition[1] >> 3; - *vptr++ = x | (y << 16); + 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]; + } - // TODO hires-upgraded positions? - //*vptr++ = vtx->FinalPosition[0] | (vtx->FinalPosition[1] << 16); - //*vptr++ = (vtx->FinalPosition[0] << 1) | (vtx->FinalPosition[1] << 17); - //*vptr++ = (vtx->FinalPosition[0] << 2) | (vtx->FinalPosition[1] << 18); + *vptr++ = x | (y << 16); *vptr++ = z | (w << 16); *vptr++ = (vtx->FinalColor[0] >> 1) | @@ -1163,7 +1183,7 @@ void RenderSceneChunk(int y, int h) u32 flags = 0; if (RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer; - if (h != 192) glScissor(0, y*2, 256*2, h*2); + if (h != 192) glScissor(0, y<> 2) | (a >> 3); } - return (u32*)&Framebuffer[512*2*4 * line]; + return &Framebuffer[stride * line]; } } diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp index 932b5d4..ac5cd93 100644 --- a/src/GPU3D_Soft.cpp +++ b/src/GPU3D_Soft.cpp @@ -138,6 +138,11 @@ void Reset() SetupRenderThread(); } +void SetScale(int scale) +{ + printf("SOFT RENDERER SCALE FACTOR: TODO!!!\n"); +} + // Notes on the interpolator: diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index ab7ed33..2853a90 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -642,6 +642,7 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) } if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; + if (!GPU::Framebuffer[0][0]) return; uiRect top = {0, 0, 256*ScreenScale, 192*ScreenScale}; uiRect bot = {0, 0, 256*ScreenScale, 192*ScreenScale}; -- cgit v1.2.3 From f5ba35ca9f42974f250c0241ccf18a3f36da79c4 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 16:47:34 +0200 Subject: don't scale the screen gap --- src/GPU.cpp | 11 ++++++----- src/libui_sdl/DlgVideoSettings.cpp | 8 +++++++- src/libui_sdl/main.cpp | 27 +++++++++++++++++---------- 3 files changed, 30 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/GPU.cpp b/src/GPU.cpp index a904a90..f4e9fd4 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -92,11 +92,6 @@ bool Init() //SetFramebufferScale(1); SetFramebufferScale(1, 1); - memset(Framebuffer[0][0], 0, (256*192)<<(FBScale[0]*2)); - memset(Framebuffer[0][1], 0, (256*192)<<(FBScale[1]*2)); - memset(Framebuffer[1][0], 0, (256*192)<<(FBScale[0]*2)); - memset(Framebuffer[1][1], 0, (256*192)<<(FBScale[1]*2)); - return true; } @@ -264,6 +259,9 @@ void SetFramebufferScale(int top, int bottom) Framebuffer[0][0] = new u32[fbsize]; Framebuffer[1][0] = new u32[fbsize]; + memset(Framebuffer[0][0], 0, fbsize*4); + memset(Framebuffer[1][0], 0, fbsize*4); + int backbuf = FrontBuffer ? 0 : 1; if (NDS::PowerControl9 & (1<<15)) { @@ -288,6 +286,9 @@ void SetFramebufferScale(int top, int bottom) Framebuffer[0][1] = new u32[fbsize]; Framebuffer[1][1] = new u32[fbsize]; + memset(Framebuffer[0][1], 0, fbsize*4); + memset(Framebuffer[1][1], 0, fbsize*4); + int backbuf = FrontBuffer ? 0 : 1; if (NDS::PowerControl9 & (1<<15)) { diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index b6544ed..4d5de71 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -46,7 +46,12 @@ int OnCloseWindow(uiWindow* window, void* blarg) return 1; } -// +void OnResolutionChanged(uiRadioButtons* rb, void* blarg) +{ + int id = uiRadioButtonsSelected(rb); + + printf("res=%d\n", id); +} void OnCancel(uiButton* btn, void* blarg) { @@ -144,6 +149,7 @@ void Open() uiBoxAppend(in_ctrl, uiControl(lbl), 0); uiRadioButtons* rbResolution = uiNewRadioButtons(); + uiRadioButtonsOnSelected(rbResolution, OnResolutionChanged, NULL); uiRadioButtonsAppend(rbResolution, "1x"); uiRadioButtonsAppend(rbResolution, "2x"); uiRadioButtonsAppend(rbResolution, "4x"); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 2853a90..b79853e 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -834,7 +834,6 @@ void SetupScreenRects(int width, int height) screenW *= ScreenScale; screenH *= ScreenScale; - gap *= ScreenScale; uiRect *topscreen, *bottomscreen; if (ScreenRotation == 1 || ScreenRotation == 2) @@ -1029,9 +1028,6 @@ void SetMinSize(int w, int h) int cw, ch; uiWindowContentSize(MainWindow, &cw, &ch); - w *= ScreenScale; - h *= ScreenScale; - uiControlSetMinSize(uiControl(MainDrawArea), w, h); if ((cw < w) || (ch < h)) { @@ -1534,26 +1530,31 @@ void EnsureProperMinSize() { bool isHori = (ScreenRotation == 1 || ScreenRotation == 3); + int w0 = 256 * ScreenScale; + int h0 = 192 * ScreenScale; + int w1 = 256 * ScreenScale; + int h1 = 192 * ScreenScale; + if (ScreenLayout == 0) // natural { if (isHori) - SetMinSize(384+ScreenGap, 256); + SetMinSize(h0+ScreenGap+h1, std::max(w0,w1)); else - SetMinSize(256, 384+ScreenGap); + SetMinSize(std::max(w0,w1), h0+ScreenGap+h1); } else if (ScreenLayout == 1) // vertical { if (isHori) - SetMinSize(192, 512+ScreenGap); + SetMinSize(std::max(h0,h1), w0+ScreenGap+w1); else - SetMinSize(256, 384+ScreenGap); + SetMinSize(std::max(w0,w1), h0+ScreenGap+h1); } else // horizontal { if (isHori) - SetMinSize(384+ScreenGap, 256); + SetMinSize(h0+ScreenGap+h1, std::max(w0,w1)); else - SetMinSize(512+ScreenGap, 192); + SetMinSize(w0+ScreenGap+w1, std::max(h0,h1)); } } @@ -1565,6 +1566,8 @@ void OnSetScreenSize(uiMenuItem* item, uiWindow* window, void* param) int w = 256*factor * ScreenScale; int h = 192*factor * ScreenScale; + // FIXME + if (ScreenLayout == 0) // natural { if (isHori) @@ -1696,6 +1699,10 @@ void ApplyNewSettings(int type) Platform::LAN_DeInit(); Platform::LAN_Init(); } + else if (type == 2) // upscaling/video settings + { + // + } EmuRunning = prevstatus; } -- cgit v1.2.3 From 02b4919005a3bab00a2b0aa9e62ae50541ef6513 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 17:43:39 +0200 Subject: resolution switch somewhat functional --- src/GPU2D.cpp | 8 +-- src/libui_sdl/DlgVideoSettings.cpp | 9 +-- src/libui_sdl/main.cpp | 109 ++++++++++++++++++++++++++----------- 3 files changed, 85 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 521d86a..3a99964 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -1489,8 +1489,8 @@ void GPU2D::DrawBG_3D() { for (; i < iend; i++) { - int is = i << 1; - int xs = xoff << 1; + int is = i << 2; + int xs = xoff << 2; u32 c; xoff++; @@ -1511,8 +1511,8 @@ void GPU2D::DrawBG_3D() xs++; } - is += 1021; - xs += 1021; + is += 1020; + xs += 1020; } } } diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index 4d5de71..aee6d51 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -28,7 +28,7 @@ #include "DlgVideoSettings.h" -// +void ApplyNewSettings(int type); namespace DlgVideoSettings @@ -50,7 +50,8 @@ void OnResolutionChanged(uiRadioButtons* rb, void* blarg) { int id = uiRadioButtonsSelected(rb); - printf("res=%d\n", id); + Config::ScreenScale = id; + ApplyNewSettings(2); } void OnCancel(uiButton* btn, void* blarg) @@ -167,8 +168,8 @@ void Open() uiRadioButtons* rbApplyScalingTo = uiNewRadioButtons(); uiRadioButtonsAppend(rbApplyScalingTo, "Both screens"); uiRadioButtonsAppend(rbApplyScalingTo, "Emphasized screen (see 'Screen sizing')"); - uiRadioButtonsAppend(rbApplyScalingTo, "Top screen"); - uiRadioButtonsAppend(rbApplyScalingTo, "Bottom screen"); + //uiRadioButtonsAppend(rbApplyScalingTo, "Top screen"); + //uiRadioButtonsAppend(rbApplyScalingTo, "Bottom screen"); uiBoxAppend(in_ctrl, uiControl(rbApplyScalingTo), 0); } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index b79853e..6fcb1ae 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -96,10 +96,9 @@ bool SavestateLoaded; bool ScreenDrawInited = false; uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; -SDL_mutex* ScreenMutex; -u32* ScreenBuffer; -int ScreenScale; +int ScreenScale[3]; +int ScreenScaleMode; int ScreenGap = 0; int ScreenLayout = 0; @@ -400,13 +399,18 @@ int EmuThreadFunc(void* burp) uiGLMakeContextCurrent(GLContext); NDS::Init(); - ScreenBuffer = new u32[(256*ScreenScale) * (384*ScreenScale)]; - MainScreenPos[0] = 0; MainScreenPos[1] = 0; MainScreenPos[2] = 0; AutoScreenSizing = 0; + // FIXME + ScreenScale[2] = Config::ScreenScale; + ScreenScale[0] = ScreenScale[2]; + ScreenScale[1] = ScreenScale[2]; + + int lastscale[2] = {-1, -1}; + Touching = false; KeyInputMask = 0xFFF; HotkeyMask = 0; @@ -522,11 +526,6 @@ int EmuThreadFunc(void* burp) // microphone input FeedMicInput(); - // emulate - u32 nlines = NDS::RunFrame(); - - if (EmuRunning == 0) break; - // auto screen layout { MainScreenPos[2] = MainScreenPos[1]; @@ -556,7 +555,18 @@ int EmuThreadFunc(void* burp) } } - //memcpy(ScreenBuffer, GPU::Framebuffer, (256*ScreenScale)*(384*ScreenScale)*4); + if (ScreenScale[0] != lastscale[0] || + ScreenScale[1] != lastscale[1]) + { + GPU::SetFramebufferScale(ScreenScale[0], ScreenScale[1]); + ScreenDrawInited = false; + } + + // emulate + u32 nlines = NDS::RunFrame(); + + if (EmuRunning == 0) break; + uiAreaQueueRedrawAll(MainDrawArea); // framerate limiter based off SDL2_gfx @@ -622,8 +632,6 @@ int EmuThreadFunc(void* burp) if (joybuttons) delete[] joybuttons; - delete[] ScreenBuffer; - NDS::DeInit(); Platform::LAN_DeInit(); @@ -636,16 +644,19 @@ 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*ScreenScale, 192*ScreenScale); - ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 192*ScreenScale); + ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256<Context, 256< Date: Mon, 13 May 2019 23:05:50 +0100 Subject: Firmware backup writing now uses OpenLocalFile --- src/SPI.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/SPI.cpp b/src/SPI.cpp index e550abd..759bbd9 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -130,11 +130,11 @@ void Reset() // take a backup const char* firmbkp = "firmware.bin.bak"; - f = fopen(firmbkp, "rb"); + f = Platform::OpenLocalFile(firmbkp, "rb"); if (f) fclose(f); else { - f = fopen(firmbkp, "wb"); + f = Platform::OpenLocalFile(firmbkp, "wb"); fwrite(Firmware, 1, FirmwareLength, f); fclose(f); } -- cgit v1.2.3 From 71ecb6a65b75ba935c5d510809811777c5162945 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 14 May 2019 15:10:58 +0200 Subject: derping around --- src/GPU3D_OpenGL43.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++++--- src/SPU.cpp | 4 +++- 2 files changed, 60 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 3bd8932..d792030 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -168,7 +168,7 @@ flat in uvec3 fPolygonAttr; layout(location=0) out vec4 oColor; layout(location=1) out uvec3 oAttr; -vec4 TextureLookup() +vec4 TextureLookup(ivec2 st) { uint attr = fPolygonAttr.y; uint paladdr = fPolygonAttr.z; @@ -181,7 +181,6 @@ vec4 TextureLookup() int th = 8 << int((attr >> 23) & 0x7); int vramaddr = int(attr & 0xFFFF) << 3; - ivec2 st = ivec2(fTexcoord); if ((attr & (1<<16)) != 0) { @@ -366,6 +365,60 @@ vec4 TextureLookup() } } +vec4 TextureLookup_Nearest(vec2 texcoord) +{ + return TextureLookup(ivec2(texcoord)); +} + +vec4 TextureLookup_Linear(vec2 texcoord) +{ + ivec2 intpart = ivec2(texcoord); + vec2 fracpart = fract(texcoord); + + vec4 A = TextureLookup(intpart); + vec4 B = TextureLookup(intpart + ivec2(1,0)); + vec4 C = TextureLookup(intpart + ivec2(0,1)); + vec4 D = TextureLookup(intpart + ivec2(1,1)); + + float fx = fracpart.x; + vec4 AB; + if (A.a < (0.5/31.0) && B.a < (0.5/31.0)) + AB = vec4(0); + else + { + //if (A.a < (0.5/31.0) || B.a < (0.5/31.0)) + // fx = step(0.5, fx); + + AB = mix(A, B, fx); + } + + fx = fracpart.x; + vec4 CD; + if (C.a < (0.5/31.0) && D.a < (0.5/31.0)) + CD = vec4(0); + else + { + //if (C.a < (0.5/31.0) || D.a < (0.5/31.0)) + // fx = step(0.5, fx); + + CD = mix(C, D, fx); + } + + fx = fracpart.y; + vec4 ret; + if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0)) + ret = vec4(0); + else + { + //if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0)) + // fx = step(0.5, fx); + + ret = mix(AB, CD, fx); + } + + return ret; +} + vec4 FinalColor() { vec4 col; @@ -394,7 +447,8 @@ vec4 FinalColor() } else { - vec4 tcol = TextureLookup(); + vec4 tcol = TextureLookup_Nearest(fTexcoord); + //vec4 tcol = TextureLookup_Linear(fTexcoord); if ((blendmode & 1) != 0) { diff --git a/src/SPU.cpp b/src/SPU.cpp index 93fdb00..ee9237f 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -23,7 +23,9 @@ // SPU TODO -// * loop mode 3, what does it do? +// * capture addition modes, overflow bugs +// * channel hold +// * 'length less than 4' glitch namespace SPU -- cgit v1.2.3 From 4d427c9d2dea9ff0b965c3ffbbecc5e1cb40a01b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 14 May 2019 17:45:16 +0200 Subject: BAHAHAHAHAHA --- src/GPU3D_OpenGL43.cpp | 408 +++++++++++++++++++++++++++++-------------------- 1 file changed, 242 insertions(+), 166 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index d792030..57a80f1 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -168,206 +168,221 @@ flat in uvec3 fPolygonAttr; layout(location=0) out vec4 oColor; layout(location=1) out uvec3 oAttr; -vec4 TextureLookup(ivec2 st) +int TexcoordWrap(int c, int maxc, uint mode) { - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); - - int vramaddr = int(attr & 0xFFFF) << 3; - - if ((attr & (1<<16)) != 0) + if ((mode & (1<<0)) != 0) { - if ((attr & (1<<18)) != 0) - { - if ((st.x & tw) != 0) - st.x = (tw-1) - (st.x & (tw-1)); - else - st.x = (st.x & (tw-1)); - } + if ((mode & (1<<2)) != 0 && (c & maxc) != 0) + return (maxc-1) - (c & (maxc-1)); else - st.x &= (tw-1); + return (c & (maxc-1)); } else - st.x = clamp(st.x, 0, tw-1); + return clamp(c, 0, maxc-1); +} - if ((attr & (1<<17)) != 0) - { - if ((attr & (1<<19)) != 0) - { - if ((st.y & th) != 0) - st.y = (th-1) - (st.y & (th-1)); - else - st.y = (st.y & (th-1)); - } - else - st.y &= (th-1); - } - else - st.y = clamp(st.y, 0, th-1); +vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - uint type = (attr >> 26) & 0x7; - if (type == 1) - { - vramaddr += ((st.y * tw) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - pixel.a = (pixel.r & 0xE0); - pixel.a = (pixel.a >> 3) + (pixel.a >> 6); - pixel.r &= 0x1F; + pixel.a = (pixel.r & 0xE0); + pixel.a = (pixel.a >> 3) + (pixel.a >> 6); + pixel.r &= 0x1F; - paladdr = (paladdr << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, float(pixel.a)/31.0); - } - else if (type == 2) - { - vramaddr += ((st.y * tw) + st.x) >> 2; - uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); - pixel.r >>= (2 * (st.x & 3)); - pixel.r &= 0x03; + return vec4(color.rgb, float(pixel.a)/31.0); +} - paladdr = (paladdr << 2) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); +vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); - } - else if (type == 3) - { - vramaddr += ((st.y * tw) + st.x) >> 1; - uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); - if ((st.x & 1) != 0) pixel.r >>= 4; - else pixel.r &= 0x0F; + addr.x += ((st.y * st.z) + st.x) >> 2; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + pixel.r >>= (2 * (st.x & 3)); + pixel.r &= 0x03; - paladdr = (paladdr << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + addr.y = (addr.y << 2) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); - } - else if (type == 4) - { - vramaddr += ((st.y * tw) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} - paladdr = (paladdr << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); +vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); - } - else if (type == 5) - { - vramaddr += ((st.y & 0x3FC) * (tw>>2)) + (st.x & 0x3FC) + (st.y & 0x3); - uvec4 p = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); - uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; + addr.x += ((st.y * st.z) + st.x) >> 1; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + if ((st.x & 1) != 0) pixel.r >>= 4; + else pixel.r &= 0x0F; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); + uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; - int slot1addr = 0x20000 + ((vramaddr & 0x1FFFC) >> 1); - if (vramaddr >= 0x40000) slot1addr += 0x10000; + int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); + if (addr.x >= 0x40000) slot1addr += 0x10000; - uint palinfo; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo = p.r; - slot1addr++; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo |= (p.r << 8); + uint palinfo; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo = p.r; + slot1addr++; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo |= (p.r << 8); - paladdr = (paladdr << 3) + ((palinfo & 0x3FFF) << 1); - palinfo >>= 14; + addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1); + palinfo >>= 14; - if (val == 0) + if (val == 0) + { + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 1) + { + addr.y++; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 2) + { + if (palinfo == 1) { - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); + } + else + { + addr.y += 2; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); return vec4(color.rgb, 1.0); } - else if (val == 1) + } + else + { + if (palinfo == 2) { - paladdr++; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + addr.y += 3; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); return vec4(color.rgb, 1.0); } - else if (val == 2) + else if (palinfo == 3) { - if (palinfo == 1) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - paladdr++; - vec4 color1 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - paladdr++; - vec4 color1 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); - } - else - { - paladdr += 2; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4(color.rgb, 1.0); - } + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); } else { - if (palinfo == 2) - { - paladdr += 3; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - paladdr++; - vec4 color1 = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); - return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); - } - else - { - return vec4(0.0); - } + return vec4(0.0); } } - else if (type == 6) - { - vramaddr += ((st.y * tw) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); +} - pixel.a = (pixel.r & 0xF8) >> 3; - pixel.r &= 0x07; +vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - paladdr = (paladdr << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(paladdr&0x3FF, paladdr>>10), 0); + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - return vec4(color.rgb, float(pixel.a)/31.0); - } - else - { - vramaddr += ((st.y * tw) + st.x) << 1; - uvec4 pixelL = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); - vramaddr++; - uvec4 pixelH = texelFetch(TexMem, ivec2(vramaddr&0x3FF, vramaddr>>10), 0); - - vec4 color; - color.r = float(pixelL.r & 0x1F) / 31.0; - color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; - color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; - color.a = float(pixelH.r >> 7); - - return color; - } + pixel.a = (pixel.r & 0xF8) >> 3; + pixel.r &= 0x07; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); } -vec4 TextureLookup_Nearest(vec2 texcoord) +vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) { - return TextureLookup(ivec2(texcoord)); + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) << 1; + uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + addr.x++; + uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + vec4 color; + color.r = float(pixelL.r & 0x1F) / 31.0; + color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; + color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; + color.a = float(pixelH.r >> 7); + + return color; +} + +vec4 TextureLookup_Nearest(vec2 st) +{ + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(ivec2(st), tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + uint type = (attr >> 26) & 0x7; + if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); + else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); + else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); + else return TextureFetch_Direct (vramaddr, st_full, wrapmode); } vec4 TextureLookup_Linear(vec2 texcoord) @@ -375,10 +390,71 @@ vec4 TextureLookup_Linear(vec2 texcoord) ivec2 intpart = ivec2(texcoord); vec2 fracpart = fract(texcoord); - vec4 A = TextureLookup(intpart); - vec4 B = TextureLookup(intpart + ivec2(1,0)); - vec4 C = TextureLookup(intpart + ivec2(0,1)); - vec4 D = TextureLookup(intpart + ivec2(1,1)); + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(intpart, tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + vec4 A, B, C, D; + uint type = (attr >> 26) & 0x7; + if (type == 5) + { + A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); + B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 2) + { + A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 3) + { + A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 4) + { + A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 1) + { + A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); + B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 6) + { + A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); + B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else + { + A = TextureFetch_Direct(vramaddr, st_full , wrapmode); + B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } float fx = fracpart.x; vec4 AB; -- cgit v1.2.3 From a89366cb5a1106152374c9e91ebef96149db76cc Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 15 May 2019 16:43:56 +0200 Subject: begin butchering uiArea --- src/libui_sdl/DlgInputConfig.cpp | 2 +- src/libui_sdl/libui/ui.h | 3 ++- src/libui_sdl/libui/windows/area.cpp | 23 +++++++++++++++++++---- src/libui_sdl/libui/windows/area.hpp | 6 +++++- src/libui_sdl/libui/windows/areadraw.cpp | 27 ++++++++++++++++++++------- src/libui_sdl/libui/windows/areaevents.cpp | 2 +- src/libui_sdl/libui/windows/areautil.cpp | 21 ++++++++++++++++++--- src/libui_sdl/libui/windows/gl.cpp | 5 +++++ src/libui_sdl/main.cpp | 6 ++++-- 9 files changed, 75 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/DlgInputConfig.cpp b/src/libui_sdl/DlgInputConfig.cpp index 513bd90..4c464f1 100644 --- a/src/libui_sdl/DlgInputConfig.cpp +++ b/src/libui_sdl/DlgInputConfig.cpp @@ -432,7 +432,7 @@ void Open(int type) uiLabel* dummy = uiNewLabel(""); uiBoxAppend(in_ctrl, uiControl(dummy), 1); - dlg->keypresscatcher = uiNewArea(&dlg->areahandler); + dlg->keypresscatcher = uiNewArea(&dlg->areahandler, 0); uiControl(dlg->keypresscatcher)->UserData = dlg; uiBoxAppend(in_ctrl, uiControl(dlg->keypresscatcher), 0); diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h index dd1c786..2641f30 100644 --- a/src/libui_sdl/libui/ui.h +++ b/src/libui_sdl/libui/ui.h @@ -341,7 +341,7 @@ _UI_EXTERN void uiAreaScrollTo(uiArea *a, double x, double y, double width, doub _UI_EXTERN void uiAreaBeginUserWindowMove(uiArea *a); _UI_EXTERN void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge); _UI_EXTERN void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b); -_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah); +_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah, int opengl); _UI_EXTERN uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height); struct uiAreaDrawParams { @@ -608,6 +608,7 @@ _UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c, int vermajor, int verminor) _UI_EXTERN void uiGLFreeContext(uiGLContext* ctx); _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx); _UI_EXTERN void *uiGLGetProcAddress(const char* proc); +_UI_EXTERN void uiGLSwapBuffers(uiGLContext* ctx); _UI_ENUM(uiModifiers) { diff --git a/src/libui_sdl/libui/windows/area.cpp b/src/libui_sdl/libui/windows/area.cpp index 2185f25..99c843e 100644 --- a/src/libui_sdl/libui/windows/area.cpp +++ b/src/libui_sdl/libui/windows/area.cpp @@ -25,8 +25,11 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM } // always recreate the render target if necessary - if (a->rt == NULL) - a->rt = makeHWNDRenderTarget(a->hwnd); + if (!a->openGL) + { + if (a->rt == NULL) + a->rt = makeHWNDRenderTarget(a->hwnd); + } if (areaDoDraw(a, uMsg, wParam, lParam, &lResult) != FALSE) return lResult; @@ -34,12 +37,14 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM if (uMsg == WM_WINDOWPOSCHANGED) { if ((wp->flags & SWP_NOSIZE) != 0) return DefWindowProcW(hwnd, uMsg, wParam, lParam); + a->width = -1; + a->height = -1; uiWindowsEnsureGetClientRect(a->hwnd, &client); areaDrawOnResize(a, &client); areaScrollOnResize(a, &client); { double w, h; - loadAreaSize(a, a->rt, &w, &h); + loadAreaSize(a, &w, &h); a->ah->Resize(a->ah, a, (int)w, (int)h); } return 0; @@ -176,12 +181,15 @@ void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b) } -uiArea *uiNewArea(uiAreaHandler *ah) +uiArea *uiNewArea(uiAreaHandler *ah, int opengl) { uiArea *a; uiWindowsNewControl(uiArea, a); + a->width = -1; + a->height = -1; + a->ah = ah; a->scrolling = FALSE; clickCounterReset(&(a->cc)); @@ -195,6 +203,8 @@ uiArea *uiNewArea(uiAreaHandler *ah) uiAreaSetBackgroundColor(a, -1, -1, -1); + a->openGL = opengl; + return a; } @@ -204,6 +214,9 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height) uiWindowsNewControl(uiArea, a); + a->width = -1; + a->height = -1; + a->ah = ah; a->scrolling = TRUE; a->scrollWidth = width; @@ -219,6 +232,8 @@ uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height) uiAreaSetBackgroundColor(a, -1, -1, -1); + a->openGL = 0; // TODO, eventually??? + // set initial scrolling parameters areaUpdateScroll(a); diff --git a/src/libui_sdl/libui/windows/area.hpp b/src/libui_sdl/libui/windows/area.hpp index add62dd..f8abd4f 100644 --- a/src/libui_sdl/libui/windows/area.hpp +++ b/src/libui_sdl/libui/windows/area.hpp @@ -10,6 +10,8 @@ struct uiArea { HWND hwnd; uiAreaHandler *ah; + int width, height; + BOOL scrolling; int scrollWidth; int scrollHeight; @@ -26,6 +28,8 @@ struct uiArea { int bgR, bgG, bgB; + int openGL; + ID2D1HwndRenderTarget *rt; }; @@ -42,6 +46,6 @@ extern void areaUpdateScroll(uiArea *a); extern BOOL areaDoEvents(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult); // areautil.cpp -extern void loadAreaSize(uiArea *a, ID2D1RenderTarget *rt, double *width, double *height); +extern void loadAreaSize(uiArea *a, double *width, double *height); extern void pixelsToDIP(uiArea *a, double *x, double *y); extern void dipToPixels(uiArea *a, double *x, double *y); diff --git a/src/libui_sdl/libui/windows/areadraw.cpp b/src/libui_sdl/libui/windows/areadraw.cpp index a9ad477..6b4845a 100644 --- a/src/libui_sdl/libui/windows/areadraw.cpp +++ b/src/libui_sdl/libui/windows/areadraw.cpp @@ -6,6 +6,13 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip) { uiAreaHandler *ah = a->ah; uiAreaDrawParams dp; + + if (a->openGL) + { + (*(ah->Draw))(ah, a, &dp); + return S_OK; + } + COLORREF bgcolorref; D2D1_COLOR_F bgcolor; D2D1_MATRIX_3X2_F scrollTransform; @@ -13,7 +20,7 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip) // no need to save or restore the graphics state to reset transformations; it's handled by resetTarget() in draw.c, called during the following dp.Context = newContext(rt); - loadAreaSize(a, rt, &(dp.AreaWidth), &(dp.AreaHeight)); + loadAreaSize(a, &(dp.AreaWidth), &(dp.AreaHeight)); dp.ClipX = clip->left; dp.ClipY = clip->top; @@ -113,6 +120,9 @@ static void onWM_PAINT(uiArea *a) static void onWM_PRINTCLIENT(uiArea *a, HDC dc) { + // TODO???? + if (a->openGL) return; + ID2D1DCRenderTarget *rt; RECT client; HRESULT hr; @@ -143,13 +153,16 @@ BOOL areaDoDraw(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lRe // TODO only if the render target wasn't just created? void areaDrawOnResize(uiArea *a, RECT *newClient) { - D2D1_SIZE_U size; + if (!a->openGL) + { + D2D1_SIZE_U size; - size.width = newClient->right - newClient->left; - size.height = newClient->bottom - newClient->top; - // don't track the error; we'll get that in EndDraw() - // see https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994%28v=vs.85%29.aspx - a->rt->Resize(&size); + size.width = newClient->right - newClient->left; + size.height = newClient->bottom - newClient->top; + // don't track the error; we'll get that in EndDraw() + // see https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994%28v=vs.85%29.aspx + a->rt->Resize(&size); + } // according to Rick Brewster, we must always redraw the entire client area after calling ID2D1RenderTarget::Resize() (see http://stackoverflow.com/a/33222983/3408572) // we used to have a uiAreaHandler.RedrawOnResize() method to decide this; now you know why we don't anymore diff --git a/src/libui_sdl/libui/windows/areaevents.cpp b/src/libui_sdl/libui/windows/areaevents.cpp index 3ff7a47..46d6ab9 100644 --- a/src/libui_sdl/libui/windows/areaevents.cpp +++ b/src/libui_sdl/libui/windows/areaevents.cpp @@ -109,7 +109,7 @@ static void areaMouseEvent(uiArea *a, int down, int up, WPARAM wParam, LPARAM l me.Y += a->vscrollpos; } - loadAreaSize(a, NULL, &(me.AreaWidth), &(me.AreaHeight)); + loadAreaSize(a, &(me.AreaWidth), &(me.AreaHeight)); me.Down = down; me.Up = up; diff --git a/src/libui_sdl/libui/windows/areautil.cpp b/src/libui_sdl/libui/windows/areautil.cpp index 212ea42..ea13221 100644 --- a/src/libui_sdl/libui/windows/areautil.cpp +++ b/src/libui_sdl/libui/windows/areautil.cpp @@ -2,20 +2,35 @@ #include "uipriv_windows.hpp" #include "area.hpp" -void loadAreaSize(uiArea *a, ID2D1RenderTarget *rt, double *width, double *height) +// TODO: make those int rather than double +void loadAreaSize(uiArea *a, double *width, double *height) { D2D1_SIZE_F size; + if (a->width != -1) + { + *width = (double)a->width; + *height = (double)a->height; + return; + } + *width = 0; *height = 0; if (!a->scrolling) { - if (rt == NULL) + /*if (rt == NULL) rt = a->rt; size = realGetSize(rt); *width = size.width; *height = size.height; - dipToPixels(a, width, height); + dipToPixels(a, width, height);*/ + RECT rect; + GetWindowRect(a->hwnd, &rect); + *width = (double)(rect.right - rect.left); + *height = (double)(rect.bottom - rect.top); } + + a->width = (int)*width; + a->height = (int)*height; } void pixelsToDIP(uiArea *a, double *x, double *y) diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp index beccb79..67eaeda 100644 --- a/src/libui_sdl/libui/windows/gl.cpp +++ b/src/libui_sdl/libui/windows/gl.cpp @@ -134,3 +134,8 @@ void *uiGLGetProcAddress(const char* proc) { return (void*)wglGetProcAddress(proc); } + +void uiGLSwapBuffers(uiGLContext* ctx) +{ + SwapBuffers(ctx->dc); +} diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 6fcb1ae..b39f493 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -568,6 +568,7 @@ int EmuThreadFunc(void* burp) if (EmuRunning == 0) break; uiAreaQueueRedrawAll(MainDrawArea); + //uiGLSwapBuffers(GLContext); // framerate limiter based off SDL2_gfx float framerate; @@ -619,7 +620,8 @@ int EmuThreadFunc(void* burp) if (EmuRunning == 2) { - uiAreaQueueRedrawAll(MainDrawArea); + //uiAreaQueueRedrawAll(MainDrawArea); + //uiGLSwapBuffers(GLContext); } EmuStatus = EmuRunning; @@ -2061,7 +2063,7 @@ int main(int argc, char** argv) areahandler.Resize = OnAreaResize; ScreenDrawInited = false; - MainDrawArea = uiNewArea(&areahandler); + MainDrawArea = uiNewArea(&areahandler, 0); uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); // TODO: make configurable? -- cgit v1.2.3 From 256b8cb69c751f43a7766eafc6f8798eefa3217e Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 15 May 2019 19:49:21 +0200 Subject: botch GL support. --- melonDS.cbp | 2 + src/GPU3D_OpenGL43.cpp | 124 +------------------------------ src/OpenGLSupport.cpp | 30 ++++++++ src/OpenGLSupport.h | 112 ++++++++++++++++++++++++++++ src/libui_sdl/libui/windows/areadraw.cpp | 2 +- 5 files changed, 147 insertions(+), 123 deletions(-) create mode 100644 src/OpenGLSupport.cpp create mode 100644 src/OpenGLSupport.h (limited to 'src') diff --git a/melonDS.cbp b/melonDS.cbp index b396861..4634513 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -112,6 +112,8 @@ + + diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 57a80f1..3a2a3f1 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -16,77 +16,17 @@ with melonDS. If not, see http://www.gnu.org/licenses/. */ -#include -#include - #include #include #include "NDS.h" #include "GPU.h" -#include "Platform.h" +#include "OpenGLSupport.h" namespace GPU3D { namespace GLRenderer43 { -PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; -PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; -PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; -PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; -PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; - -PFNGLGENBUFFERSPROC glGenBuffers; -PFNGLDELETEBUFFERSPROC glDeleteBuffers; -PFNGLBINDBUFFERPROC glBindBuffer; -PFNGLMAPBUFFERPROC glMapBuffer; -PFNGLMAPBUFFERRANGEPROC glMapBufferRange; -PFNGLUNMAPBUFFERPROC glUnmapBuffer; -PFNGLBUFFERDATAPROC glBufferData; -PFNGLBUFFERSUBDATAPROC glBufferSubData; -PFNGLBINDBUFFERBASEPROC glBindBufferBase; - -PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; -PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; -PFNGLBINDVERTEXARRAYPROC glBindVertexArray; -PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; -PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; - -PFNGLCREATESHADERPROC glCreateShader; -PFNGLSHADERSOURCEPROC glShaderSource; -PFNGLCOMPILESHADERPROC glCompileShader; -PFNGLCREATEPROGRAMPROC glCreateProgram; -PFNGLATTACHSHADERPROC glAttachShader; -PFNGLLINKPROGRAMPROC glLinkProgram; -PFNGLUSEPROGRAMPROC glUseProgram; -PFNGLGETSHADERIVPROC glGetShaderiv; -PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; -PFNGLGETPROGRAMIVPROC glGetProgramiv; -PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; -PFNGLDELETESHADERPROC glDeleteShader; -PFNGLDELETEPROGRAMPROC glDeleteProgram; - -PFNGLUNIFORM1UIPROC glUniform1ui; -PFNGLUNIFORM4UIPROC glUniform4ui; -PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding; - -PFNGLACTIVETEXTUREPROC glActiveTexture; -PFNGLBINDIMAGETEXTUREPROC glBindImageTexture; - -PFNGLDRAWBUFFERSPROC glDrawBuffers; - -PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei; -PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei; - -PFNGLCOLORMASKIPROC glColorMaski; - -PFNGLMEMORYBARRIERPROC glMemoryBarrier; - -PFNGLGETSTRINGIPROC glGetStringi; - - // GL version requirements // * explicit uniform location: 4.3 (or extension) // * texelFetch: 3.0 (GLSL 1.30) (3.2/1.50 for MS) @@ -792,67 +732,7 @@ bool ChunkedRendering = false; bool InitGLExtensions() { -#define LOADPROC(type, name) \ - name = (PFN##type##PROC)Platform::GL_GetProcAddress(#name); \ - if (!name) { printf("OpenGL: " #name " not found\n"); return false; } - - LOADPROC(GLGENFRAMEBUFFERS, glGenFramebuffers); - LOADPROC(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers); - LOADPROC(GLBINDFRAMEBUFFER, glBindFramebuffer); - LOADPROC(GLFRAMEBUFFERTEXTURE, glFramebufferTexture); - LOADPROC(GLBLITFRAMEBUFFER, glBlitFramebuffer); - - LOADPROC(GLGENBUFFERS, glGenBuffers); - LOADPROC(GLDELETEBUFFERS, glDeleteBuffers); - LOADPROC(GLBINDBUFFER, glBindBuffer); - LOADPROC(GLMAPBUFFER, glMapBuffer); - LOADPROC(GLMAPBUFFERRANGE, glMapBufferRange); - LOADPROC(GLUNMAPBUFFER, glUnmapBuffer); - LOADPROC(GLBUFFERDATA, glBufferData); - LOADPROC(GLBUFFERSUBDATA, glBufferSubData); - LOADPROC(GLBINDBUFFERBASE, glBindBufferBase); - - LOADPROC(GLGENVERTEXARRAYS, glGenVertexArrays); - LOADPROC(GLDELETEVERTEXARRAYS, glDeleteVertexArrays); - LOADPROC(GLBINDVERTEXARRAY, glBindVertexArray); - LOADPROC(GLENABLEVERTEXATTRIBARRAY, glEnableVertexAttribArray); - LOADPROC(GLDISABLEVERTEXATTRIBARRAY, glDisableVertexAttribArray); - LOADPROC(GLVERTEXATTRIBPOINTER, glVertexAttribPointer); - LOADPROC(GLVERTEXATTRIBIPOINTER, glVertexAttribIPointer); - - LOADPROC(GLCREATESHADER, glCreateShader); - LOADPROC(GLSHADERSOURCE, glShaderSource); - LOADPROC(GLCOMPILESHADER, glCompileShader); - LOADPROC(GLCREATEPROGRAM, glCreateProgram); - LOADPROC(GLATTACHSHADER, glAttachShader); - LOADPROC(GLLINKPROGRAM, glLinkProgram); - LOADPROC(GLUSEPROGRAM, glUseProgram); - LOADPROC(GLGETSHADERIV, glGetShaderiv); - LOADPROC(GLGETSHADERINFOLOG, glGetShaderInfoLog); - LOADPROC(GLGETPROGRAMIV, glGetProgramiv); - LOADPROC(GLGETPROGRAMINFOLOG, glGetProgramInfoLog); - LOADPROC(GLDELETESHADER, glDeleteShader); - LOADPROC(GLDELETEPROGRAM, glDeleteProgram); - - LOADPROC(GLUNIFORM1UI, glUniform1ui); - LOADPROC(GLUNIFORM4UI, glUniform4ui); - LOADPROC(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); - - LOADPROC(GLACTIVETEXTURE, glActiveTexture); - LOADPROC(GLBINDIMAGETEXTURE, glBindImageTexture); - - LOADPROC(GLDRAWBUFFERS, glDrawBuffers); - - LOADPROC(GLBLENDFUNCSEPARATEI, glBlendFuncSeparatei); - LOADPROC(GLBLENDEQUATIONSEPARATEI, glBlendEquationSeparatei); - - LOADPROC(GLCOLORMASKI, glColorMaski); - - LOADPROC(GLMEMORYBARRIER, glMemoryBarrier); - - LOADPROC(GLGETSTRINGI, glGetStringi); - -#undef LOADPROC + if (!OpenGL_Init()) return false; return true; } diff --git a/src/OpenGLSupport.cpp b/src/OpenGLSupport.cpp new file mode 100644 index 0000000..c22fd1c --- /dev/null +++ b/src/OpenGLSupport.cpp @@ -0,0 +1,30 @@ +/* + 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 "OpenGLSupport.h" + + +DO_PROCLIST(DECLPROC); + + +bool OpenGL_Init() +{ + DO_PROCLIST(LOADPROC); + + return true; +} 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 diff --git a/src/libui_sdl/libui/windows/areadraw.cpp b/src/libui_sdl/libui/windows/areadraw.cpp index 6b4845a..f369255 100644 --- a/src/libui_sdl/libui/windows/areadraw.cpp +++ b/src/libui_sdl/libui/windows/areadraw.cpp @@ -9,7 +9,7 @@ static HRESULT doPaint(uiArea *a, ID2D1RenderTarget *rt, RECT *clip) if (a->openGL) { - (*(ah->Draw))(ah, a, &dp); + //(*(ah->Draw))(ah, a, &dp); return S_OK; } -- 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') 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 f75106c61b5e5baf71c47d9e17e759044a019989 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 16 May 2019 00:46:50 +0200 Subject: don't hardcode screen sizes --- src/libui_sdl/main.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 23e6617..dc67bb2 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -223,8 +223,6 @@ void GLDrawing_DrawScreen() glUnmapBuffer(GL_UNIFORM_BUFFER); float scwidth, scheight; - scwidth = 512; - scheight = 384; float x0, y0, x1, y1; float s0, s1, s2, s3; @@ -241,6 +239,9 @@ void GLDrawing_DrawScreen() x1 = TopScreenRect.X + TopScreenRect.Width; y1 = TopScreenRect.Y + TopScreenRect.Height; + scwidth = 256 << ScreenScale[0]; + scheight = 192 << ScreenScale[0]; + switch (ScreenRotation) { case 0: @@ -279,13 +280,14 @@ void GLDrawing_DrawScreen() 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; + scwidth = 256 << ScreenScale[1]; + scheight = 192 << ScreenScale[1]; + switch (ScreenRotation) { case 0: -- cgit v1.2.3 From 4b874cc440c8e9f69f9ae983c5ea253f3f560a4b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 16 May 2019 01:08:53 +0200 Subject: make GL renderer able to coexist with GL screen drawing --- src/GPU3D_OpenGL43.cpp | 87 +++++--------------------------------------------- src/libui_sdl/main.cpp | 5 ++- 2 files changed, 12 insertions(+), 80 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index b3e0856..e76db7f 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -737,79 +737,6 @@ bool InitGLExtensions() return true; } -bool 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; -} - bool BuildRenderShader(u32 flags, const char* vs, const char* fs) { char shadername[32]; @@ -831,7 +758,7 @@ bool BuildRenderShader(u32 flags, const char* vs, const char* fs) strcpy(&fsbuf[headerlen], kRenderFSCommon); strcpy(&fsbuf[headerlen + fsclen], fs); - bool ret = BuildShaderProgram(vsbuf, fsbuf, RenderShader[flags], shadername); + bool ret = OpenGL_BuildShaderProgram(vsbuf, fsbuf, RenderShader[flags], shadername); delete[] vsbuf; delete[] fsbuf; @@ -881,7 +808,7 @@ bool Init() glClearDepth(1.0); - if (!BuildShaderProgram(kClearVS, kClearFS, ClearShaderPlain, "ClearShader")) + if (!OpenGL_BuildShaderProgram(kClearVS, kClearFS, ClearShaderPlain, "ClearShader")) return false; memset(RenderShader, 0, sizeof(RenderShader)); @@ -1049,8 +976,6 @@ void SetScale(int scale) ScreenW = 256 << scale; ScreenH = 192 << scale; - glViewport(0, 0, ScreenW, ScreenH); - 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]); @@ -1386,7 +1311,7 @@ void VCount144() } void RenderFrame() -{return; +{ ShaderConfig.uScreenSize[0] = ScreenW; ShaderConfig.uScreenSize[1] = ScreenH; ShaderConfig.uDispCnt = RenderDispCnt; @@ -1441,6 +1366,10 @@ void RenderFrame() } glDisable(GL_SCISSOR_TEST); + glEnable(GL_DEPTH_TEST); + glEnable(GL_STENCIL_TEST); + + glViewport(0, 0, ScreenW, ScreenH); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); glDisable(GL_BLEND); @@ -1545,7 +1474,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/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index dc67bb2..4d3cf64 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -333,14 +333,16 @@ void GLDrawing_DrawScreen() } glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glViewport(0, 0, WindowWidth, WindowHeight); OpenGL_UseShaderProgram(GL_ScreenShader); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glClearColor(0, 1, 0, 1); + glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); int frontbuf = GPU::FrontBuffer; @@ -353,6 +355,7 @@ void GLDrawing_DrawScreen() glBindVertexArray(GL_ScreenVertexArrayID); glDrawArrays(GL_TRIANGLES, 0, 4*3); + glFlush(); uiGLSwapBuffers(GLContext); uiAreaQueueRedrawAll(MainDrawArea); } -- cgit v1.2.3 From f2282e9e32cce0c335f0ca065e5a3b1bc564e406 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 16 May 2019 01:46:09 +0200 Subject: Arisotura is a fucking derp --- src/libui_sdl/main.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 4d3cf64..47f5f13 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -184,6 +184,7 @@ bool GLDrawing_Init() glEnableVertexAttribArray(1); // texcoord glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(2*4)); + // TODO: consider reallocating the texture when changing screen sizes glGenTextures(1, &GL_ScreenTexture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); @@ -348,8 +349,10 @@ void GLDrawing_DrawScreen() 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]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256< Date: Thu, 16 May 2019 16:27:45 +0200 Subject: BAHAHAHAHAHAHAHAA --- melonDS.cbp | 1 + src/GPU.cpp | 40 +-- src/GPU.h | 2 +- src/GPU2D.cpp | 169 +++++++----- src/GPU2D.h | 4 +- src/GPU3D.cpp | 4 +- src/GPU3D.h | 9 +- src/GPU3D_OpenGL43.cpp | 641 +----------------------------------------- src/GPU3D_OpenGL43_shaders.h | 645 +++++++++++++++++++++++++++++++++++++++++++ src/GPU3D_Soft.cpp | 7 +- src/libui_sdl/main.cpp | 19 +- 11 files changed, 813 insertions(+), 728 deletions(-) create mode 100644 src/GPU3D_OpenGL43_shaders.h (limited to 'src') diff --git a/melonDS.cbp b/melonDS.cbp index ff01ebf..0bdac7f 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -107,6 +107,7 @@ + diff --git a/src/GPU.cpp b/src/GPU.cpp index f4e9fd4..1d073f5 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -74,6 +74,7 @@ u32 VRAMMap_ARM7[2]; int FrontBuffer; u32* Framebuffer[2][2]; int FBScale[2]; +bool Accelerated; GPU2D* GPU2D_A; GPU2D* GPU2D_B; @@ -88,9 +89,8 @@ bool Init() FrontBuffer = 0; Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL; Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL; - FBScale[0] = -1; FBScale[1] = -1; - //SetFramebufferScale(1); - SetFramebufferScale(1, 1); + FBScale[0] = -1; FBScale[1] = -1; Accelerated = false; + SetDisplaySettings(0, 0, false); return true; } @@ -247,13 +247,15 @@ void AssignFramebuffers() } } -void SetFramebufferScale(int top, int bottom) -{ - if (top != FBScale[0]) +void SetDisplaySettings(int topscale, int bottomscale, bool accel) +{accel=true; + if (topscale != FBScale[0] || accel != Accelerated) { - FBScale[0] = top; + FBScale[0] = accel ? 0 : topscale; - int fbsize = (256 * 192) << (FBScale[0] * 2); + int fbsize; + if (accel) fbsize = 256*3 * 192; + else fbsize = (256 * 192) << (FBScale[0] * 2); if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; Framebuffer[0][0] = new u32[fbsize]; @@ -266,21 +268,23 @@ void SetFramebufferScale(int top, int bottom) if (NDS::PowerControl9 & (1<<15)) { GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_A->SetScale(FBScale[0]); - GPU3D::SetScale(FBScale[0]); + GPU2D_A->SetDisplaySettings(FBScale[0], accel); + GPU3D::SetDisplaySettings(topscale, accel); } else { GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_B->SetScale(FBScale[0]); + GPU2D_B->SetDisplaySettings(FBScale[0], accel); } } - if (bottom != FBScale[1]) + if (bottomscale != FBScale[1] || accel != Accelerated) { - FBScale[1] = bottom; + FBScale[1] = accel ? 0 : bottomscale; - int fbsize = (256 * 192) << (FBScale[1] * 2); + int fbsize; + if (accel) fbsize = 256*3 * 192; + else fbsize = (256 * 192) << (FBScale[1] * 2); if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; Framebuffer[0][1] = new u32[fbsize]; @@ -293,15 +297,17 @@ void SetFramebufferScale(int top, int bottom) if (NDS::PowerControl9 & (1<<15)) { GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_B->SetScale(FBScale[1]); + GPU2D_B->SetDisplaySettings(FBScale[1], accel); } else { GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_A->SetScale(FBScale[1]); - GPU3D::SetScale(FBScale[1]); + GPU2D_A->SetDisplaySettings(FBScale[1], accel); + GPU3D::SetDisplaySettings(bottomscale, accel); } } + + Accelerated = accel; } diff --git a/src/GPU.h b/src/GPU.h index 2e47fc4..cfa8d7d 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -75,7 +75,7 @@ void Stop(); void DoSavestate(Savestate* file); -void SetFramebufferScale(int top, int bottom); +void SetDisplaySettings(int topscale, int bottomscale, bool accel); void MapVRAM_AB(u32 bank, u8 cnt); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 3a99964..34c17ff 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -82,7 +82,6 @@ GPU2D::GPU2D(u32 num) { Num = num; - SetScale(0); } GPU2D::~GPU2D() @@ -216,12 +215,16 @@ void GPU2D::SetFramebuffer(u32* buf) Framebuffer = buf; } -void GPU2D::SetScale(int scale) +void GPU2D::SetDisplaySettings(int scale, bool accel) { + if (accel) scale = 0; + Accelerated = accel; + LineScale = scale; LineStride = 256 << (scale*2); - if (scale == 1) DrawPixel = DrawPixel_2x; + if (Accelerated) DrawPixel = DrawPixel_Accel; + else if (scale == 1) DrawPixel = DrawPixel_2x; else if (scale == 2) DrawPixel = DrawPixel_4x; else DrawPixel = DrawPixel_1x; } @@ -623,7 +626,8 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - u32* dst = &Framebuffer[LineStride * line]; + int stride = Accelerated ? (256*3) : LineStride; + u32* dst = &Framebuffer[stride * line]; int n3dline = line; line = GPU::VCount; @@ -652,7 +656,7 @@ void GPU2D::DrawScanline(u32 line) u32 dispmode = DispCnt >> 16; dispmode &= (Num ? 0x1 : 0x3); - if (Num == 0) + if (Num == 0 && !Accelerated) _3DLine = GPU3D::GetLine(n3dline); // always render regular graphics @@ -663,13 +667,13 @@ void GPU2D::DrawScanline(u32 line) case 0: // screen off { for (int i = 0; i < LineStride; i++) - dst[i] = 0xFF3F3F3F; + dst[i] = 0x003F3F3F; } break; case 1: // regular display { - for (int i = 0; i < LineStride; i+=2) + for (int i = 0; i < stride; i+=2) *(u64*)&dst[i] = *(u64*)&BGOBJLine[i]; } break; @@ -783,6 +787,8 @@ void GPU2D::DrawScanline(u32 line) DoCapture(line, capwidth); } + if (Accelerated) return; + // master brightness if (dispmode != 0) { @@ -861,6 +867,8 @@ void GPU2D::DoCapture(u32 line, u32 width) u16* dst = (u16*)GPU::VRAM[dstvram]; u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width); + // TODO: handle 3D in accelerated mode!! + u32* srcA; if (CaptureCnt & (1<<24)) srcA = _3DLine; @@ -1272,88 +1280,91 @@ void GPU2D::DrawScanline_Mode1(u32 line) // color special effects // can likely be optimized - u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - - for (int i = 0; i < LineStride; i++) + if (!Accelerated) { - int j = (i >> LineScale) & 0xFF; + u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - u32 val1 = BGOBJLine[i]; - u32 val2 = BGOBJLine[4096+i]; + for (int i = 0; i < LineStride; i++) + { + int j = (i >> LineScale) & 0xFF; - u32 coloreffect, eva, evb; + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[4096+i]; - u32 flag1 = val1 >> 24; - u32 flag2 = val2 >> 24; + u32 coloreffect, eva, evb; - u32 target2; - if (flag2 & 0x80) target2 = 0x1000; - else if (flag2 & 0x40) target2 = 0x0100; - else target2 = flag2 << 8; + u32 flag1 = val1 >> 24; + u32 flag2 = val2 >> 24; - if ((flag1 & 0x80) && (BlendCnt & target2)) - { - // sprite blending + u32 target2; + if (flag2 & 0x80) target2 = 0x1000; + else if (flag2 & 0x40) target2 = 0x0100; + else target2 = flag2 << 8; - coloreffect = 1; + if ((flag1 & 0x80) && (BlendCnt & target2)) + { + // sprite blending + + coloreffect = 1; - if (flag1 & 0x40) + if (flag1 & 0x40) + { + eva = flag1 & 0x1F; + evb = 16 - eva; + } + else + { + eva = EVA; + evb = EVB; + } + } + else if ((flag1 & 0x40) && (BlendCnt & target2)) { - eva = flag1 & 0x1F; - evb = 16 - eva; + // 3D layer blending + + BGOBJLine[i] = ColorBlend5(val1, val2); + continue; } else { - eva = EVA; - evb = EVB; - } - } - else if ((flag1 & 0x40) && (BlendCnt & target2)) - { - // 3D layer blending - - BGOBJLine[i] = ColorBlend5(val1, val2); - continue; - } - else - { - if (flag1 & 0x80) flag1 = 0x10; - else if (flag1 & 0x40) flag1 = 0x01; + if (flag1 & 0x80) flag1 = 0x10; + else if (flag1 & 0x40) flag1 = 0x01; - if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) - { - if ((bldcnteffect == 1) && (BlendCnt & target2)) + if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) { - coloreffect = 1; - eva = EVA; - evb = EVB; + if ((bldcnteffect == 1) && (BlendCnt & target2)) + { + coloreffect = 1; + eva = EVA; + evb = EVB; + } + else if (bldcnteffect >= 2) + coloreffect = bldcnteffect; + else + coloreffect = 0; } - else if (bldcnteffect >= 2) - coloreffect = bldcnteffect; else coloreffect = 0; } - else - coloreffect = 0; - } - switch (coloreffect) - { - case 0: - BGOBJLine[i] = val1; - break; + switch (coloreffect) + { + case 0: + BGOBJLine[i] = val1; + break; - case 1: - BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); - break; + case 1: + BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); + break; - case 2: - BGOBJLine[i] = ColorBrightnessUp(val1, EVY); - break; + case 2: + BGOBJLine[i] = ColorBrightnessUp(val1, EVY); + break; - case 3: - BGOBJLine[i] = ColorBrightnessDown(val1, EVY); - break; + case 3: + BGOBJLine[i] = ColorBrightnessDown(val1, EVY); + break; + } } } @@ -1429,6 +1440,17 @@ void GPU2D::DrawPixel_4x(u32* dst, u16 color, u32 flag) *(u64*)(dst+3072+2) = val; } +void GPU2D::DrawPixel_Accel(u32* dst, u16 color, u32 flag) +{ + u8 r = (color & 0x001F) << 1; + u8 g = (color & 0x03E0) >> 4; + u8 b = (color & 0x7C00) >> 9; + + *(dst+512) = *(dst+256); + *(dst+256) = *dst; + *dst = r | (g << 8) | (b << 16) | flag; +} + void GPU2D::DrawBG_3D() { u16 xoff = BGXPos[0]; @@ -1445,7 +1467,18 @@ void GPU2D::DrawBG_3D() iend -= (xoff & 0xFF); } - if (LineScale == 1) + if (Accelerated) + { + for (; i < iend; i++) + { + if (!(WindowMask[i] & 0x01)) continue; + + BGOBJLine[i+512] = BGOBJLine[i+256]; + BGOBJLine[i+256] = BGOBJLine[i]; + BGOBJLine[i] = 0x40000000; // 3D-layer placeholder + } + } + else if (LineScale == 1) { for (; i < iend; i++) { diff --git a/src/GPU2D.h b/src/GPU2D.h index aca1f7e..fc420a5 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 SetScale(int scale); + void SetDisplaySettings(int scale, bool accel); u8 Read8(u32 addr); u16 Read16(u32 addr); @@ -71,6 +71,7 @@ private: u32 LineStride; u32 LineScale; + bool Accelerated; u32 BGOBJLine[1024*4 * 2]; u32* _3DLine; @@ -136,6 +137,7 @@ private: static void DrawPixel_1x(u32* dst, u16 color, u32 flag); static void DrawPixel_2x(u32* dst, u16 color, u32 flag); static void DrawPixel_4x(u32* dst, u16 color, u32 flag); + static void DrawPixel_Accel(u32* dst, u16 color, u32 flag); void (*DrawPixel)(u32* dst, u16 color, u32 flag); void DrawBG_3D(); diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 8c0588d..61629a7 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -607,9 +607,9 @@ void SetEnabled(bool geometry, bool rendering) if (!rendering) ResetRenderingState(); } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { - GLRenderer43::SetScale(scale); + GLRenderer43::SetDisplaySettings(scale, accel); } diff --git a/src/GPU3D.h b/src/GPU3D.h index 68bc696..2fe5bee 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -97,7 +97,7 @@ void Reset(); void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void ExecuteCommand(); @@ -110,6 +110,7 @@ void VCount144(); void VBlank(); void VCount215(); u32* GetLine(int line); +void SetupAccelFrame(); void WriteToGXFIFO(u32 val); @@ -127,13 +128,14 @@ bool Init(); void DeInit(); void Reset(); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void SetupRenderThread(); void VCount144(); void RenderFrame(); u32* GetLine(int line); +void SetupAccelFrame(); } @@ -144,11 +146,12 @@ bool Init(); void DeInit(); void Reset(); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void VCount144(); void RenderFrame(); u32* GetLine(int line); +void SetupAccelFrame(); } diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index e76db7f..6db9a18 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -21,6 +21,7 @@ #include "NDS.h" #include "GPU.h" #include "OpenGLSupport.h" +#include "GPU3D_OpenGL43_shaders.h" namespace GPU3D { @@ -33,631 +34,6 @@ namespace GLRenderer43 // * UBO: 3.1 // * glMemoryBarrier: 4.2 -// TODO: consider other way to handle uniforms (UBO?) - -#define kShaderHeader "#version 430" - - -const char* kClearVS = kShaderHeader R"( - -layout(location=0) in vec2 vPosition; - -layout(location=1) uniform uint uDepth; - -void main() -{ - float fdepth = (float(uDepth) / 8388608.0) - 1.0; - gl_Position = vec4(vPosition, fdepth, 1.0); -} -)"; - -const char* kClearFS = kShaderHeader R"( - -layout(location=0) uniform uvec4 uColor; -layout(location=2) uniform uint uOpaquePolyID; -layout(location=3) uniform uint uFogFlag; - -layout(location=0) out vec4 oColor; -layout(location=1) out uvec3 oAttr; - -void main() -{ - oColor = vec4(uColor).bgra / 31.0; - oAttr.r = 0; - oAttr.g = uOpaquePolyID; - oAttr.b = 0; -} -)"; - - -const char* kRenderVSCommon = R"( - -layout(std140, binding=0) uniform uConfig -{ - vec2 uScreenSize; - uint uDispCnt; - vec4 uToonColors[32]; -}; - -layout(location=0) in uvec4 vPosition; -layout(location=1) in uvec4 vColor; -layout(location=2) in ivec2 vTexcoord; -layout(location=3) in uvec3 vPolygonAttr; - -smooth out vec4 fColor; -smooth out vec2 fTexcoord; -flat out uvec3 fPolygonAttr; -)"; - -const char* kRenderFSCommon = R"( - -layout(binding=0) uniform usampler2D TexMem; -layout(binding=1) uniform sampler2D TexPalMem; - -layout(std140, binding=0) uniform uConfig -{ - vec2 uScreenSize; - uint uDispCnt; - vec4 uToonColors[32]; -}; - -smooth in vec4 fColor; -smooth in vec2 fTexcoord; -flat in uvec3 fPolygonAttr; - -layout(location=0) out vec4 oColor; -layout(location=1) out uvec3 oAttr; - -int TexcoordWrap(int c, int maxc, uint mode) -{ - if ((mode & (1<<0)) != 0) - { - if ((mode & (1<<2)) != 0 && (c & maxc) != 0) - return (maxc-1) - (c & (maxc-1)); - else - return (c & (maxc-1)); - } - else - return clamp(c, 0, maxc-1); -} - -vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - pixel.a = (pixel.r & 0xE0); - pixel.a = (pixel.a >> 3) + (pixel.a >> 6); - pixel.r &= 0x1F; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, float(pixel.a)/31.0); -} - -vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) >> 2; - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - pixel.r >>= (2 * (st.x & 3)); - pixel.r &= 0x03; - - addr.y = (addr.y << 2) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) >> 1; - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - if ((st.x & 1) != 0) pixel.r >>= 4; - else pixel.r &= 0x0F; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); - uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; - - int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); - if (addr.x >= 0x40000) slot1addr += 0x10000; - - uint palinfo; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo = p.r; - slot1addr++; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo |= (p.r << 8); - - addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1); - palinfo >>= 14; - - if (val == 0) - { - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (val == 1) - { - addr.y++; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (val == 2) - { - if (palinfo == 1) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); - } - else - { - addr.y += 2; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - } - else - { - if (palinfo == 2) - { - addr.y += 3; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); - } - else - { - return vec4(0.0); - } - } -} - -vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - pixel.a = (pixel.r & 0xF8) >> 3; - pixel.r &= 0x07; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, float(pixel.a)/31.0); -} - -vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) << 1; - uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - addr.x++; - uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - vec4 color; - color.r = float(pixelL.r & 0x1F) / 31.0; - color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; - color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; - color.a = float(pixelH.r >> 7); - - return color; -} - -vec4 TextureLookup_Nearest(vec2 st) -{ - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); - ivec4 st_full = ivec4(ivec2(st), tw, th); - - ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); - uint wrapmode = attr >> 16; - - uint type = (attr >> 26) & 0x7; - if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); - else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); - else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); - else return TextureFetch_Direct (vramaddr, st_full, wrapmode); -} - -vec4 TextureLookup_Linear(vec2 texcoord) -{ - ivec2 intpart = ivec2(texcoord); - vec2 fracpart = fract(texcoord); - - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); - ivec4 st_full = ivec4(intpart, tw, th); - - ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); - uint wrapmode = attr >> 16; - - vec4 A, B, C, D; - uint type = (attr >> 26) & 0x7; - if (type == 5) - { - A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); - B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else if (type == 2) - { - A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 3) - { - A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 4) - { - A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 1) - { - A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); - B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else if (type == 6) - { - A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); - B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else - { - A = TextureFetch_Direct(vramaddr, st_full , wrapmode); - B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - - float fx = fracpart.x; - vec4 AB; - if (A.a < (0.5/31.0) && B.a < (0.5/31.0)) - AB = vec4(0); - else - { - //if (A.a < (0.5/31.0) || B.a < (0.5/31.0)) - // fx = step(0.5, fx); - - AB = mix(A, B, fx); - } - - fx = fracpart.x; - vec4 CD; - if (C.a < (0.5/31.0) && D.a < (0.5/31.0)) - CD = vec4(0); - else - { - //if (C.a < (0.5/31.0) || D.a < (0.5/31.0)) - // fx = step(0.5, fx); - - CD = mix(C, D, fx); - } - - fx = fracpart.y; - vec4 ret; - if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0)) - ret = vec4(0); - else - { - //if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0)) - // fx = step(0.5, fx); - - ret = mix(AB, CD, fx); - } - - return ret; -} - -vec4 FinalColor() -{ - vec4 col; - vec4 vcol = fColor; - uint blendmode = (fPolygonAttr.x >> 4) & 0x3; - - if (blendmode == 2) - { - if ((uDispCnt & (1<<1)) == 0) - { - // toon - vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; - vcol.rgb = tooncolor; - } - else - { - // highlight - vcol.rgb = vcol.rrr; - } - } - - if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0)) - { - // no texture - col = vcol; - } - else - { - vec4 tcol = TextureLookup_Nearest(fTexcoord); - //vec4 tcol = TextureLookup_Linear(fTexcoord); - - if ((blendmode & 1) != 0) - { - // decal - col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a)); - col.a = vcol.a; - } - else - { - // modulate - col = vcol * tcol; - } - } - - if (blendmode == 2) - { - if ((uDispCnt & (1<<1)) != 0) - { - vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; - col.rgb = min(col.rgb + tooncolor, 1.0); - } - } - - return col.bgra; -} -)"; - - -const char* kRenderVS_Z = R"( - -void main() -{ - uint attr = vPolygonAttr.x; - uint zshift = (attr >> 16) & 0x1F; - - vec4 fpos; - fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; - fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; - fpos.w = float(vPosition.w) / 65536.0f; - fpos.xyz *= fpos.w; - - fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); - fTexcoord = vec2(vTexcoord) / 16.0; - fPolygonAttr = vPolygonAttr; - - gl_Position = fpos; -} -)"; - -const char* kRenderVS_W = R"( - -smooth out float fZ; - -void main() -{ - uint attr = vPolygonAttr.x; - uint zshift = (attr >> 16) & 0x1F; - - vec4 fpos; - fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; - fZ = float(vPosition.z << zshift) / 16777216.0; - fpos.w = float(vPosition.w) / 65536.0f; - fpos.xy *= fpos.w; - - fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); - fTexcoord = vec2(vTexcoord) / 16.0; - fPolygonAttr = vPolygonAttr; - - gl_Position = fpos; -} -)"; - - -const char* kRenderFS_ZO = R"( - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 30.5/31) discard; - - oColor = col; - oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; -} -)"; - -const char* kRenderFS_WO = R"( - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 30.5/31) discard; - - oColor = col; - oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZT = R"( - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - oColor = col; - oAttr.g = 0xFF; -} -)"; - -const char* kRenderFS_WT = R"( - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - oColor = col; - oAttr.g = 0xFF; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZSM = R"( - -void main() -{ - oColor = vec4(0,0,0,1); - oAttr.g = 0xFF; - oAttr.b = 1; -} -)"; - -const char* kRenderFS_WSM = R"( - -smooth in float fZ; - -void main() -{ - oColor = vec4(0,0,0,1); - oAttr.g = 0xFF; - oAttr.b = 1; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZS = R"( - -layout(binding=2) uniform usampler2D iAttrTex; -//layout(origin_upper_left) in vec4 gl_FragCoord; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.b != 1) discard; - if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; - - oColor = col; -} -)"; - -const char* kRenderFS_WS = R"( - -layout(binding=2) uniform usampler2D iAttrTex; -//layout(origin_upper_left) in vec4 gl_FragCoord; - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.b != 1) discard; - if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; - - oColor = col; - gl_FragDepth = fZ; -} -)"; - enum { @@ -721,6 +97,7 @@ GLuint TexMemID; GLuint TexPalMemID; int ScaleFactor; +bool Accelerated; int ScreenW, ScreenH; GLuint FramebufferTex[4]; @@ -968,9 +345,10 @@ void Reset() // } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { ScaleFactor = scale; + Accelerated = accel; // TODO: antialiasing setting ScreenW = 256 << scale; @@ -986,10 +364,12 @@ void SetScale(int scale) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); + if (accel) glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); + else glBufferData(GL_PIXEL_PACK_BUFFER, 256*192, NULL, GL_DYNAMIC_READ); if (Framebuffer) delete[] Framebuffer; - Framebuffer = new u32[ScreenW*ScreenH]; + if (accel) Framebuffer = new u32[256*192]; + else Framebuffer = new u32[ScreenW*ScreenH]; } @@ -1533,5 +913,10 @@ u32* GetLine(int line) return &Framebuffer[stride * line]; } +void SetupAccelFrame() +{ + // +} + } } diff --git a/src/GPU3D_OpenGL43_shaders.h b/src/GPU3D_OpenGL43_shaders.h new file mode 100644 index 0000000..8a69566 --- /dev/null +++ b/src/GPU3D_OpenGL43_shaders.h @@ -0,0 +1,645 @@ +/* + 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 GPU3D_OPENGL43_SHADERS_H +#define GPU3D_OPENGL43_SHADERS_H + +#define kShaderHeader "#version 430" + + +const char* kClearVS = kShaderHeader R"( + +layout(location=0) in vec2 vPosition; + +layout(location=1) uniform uint uDepth; + +void main() +{ + float fdepth = (float(uDepth) / 8388608.0) - 1.0; + gl_Position = vec4(vPosition, fdepth, 1.0); +} +)"; + +const char* kClearFS = kShaderHeader R"( + +layout(location=0) uniform uvec4 uColor; +layout(location=2) uniform uint uOpaquePolyID; +layout(location=3) uniform uint uFogFlag; + +layout(location=0) out vec4 oColor; +layout(location=1) out uvec3 oAttr; + +void main() +{ + oColor = vec4(uColor).bgra / 31.0; + oAttr.r = 0; + oAttr.g = uOpaquePolyID; + oAttr.b = 0; +} +)"; + + +const char* kRenderVSCommon = R"( + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uDispCnt; + vec4 uToonColors[32]; +}; + +layout(location=0) in uvec4 vPosition; +layout(location=1) in uvec4 vColor; +layout(location=2) in ivec2 vTexcoord; +layout(location=3) in uvec3 vPolygonAttr; + +smooth out vec4 fColor; +smooth out vec2 fTexcoord; +flat out uvec3 fPolygonAttr; +)"; + +const char* kRenderFSCommon = R"( + +layout(binding=0) uniform usampler2D TexMem; +layout(binding=1) uniform sampler2D TexPalMem; + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uDispCnt; + vec4 uToonColors[32]; +}; + +smooth in vec4 fColor; +smooth in vec2 fTexcoord; +flat in uvec3 fPolygonAttr; + +layout(location=0) out vec4 oColor; +layout(location=1) out uvec3 oAttr; + +int TexcoordWrap(int c, int maxc, uint mode) +{ + if ((mode & (1<<0)) != 0) + { + if ((mode & (1<<2)) != 0 && (c & maxc) != 0) + return (maxc-1) - (c & (maxc-1)); + else + return (c & (maxc-1)); + } + else + return clamp(c, 0, maxc-1); +} + +vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + pixel.a = (pixel.r & 0xE0); + pixel.a = (pixel.a >> 3) + (pixel.a >> 6); + pixel.r &= 0x1F; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); +} + +vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) >> 2; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + pixel.r >>= (2 * (st.x & 3)); + pixel.r &= 0x03; + + addr.y = (addr.y << 2) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) >> 1; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + if ((st.x & 1) != 0) pixel.r >>= 4; + else pixel.r &= 0x0F; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); + uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; + + int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); + if (addr.x >= 0x40000) slot1addr += 0x10000; + + uint palinfo; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo = p.r; + slot1addr++; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo |= (p.r << 8); + + addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1); + palinfo >>= 14; + + if (val == 0) + { + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 1) + { + addr.y++; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 2) + { + if (palinfo == 1) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); + } + else + { + addr.y += 2; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + } + else + { + if (palinfo == 2) + { + addr.y += 3; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); + } + else + { + return vec4(0.0); + } + } +} + +vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + pixel.a = (pixel.r & 0xF8) >> 3; + pixel.r &= 0x07; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); +} + +vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) << 1; + uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + addr.x++; + uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + vec4 color; + color.r = float(pixelL.r & 0x1F) / 31.0; + color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; + color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; + color.a = float(pixelH.r >> 7); + + return color; +} + +vec4 TextureLookup_Nearest(vec2 st) +{ + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(ivec2(st), tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + uint type = (attr >> 26) & 0x7; + if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); + else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); + else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); + else return TextureFetch_Direct (vramaddr, st_full, wrapmode); +} + +vec4 TextureLookup_Linear(vec2 texcoord) +{ + ivec2 intpart = ivec2(texcoord); + vec2 fracpart = fract(texcoord); + + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(intpart, tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + vec4 A, B, C, D; + uint type = (attr >> 26) & 0x7; + if (type == 5) + { + A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); + B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 2) + { + A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 3) + { + A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 4) + { + A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 1) + { + A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); + B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 6) + { + A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); + B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else + { + A = TextureFetch_Direct(vramaddr, st_full , wrapmode); + B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + + float fx = fracpart.x; + vec4 AB; + if (A.a < (0.5/31.0) && B.a < (0.5/31.0)) + AB = vec4(0); + else + { + //if (A.a < (0.5/31.0) || B.a < (0.5/31.0)) + // fx = step(0.5, fx); + + AB = mix(A, B, fx); + } + + fx = fracpart.x; + vec4 CD; + if (C.a < (0.5/31.0) && D.a < (0.5/31.0)) + CD = vec4(0); + else + { + //if (C.a < (0.5/31.0) || D.a < (0.5/31.0)) + // fx = step(0.5, fx); + + CD = mix(C, D, fx); + } + + fx = fracpart.y; + vec4 ret; + if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0)) + ret = vec4(0); + else + { + //if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0)) + // fx = step(0.5, fx); + + ret = mix(AB, CD, fx); + } + + return ret; +} + +vec4 FinalColor() +{ + vec4 col; + vec4 vcol = fColor; + uint blendmode = (fPolygonAttr.x >> 4) & 0x3; + + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) == 0) + { + // toon + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + vcol.rgb = tooncolor; + } + else + { + // highlight + vcol.rgb = vcol.rrr; + } + } + + if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0)) + { + // no texture + col = vcol; + } + else + { + vec4 tcol = TextureLookup_Nearest(fTexcoord); + //vec4 tcol = TextureLookup_Linear(fTexcoord); + + if ((blendmode & 1) != 0) + { + // decal + col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a)); + col.a = vcol.a; + } + else + { + // modulate + col = vcol * tcol; + } + } + + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) != 0) + { + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + col.rgb = min(col.rgb + tooncolor, 1.0); + } + } + + return col.bgra; +} +)"; + + +const char* kRenderVS_Z = R"( + +void main() +{ + uint attr = vPolygonAttr.x; + uint zshift = (attr >> 16) & 0x1F; + + vec4 fpos; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; + fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; + fpos.w = float(vPosition.w) / 65536.0f; + fpos.xyz *= fpos.w; + + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; + + gl_Position = fpos; +} +)"; + +const char* kRenderVS_W = R"( + +smooth out float fZ; + +void main() +{ + uint attr = vPolygonAttr.x; + uint zshift = (attr >> 16) & 0x1F; + + vec4 fpos; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; + fZ = float(vPosition.z << zshift) / 16777216.0; + fpos.w = float(vPosition.w) / 65536.0f; + fpos.xy *= fpos.w; + + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; + + gl_Position = fpos; +} +)"; + + +const char* kRenderFS_ZO = R"( + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 30.5/31) discard; + + oColor = col; + oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; +} +)"; + +const char* kRenderFS_WO = R"( + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 30.5/31) discard; + + oColor = col; + oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZT = R"( + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + oColor = col; + oAttr.g = 0xFF; +} +)"; + +const char* kRenderFS_WT = R"( + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + oColor = col; + oAttr.g = 0xFF; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZSM = R"( + +void main() +{ + oColor = vec4(0,0,0,1); + oAttr.g = 0xFF; + oAttr.b = 1; +} +)"; + +const char* kRenderFS_WSM = R"( + +smooth in float fZ; + +void main() +{ + oColor = vec4(0,0,0,1); + oAttr.g = 0xFF; + oAttr.b = 1; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZS = R"( + +layout(binding=2) uniform usampler2D iAttrTex; +//layout(origin_upper_left) in vec4 gl_FragCoord; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); + if (iAttr.b != 1) discard; + if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; + + oColor = col; +} +)"; + +const char* kRenderFS_WS = R"( + +layout(binding=2) uniform usampler2D iAttrTex; +//layout(origin_upper_left) in vec4 gl_FragCoord; + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); + if (iAttr.b != 1) discard; + if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; + + oColor = col; + gl_FragDepth = fZ; +} +)"; + +#endif // GPU3D_OPENGL43_SHADERS_H diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp index ac5cd93..20283d3 100644 --- a/src/GPU3D_Soft.cpp +++ b/src/GPU3D_Soft.cpp @@ -138,7 +138,7 @@ void Reset() SetupRenderThread(); } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { printf("SOFT RENDERER SCALE FACTOR: TODO!!!\n"); } @@ -2122,5 +2122,10 @@ u32* GetLine(int line) return &ColorBuffer[(line * ScanlineWidth) + FirstPixelOffset]; } +void SetupAccelFrame() +{ + // TODO +} + } } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 47f5f13..b77d67f 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -240,8 +240,8 @@ void GLDrawing_DrawScreen() x1 = TopScreenRect.X + TopScreenRect.Width; y1 = TopScreenRect.Y + TopScreenRect.Height; - scwidth = 256 << ScreenScale[0]; - scheight = 192 << ScreenScale[0]; + scwidth = 256;// << ScreenScale[0]; + scheight = 192;// << ScreenScale[0]; switch (ScreenRotation) { @@ -286,8 +286,8 @@ void GLDrawing_DrawScreen() x1 = BottomScreenRect.X + BottomScreenRect.Width; y1 = BottomScreenRect.Y + BottomScreenRect.Height; - scwidth = 256 << ScreenScale[1]; - scheight = 192 << ScreenScale[1]; + scwidth = 256;// << ScreenScale[1]; + scheight = 192;// << ScreenScale[1]; switch (ScreenRotation) { @@ -349,9 +349,13 @@ void GLDrawing_DrawScreen() int frontbuf = GPU::FrontBuffer; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256< Date: Thu, 16 May 2019 20:58:07 +0200 Subject: BAHAHAHHHH HARK HARK HARK --- src/GPU.cpp | 4 +- src/GPU2D.cpp | 25 +++++++-- src/GPU3D.cpp | 10 ++++ src/GPU3D.h | 3 ++ src/GPU3D_OpenGL43.cpp | 118 +++++++++++++++++------------------------ src/GPU3D_Soft.cpp | 5 ++ src/libui_sdl/main.cpp | 11 ++-- src/libui_sdl/main_shaders.h | 123 ++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 219 insertions(+), 80 deletions(-) (limited to 'src') diff --git a/src/GPU.cpp b/src/GPU.cpp index 1d073f5..8142e47 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -254,7 +254,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[0] = accel ? 0 : topscale; int fbsize; - if (accel) fbsize = 256*3 * 192; + if (accel) fbsize = (256*3 + 1) * 192; else fbsize = (256 * 192) << (FBScale[0] * 2); if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; @@ -283,7 +283,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[1] = accel ? 0 : bottomscale; int fbsize; - if (accel) fbsize = 256*3 * 192; + if (accel) fbsize = (256*3 + 1) * 192; else fbsize = (256 * 192) << (FBScale[1] * 2); if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 34c17ff..f80eb85 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -626,7 +626,7 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - int stride = Accelerated ? (256*3) : LineStride; + int stride = Accelerated ? (256*3 + 1) : LineStride; u32* dst = &Framebuffer[stride * line]; int n3dline = line; @@ -787,7 +787,17 @@ void GPU2D::DrawScanline(u32 line) DoCapture(line, capwidth); } - if (Accelerated) return; + if (Accelerated) + { + u32 ctl = (BlendCnt & 0x3FFF); + ctl |= ((DispCnt & 0x30000) >> 2); + ctl |= (EVA << 16); + ctl |= (EVB << 21); + ctl |= (EVY << 26); + + dst[256*3] = ctl; + return; + } // master brightness if (dispmode != 0) @@ -1367,6 +1377,13 @@ void GPU2D::DrawScanline_Mode1(u32 line) } } } + else + { + for (int i = 0; i < 256; i++) + { + BGOBJLine[i] |= ((WindowMask[i] & 0x20) << 18); + } + } if (BGMosaicY >= BGMosaicYMax) { @@ -1471,11 +1488,13 @@ void GPU2D::DrawBG_3D() { for (; i < iend; i++) { + int pos = xoff++; + if (!(WindowMask[i] & 0x01)) continue; BGOBJLine[i+512] = BGOBJLine[i+256]; BGOBJLine[i+256] = BGOBJLine[i]; - BGOBJLine[i] = 0x40000000; // 3D-layer placeholder + BGOBJLine[i] = 0x40000000 | pos; // 3D-layer placeholder } } else if (LineScale == 1) diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 61629a7..ec395ad 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -612,6 +612,11 @@ void SetDisplaySettings(int scale, bool accel) GLRenderer43::SetDisplaySettings(scale, accel); } +int GetScale() +{ + return GLRenderer43::GetScale(); +} + void MatrixLoadIdentity(s32* m) @@ -2441,6 +2446,11 @@ u32* GetLine(int line) return GLRenderer43::GetLine(line); } +void SetupAccelFrame() +{ + GLRenderer43::SetupAccelFrame(); +} + void WriteToGXFIFO(u32 val) { diff --git a/src/GPU3D.h b/src/GPU3D.h index 2fe5bee..10c8966 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -98,6 +98,7 @@ void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); void SetDisplaySettings(int scale, bool accel); +int GetScale(); void ExecuteCommand(); @@ -129,6 +130,7 @@ void DeInit(); void Reset(); void SetDisplaySettings(int scale, bool accel); +int GetScale(); void SetupRenderThread(); @@ -147,6 +149,7 @@ void DeInit(); void Reset(); void SetDisplaySettings(int scale, bool accel); +int GetScale(); void VCount144(); void RenderFrame(); diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 6db9a18..0181192 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -100,7 +100,8 @@ int ScaleFactor; bool Accelerated; int ScreenW, ScreenH; -GLuint FramebufferTex[4]; +GLuint FramebufferTex[6]; +int FrontBuffer; GLuint FramebufferID[2], PixelbufferID; u32* Framebuffer = NULL; @@ -262,8 +263,10 @@ bool Init() glGenFramebuffers(2, &FramebufferID[0]); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); - // color buffer - glGenTextures(4, &FramebufferTex[0]); + glGenTextures(6, &FramebufferTex[0]); + FrontBuffer = 0; + + // color buffers glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -271,33 +274,39 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); - // depth/stencil buffer glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[1], 0); + + // depth/stencil buffer + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); // attribute buffer // R: opaque polyID (for edgemarking) // G: opaque polyID (for shadows, suppressed when rendering translucent polygons) // B: stencil flag - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[2], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); // downscale framebuffer, for antialiased mode glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[3], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[2], 0); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); @@ -330,7 +339,7 @@ bool Init() glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL); glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); // opaque polyID / shadow bits + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); // opaque polyID / shadow bits return true; } @@ -357,11 +366,13 @@ void SetDisplaySettings(int scale, bool accel) glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); if (accel) glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); @@ -372,6 +383,11 @@ void SetDisplaySettings(int scale, bool accel) else Framebuffer = new u32[ScreenW*ScreenH]; } +int GetScale() +{ + return ScaleFactor; +} + void SetupPolygon(RendererPolygon* rp, Polygon* polygon) { @@ -756,6 +772,12 @@ void RenderFrame() glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMaski(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + if (Accelerated) + { + int backbuf = FrontBuffer ? 0 : 1; + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[backbuf], 0); + } + // clear buffers // TODO: clear bitmap // TODO: check whether 'clear polygon ID' affects translucent polyID @@ -818,15 +840,7 @@ void RenderFrame() glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); - if (!ChunkedRendering) - { - RenderSceneChunk(0, 192); - } - else - { - glEnable(GL_SCISSOR_TEST); - RenderSceneChunk(0, 48); - } + RenderSceneChunk(0, 192); } if (false) @@ -842,63 +856,24 @@ void RenderFrame() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); } - glReadBuffer(GL_COLOR_ATTACHMENT0); - glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); + if (!Accelerated) + { + glReadBuffer(GL_COLOR_ATTACHMENT0); + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - if (!ChunkedRendering) glReadPixels(0, 0, 256<> 6) & 0x3; + + if (dispmode == 1) + { + uint eva = ctl.b & 0x1F; + uint evb = (ctl.b >> 5) | ((ctl.a & 0x03) << 3); + uint evy = ctl.a >> 2; + + uvec4 top = pixel; + uvec4 mid = texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0); + uvec4 bot = texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0); + + uint winmask = top.b >> 7; + + if ((top.a & 0x40) != 0) + { + float xpos = top.r + fract(fTexcoord.x); + uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, fTexcoord.y)*u3DScale), 0).bgra + * vec4(63,63,63,31)); + + if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } + else top = mid; + } + else if ((mid.a & 0x40) != 0) + { + float xpos = mid.r + fract(fTexcoord.x); + uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, fTexcoord.y)*u3DScale), 0).bgra + * vec4(63,63,63,31)); + + if (_3dpix.a > 0) { bot = _3dpix; bot.a |= 0x40; } + } + else + { + // conditional texture fetch no good for performance, apparently + //texelFetch(_3DTex, ivec2(0, fTexcoord.y*2), 0); + bot = mid; + } + + top.b &= 0x3F; + bot.b &= 0x3F; + + uint target2; + if ((bot.a & 0x80) != 0) target2 = 0x10; + else if ((bot.a & 0x40) != 0) target2 = 0x01; + else target2 = bot.a; + bool t2pass = ((ctl.g & target2) != 0); + + uint coloreffect = 0; + + if ((top.a & 0x80) != 0 && t2pass) + { + // sprite blending + + coloreffect = 1; + + if ((top.a & 0x40) != 0) + { + eva = top.a & 0x1F; + evb = 16 - eva; + } + } + else if ((top.a & 0x40) != 0 && t2pass) + { + // 3D layer blending + + coloreffect = 4; + eva = (top.a & 0x1F) + 1; + evb = 32 - eva; + } + else + { + if ((top.a & 0x80) != 0) top.a = 0x10; + else if ((top.a & 0x40) != 0) top.a = 0x01; + + if ((ctl.r & top.a) != 0 && winmask != 0) + { + uint effect = ctl.r >> 6; + if ((effect != 1) || t2pass) coloreffect = effect; + } + } + + if (coloreffect == 0) + { + pixel = top; + } + else if (coloreffect == 1) + { + pixel = ((top * eva) + (bot * evb)) >> 4; + pixel = min(pixel, 0x3F); + } + else if (coloreffect == 2) + { + pixel = top; + pixel += ((uvec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; + } + else if (coloreffect == 3) + { + pixel = top; + pixel -= (pixel * evy) >> 4; + } + else + { + pixel = ((top * eva) + (bot * evb)) >> 5; + if (eva <= 16) pixel += uvec4(1,1,1,0); + pixel = min(pixel, 0x3F); + } + } + + pixel.rgb <<= 2; + pixel.rgb |= (pixel.rgb >> 6); + // TODO: filters - oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0); + oColor = vec4(vec3(pixel.rgb) / 255.0, 1.0); + //oColor = texelFetch(_3DTex, ivec2(fTexcoord*4), 0).bgra; } )"; -- cgit v1.2.3 From 72920bb763c73a761992391568ad418750070c7c Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 16 May 2019 22:04:27 +0200 Subject: fix 3D on bottom screen --- src/libui_sdl/main_shaders.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h index b602013..85ff794 100644 --- a/src/libui_sdl/main_shaders.h +++ b/src/libui_sdl/main_shaders.h @@ -89,7 +89,8 @@ void main() if ((top.a & 0x40) != 0) { float xpos = top.r + fract(fTexcoord.x); - uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, fTexcoord.y)*u3DScale), 0).bgra + float ypos = mod(fTexcoord.y, 768); + uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra * vec4(63,63,63,31)); if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } @@ -98,7 +99,8 @@ void main() else if ((mid.a & 0x40) != 0) { float xpos = mid.r + fract(fTexcoord.x); - uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, fTexcoord.y)*u3DScale), 0).bgra + float ypos = mod(fTexcoord.y, 768); + uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra * vec4(63,63,63,31)); if (_3dpix.a > 0) { bot = _3dpix; bot.a |= 0x40; } -- cgit v1.2.3 From 8bf45571754a1469758f83ab8f98f951122c96f8 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 17 May 2019 15:47:40 +0200 Subject: make screen shaders work with OpenGL 3.1 --- src/OpenGLSupport.h | 5 +++++ src/libui_sdl/main.cpp | 14 +++++++++++- src/libui_sdl/main_shaders.h | 53 ++++++++++++++++++++++---------------------- 3 files changed, 44 insertions(+), 28 deletions(-) (limited to 'src') 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 26f997172b0765cd807ebfb7c20993276fe871a4 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 17 May 2019 19:09:41 +0200 Subject: fix 3D doublebuffering --- src/GPU3D_OpenGL43.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 0181192..062e40e 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -774,8 +774,8 @@ void RenderFrame() if (Accelerated) { - int backbuf = FrontBuffer ? 0 : 1; - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[backbuf], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[FrontBuffer], 0); + FrontBuffer = FrontBuffer ? 0 : 1; } // clear buffers @@ -891,7 +891,6 @@ u32* GetLine(int line) void SetupAccelFrame() { glBindTexture(GL_TEXTURE_2D, FramebufferTex[FrontBuffer]); - FrontBuffer = FrontBuffer ? 0 : 1; } } -- cgit v1.2.3 From de287825eec01aaa5e8ab925171cd75d86a23cb4 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 17 May 2019 22:50:41 +0200 Subject: start work on display capture also fix a bug in the compositing shader --- src/GPU.cpp | 2 +- src/GPU2D.cpp | 20 +++++++++-- src/GPU3D.h | 1 + src/GPU3D_OpenGL43.cpp | 81 ++++++++++++++++++++++++++++++++++++-------- src/libui_sdl/main_shaders.h | 6 ++-- 5 files changed, 88 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/GPU.cpp b/src/GPU.cpp index 8142e47..1799ef8 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -907,7 +907,7 @@ void StartScanline(u32 line) else { if (VCount == 192) - {//printf("- VBLANK -\n");vbltime=NDS::ARM9Timestamp; + { // VBlank DispStat[0] |= (1<<0); DispStat[1] |= (1<<0); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index f80eb85..e18f30e 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -656,8 +656,16 @@ void GPU2D::DrawScanline(u32 line) u32 dispmode = DispCnt >> 16; dispmode &= (Num ? 0x1 : 0x3); - if (Num == 0 && !Accelerated) - _3DLine = GPU3D::GetLine(n3dline); + if (Num == 0) + { + if (!Accelerated) + _3DLine = GPU3D::GetLine(n3dline); + else if ((CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) + { + _3DLine = GPU3D::GetLine(n3dline); + //GPU3D::GLRenderer43::PrepareCaptureFrame(); + } + } // always render regular graphics DrawScanline_Mode1(line); @@ -862,6 +870,12 @@ void GPU2D::VBlankEnd() BGMosaicYMax = BGMosaicSize[1]; OBJMosaicY = 0; OBJMosaicYMax = OBJMosaicSize[1]; + + // TODO: make optional + if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) + { + GPU3D::GLRenderer43::PrepareCaptureFrame(); + } } @@ -884,7 +898,7 @@ void GPU2D::DoCapture(u32 line, u32 width) srcA = _3DLine; else srcA = BGOBJLine; - +srcA = _3DLine; u16* srcB = NULL; u32 srcBaddr = line * 256; diff --git a/src/GPU3D.h b/src/GPU3D.h index 10c8966..708811f 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -153,6 +153,7 @@ int GetScale(); void VCount144(); void RenderFrame(); +void PrepareCaptureFrame(); u32* GetLine(int line); void SetupAccelFrame(); diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 062e40e..72956fb 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -100,9 +100,9 @@ int ScaleFactor; bool Accelerated; int ScreenW, ScreenH; -GLuint FramebufferTex[6]; +GLuint FramebufferTex[8]; int FrontBuffer; -GLuint FramebufferID[2], PixelbufferID; +GLuint FramebufferID[4], PixelbufferID; u32* Framebuffer = NULL; bool ChunkedRendering = false; @@ -260,10 +260,10 @@ bool Init() glVertexAttribIPointer(3, 3, GL_UNSIGNED_INT, 7*4, (void*)(4*4)); - glGenFramebuffers(2, &FramebufferID[0]); + glGenFramebuffers(4, &FramebufferID[0]); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); - glGenTextures(6, &FramebufferTex[0]); + glGenTextures(8, &FramebufferTex[0]); FrontBuffer = 0; // color buffers @@ -286,7 +286,12 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); + + glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // attribute buffer // R: opaque polyID (for edgemarking) @@ -297,16 +302,40 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); - // downscale framebuffer, for antialiased mode - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + // downscale framebuffer for antialiased mode + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[2], 0); + + // downscale framebuffer for display capture (always 256x192) + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[3]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[3], 0); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[1], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[6], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[7], 0); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); @@ -373,10 +402,13 @@ void SetDisplaySettings(int scale, bool accel) glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - if (accel) glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); - else glBufferData(GL_PIXEL_PACK_BUFFER, 256*192, NULL, GL_DYNAMIC_READ); + glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); if (Framebuffer) delete[] Framebuffer; if (accel) Framebuffer = new u32[256*192]; @@ -774,7 +806,8 @@ void RenderFrame() if (Accelerated) { - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[FrontBuffer], 0); + //glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[FrontBuffer], 0); + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); FrontBuffer = FrontBuffer ? 0 : 1; } @@ -856,18 +889,36 @@ void RenderFrame() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); } - if (!Accelerated) + /*if (!Accelerated) { glReadBuffer(GL_COLOR_ATTACHMENT0); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); glReadPixels(0, 0, 256<> 7; - if ((top.a & 0x40) != 0) + if ((top.a & 0xC0) == 0x40) { float xpos = top.r + fract(fTexcoord.x); float ypos = mod(fTexcoord.y, 768); @@ -96,7 +96,7 @@ void main() if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } else top = mid; } - else if ((mid.a & 0x40) != 0) + else if ((mid.a & 0xC0) == 0x40) { float xpos = mid.r + fract(fTexcoord.x); float ypos = mod(fTexcoord.y, 768); -- cgit v1.2.3 From f1a970ec30062328ae5bd4d30f118c175f051d5c Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 18 May 2019 01:21:46 +0200 Subject: actually finish display capture in hardware-accel mode --- src/GPU2D.cpp | 123 +++++++++++++++++++++++++++++++++++++++++++++++-- src/GPU2D.h | 2 +- src/GPU3D_OpenGL43.cpp | 1 - 3 files changed, 121 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index e18f30e..4a98248 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -668,7 +668,7 @@ void GPU2D::DrawScanline(u32 line) } // always render regular graphics - DrawScanline_Mode1(line); + DrawScanline_BGOBJ(line); switch (dispmode) { @@ -895,10 +895,127 @@ void GPU2D::DoCapture(u32 line, u32 width) u32* srcA; if (CaptureCnt & (1<<24)) + { srcA = _3DLine; + } else + { srcA = BGOBJLine; -srcA = _3DLine; + if (Accelerated) + { + // in accelerated mode, compositing is normally done on the GPU + // 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]; + + if ((val1 >> 30) == 1) + { + u32 _3dval = _3DLine[i]; + if ((_3dval >> 24) > 0) + { + val1 = _3dval | 0x40000000; + val2 = val3; + } + else + val1 = val3; + } + else if ((val3 >> 30) == 1) + { + u32 _3dval = _3DLine[i]; + 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; + } + else + { + eva = EVA; + evb = EVB; + } + } + else if ((flag1 & 0x40) && (BlendCnt & target2)) + { + // 3D layer blending + + BGOBJLine[i] = ColorBlend5(val1, val2); + continue; + } + else + { + if (flag1 & 0x80) flag1 = 0x10; + else if (flag1 & 0x40) flag1 = 0x01; + + if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + { + if ((bldcnteffect == 1) && (BlendCnt & target2)) + { + coloreffect = 1; + eva = EVA; + evb = EVB; + } + else if (bldcnteffect >= 2) + coloreffect = bldcnteffect; + else + coloreffect = 0; + } + 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; + + case 3: + BGOBJLine[i] = ColorBrightnessDown(val1, EVY); + break; + } + } + } + } + u16* srcB = NULL; u32 srcBaddr = line * 256; @@ -1261,7 +1378,7 @@ void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites) } } -void GPU2D::DrawScanline_Mode1(u32 line) +void GPU2D::DrawScanline_BGOBJ(u32 line) { u64 backdrop; if (Num) backdrop = *(u16*)&GPU::Palette[0x400]; diff --git a/src/GPU2D.h b/src/GPU2D.h index fc420a5..c19ddf7 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -132,7 +132,7 @@ private: template void DrawScanlineBGMode(u32 line, u32 nsprites); void DrawScanlineBGMode6(u32 line, u32 nsprites); - void DrawScanline_Mode1(u32 line); + void DrawScanline_BGOBJ(u32 line); static void DrawPixel_1x(u32* dst, u16 color, u32 flag); static void DrawPixel_2x(u32* dst, u16 color, u32 flag); diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 72956fb..71960ae 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -272,7 +272,6 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); -- cgit v1.2.3 From a752b1d7c2701da34d325ce1e439ee5935fd7fa3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 18 May 2019 01:32:31 +0200 Subject: woops --- src/GPU2D.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 4a98248..9ec240b 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -917,7 +917,7 @@ void GPU2D::DoCapture(u32 line, u32 width) if ((val1 >> 30) == 1) { - u32 _3dval = _3DLine[i]; + u32 _3dval = _3DLine[val1 & 0xFF]; if ((_3dval >> 24) > 0) { val1 = _3dval | 0x40000000; @@ -928,7 +928,7 @@ void GPU2D::DoCapture(u32 line, u32 width) } else if ((val3 >> 30) == 1) { - u32 _3dval = _3DLine[i]; + u32 _3dval = _3DLine[val3 & 0xFF]; if ((_3dval >> 24) > 0) val2 = _3dval | 0x40000000; } -- cgit v1.2.3 From f5a7cb71fd17d5eb97ce3325892a2c769258c8ce Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 18 May 2019 01:42:50 +0200 Subject: also, do master brightness --- src/GPU.cpp | 4 ++-- src/GPU2D.cpp | 3 ++- src/libui_sdl/main.cpp | 4 ++-- src/libui_sdl/main_shaders.h | 24 +++++++++++++++++++++++- 4 files changed, 29 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/GPU.cpp b/src/GPU.cpp index 1799ef8..23e4fa8 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -254,7 +254,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[0] = accel ? 0 : topscale; int fbsize; - if (accel) fbsize = (256*3 + 1) * 192; + if (accel) fbsize = (256*3 + 2) * 192; else fbsize = (256 * 192) << (FBScale[0] * 2); if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; @@ -283,7 +283,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[1] = accel ? 0 : bottomscale; int fbsize; - if (accel) fbsize = (256*3 + 1) * 192; + if (accel) fbsize = (256*3 + 2) * 192; else fbsize = (256 * 192) << (FBScale[1] * 2); if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 9ec240b..88436db 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -626,7 +626,7 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - int stride = Accelerated ? (256*3 + 1) : LineStride; + int stride = Accelerated ? (256*3 + 2) : LineStride; u32* dst = &Framebuffer[stride * line]; int n3dline = line; @@ -804,6 +804,7 @@ void GPU2D::DrawScanline(u32 line) ctl |= (EVY << 26); dst[256*3] = ctl; + dst[256*3 + 1] = MasterBrightness; return; } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index f4a1fdb..27f0369 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -367,9 +367,9 @@ void GLDrawing_DrawScreen() GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256<> 6) & 0x3; if (dispmode == 1) @@ -182,6 +183,27 @@ ivec4 zog=pixel; } } + if (dispmode != 0) + { + int brightmode = mbright.g >> 6; + if (brightmode == 1) + { + // up + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; + } + else if (brightmode == 2) + { + // down + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel -= (pixel * evy) >> 4; + } + } + pixel.rgb <<= 2; pixel.rgb |= (pixel.rgb >> 6); -- cgit v1.2.3 From 5448969ca1b8687b0c95b4d621b73c7cef50106a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 18 May 2019 02:16:07 +0200 Subject: 'fix' shadows --- src/GPU3D_OpenGL43.cpp | 70 +++++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 71960ae..234ee1b 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -149,6 +149,15 @@ 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() { if (!InitGLExtensions()) return false; @@ -267,80 +276,46 @@ bool Init() FrontBuffer = 0; // color buffers - glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + SetupDefaultTexParams(FramebufferTex[0]); + SetupDefaultTexParams(FramebufferTex[1]); // depth/stencil buffer - glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + 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 - glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + SetupDefaultTexParams(FramebufferTex[5]); + SetupDefaultTexParams(FramebufferTex[7]); // downscale framebuffer for antialiased mode glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + SetupDefaultTexParams(FramebufferTex[2]); // downscale framebuffer for display capture (always 256x192) glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[3]); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + 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]); - GLenum fbassign[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; - glDrawBuffers(2, fbassign); - glEnable(GL_BLEND); glBlendFuncSeparatei(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); glBlendEquationSeparatei(0, GL_ADD, GL_MAX); @@ -802,6 +777,8 @@ void RenderFrame() 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); if (Accelerated) { @@ -817,7 +794,6 @@ void RenderFrame() { glUseProgram(ClearShaderPlain[2]); glDepthFunc(GL_ALWAYS); - glDepthMask(GL_TRUE); u32 r = RenderClearAttr1 & 0x1F; u32 g = (RenderClearAttr1 >> 5) & 0x1F; -- cgit v1.2.3 From 61c1ebe01cc4c684a3ce71bfd16d02385473a943 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 18 May 2019 02:34:14 +0200 Subject: finally fix shadows, mostly --- src/GPU3D_OpenGL43.cpp | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 234ee1b..c414f92 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -647,15 +647,31 @@ if (PolygonList[NumOpaqueFinalPolys].PolyData->IsShadow) printf("!! GLORG!!! %08 lastwasshadow = true; }*/ - glDisable(GL_BLEND); - UseRenderShader(flags | RenderFlag_ShadowMask); + // clear 'stencil buffer' + glUseProgram(ClearShaderPlain[2]); + glDisable(GL_BLEND); glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glColorMaski(1, GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE); glDepthMask(GL_FALSE); + + glDepthFunc(GL_ALWAYS); + glStencilFunc(GL_ALWAYS, 0, 0); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID); + glBindVertexArray(ClearVertexArrayID); + glDrawArrays(GL_TRIANGLES, 0, 2*3); + + // draw actual shadow mask + + UseRenderShader(flags | RenderFlag_ShadowMask); + glDepthFunc(GL_GEQUAL); - glStencilFunc(GL_ALWAYS,0,0); - glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); + + glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); + glBindVertexArray(VertexArrayID); + lastwasshadow=true; darp = false; @@ -773,20 +789,23 @@ void RenderFrame() glViewport(0, 0, ScreenW, ScreenH); - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); - 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); - if (Accelerated) { //glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[FrontBuffer], 0); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[FrontBuffer ? 7 : 5]); + 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 -- cgit v1.2.3 From cd8236303ec178a25f07408c892ed5f941fe3273 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 19 May 2019 19:37:13 +0200 Subject: begin botching the code BAHAHAHAAAA --- src/GPU2D.cpp | 247 ++++++++++------------------------------------------------ src/GPU2D.h | 8 +- 2 files changed, 42 insertions(+), 213 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 88436db..e810275 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -217,16 +217,10 @@ void GPU2D::SetFramebuffer(u32* buf) void GPU2D::SetDisplaySettings(int scale, bool accel) { - if (accel) scale = 0; Accelerated = accel; - LineScale = scale; - LineStride = 256 << (scale*2); - - if (Accelerated) DrawPixel = DrawPixel_Accel; - else if (scale == 1) DrawPixel = DrawPixel_2x; - else if (scale == 2) DrawPixel = DrawPixel_4x; - else DrawPixel = DrawPixel_1x; + if (Accelerated) DrawPixel = DrawPixel_Accel; + else DrawPixel = DrawPixel_Normal; } @@ -626,7 +620,7 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - int stride = Accelerated ? (256*3 + 2) : LineStride; + int stride = Accelerated ? (256*3 + 2) : 256; u32* dst = &Framebuffer[stride * line]; int n3dline = line; @@ -648,8 +642,14 @@ void GPU2D::DrawScanline(u32 line) if (forceblank) { - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) dst[i] = 0xFFFFFFFF; + + if (Accelerated) + { + dst[256*3] = 0; + dst[256*3 + 1] = 0; + } return; } @@ -674,7 +674,7 @@ void GPU2D::DrawScanline(u32 line) { case 0: // screen off { - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) dst[i] = 0x003F3F3F; } break; @@ -701,37 +701,12 @@ void GPU2D::DrawScanline(u32 line) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - int d = i << LineScale; - dst[d] = r | (g << 8) | (b << 16); - if (LineScale == 1) - { - dst[d+1] = dst[d]; - dst[d+512] = dst[d]; - dst[d+513] = dst[d]; - } - else if (LineScale == 2) - { - dst[d+1] = dst[d]; - dst[d+2] = dst[d]; - dst[d+3] = dst[d]; - dst[d+1024] = dst[d]; - dst[d+1024+1] = dst[d]; - dst[d+1024+2] = dst[d]; - dst[d+1024+3] = dst[d]; - dst[d+2048] = dst[d]; - dst[d+2048+1] = dst[d]; - dst[d+2048+2] = dst[d]; - dst[d+2048+3] = dst[d]; - dst[d+3072] = dst[d]; - dst[d+3072+1] = dst[d]; - dst[d+3072+2] = dst[d]; - dst[d+3072+3] = dst[d]; - } + dst[i] = r | (g << 8) | (b << 16); } } else { - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) { dst[i] = 0; } @@ -748,32 +723,7 @@ void GPU2D::DrawScanline(u32 line) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - int d = i << LineScale; - dst[d] = r | (g << 8) | (b << 16); - if (LineScale == 1) - { - dst[d+1] = dst[d]; - dst[d+512] = dst[d]; - dst[d+513] = dst[d]; - } - else if (LineScale == 2) - { - dst[d+1] = dst[d]; - dst[d+2] = dst[d]; - dst[d+3] = dst[d]; - dst[d+1024] = dst[d]; - dst[d+1024+1] = dst[d]; - dst[d+1024+2] = dst[d]; - dst[d+1024+3] = dst[d]; - dst[d+2048] = dst[d]; - dst[d+2048+1] = dst[d]; - dst[d+2048+2] = dst[d]; - dst[d+2048+3] = dst[d]; - dst[d+3072] = dst[d]; - dst[d+3072+1] = dst[d]; - dst[d+3072+2] = dst[d]; - dst[d+3072+3] = dst[d]; - } + dst[i] = r | (g << 8) | (b << 16); } } break; @@ -817,7 +767,7 @@ void GPU2D::DrawScanline(u32 line) u32 factor = MasterBrightness & 0x1F; if (factor > 16) factor = 16; - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) { dst[i] = ColorBrightnessUp(dst[i], factor); } @@ -828,7 +778,7 @@ void GPU2D::DrawScanline(u32 line) u32 factor = MasterBrightness & 0x1F; if (factor > 16) factor = 16; - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) { dst[i] = ColorBrightnessDown(dst[i], factor); } @@ -838,7 +788,7 @@ void GPU2D::DrawScanline(u32 line) // convert to 32-bit BGRA // note: 32-bit RGBA would be more straightforward, but // BGRA seems to be more compatible (Direct2D soft, cairo...) - for (int i = 0; i < LineStride; i+=2) + for (int i = 0; i < 256; i+=2) { u64 c = *(u64*)&dst[i]; @@ -1044,7 +994,7 @@ void GPU2D::DoCapture(u32 line, u32 width) { for (u32 i = 0; i < width; i++) { - u32 val = srcA[i << LineScale]; + u32 val = srcA[i]; // TODO: check what happens when alpha=0 @@ -1095,7 +1045,7 @@ void GPU2D::DoCapture(u32 line, u32 width) { for (u32 i = 0; i < width; i++) { - u32 val = srcA[i << LineScale]; + u32 val = srcA[i]; // TODO: check what happens when alpha=0 @@ -1129,7 +1079,7 @@ void GPU2D::DoCapture(u32 line, u32 width) { for (u32 i = 0; i < width; i++) { - u32 val = srcA[i << LineScale]; + u32 val = srcA[i]; // TODO: check what happens when alpha=0 @@ -1393,7 +1343,7 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) backdrop = r | (g << 8) | (b << 16) | 0x20000000; backdrop |= (backdrop << 32); - for (int i = 0; i < LineStride; i+=2) + for (int i = 0; i < 256; i+=2) *(u64*)&BGOBJLine[i] = backdrop; } @@ -1426,12 +1376,10 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) { u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) { - int j = (i >> LineScale) & 0xFF; - u32 val1 = BGOBJLine[i]; - u32 val2 = BGOBJLine[4096+i]; + u32 val2 = BGOBJLine[256+i]; u32 coloreffect, eva, evb; @@ -1472,7 +1420,7 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) if (flag1 & 0x80) flag1 = 0x10; else if (flag1 & 0x40) flag1 = 0x01; - if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) + if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) { if ((bldcnteffect == 1) && (BlendCnt & target2)) { @@ -1535,60 +1483,16 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) } -void GPU2D::DrawPixel_1x(u32* dst, u16 color, u32 flag) +void GPU2D::DrawPixel_Normal(u32* dst, u16 color, u32 flag) { u8 r = (color & 0x001F) << 1; u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - *(dst+4096) = *dst; + *(dst+256) = *dst; *dst = r | (g << 8) | (b << 16) | flag; } -void GPU2D::DrawPixel_2x(u32* dst, u16 color, u32 flag) -{ - u8 r = (color & 0x001F) << 1; - u8 g = (color & 0x03E0) >> 4; - u8 b = (color & 0x7C00) >> 9; - - u64 val = r | (g << 8) | (b << 16) | flag; - val |= (val << 32); - - *(u64*)(dst+4096) = *(u64*)dst; - *(u64*)(dst+4096+512) = *(u64*)(dst+512); - - *(u64*)dst = val; - *(u64*)(dst+512) = val; -} - -void GPU2D::DrawPixel_4x(u32* dst, u16 color, u32 flag) -{ - u8 r = (color & 0x001F) << 1; - u8 g = (color & 0x03E0) >> 4; - u8 b = (color & 0x7C00) >> 9; - - u64 val = r | (g << 8) | (b << 16) | flag; - val |= (val << 32); - - *(u64*)(dst+4096) = *(u64*)dst; - *(u64*)(dst+4096+2) = *(u64*)(dst+2); - *(u64*)(dst+4096+1024) = *(u64*)(dst+1024); - *(u64*)(dst+4096+1024+2) = *(u64*)(dst+1024+2); - *(u64*)(dst+4096+2048) = *(u64*)(dst+2048); - *(u64*)(dst+4096+2048+2) = *(u64*)(dst+2048+2); - *(u64*)(dst+4096+3072) = *(u64*)(dst+3072); - *(u64*)(dst+4096+3072+2) = *(u64*)(dst+3072+2); - - *(u64*)dst = val; - *(u64*)(dst+2) = val; - *(u64*)(dst+1024) = val; - *(u64*)(dst+1024+2) = val; - *(u64*)(dst+2048) = val; - *(u64*)(dst+2048+2) = val; - *(u64*)(dst+3072) = val; - *(u64*)(dst+3072+2) = val; -} - void GPU2D::DrawPixel_Accel(u32* dst, u16 color, u32 flag) { u8 r = (color & 0x001F) << 1; @@ -1629,77 +1533,6 @@ void GPU2D::DrawBG_3D() BGOBJLine[i] = 0x40000000 | pos; // 3D-layer placeholder } } - else if (LineScale == 1) - { - for (; i < iend; i++) - { - int is = i << 1; - int xs = xoff << 1; - u32 c; - - xoff++; - if (!(WindowMask[i] & 0x01)) continue; - - c = _3DLine[xs]; - if ((c >> 24) != 0) - { - BGOBJLine[is+4096] = BGOBJLine[is]; - BGOBJLine[is] = c | 0x40000000; - } - - c = _3DLine[xs+1]; is++; - if ((c >> 24) != 0) - { - BGOBJLine[is+4096] = BGOBJLine[is]; - BGOBJLine[is] = c | 0x40000000; - } - - c = _3DLine[xs+512]; is += 511; - if ((c >> 24) != 0) - { - BGOBJLine[is+4096] = BGOBJLine[is]; - BGOBJLine[is] = c | 0x40000000; - } - - c = _3DLine[xs+513]; is++; - if ((c >> 24) != 0) - { - BGOBJLine[is+4096] = BGOBJLine[is]; - BGOBJLine[is] = c | 0x40000000; - } - } - } - else if (LineScale == 2) - { - for (; i < iend; i++) - { - int is = i << 2; - int xs = xoff << 2; - u32 c; - - xoff++; - if (!(WindowMask[i] & 0x01)) continue; - - for (int by = 0; by < 4; by++) - { - for (int bx = 0; bx < 4; bx++) - { - c = _3DLine[xs]; - if ((c >> 24) != 0) - { - BGOBJLine[is+4096] = BGOBJLine[is]; - BGOBJLine[is] = c | 0x40000000; - } - - is++; - xs++; - } - - is += 1020; - xs += 1020; - } - } - } else { for (; i < iend; i++) @@ -1710,7 +1543,7 @@ void GPU2D::DrawBG_3D() if ((c >> 24) == 0) continue; if (!(WindowMask[i] & 0x01)) continue; - BGOBJLine[i+4096] = BGOBJLine[i]; + BGOBJLine[i+256] = BGOBJLine[i]; BGOBJLine[i] = c | 0x40000000; } } @@ -1814,7 +1647,7 @@ void GPU2D::DrawBG_Text(u32 line, u32 bgnum) xmos--; if (color) - DrawPixel(&BGOBJLine[i< 0) { if (color) - DrawPixel(&BGOBJLine[i<(tilesetaddr + (curtile << 6) + (tileyoff << 3) + tilexoff); if (color) - DrawPixel(&BGOBJLine[i< 0) { if (color & 0x8000) - DrawPixel(&BGOBJLine[i<(tilemapaddr + (((((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)) << 1)); if (color & 0x8000) - DrawPixel(&BGOBJLine[i< 0) { if (color) - DrawPixel(&BGOBJLine[i<(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)); if (color) - DrawPixel(&BGOBJLine[i< 0) { if (color) - DrawPixel(&BGOBJLine[i<(tilesetaddr + ((curtile & 0x03FF) << 6) + (tileyoff << 3) + tilexoff); if (color) - DrawPixel(&BGOBJLine[i< 0) { if (color) - DrawPixel(&BGOBJLine[i<(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)); if (color) - DrawPixel(&BGOBJLine[i< Date: Sun, 19 May 2019 19:47:23 +0200 Subject: botch more code --- src/GPU.cpp | 68 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 32 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/GPU.cpp b/src/GPU.cpp index 23e4fa8..8b94c94 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -73,7 +73,7 @@ u32 VRAMMap_ARM7[2]; int FrontBuffer; u32* Framebuffer[2][2]; -int FBScale[2]; +int ScreenScale[2]; bool Accelerated; GPU2D* GPU2D_A; @@ -89,7 +89,7 @@ bool Init() FrontBuffer = 0; Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL; Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL; - FBScale[0] = -1; FBScale[1] = -1; Accelerated = false; + ScreenScale[0] = -1; ScreenScale[1] = -1; Accelerated = false; SetDisplaySettings(0, 0, false); return true; @@ -152,12 +152,12 @@ void Reset() VRAMMap_ARM7[0] = 0; VRAMMap_ARM7[1] = 0; - for (int i = 0; i < (256*192)<<(FBScale[0]*2); i++) + for (int i = 0; i < (256*192); i++) { Framebuffer[0][0][i] = 0xFFFFFFFF; Framebuffer[1][0][i] = 0xFFFFFFFF; } - for (int i = 0; i < (256*192)<<(FBScale[1]*2); i++) + for (int i = 0; i < (256*192); i++) { Framebuffer[0][1][i] = 0xFFFFFFFF; Framebuffer[1][1][i] = 0xFFFFFFFF; @@ -174,10 +174,10 @@ void Reset() void Stop() { - memset(Framebuffer[0][0], 0, (256*192)<<(FBScale[0]*2)); - memset(Framebuffer[0][1], 0, (256*192)<<(FBScale[1]*2)); - memset(Framebuffer[1][0], 0, (256*192)<<(FBScale[0]*2)); - memset(Framebuffer[1][1], 0, (256*192)<<(FBScale[1]*2)); + memset(Framebuffer[0][0], 0, 256*192); + memset(Framebuffer[0][1], 0, 256*192); + memset(Framebuffer[1][0], 0, 256*192); + memset(Framebuffer[1][1], 0, 256*192); } void DoSavestate(Savestate* file) @@ -249,61 +249,57 @@ void AssignFramebuffers() void SetDisplaySettings(int topscale, int bottomscale, bool accel) {accel=true; - if (topscale != FBScale[0] || accel != Accelerated) + if (accel != Accelerated) { - FBScale[0] = accel ? 0 : topscale; + ScreenScale[0] = accel ? 0 : topscale; int fbsize; if (accel) fbsize = (256*3 + 2) * 192; - else fbsize = (256 * 192) << (FBScale[0] * 2); + else fbsize = 256 * 192; if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; + if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; + if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; Framebuffer[0][0] = new u32[fbsize]; Framebuffer[1][0] = new u32[fbsize]; + Framebuffer[0][1] = new u32[fbsize]; + Framebuffer[1][1] = new u32[fbsize]; memset(Framebuffer[0][0], 0, fbsize*4); memset(Framebuffer[1][0], 0, fbsize*4); + memset(Framebuffer[0][1], 0, fbsize*4); + memset(Framebuffer[1][1], 0, fbsize*4); + + AssignFramebuffers(); + } + + if (topscale != ScreenScale[0]) + { + ScreenScale[0] = topscale; - int backbuf = FrontBuffer ? 0 : 1; if (NDS::PowerControl9 & (1<<15)) { - GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_A->SetDisplaySettings(FBScale[0], accel); - GPU3D::SetDisplaySettings(topscale, accel); + GPU2D_A->SetDisplaySettings(ScreenScale[0], accel); + GPU3D::SetDisplaySettings(ScreenScale[0], accel); } else { - GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_B->SetDisplaySettings(FBScale[0], accel); + GPU2D_B->SetDisplaySettings(ScreenScale[0], accel); } } - if (bottomscale != FBScale[1] || accel != Accelerated) + if (bottomscale != ScreenScale[1] || accel != Accelerated) { - FBScale[1] = accel ? 0 : bottomscale; - - int fbsize; - if (accel) fbsize = (256*3 + 2) * 192; - else fbsize = (256 * 192) << (FBScale[1] * 2); - if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; - if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; - Framebuffer[0][1] = new u32[fbsize]; - Framebuffer[1][1] = new u32[fbsize]; - - memset(Framebuffer[0][1], 0, fbsize*4); - memset(Framebuffer[1][1], 0, fbsize*4); + ScreenScale[1] = bottomscale; - int backbuf = FrontBuffer ? 0 : 1; if (NDS::PowerControl9 & (1<<15)) { - GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_B->SetDisplaySettings(FBScale[1], accel); + GPU2D_B->SetDisplaySettings(ScreenScale[1], accel); } else { - GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_A->SetDisplaySettings(FBScale[1], accel); - GPU3D::SetDisplaySettings(bottomscale, accel); + GPU2D_A->SetDisplaySettings(ScreenScale[1], accel); + GPU3D::SetDisplaySettings(ScreenScale[1], accel); } } -- cgit v1.2.3 From 6dbb645ffa84666a83cc3d77cd5cd9ca298bc7f7 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 19 May 2019 22:08:30 +0200 Subject: make shadows work without relying on black magic. clean up the code some. --- src/GPU3D_OpenGL43.cpp | 187 ++++++++++++++++++++++--------------------- src/GPU3D_OpenGL43_shaders.h | 41 ---------- 2 files changed, 96 insertions(+), 132 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index c414f92..66e9d53 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -40,7 +40,6 @@ enum RenderFlag_WBuffer = 0x01, RenderFlag_Trans = 0x02, RenderFlag_ShadowMask = 0x04, - RenderFlag_Shadow = 0x08, }; @@ -212,10 +211,6 @@ bool Init() kRenderVS_Z, kRenderFS_ZSM)) return false; if (!BuildRenderShader(RenderFlag_ShadowMask | RenderFlag_WBuffer, kRenderVS_W, kRenderFS_WSM)) return false; - if (!BuildRenderShader(RenderFlag_Shadow, - kRenderVS_Z, kRenderFS_ZS)) return false; - if (!BuildRenderShader(RenderFlag_Shadow | RenderFlag_WBuffer, - kRenderVS_W, kRenderFS_WS)) return false; memset(&ShaderConfig, 0, sizeof(ShaderConfig)); @@ -341,9 +336,6 @@ bool Init() 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); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); // opaque polyID / shadow bits - return true; } @@ -428,6 +420,7 @@ void SetupPolygon(RendererPolygon* rp, Polygon* polygon) { if ((polygon->Attr & 0x001F0000) == 0) rp->RenderKey |= 0x2; + rp->RenderKey |= (polygon->Attr & 0x3F000000) >> 16; // polygon ID } } else @@ -521,6 +514,9 @@ 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); - u16* iptr; - u32 curkey; - bool lastwasshadow;bool darp; -//printf("morp %08X\n", RenderClearAttr1); 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 + + 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) @@ -583,9 +605,9 @@ if (PolygonList[NumOpaqueFinalPolys].PolyData->IsShadow) printf("!! GLORG!!! %08 u32 polyattr = rp->PolyData->Attr; u32 polyid = (polyattr >> 24) & 0x3F; - glStencilFunc(GL_EQUAL, 0, 0xFF); + glStencilFunc(GL_EQUAL, 0xFF, 0xFF); glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); - glStencilMask(0x40|polyid); // heheh + glStencilMask(~(0x40|polyid)); // heheh if (polyattr & (1<<11)) glDepthMask(GL_TRUE); else glDepthMask(GL_FALSE); @@ -606,12 +628,10 @@ if (PolygonList[NumOpaqueFinalPolys].PolyData->IsShadow) printf("!! GLORG!!! %08 iptr = PolygonList[NumOpaqueFinalPolys].Indices; curkey = 0xFFFFFFFF; - lastwasshadow = false; darp = false; for (int i = NumOpaqueFinalPolys; i < NumFinalPolys; i++) { RendererPolygon* rp = &PolygonList[i]; - //printf("PASS 3 POLYGON %i: ATTR %08X (%d) | KEY %08X\n", i, rp->PolyData->Attr, (rp->PolyData->Attr>>4)&0x3, rp->RenderKey); if (rp->RenderKey != curkey) { u16* endptr = rp->Indices; @@ -625,90 +645,83 @@ if (PolygonList[NumOpaqueFinalPolys].PolyData->IsShadow) printf("!! GLORG!!! %08 if (rp->PolyData->IsShadowMask) { - //printf("beginning shadowmask batch: %d, %d\n", lastwasshadow, darp); - /*if (!lastwasshadow) - { - //glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); - - glDisable(GL_BLEND); - UseRenderShader(flags | RenderFlag_ShadowMask); + // clear shadow bits in stencil buffer - // shadow bits are set where the depth test fails - // sure enough, if GL_LESS fails, the opposite function would pass - glDepthFunc(GL_GEQUAL); + glStencilMask(0x80); + glClear(GL_STENCIL_BUFFER_BIT); - //glStencilFunc(GL_ALWAYS, 0x80, 0x80); - //glStencilOp(GL_REPLACE, GL_REPLACE, GL_KEEP); - - glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glColorMaski(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); - glDepthMask(GL_FALSE); - - lastwasshadow = true; - }*/ + // draw actual shadow mask - // clear 'stencil buffer' - glUseProgram(ClearShaderPlain[2]); + UseRenderShader(flags | RenderFlag_ShadowMask); glDisable(GL_BLEND); glColorMaski(0, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glColorMaski(1, GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE); + glColorMaski(1, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthMask(GL_FALSE); - glDepthFunc(GL_ALWAYS); - glStencilFunc(GL_ALWAYS, 0, 0); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - - glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID); - glBindVertexArray(ClearVertexArrayID); - glDrawArrays(GL_TRIANGLES, 0, 2*3); - - // draw actual shadow mask - - UseRenderShader(flags | RenderFlag_ShadowMask); - - glDepthFunc(GL_GEQUAL); + glDepthFunc(GL_LESS); + glStencilFunc(GL_ALWAYS, 0x80, 0x80); + glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); glBindVertexArray(VertexArrayID); - - lastwasshadow=true; - - darp = false; } else { - if (rp->PolyData->IsShadow) glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); - //if (rp->PolyData->IsShadow) printf("beginning shadow batch: %d, %d\n", lastwasshadow, darp); + UseRenderShader(flags | RenderFlag_Trans); - if (rp->PolyData->IsShadow) - UseRenderShader(flags | RenderFlag_Shadow); - else - UseRenderShader(flags | RenderFlag_Trans); + u32 polyattr = rp->PolyData->Attr; + u32 polyid = (polyattr >> 24) & 0x3F; - if (lastwasshadow) + // zorp + glDepthFunc(GL_LESS); + + if (rp->PolyData->IsShadow) { - glEnable(GL_BLEND); + 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; + } + } + 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); - lastwasshadow = 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); - // zorp - glDepthFunc(GL_LESS); - - u32 polyattr = rp->PolyData->Attr; - u32 polyid = (polyattr >> 24) & 0x3F; - - glStencilFunc(GL_NOTEQUAL, 0x40|polyid, 0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + 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); - - darp = rp->PolyData->IsShadow; } } } @@ -789,16 +802,8 @@ void RenderFrame() glViewport(0, 0, ScreenW, ScreenH); - if (Accelerated) - { - //glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[FrontBuffer], 0); - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); - - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[FrontBuffer ? 7 : 5]); - - FrontBuffer = FrontBuffer ? 0 : 1; - } + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); + FrontBuffer = FrontBuffer ? 0 : 1; glDisable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -822,7 +827,7 @@ void RenderFrame() u32 polyid = (RenderClearAttr1 >> 24) & 0x3F; u32 z = ((RenderClearAttr2 & 0x7FFF) * 0x200) + 0x1FF; - glStencilFunc(GL_ALWAYS, 0, 0xFF); + glStencilFunc(GL_ALWAYS, 0xFF, 0xFF); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); /*if (r) r = r*2 + 1; diff --git a/src/GPU3D_OpenGL43_shaders.h b/src/GPU3D_OpenGL43_shaders.h index 8a69566..197f21f 100644 --- a/src/GPU3D_OpenGL43_shaders.h +++ b/src/GPU3D_OpenGL43_shaders.h @@ -601,45 +601,4 @@ void main() } )"; -const char* kRenderFS_ZS = R"( - -layout(binding=2) uniform usampler2D iAttrTex; -//layout(origin_upper_left) in vec4 gl_FragCoord; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.b != 1) discard; - if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; - - oColor = col; -} -)"; - -const char* kRenderFS_WS = R"( - -layout(binding=2) uniform usampler2D iAttrTex; -//layout(origin_upper_left) in vec4 gl_FragCoord; - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.b != 1) discard; - if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; - - oColor = col; - gl_FragDepth = fZ; -} -)"; - #endif // GPU3D_OPENGL43_SHADERS_H -- cgit v1.2.3 From 1fb396804756eba6f87ea2112c73868d6d651ea8 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 19 May 2019 23:06:42 +0200 Subject: properly clean up GL resources --- src/GPU3D_OpenGL43.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 66e9d53..af94432 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -104,16 +104,8 @@ int FrontBuffer; GLuint FramebufferID[4], PixelbufferID; u32* Framebuffer = NULL; -bool ChunkedRendering = false; -bool InitGLExtensions() -{ - // TODO move this elsewhere!! - //if (!OpenGL_Init()) return false; - return true; -} - bool BuildRenderShader(u32 flags, const char* vs, const char* fs) { char shadername[32]; @@ -159,8 +151,6 @@ void SetupDefaultTexParams(GLuint tex) bool Init() { - if (!InitGLExtensions()) 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); @@ -341,7 +331,24 @@ bool Init() void DeInit() { - // TODO CLEAN UP SHIT!!!! + 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() @@ -696,6 +703,8 @@ void RenderSceneChunk(int y, int h) _endptr = rp->Indices; break; } + + // berg. } u32 num = (u32)(_endptr - iptr); if (num) glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, iptr); -- cgit v1.2.3 From a4417b727a6716f821ff12b7a40a0d696da0da47 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 19 May 2019 23:59:43 +0200 Subject: lower GL requirement of renderer itself to 3.1 --- src/GPU3D_OpenGL43.cpp | 48 +++++++++---- src/GPU3D_OpenGL43_shaders.h | 158 +++++++++++++++++++++---------------------- 2 files changed, 113 insertions(+), 93 deletions(-) (limited to 'src') diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index af94432..f6e6312 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -29,10 +29,8 @@ namespace GLRenderer43 { // GL version requirements -// * explicit uniform location: 4.3 (or extension) // * texelFetch: 3.0 (GLSL 1.30) (3.2/1.50 for MS) // * UBO: 3.1 -// * glMemoryBarrier: 4.2 enum @@ -71,6 +69,7 @@ RendererPolygon PolygonList[2048]; int NumFinalPolys, NumOpaqueFinalPolys; GLuint ClearVertexBufferID, ClearVertexArrayID; +GLint ClearUniformLoc[4]; // vertex buffer // * XYZW: 4x16bit @@ -132,7 +131,28 @@ bool BuildRenderShader(u32 flags, const char* vs, const char* fs) delete[] vsbuf; delete[] fsbuf; - return ret; + 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) @@ -187,6 +207,14 @@ bool Init() 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, @@ -210,12 +238,6 @@ bool Init() glBufferData(GL_UNIFORM_BUFFER, sizeof(ShaderConfig), &ShaderConfig, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, 0, ShaderConfigUBO); - for (int i = 0; i < 16; i++) - { - if (!RenderShader[i][2]) continue; - glUniformBlockBinding(RenderShader[i][2], 0, 0); - } - float clearvtx[6*2] = { @@ -843,10 +865,10 @@ void RenderFrame() if (g) g = g*2 + 1; if (b) b = b*2 + 1;*/ - glUniform4ui(0, r, g, b, a); - glUniform1ui(1, z); - glUniform1ui(2, polyid); - glUniform1ui(3, fog); + 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); diff --git a/src/GPU3D_OpenGL43_shaders.h b/src/GPU3D_OpenGL43_shaders.h index 197f21f..5be7060 100644 --- a/src/GPU3D_OpenGL43_shaders.h +++ b/src/GPU3D_OpenGL43_shaders.h @@ -19,14 +19,14 @@ #ifndef GPU3D_OPENGL43_SHADERS_H #define GPU3D_OPENGL43_SHADERS_H -#define kShaderHeader "#version 430" +#define kShaderHeader "#version 140" const char* kClearVS = kShaderHeader R"( -layout(location=0) in vec2 vPosition; +in vec2 vPosition; -layout(location=1) uniform uint uDepth; +uniform uint uDepth; void main() { @@ -37,62 +37,62 @@ void main() const char* kClearFS = kShaderHeader R"( -layout(location=0) uniform uvec4 uColor; -layout(location=2) uniform uint uOpaquePolyID; -layout(location=3) uniform uint uFogFlag; +uniform uvec4 uColor; +uniform uint uOpaquePolyID; +uniform uint uFogFlag; -layout(location=0) out vec4 oColor; -layout(location=1) out uvec3 oAttr; +out vec4 oColor; +out uvec3 oAttr; void main() { oColor = vec4(uColor).bgra / 31.0; - oAttr.r = 0; + oAttr.r = uint(0); oAttr.g = uOpaquePolyID; - oAttr.b = 0; + oAttr.b = uint(0); } )"; const char* kRenderVSCommon = R"( -layout(std140, binding=0) uniform uConfig +layout(std140) uniform uConfig { vec2 uScreenSize; - uint uDispCnt; + int uDispCnt; vec4 uToonColors[32]; }; -layout(location=0) in uvec4 vPosition; -layout(location=1) in uvec4 vColor; -layout(location=2) in ivec2 vTexcoord; -layout(location=3) in uvec3 vPolygonAttr; +in uvec4 vPosition; +in uvec4 vColor; +in ivec2 vTexcoord; +in ivec3 vPolygonAttr; smooth out vec4 fColor; smooth out vec2 fTexcoord; -flat out uvec3 fPolygonAttr; +flat out ivec3 fPolygonAttr; )"; const char* kRenderFSCommon = R"( -layout(binding=0) uniform usampler2D TexMem; -layout(binding=1) uniform sampler2D TexPalMem; +uniform usampler2D TexMem; +uniform sampler2D TexPalMem; -layout(std140, binding=0) uniform uConfig +layout(std140) uniform uConfig { vec2 uScreenSize; - uint uDispCnt; + int uDispCnt; vec4 uToonColors[32]; }; smooth in vec4 fColor; smooth in vec2 fTexcoord; -flat in uvec3 fPolygonAttr; +flat in ivec3 fPolygonAttr; -layout(location=0) out vec4 oColor; -layout(location=1) out uvec3 oAttr; +out vec4 oColor; +out uvec3 oAttr; -int TexcoordWrap(int c, int maxc, uint mode) +int TexcoordWrap(int c, int maxc, int mode) { if ((mode & (1<<0)) != 0) { @@ -105,90 +105,90 @@ int TexcoordWrap(int c, int maxc, uint mode) return clamp(c, 0, maxc-1); } -vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode) +vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, int wrapmode) { st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); pixel.a = (pixel.r & 0xE0); pixel.a = (pixel.a >> 3) + (pixel.a >> 6); pixel.r &= 0x1F; - addr.y = (addr.y << 3) + int(pixel.r); + addr.y = (addr.y << 3) + pixel.r; vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); return vec4(color.rgb, float(pixel.a)/31.0); } -vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +vec4 TextureFetch_I2(ivec2 addr, ivec4 st, int wrapmode, float alpha0) { st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); addr.x += ((st.y * st.z) + st.x) >> 2; - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); pixel.r >>= (2 * (st.x & 3)); pixel.r &= 0x03; - addr.y = (addr.y << 2) + int(pixel.r); + addr.y = (addr.y << 2) + pixel.r; vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); + return vec4(color.rgb, (pixel.r>0)?1:alpha0); } -vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +vec4 TextureFetch_I4(ivec2 addr, ivec4 st, int wrapmode, float alpha0) { st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); addr.x += ((st.y * st.z) + st.x) >> 1; - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); if ((st.x & 1) != 0) pixel.r >>= 4; else pixel.r &= 0x0F; - addr.y = (addr.y << 3) + int(pixel.r); + addr.y = (addr.y << 3) + pixel.r; vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); + return vec4(color.rgb, (pixel.r>0)?1:alpha0); } -vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +vec4 TextureFetch_I8(ivec2 addr, ivec4 st, int wrapmode, float alpha0) { st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); - addr.y = (addr.y << 3) + int(pixel.r); + addr.y = (addr.y << 3) + pixel.r; vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); + return vec4(color.rgb, (pixel.r>0)?1:alpha0); } -vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) +vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, int wrapmode) { st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); - uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; + ivec4 p = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); + int val = (p.r >> (2 * (st.x & 0x3))) & 0x3; int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); if (addr.x >= 0x40000) slot1addr += 0x10000; - uint palinfo; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + int palinfo; + p = ivec4(texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0)); palinfo = p.r; slot1addr++; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + p = ivec4(texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0)); palinfo |= (p.r << 8); - addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1); + addr.y = (addr.y << 3) + ((palinfo & 0x3FFF) << 1); palinfo >>= 14; if (val == 0) @@ -247,32 +247,32 @@ vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) } } -vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode) +vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, int wrapmode) { st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); pixel.a = (pixel.r & 0xF8) >> 3; pixel.r &= 0x07; - addr.y = (addr.y << 3) + int(pixel.r); + addr.y = (addr.y << 3) + pixel.r; vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); return vec4(color.rgb, float(pixel.a)/31.0); } -vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) +vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, int wrapmode) { st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); addr.x += ((st.y * st.z) + st.x) << 1; - uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + ivec4 pixelL = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); addr.x++; - uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + ivec4 pixelH = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); vec4 color; color.r = float(pixelL.r & 0x1F) / 31.0; @@ -285,21 +285,21 @@ vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) vec4 TextureLookup_Nearest(vec2 st) { - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; + int attr = int(fPolygonAttr.y); + int paladdr = int(fPolygonAttr.z); float alpha0; if ((attr & (1<<29)) != 0) alpha0 = 0.0; else alpha0 = 1.0; - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); + int tw = 8 << ((attr >> 20) & 0x7); + int th = 8 << ((attr >> 23) & 0x7); ivec4 st_full = ivec4(ivec2(st), tw, th); - ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); - uint wrapmode = attr >> 16; + ivec2 vramaddr = ivec2((attr & 0xFFFF) << 3, paladdr); + int wrapmode = (attr >> 16); - uint type = (attr >> 26) & 0x7; + int type = (attr >> 26) & 0x7; if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); @@ -314,22 +314,22 @@ vec4 TextureLookup_Linear(vec2 texcoord) ivec2 intpart = ivec2(texcoord); vec2 fracpart = fract(texcoord); - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; + int attr = int(fPolygonAttr.y); + int paladdr = int(fPolygonAttr.z); float alpha0; if ((attr & (1<<29)) != 0) alpha0 = 0.0; else alpha0 = 1.0; - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); + int tw = 8 << ((attr >> 20) & 0x7); + int th = 8 << ((attr >> 23) & 0x7); ivec4 st_full = ivec4(intpart, tw, th); - ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); - uint wrapmode = attr >> 16; + ivec2 vramaddr = ivec2((attr & 0xFFFF) << 3, paladdr); + int wrapmode = (attr >> 16); vec4 A, B, C, D; - uint type = (attr >> 26) & 0x7; + int type = (attr >> 26) & 0x7; if (type == 5) { A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); @@ -423,7 +423,7 @@ vec4 FinalColor() { vec4 col; vec4 vcol = fColor; - uint blendmode = (fPolygonAttr.x >> 4) & 0x3; + int blendmode = (fPolygonAttr.x >> 4) & 0x3; if (blendmode == 2) { @@ -481,8 +481,8 @@ const char* kRenderVS_Z = R"( void main() { - uint attr = vPolygonAttr.x; - uint zshift = (attr >> 16) & 0x1F; + int attr = vPolygonAttr.x; + int zshift = (attr >> 16) & 0x1F; vec4 fpos; fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; @@ -504,8 +504,8 @@ smooth out float fZ; void main() { - uint attr = vPolygonAttr.x; - uint zshift = (attr >> 16) & 0x1F; + int attr = vPolygonAttr.x; + int zshift = (attr >> 16) & 0x1F; vec4 fpos; fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; @@ -530,7 +530,7 @@ void main() if (col.a < 30.5/31) discard; oColor = col; - oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; + oAttr.g = uint((fPolygonAttr.x >> 24) & 0x3F); } )"; @@ -544,7 +544,7 @@ void main() if (col.a < 30.5/31) discard; oColor = col; - oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; + oAttr.g = uint((fPolygonAttr.x >> 24) & 0x3F); gl_FragDepth = fZ; } )"; @@ -558,7 +558,7 @@ void main() if (col.a >= 30.5/31) discard; oColor = col; - oAttr.g = 0xFF; + oAttr.g = uint(0xFF); } )"; @@ -573,7 +573,7 @@ void main() if (col.a >= 30.5/31) discard; oColor = col; - oAttr.g = 0xFF; + oAttr.g = uint(0xFF); gl_FragDepth = fZ; } )"; @@ -583,8 +583,7 @@ const char* kRenderFS_ZSM = R"( void main() { oColor = vec4(0,0,0,1); - oAttr.g = 0xFF; - oAttr.b = 1; + oAttr.g = uint(0xFF); } )"; @@ -595,8 +594,7 @@ smooth in float fZ; void main() { oColor = vec4(0,0,0,1); - oAttr.g = 0xFF; - oAttr.b = 1; + oAttr.g = uint(0xFF); gl_FragDepth = fZ; } )"; -- cgit v1.2.3 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/GPU2D.cpp | 4 +- src/GPU3D.cpp | 16 +- src/GPU3D.h | 3 +- src/GPU3D_OpenGL.cpp | 974 ++++++++++++++++++++++++++++++++++++++++++ src/GPU3D_OpenGL43.cpp | 978 ------------------------------------------- src/GPU3D_OpenGL43_shaders.h | 602 -------------------------- src/GPU3D_OpenGL_shaders.h | 602 ++++++++++++++++++++++++++ 7 files changed, 1587 insertions(+), 1592 deletions(-) create mode 100644 src/GPU3D_OpenGL.cpp delete mode 100644 src/GPU3D_OpenGL43.cpp delete mode 100644 src/GPU3D_OpenGL43_shaders.h create mode 100644 src/GPU3D_OpenGL_shaders.h (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index e810275..fe1645e 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -663,7 +663,7 @@ void GPU2D::DrawScanline(u32 line) else if ((CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) { _3DLine = GPU3D::GetLine(n3dline); - //GPU3D::GLRenderer43::PrepareCaptureFrame(); + //GPU3D::GLRenderer::PrepareCaptureFrame(); } } @@ -825,7 +825,7 @@ void GPU2D::VBlankEnd() // TODO: make optional if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) { - GPU3D::GLRenderer43::PrepareCaptureFrame(); + GPU3D::GLRenderer::PrepareCaptureFrame(); } } diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index ec395ad..04ec55e 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -276,7 +276,7 @@ bool Init() CmdStallQueue = new FIFO(64); //if (!SoftRenderer::Init()) return false; - if (!GLRenderer43::Init()) return false; + if (!GLRenderer::Init()) return false; return true; } @@ -284,7 +284,7 @@ bool Init() void DeInit() { //SoftRenderer::DeInit(); - GLRenderer43::DeInit(); + GLRenderer::DeInit(); delete CmdFIFO; delete CmdPIPE; @@ -385,7 +385,7 @@ void Reset() ResetRenderingState(); //SoftRenderer::Reset(); - GLRenderer43::Reset(); + GLRenderer::Reset(); } void DoSavestate(Savestate* file) @@ -609,12 +609,12 @@ void SetEnabled(bool geometry, bool rendering) void SetDisplaySettings(int scale, bool accel) { - GLRenderer43::SetDisplaySettings(scale, accel); + GLRenderer::SetDisplaySettings(scale, accel); } int GetScale() { - return GLRenderer43::GetScale(); + return GLRenderer::GetScale(); } @@ -2437,18 +2437,18 @@ void VBlank() void VCount215() { //SoftRenderer::RenderFrame(); - GLRenderer43::RenderFrame(); + GLRenderer::RenderFrame(); } u32* GetLine(int line) { //return SoftRenderer::GetLine(line); - return GLRenderer43::GetLine(line); + return GLRenderer::GetLine(line); } void SetupAccelFrame() { - GLRenderer43::SetupAccelFrame(); + GLRenderer::SetupAccelFrame(); } diff --git a/src/GPU3D.h b/src/GPU3D.h index 708811f..280b99e 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -141,7 +141,7 @@ void SetupAccelFrame(); } -namespace GLRenderer43 +namespace GLRenderer { bool Init(); @@ -151,7 +151,6 @@ void Reset(); void SetDisplaySettings(int scale, bool accel); int GetScale(); -void VCount144(); void RenderFrame(); void PrepareCaptureFrame(); u32* GetLine(int line); 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]); +} + +} +} diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp deleted file mode 100644 index f6e6312..0000000 --- a/src/GPU3D_OpenGL43.cpp +++ /dev/null @@ -1,978 +0,0 @@ -/* - 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_OpenGL43_shaders.h" - -namespace GPU3D -{ -namespace GLRenderer43 -{ - -// 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 VCount144() -{ -} - -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]); -} - -} -} diff --git a/src/GPU3D_OpenGL43_shaders.h b/src/GPU3D_OpenGL43_shaders.h deleted file mode 100644 index 5be7060..0000000 --- a/src/GPU3D_OpenGL43_shaders.h +++ /dev/null @@ -1,602 +0,0 @@ -/* - 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 GPU3D_OPENGL43_SHADERS_H -#define GPU3D_OPENGL43_SHADERS_H - -#define kShaderHeader "#version 140" - - -const char* kClearVS = kShaderHeader R"( - -in vec2 vPosition; - -uniform uint uDepth; - -void main() -{ - float fdepth = (float(uDepth) / 8388608.0) - 1.0; - gl_Position = vec4(vPosition, fdepth, 1.0); -} -)"; - -const char* kClearFS = kShaderHeader R"( - -uniform uvec4 uColor; -uniform uint uOpaquePolyID; -uniform uint uFogFlag; - -out vec4 oColor; -out uvec3 oAttr; - -void main() -{ - oColor = vec4(uColor).bgra / 31.0; - oAttr.r = uint(0); - oAttr.g = uOpaquePolyID; - oAttr.b = uint(0); -} -)"; - - -const char* kRenderVSCommon = R"( - -layout(std140) uniform uConfig -{ - vec2 uScreenSize; - int uDispCnt; - vec4 uToonColors[32]; -}; - -in uvec4 vPosition; -in uvec4 vColor; -in ivec2 vTexcoord; -in ivec3 vPolygonAttr; - -smooth out vec4 fColor; -smooth out vec2 fTexcoord; -flat out ivec3 fPolygonAttr; -)"; - -const char* kRenderFSCommon = R"( - -uniform usampler2D TexMem; -uniform sampler2D TexPalMem; - -layout(std140) uniform uConfig -{ - vec2 uScreenSize; - int uDispCnt; - vec4 uToonColors[32]; -}; - -smooth in vec4 fColor; -smooth in vec2 fTexcoord; -flat in ivec3 fPolygonAttr; - -out vec4 oColor; -out uvec3 oAttr; - -int TexcoordWrap(int c, int maxc, int mode) -{ - if ((mode & (1<<0)) != 0) - { - if ((mode & (1<<2)) != 0 && (c & maxc) != 0) - return (maxc-1) - (c & (maxc-1)); - else - return (c & (maxc-1)); - } - else - return clamp(c, 0, maxc-1); -} - -vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, int wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); - - pixel.a = (pixel.r & 0xE0); - pixel.a = (pixel.a >> 3) + (pixel.a >> 6); - pixel.r &= 0x1F; - - addr.y = (addr.y << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, float(pixel.a)/31.0); -} - -vec4 TextureFetch_I2(ivec2 addr, ivec4 st, int wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) >> 2; - ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); - pixel.r >>= (2 * (st.x & 3)); - pixel.r &= 0x03; - - addr.y = (addr.y << 2) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, (pixel.r>0)?1:alpha0); -} - -vec4 TextureFetch_I4(ivec2 addr, ivec4 st, int wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) >> 1; - ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); - if ((st.x & 1) != 0) pixel.r >>= 4; - else pixel.r &= 0x0F; - - addr.y = (addr.y << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, (pixel.r>0)?1:alpha0); -} - -vec4 TextureFetch_I8(ivec2 addr, ivec4 st, int wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); - - addr.y = (addr.y << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, (pixel.r>0)?1:alpha0); -} - -vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, int wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); - ivec4 p = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); - int val = (p.r >> (2 * (st.x & 0x3))) & 0x3; - - int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); - if (addr.x >= 0x40000) slot1addr += 0x10000; - - int palinfo; - p = ivec4(texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0)); - palinfo = p.r; - slot1addr++; - p = ivec4(texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0)); - palinfo |= (p.r << 8); - - addr.y = (addr.y << 3) + ((palinfo & 0x3FFF) << 1); - palinfo >>= 14; - - if (val == 0) - { - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (val == 1) - { - addr.y++; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (val == 2) - { - if (palinfo == 1) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); - } - else - { - addr.y += 2; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - } - else - { - if (palinfo == 2) - { - addr.y += 3; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); - } - else - { - return vec4(0.0); - } - } -} - -vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, int wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); - - pixel.a = (pixel.r & 0xF8) >> 3; - pixel.r &= 0x07; - - addr.y = (addr.y << 3) + pixel.r; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, float(pixel.a)/31.0); -} - -vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, int wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) << 1; - ivec4 pixelL = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); - addr.x++; - ivec4 pixelH = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); - - vec4 color; - color.r = float(pixelL.r & 0x1F) / 31.0; - color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; - color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; - color.a = float(pixelH.r >> 7); - - return color; -} - -vec4 TextureLookup_Nearest(vec2 st) -{ - int attr = int(fPolygonAttr.y); - int paladdr = int(fPolygonAttr.z); - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << ((attr >> 20) & 0x7); - int th = 8 << ((attr >> 23) & 0x7); - ivec4 st_full = ivec4(ivec2(st), tw, th); - - ivec2 vramaddr = ivec2((attr & 0xFFFF) << 3, paladdr); - int wrapmode = (attr >> 16); - - int type = (attr >> 26) & 0x7; - if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); - else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); - else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); - else return TextureFetch_Direct (vramaddr, st_full, wrapmode); -} - -vec4 TextureLookup_Linear(vec2 texcoord) -{ - ivec2 intpart = ivec2(texcoord); - vec2 fracpart = fract(texcoord); - - int attr = int(fPolygonAttr.y); - int paladdr = int(fPolygonAttr.z); - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << ((attr >> 20) & 0x7); - int th = 8 << ((attr >> 23) & 0x7); - ivec4 st_full = ivec4(intpart, tw, th); - - ivec2 vramaddr = ivec2((attr & 0xFFFF) << 3, paladdr); - int wrapmode = (attr >> 16); - - vec4 A, B, C, D; - int type = (attr >> 26) & 0x7; - if (type == 5) - { - A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); - B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else if (type == 2) - { - A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 3) - { - A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 4) - { - A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 1) - { - A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); - B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else if (type == 6) - { - A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); - B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else - { - A = TextureFetch_Direct(vramaddr, st_full , wrapmode); - B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - - float fx = fracpart.x; - vec4 AB; - if (A.a < (0.5/31.0) && B.a < (0.5/31.0)) - AB = vec4(0); - else - { - //if (A.a < (0.5/31.0) || B.a < (0.5/31.0)) - // fx = step(0.5, fx); - - AB = mix(A, B, fx); - } - - fx = fracpart.x; - vec4 CD; - if (C.a < (0.5/31.0) && D.a < (0.5/31.0)) - CD = vec4(0); - else - { - //if (C.a < (0.5/31.0) || D.a < (0.5/31.0)) - // fx = step(0.5, fx); - - CD = mix(C, D, fx); - } - - fx = fracpart.y; - vec4 ret; - if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0)) - ret = vec4(0); - else - { - //if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0)) - // fx = step(0.5, fx); - - ret = mix(AB, CD, fx); - } - - return ret; -} - -vec4 FinalColor() -{ - vec4 col; - vec4 vcol = fColor; - int blendmode = (fPolygonAttr.x >> 4) & 0x3; - - if (blendmode == 2) - { - if ((uDispCnt & (1<<1)) == 0) - { - // toon - vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; - vcol.rgb = tooncolor; - } - else - { - // highlight - vcol.rgb = vcol.rrr; - } - } - - if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0)) - { - // no texture - col = vcol; - } - else - { - vec4 tcol = TextureLookup_Nearest(fTexcoord); - //vec4 tcol = TextureLookup_Linear(fTexcoord); - - if ((blendmode & 1) != 0) - { - // decal - col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a)); - col.a = vcol.a; - } - else - { - // modulate - col = vcol * tcol; - } - } - - if (blendmode == 2) - { - if ((uDispCnt & (1<<1)) != 0) - { - vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; - col.rgb = min(col.rgb + tooncolor, 1.0); - } - } - - return col.bgra; -} -)"; - - -const char* kRenderVS_Z = R"( - -void main() -{ - int attr = vPolygonAttr.x; - int zshift = (attr >> 16) & 0x1F; - - vec4 fpos; - fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; - fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; - fpos.w = float(vPosition.w) / 65536.0f; - fpos.xyz *= fpos.w; - - fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); - fTexcoord = vec2(vTexcoord) / 16.0; - fPolygonAttr = vPolygonAttr; - - gl_Position = fpos; -} -)"; - -const char* kRenderVS_W = R"( - -smooth out float fZ; - -void main() -{ - int attr = vPolygonAttr.x; - int zshift = (attr >> 16) & 0x1F; - - vec4 fpos; - fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; - fZ = float(vPosition.z << zshift) / 16777216.0; - fpos.w = float(vPosition.w) / 65536.0f; - fpos.xy *= fpos.w; - - fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); - fTexcoord = vec2(vTexcoord) / 16.0; - fPolygonAttr = vPolygonAttr; - - gl_Position = fpos; -} -)"; - - -const char* kRenderFS_ZO = R"( - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 30.5/31) discard; - - oColor = col; - oAttr.g = uint((fPolygonAttr.x >> 24) & 0x3F); -} -)"; - -const char* kRenderFS_WO = R"( - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 30.5/31) discard; - - oColor = col; - oAttr.g = uint((fPolygonAttr.x >> 24) & 0x3F); - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZT = R"( - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - oColor = col; - oAttr.g = uint(0xFF); -} -)"; - -const char* kRenderFS_WT = R"( - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - oColor = col; - oAttr.g = uint(0xFF); - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZSM = R"( - -void main() -{ - oColor = vec4(0,0,0,1); - oAttr.g = uint(0xFF); -} -)"; - -const char* kRenderFS_WSM = R"( - -smooth in float fZ; - -void main() -{ - oColor = vec4(0,0,0,1); - oAttr.g = uint(0xFF); - gl_FragDepth = fZ; -} -)"; - -#endif // GPU3D_OPENGL43_SHADERS_H diff --git a/src/GPU3D_OpenGL_shaders.h b/src/GPU3D_OpenGL_shaders.h new file mode 100644 index 0000000..e436544 --- /dev/null +++ b/src/GPU3D_OpenGL_shaders.h @@ -0,0 +1,602 @@ +/* + 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 GPU3D_OPENGL_SHADERS_H +#define GPU3D_OPENGL_SHADERS_H + +#define kShaderHeader "#version 140" + + +const char* kClearVS = kShaderHeader R"( + +in vec2 vPosition; + +uniform uint uDepth; + +void main() +{ + float fdepth = (float(uDepth) / 8388608.0) - 1.0; + gl_Position = vec4(vPosition, fdepth, 1.0); +} +)"; + +const char* kClearFS = kShaderHeader R"( + +uniform uvec4 uColor; +uniform uint uOpaquePolyID; +uniform uint uFogFlag; + +out vec4 oColor; +out uvec3 oAttr; + +void main() +{ + oColor = vec4(uColor).bgra / 31.0; + oAttr.r = uint(0); + oAttr.g = uOpaquePolyID; + oAttr.b = uint(0); +} +)"; + + +const char* kRenderVSCommon = R"( + +layout(std140) uniform uConfig +{ + vec2 uScreenSize; + int uDispCnt; + vec4 uToonColors[32]; +}; + +in uvec4 vPosition; +in uvec4 vColor; +in ivec2 vTexcoord; +in ivec3 vPolygonAttr; + +smooth out vec4 fColor; +smooth out vec2 fTexcoord; +flat out ivec3 fPolygonAttr; +)"; + +const char* kRenderFSCommon = R"( + +uniform usampler2D TexMem; +uniform sampler2D TexPalMem; + +layout(std140) uniform uConfig +{ + vec2 uScreenSize; + int uDispCnt; + vec4 uToonColors[32]; +}; + +smooth in vec4 fColor; +smooth in vec2 fTexcoord; +flat in ivec3 fPolygonAttr; + +out vec4 oColor; +out uvec3 oAttr; + +int TexcoordWrap(int c, int maxc, int mode) +{ + if ((mode & (1<<0)) != 0) + { + if ((mode & (1<<2)) != 0 && (c & maxc) != 0) + return (maxc-1) - (c & (maxc-1)); + else + return (c & (maxc-1)); + } + else + return clamp(c, 0, maxc-1); +} + +vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, int wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); + + pixel.a = (pixel.r & 0xE0); + pixel.a = (pixel.a >> 3) + (pixel.a >> 6); + pixel.r &= 0x1F; + + addr.y = (addr.y << 3) + pixel.r; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); +} + +vec4 TextureFetch_I2(ivec2 addr, ivec4 st, int wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) >> 2; + ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); + pixel.r >>= (2 * (st.x & 3)); + pixel.r &= 0x03; + + addr.y = (addr.y << 2) + pixel.r; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, (pixel.r>0)?1:alpha0); +} + +vec4 TextureFetch_I4(ivec2 addr, ivec4 st, int wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) >> 1; + ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); + if ((st.x & 1) != 0) pixel.r >>= 4; + else pixel.r &= 0x0F; + + addr.y = (addr.y << 3) + pixel.r; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, (pixel.r>0)?1:alpha0); +} + +vec4 TextureFetch_I8(ivec2 addr, ivec4 st, int wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); + + addr.y = (addr.y << 3) + pixel.r; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, (pixel.r>0)?1:alpha0); +} + +vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, int wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); + ivec4 p = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); + int val = (p.r >> (2 * (st.x & 0x3))) & 0x3; + + int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); + if (addr.x >= 0x40000) slot1addr += 0x10000; + + int palinfo; + p = ivec4(texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0)); + palinfo = p.r; + slot1addr++; + p = ivec4(texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0)); + palinfo |= (p.r << 8); + + addr.y = (addr.y << 3) + ((palinfo & 0x3FFF) << 1); + palinfo >>= 14; + + if (val == 0) + { + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 1) + { + addr.y++; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 2) + { + if (palinfo == 1) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); + } + else + { + addr.y += 2; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + } + else + { + if (palinfo == 2) + { + addr.y += 3; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); + } + else + { + return vec4(0.0); + } + } +} + +vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, int wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + ivec4 pixel = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); + + pixel.a = (pixel.r & 0xF8) >> 3; + pixel.r &= 0x07; + + addr.y = (addr.y << 3) + pixel.r; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); +} + +vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, int wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) << 1; + ivec4 pixelL = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); + addr.x++; + ivec4 pixelH = ivec4(texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0)); + + vec4 color; + color.r = float(pixelL.r & 0x1F) / 31.0; + color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; + color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; + color.a = float(pixelH.r >> 7); + + return color; +} + +vec4 TextureLookup_Nearest(vec2 st) +{ + int attr = int(fPolygonAttr.y); + int paladdr = int(fPolygonAttr.z); + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << ((attr >> 20) & 0x7); + int th = 8 << ((attr >> 23) & 0x7); + ivec4 st_full = ivec4(ivec2(st), tw, th); + + ivec2 vramaddr = ivec2((attr & 0xFFFF) << 3, paladdr); + int wrapmode = (attr >> 16); + + int type = (attr >> 26) & 0x7; + if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); + else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); + else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); + else return TextureFetch_Direct (vramaddr, st_full, wrapmode); +} + +vec4 TextureLookup_Linear(vec2 texcoord) +{ + ivec2 intpart = ivec2(texcoord); + vec2 fracpart = fract(texcoord); + + int attr = int(fPolygonAttr.y); + int paladdr = int(fPolygonAttr.z); + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << ((attr >> 20) & 0x7); + int th = 8 << ((attr >> 23) & 0x7); + ivec4 st_full = ivec4(intpart, tw, th); + + ivec2 vramaddr = ivec2((attr & 0xFFFF) << 3, paladdr); + int wrapmode = (attr >> 16); + + vec4 A, B, C, D; + int type = (attr >> 26) & 0x7; + if (type == 5) + { + A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); + B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 2) + { + A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 3) + { + A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 4) + { + A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 1) + { + A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); + B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 6) + { + A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); + B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else + { + A = TextureFetch_Direct(vramaddr, st_full , wrapmode); + B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + + float fx = fracpart.x; + vec4 AB; + if (A.a < (0.5/31.0) && B.a < (0.5/31.0)) + AB = vec4(0); + else + { + //if (A.a < (0.5/31.0) || B.a < (0.5/31.0)) + // fx = step(0.5, fx); + + AB = mix(A, B, fx); + } + + fx = fracpart.x; + vec4 CD; + if (C.a < (0.5/31.0) && D.a < (0.5/31.0)) + CD = vec4(0); + else + { + //if (C.a < (0.5/31.0) || D.a < (0.5/31.0)) + // fx = step(0.5, fx); + + CD = mix(C, D, fx); + } + + fx = fracpart.y; + vec4 ret; + if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0)) + ret = vec4(0); + else + { + //if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0)) + // fx = step(0.5, fx); + + ret = mix(AB, CD, fx); + } + + return ret; +} + +vec4 FinalColor() +{ + vec4 col; + vec4 vcol = fColor; + int blendmode = (fPolygonAttr.x >> 4) & 0x3; + + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) == 0) + { + // toon + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + vcol.rgb = tooncolor; + } + else + { + // highlight + vcol.rgb = vcol.rrr; + } + } + + if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0)) + { + // no texture + col = vcol; + } + else + { + vec4 tcol = TextureLookup_Nearest(fTexcoord); + //vec4 tcol = TextureLookup_Linear(fTexcoord); + + if ((blendmode & 1) != 0) + { + // decal + col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a)); + col.a = vcol.a; + } + else + { + // modulate + col = vcol * tcol; + } + } + + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) != 0) + { + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + col.rgb = min(col.rgb + tooncolor, 1.0); + } + } + + return col.bgra; +} +)"; + + +const char* kRenderVS_Z = R"( + +void main() +{ + int attr = vPolygonAttr.x; + int zshift = (attr >> 16) & 0x1F; + + vec4 fpos; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; + fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; + fpos.w = float(vPosition.w) / 65536.0f; + fpos.xyz *= fpos.w; + + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; + + gl_Position = fpos; +} +)"; + +const char* kRenderVS_W = R"( + +smooth out float fZ; + +void main() +{ + int attr = vPolygonAttr.x; + int zshift = (attr >> 16) & 0x1F; + + vec4 fpos; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; + fZ = float(vPosition.z << zshift) / 16777216.0; + fpos.w = float(vPosition.w) / 65536.0f; + fpos.xy *= fpos.w; + + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; + + gl_Position = fpos; +} +)"; + + +const char* kRenderFS_ZO = R"( + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 30.5/31) discard; + + oColor = col; + oAttr.g = uint((fPolygonAttr.x >> 24) & 0x3F); +} +)"; + +const char* kRenderFS_WO = R"( + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 30.5/31) discard; + + oColor = col; + oAttr.g = uint((fPolygonAttr.x >> 24) & 0x3F); + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZT = R"( + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + oColor = col; + oAttr.g = uint(0xFF); +} +)"; + +const char* kRenderFS_WT = R"( + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + oColor = col; + oAttr.g = uint(0xFF); + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZSM = R"( + +void main() +{ + oColor = vec4(0,0,0,1); + oAttr.g = uint(0xFF); +} +)"; + +const char* kRenderFS_WSM = R"( + +smooth in float fZ; + +void main() +{ + oColor = vec4(0,0,0,1); + oAttr.g = uint(0xFF); + gl_FragDepth = fZ; +} +)"; + +#endif // GPU3D_OPENGL_SHADERS_H -- 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') 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 c835b24f07a317ea435b742ec2fae12dc619c01b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 21 May 2019 14:53:22 +0200 Subject: modify libui GL support so that it will be compatible with GTK --- melonDS.cbp | 4 +-- src/libui_sdl/DlgInputConfig.cpp | 2 +- src/libui_sdl/libui/ui.h | 11 +++++-- src/libui_sdl/libui/windows/area.cpp | 56 ++++++++++++++++++++++++++++++++++-- src/libui_sdl/libui/windows/area.hpp | 5 ++++ src/libui_sdl/libui/windows/gl.cpp | 33 ++++++++++----------- src/libui_sdl/main.cpp | 37 ++++++++++-------------- 7 files changed, 101 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/melonDS.cbp b/melonDS.cbp index 0bdac7f..bb4d8c7 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -106,8 +106,8 @@ - - + + diff --git a/src/libui_sdl/DlgInputConfig.cpp b/src/libui_sdl/DlgInputConfig.cpp index 4c464f1..513bd90 100644 --- a/src/libui_sdl/DlgInputConfig.cpp +++ b/src/libui_sdl/DlgInputConfig.cpp @@ -432,7 +432,7 @@ void Open(int type) uiLabel* dummy = uiNewLabel(""); uiBoxAppend(in_ctrl, uiControl(dummy), 1); - dlg->keypresscatcher = uiNewArea(&dlg->areahandler, 0); + dlg->keypresscatcher = uiNewArea(&dlg->areahandler); uiControl(dlg->keypresscatcher)->UserData = dlg; uiBoxAppend(in_ctrl, uiControl(dlg->keypresscatcher), 0); diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h index 2641f30..09092a1 100644 --- a/src/libui_sdl/libui/ui.h +++ b/src/libui_sdl/libui/ui.h @@ -326,6 +326,10 @@ _UI_ENUM(uiWindowResizeEdge) { // TODO way to bring up the system menu instead? }; +#define uiGLVersion(major, minor) ((major) | ((minor)<<16)) +#define uiGLVerMajor(ver) ((ver) & 0xFFFF) +#define uiGLVerMinor(ver) ((ver) >> 16) + #define uiArea(this) ((uiArea *) (this)) // TODO give a better name // TODO document the types of width and height @@ -341,7 +345,8 @@ _UI_EXTERN void uiAreaScrollTo(uiArea *a, double x, double y, double width, doub _UI_EXTERN void uiAreaBeginUserWindowMove(uiArea *a); _UI_EXTERN void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge); _UI_EXTERN void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b); -_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah, int opengl); +_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah); +_UI_EXTERN uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions); _UI_EXTERN uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height); struct uiAreaDrawParams { @@ -604,9 +609,9 @@ _UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayou typedef struct uiGLContext uiGLContext; -_UI_EXTERN uiGLContext *uiGLNewContext(uiControl* c, int vermajor, int verminor); -_UI_EXTERN void uiGLFreeContext(uiGLContext* ctx); +_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 void uiGLSwapBuffers(uiGLContext* ctx); diff --git a/src/libui_sdl/libui/windows/area.cpp b/src/libui_sdl/libui/windows/area.cpp index 99c843e..72d5145 100644 --- a/src/libui_sdl/libui/windows/area.cpp +++ b/src/libui_sdl/libui/windows/area.cpp @@ -61,7 +61,15 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM // control implementation -uiWindowsControlAllDefaults(uiArea) +uiWindowsControlAllDefaultsExceptDestroy(uiArea) + +static void uiAreaDestroy(uiControl *c) +{ + uiArea* a = uiArea(c); + if (a->openGL && a->glcontext) freeGLContext(a->glcontext); + uiWindowsEnsureDestroyWindow(a->hwnd); + uiFreeControl(c); +} static void uiAreaMinimumSize(uiWindowsControl *c, int *width, int *height) { @@ -181,7 +189,7 @@ void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b) } -uiArea *uiNewArea(uiAreaHandler *ah, int opengl) +uiArea *uiNewArea(uiAreaHandler *ah) { uiArea *a; @@ -203,7 +211,49 @@ uiArea *uiNewArea(uiAreaHandler *ah, int opengl) uiAreaSetBackgroundColor(a, -1, -1, -1); - a->openGL = opengl; + a->openGL = 0; + + return a; +} + +uiGLContext *uiAreaGetGLContext(uiArea* a) +{ + if (!a->openGL) userbug("trying to get GL context from non-GL area"); + + return a->glcontext; +} + +uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions) +{ + uiArea *a; + + uiWindowsNewControl(uiArea, a); + + a->width = -1; + a->height = -1; + + a->ah = ah; + a->scrolling = FALSE; + clickCounterReset(&(a->cc)); + + // a->hwnd is assigned in areaWndProc() + uiWindowsEnsureCreateControlHWND(0, + areaClass, L"", + 0, + hInstance, a, + FALSE); + + uiAreaSetBackgroundColor(a, -1, -1, -1); + + a->openGL = 1; + + for (int i = 0; req_versions[i]; i++) + { + int major = uiGLVerMajor(req_versions[i]); + int minor = uiGLVerMinor(req_versions[i]); + a->glcontext = createGLContext(a, major, minor); + if (a->glcontext) break; + } return a; } diff --git a/src/libui_sdl/libui/windows/area.hpp b/src/libui_sdl/libui/windows/area.hpp index f8abd4f..cfc45a4 100644 --- a/src/libui_sdl/libui/windows/area.hpp +++ b/src/libui_sdl/libui/windows/area.hpp @@ -29,6 +29,7 @@ struct uiArea { int bgR, bgG, bgB; int openGL; + uiGLContext* glcontext; ID2D1HwndRenderTarget *rt; }; @@ -49,3 +50,7 @@ extern BOOL areaDoEvents(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRE extern void loadAreaSize(uiArea *a, double *width, double *height); extern void pixelsToDIP(uiArea *a, double *x, double *y); extern void dipToPixels(uiArea *a, double *x, double *y); + +// gl.cpp +extern uiGLContext* createGLContext(uiArea* a, int vermajor, int verminor); +extern void freeGLContext(uiGLContext* c); diff --git a/src/libui_sdl/libui/windows/gl.cpp b/src/libui_sdl/libui/windows/gl.cpp index 832a2e5..1e3732c 100644 --- a/src/libui_sdl/libui/windows/gl.cpp +++ b/src/libui_sdl/libui/windows/gl.cpp @@ -1,39 +1,31 @@ // 31 march 2019 #include "uipriv_windows.hpp" +#include "area.hpp" #include #include struct uiGLContext { - uiControl* c; + uiArea* a; HWND hwnd; HDC dc; HGLRC rc; + + unsigned int version; }; -uiGLContext* uiGLNewContext(uiControl* c, int vermajor, int verminor) +uiGLContext* createGLContext(uiArea* a, int vermajor, int verminor) { uiGLContext* ctx; BOOL res; ctx = uiNew(uiGLContext); - ctx->c = c; - if (c) - { - ctx->hwnd = (HWND)c->Handle(c); // welp - } - else - { - // windowless context - //ctx->hwnd = GetDesktopWindow(); - // nope. - uiFree(ctx); - return NULL; - } + ctx->a = a; + ctx->hwnd = a->hwnd; PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(pfd)); @@ -103,6 +95,7 @@ uiGLContext* uiGLNewContext(uiControl* c, int vermajor, int verminor) return NULL; } + ctx->version = uiGLVersion(vermajor, verminor); ctx->rc = rc_better; wglMakeCurrent(ctx->dc, ctx->rc); } @@ -110,8 +103,9 @@ uiGLContext* uiGLNewContext(uiControl* c, int vermajor, int verminor) return ctx; } -void uiGLFreeContext(uiGLContext* ctx) +void freeGLContext(uiGLContext* ctx) { + if (ctx == NULL) return; wglMakeCurrent(NULL, NULL); wglDeleteContext(ctx->rc); ReleaseDC(ctx->hwnd, ctx->dc); @@ -130,6 +124,12 @@ void uiGLMakeContextCurrent(uiGLContext* ctx) int res = wglMakeCurrent(ctx->dc, ctx->rc); } +unsigned int uiGLGetVersion(uiGLContext* ctx) +{ + if (ctx == NULL) return 0; + return ctx->version; +} + void *uiGLGetProcAddress(const char* proc) { return (void*)wglGetProcAddress(proc); @@ -137,5 +137,6 @@ void *uiGLGetProcAddress(const char* proc) void uiGLSwapBuffers(uiGLContext* ctx) { + if (ctx == NULL) return; SwapBuffers(ctx->dc); } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index c68f323..b499da7 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -64,6 +64,9 @@ char* EmuDirectory; uiWindow* MainWindow; uiArea* MainDrawArea; +uiAreaHandler MainDrawAreaHandler; + +const u32 kGLVersions[] = {uiGLVersion(3,1), 0}; uiGLContext* GLContext; int WindowWidth, WindowHeight; @@ -1792,7 +1795,7 @@ void OnOpenHotkeyConfig(uiMenuItem* item, uiWindow* window, void* blarg) { DlgInputConfig::Open(1); } -uiAreaHandler eeareahandler; + void OnOpenVideoSettings(uiMenuItem* item, uiWindow* window, void* blarg) { //DlgVideoSettings::Open(); @@ -1805,25 +1808,17 @@ void OnOpenVideoSettings(uiMenuItem* item, uiWindow* window, void* blarg) 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); + MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions); uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); //uiControlShow(uiControl(MainDrawArea)); - GLContext = uiGLNewContext(uiControl(MainDrawArea), 3, 1); + GLContext = uiAreaGetGLContext(MainDrawArea); uiGLMakeContextCurrent(GLContext); GLDrawing_Init(); @@ -2343,16 +2338,16 @@ int main(int argc, char** argv) uiMenuItemDisable(MenuItem_Reset); uiMenuItemDisable(MenuItem_Stop); - uiAreaHandler areahandler; - areahandler.Draw = OnAreaDraw; - areahandler.MouseEvent = OnAreaMouseEvent; - areahandler.MouseCrossed = OnAreaMouseCrossed; - areahandler.DragBroken = OnAreaDragBroken; - areahandler.KeyEvent = OnAreaKeyEvent; - areahandler.Resize = OnAreaResize; + MainDrawAreaHandler.Draw = OnAreaDraw; + MainDrawAreaHandler.MouseEvent = OnAreaMouseEvent; + MainDrawAreaHandler.MouseCrossed = OnAreaMouseCrossed; + MainDrawAreaHandler.DragBroken = OnAreaDragBroken; + MainDrawAreaHandler.KeyEvent = OnAreaKeyEvent; + MainDrawAreaHandler.Resize = OnAreaResize; ScreenDrawInited = false; - MainDrawArea = uiNewArea(&areahandler, 1); + //MainDrawArea = uiNewArea(&MainDrawAreaHandler); + MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions); uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); // TODO: make configurable? @@ -2383,7 +2378,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), 3, 1); // haw haw haw + GLContext = uiAreaGetGLContext(MainDrawArea); uiGLMakeContextCurrent(GLContext); void* testor = uiGLGetProcAddress("glUseProgram"); @@ -2472,8 +2467,6 @@ int main(int argc, char** argv) if (MicWavBuffer) delete[] MicWavBuffer; - uiGLFreeContext(GLContext); - Config::ScreenRotation = ScreenRotation; Config::ScreenGap = ScreenGap; Config::ScreenLayout = ScreenLayout; -- 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') 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 3915b8cb4e37b63428335e0c86bc70c94d68c0ed Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 23 May 2019 22:41:21 +0200 Subject: botch the code --- src/libui_sdl/main.cpp | 299 +++++++++++++++++++++++++++++++------------------ 1 file changed, 190 insertions(+), 109 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index f0d7b74..9f92595 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -89,6 +89,9 @@ uiMenuItem* MenuItem_ScreenGap[6]; uiMenuItem* MenuItem_ScreenLayout[3]; uiMenuItem* MenuItem_ScreenSizing[4]; +uiMenuItem* MenuItem_ScreenFilter; +uiMenuItem* MenuItem_LimitFPS; + SDL_Thread* EmuThread; int EmuRunning; volatile int EmuStatus; @@ -985,8 +988,9 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) ScreenDrawInited = true; ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256, 192); ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192); + printf("D2D bitmaps inited\n"); } - +if (!ScreenBitmap[0] || !ScreenBitmap[1]) printf("draw but no bitmaps :(\n"); if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; if (!GPU::Framebuffer[0][0]) return; @@ -1847,10 +1851,19 @@ void OnOpenHotkeyConfig(uiMenuItem* item, uiWindow* window, void* blarg) { DlgInputConfig::Open(1); } - +void zarg(); void OnOpenVideoSettings(uiMenuItem* item, uiWindow* window, void* blarg) { - DlgVideoSettings::Open(); + //DlgVideoSettings::Open(); + int zerp = EmuRunning; + EmuRunning = 3; + while (EmuStatus != 3); + + uiControlDestroy(uiControl(window)); + + zarg(); + + EmuRunning = zerp; } void OnOpenAudioSettings(uiMenuItem* item, uiWindow* window, void* blarg) @@ -2069,107 +2082,8 @@ void ApplyNewSettings(int type) } -int main(int argc, char** argv) +void CreateMainWindowMenu() { - srand(time(NULL)); - - printf("melonDS " MELONDS_VERSION "\n"); - printf(MELONDS_URL "\n"); - - if (argc > 0 && strlen(argv[0]) > 0) - { - int len = strlen(argv[0]); - while (len > 0) - { - if (argv[0][len] == '/') break; - if (argv[0][len] == '\\') break; - len--; - } - if (len > 0) - { - EmuDirectory = new char[len+1]; - strncpy(EmuDirectory, argv[0], len); - EmuDirectory[len] = '\0'; - } - else - { - EmuDirectory = new char[2]; - strcpy(EmuDirectory, "."); - } - } - else - { - EmuDirectory = new char[2]; - strcpy(EmuDirectory, "."); - } - - // http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl - SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); - - if (SDL_Init(SDL_INIT_HAPTIC) < 0) - { - printf("SDL couldn't init rumble\n"); - } - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) - { - printf("SDL shat itself :(\n"); - return 1; - } - - SDL_JoystickEventState(SDL_ENABLE); - - uiInitOptions ui_opt; - memset(&ui_opt, 0, sizeof(uiInitOptions)); - const char* ui_err = uiInit(&ui_opt); - if (ui_err != NULL) - { - printf("libui shat itself :( %s\n", ui_err); - uiFreeInitError(ui_err); - return 1; - } - - Config::Load(); - - if (Config::AudioVolume < 0) Config::AudioVolume = 0; - else if (Config::AudioVolume > 256) Config::AudioVolume = 256; - - if (!Platform::LocalFileExists("bios7.bin") || - !Platform::LocalFileExists("bios9.bin") || - !Platform::LocalFileExists("firmware.bin")) - { - uiMsgBoxError( - NULL, - "BIOS/Firmware not found", - "One or more of the following required files don't exist or couldn't be accessed:\n\n" - "bios7.bin -- ARM7 BIOS\n" - "bios9.bin -- ARM9 BIOS\n" - "firmware.bin -- firmware image\n\n" - "Dump the files from your DS and place them in the directory you run melonDS from.\n" - "Make sure that the files can be accessed."); - - uiUninit(); - SDL_Quit(); - return 0; - } - - { - FILE* f = Platform::OpenLocalFile("romlist.bin", "rb"); - if (f) - { - u32 data; - fread(&data, 4, 1, f); - fclose(f); - - if ((data >> 24) == 0) // old CRC-based list - { - uiMsgBoxError(NULL, - "Your version of romlist.bin is outdated.", - "Save memory type detection will not work correctly.\n\n" - "You should use the latest version of romlist.bin (provided in melonDS release packages)."); - } - } - } - uiMenu* menu; uiMenuItem* menuitem; @@ -2327,14 +2241,178 @@ int main(int argc, char** argv) uiMenuAppendSubmenu(menu, submenu); } - menuitem = uiMenuAppendCheckItem(menu, "Screen filtering"); - uiMenuItemOnClicked(menuitem, OnSetScreenFiltering, NULL); - uiMenuItemSetChecked(menuitem, Config::ScreenFilter==1); + MenuItem_ScreenFilter = uiMenuAppendCheckItem(menu, "Screen filtering"); + uiMenuItemOnClicked(MenuItem_ScreenFilter, OnSetScreenFiltering, NULL); + + MenuItem_LimitFPS = uiMenuAppendCheckItem(menu, "Limit framerate"); + uiMenuItemOnClicked(MenuItem_LimitFPS, OnSetLimitFPS, NULL); +} + +void zarg() +{ + 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); + uiWindowOnClosing(MainWindow, OnCloseWindow, NULL); + + uiWindowSetDropTarget(MainWindow, 1); + uiWindowOnDropFile(MainWindow, OnDropFile, NULL); + + 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); + + ScreenRotation = Config::ScreenRotation; + ScreenGap = Config::ScreenGap; + ScreenLayout = Config::ScreenLayout; + ScreenSizing = Config::ScreenSizing; + +#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 + + /*uiMenuItemSetChecked(MenuItem_SavestateSRAMReloc, Config::SavestateRelocSRAM?1:0); + + uiMenuItemSetChecked(MenuItem_ScreenRot[ScreenRotation], 1); + uiMenuItemSetChecked(MenuItem_ScreenLayout[ScreenLayout], 1); + uiMenuItemSetChecked(MenuItem_ScreenSizing[ScreenSizing], 1); + + for (int i = 0; i < 6; i++) + { + if (ScreenGap == kScreenGap[i]) + uiMenuItemSetChecked(MenuItem_ScreenGap[i], 1); + }*/ + + OnSetScreenRotation(MenuItem_ScreenRot[ScreenRotation], MainWindow, (void*)&kScreenRot[ScreenRotation]); +} + + +int main(int argc, char** argv) +{ + srand(time(NULL)); + + printf("melonDS " MELONDS_VERSION "\n"); + printf(MELONDS_URL "\n"); + + if (argc > 0 && strlen(argv[0]) > 0) + { + int len = strlen(argv[0]); + while (len > 0) + { + if (argv[0][len] == '/') break; + if (argv[0][len] == '\\') break; + len--; + } + if (len > 0) + { + EmuDirectory = new char[len+1]; + strncpy(EmuDirectory, argv[0], len); + EmuDirectory[len] = '\0'; + } + else + { + EmuDirectory = new char[2]; + strcpy(EmuDirectory, "."); + } + } + else + { + EmuDirectory = new char[2]; + strcpy(EmuDirectory, "."); + } + + // http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl + SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); + + if (SDL_Init(SDL_INIT_HAPTIC) < 0) + { + printf("SDL couldn't init rumble\n"); + } + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) + { + printf("SDL shat itself :(\n"); + return 1; + } + + SDL_JoystickEventState(SDL_ENABLE); + + uiInitOptions ui_opt; + memset(&ui_opt, 0, sizeof(uiInitOptions)); + const char* ui_err = uiInit(&ui_opt); + if (ui_err != NULL) + { + printf("libui shat itself :( %s\n", ui_err); + uiFreeInitError(ui_err); + return 1; + } + + Config::Load(); + + if (Config::AudioVolume < 0) Config::AudioVolume = 0; + else if (Config::AudioVolume > 256) Config::AudioVolume = 256; + + if (!Platform::LocalFileExists("bios7.bin") || + !Platform::LocalFileExists("bios9.bin") || + !Platform::LocalFileExists("firmware.bin")) + { + uiMsgBoxError( + NULL, + "BIOS/Firmware not found", + "One or more of the following required files don't exist or couldn't be accessed:\n\n" + "bios7.bin -- ARM7 BIOS\n" + "bios9.bin -- ARM9 BIOS\n" + "firmware.bin -- firmware image\n\n" + "Dump the files from your DS and place them in the directory you run melonDS from.\n" + "Make sure that the files can be accessed."); + + uiUninit(); + SDL_Quit(); + return 0; + } + + { + FILE* f = Platform::OpenLocalFile("romlist.bin", "rb"); + if (f) + { + u32 data; + fread(&data, 4, 1, f); + fclose(f); - menuitem = uiMenuAppendCheckItem(menu, "Limit framerate"); - uiMenuItemOnClicked(menuitem, OnSetLimitFPS, NULL); - uiMenuItemSetChecked(menuitem, Config::LimitFPS==1); + if ((data >> 24) == 0) // old CRC-based list + { + uiMsgBoxError(NULL, + "Your version of romlist.bin is outdated.", + "Save memory type detection will not work correctly.\n\n" + "You should use the latest version of romlist.bin (provided in melonDS release packages)."); + } + } + } + CreateMainWindowMenu(); int w = Config::WindowWidth; int h = Config::WindowHeight; @@ -2405,6 +2483,9 @@ int main(int argc, char** argv) OnSetScreenRotation(MenuItem_ScreenRot[ScreenRotation], MainWindow, (void*)&kScreenRot[ScreenRotation]); + uiMenuItemSetChecked(MenuItem_ScreenFilter, Config::ScreenFilter==1); + uiMenuItemSetChecked(MenuItem_LimitFPS, Config::LimitFPS==1); + SDL_AudioSpec whatIwant, whatIget; memset(&whatIwant, 0, sizeof(SDL_AudioSpec)); whatIwant.freq = 47340; -- cgit v1.2.3 From e5236f0cdec4f3a29a8748f65ca49fee3fb54c03 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 23 May 2019 22:50:46 +0200 Subject: add API for getting/setting window size bahahahaaa --- src/libui_sdl/libui/ui.h | 2 ++ src/libui_sdl/libui/windows/window.cpp | 15 +++++++++++++++ src/libui_sdl/main.cpp | 3 +++ 3 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h index 09092a1..5b163af 100644 --- a/src/libui_sdl/libui/ui.h +++ b/src/libui_sdl/libui/ui.h @@ -108,6 +108,8 @@ typedef struct uiWindow uiWindow; #define uiWindow(this) ((uiWindow *) (this)) _UI_EXTERN char *uiWindowTitle(uiWindow *w); _UI_EXTERN void uiWindowSetTitle(uiWindow *w, const char *title); +_UI_EXTERN void uiWindowPosition(uiWindow *w, int *x, int *y); +_UI_EXTERN void uiWindowSetPosition(uiWindow *w, int x, int y); _UI_EXTERN void uiWindowContentSize(uiWindow *w, int *width, int *height); _UI_EXTERN void uiWindowSetContentSize(uiWindow *w, int width, int height); _UI_EXTERN int uiWindowMinimized(uiWindow *w); diff --git a/src/libui_sdl/libui/windows/window.cpp b/src/libui_sdl/libui/windows/window.cpp index f52e2f6..18d1171 100644 --- a/src/libui_sdl/libui/windows/window.cpp +++ b/src/libui_sdl/libui/windows/window.cpp @@ -363,6 +363,21 @@ static void windowMonitorRect(HWND hwnd, RECT *r) *r = mi.rcMonitor; } +void uiWindowPosition(uiWindow *w, int *x, int *y) +{ + RECT rect; + if (GetWindowRect(w->hwnd, &rect) == 0) + logLastError(L"error getting window position"); + *x = rect.left; + *y = rect.top; +} + +void uiWindowSetPosition(uiWindow *w, int x, int y) +{ + if (SetWindowPos(w->hwnd, NULL, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER) == 0) + logLastError(L"error moving window"); +} + void uiWindowContentSize(uiWindow *w, int *width, int *height) { RECT r; diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 9f92595..1f41bbe 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -1859,9 +1859,12 @@ void OnOpenVideoSettings(uiMenuItem* item, uiWindow* window, void* blarg) EmuRunning = 3; while (EmuStatus != 3); + int winX, winY; + uiWindowPosition(MainWindow, &winX, &winY); uiControlDestroy(uiControl(window)); zarg(); + uiWindowSetPosition(MainWindow, winX, winY); EmuRunning = zerp; } -- 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') 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 79ea104931fd50039dd903eb6a12f40235e6f004 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 24 May 2019 02:12:46 +0200 Subject: properly recreate window based on changes to either video output method or 3D renderer --- src/libui_sdl/DlgVideoSettings.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index 26c0109..329c79e 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -80,10 +80,16 @@ int OnCloseWindow(uiWindow* window, void* blarg) void OnRendererChanged(uiRadioButtons* rb, void* blarg) { int id = uiRadioButtonsSelected(rb); -printf("RENDERER CHANGE: %d\n", id); + bool old_usegl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); + Config::_3DRenderer = id; UpdateControls(); - ApplyNewSettings(3); + + bool new_usegl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); + if (new_usegl != old_usegl) + ApplyNewSettings(2); + else + ApplyNewSettings(3); } void OnGLDisplayChanged(uiCheckbox* cb, void* blarg) @@ -116,17 +122,25 @@ void OnAntialiasChanged(uiCheckbox* cb, void* blarg) void OnCancel(uiButton* btn, void* blarg) { bool apply0 = false; + bool apply2 = false; + bool apply3 = false; + + bool old_usegl = (old_gldisplay != 0) || (old_renderer != 0); + bool new_usegl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); if (old_renderer != Config::_3DRenderer) { Config::_3DRenderer = old_renderer; - ApplyNewSettings(3); + apply3 = true; } if (old_gldisplay != Config::ScreenUseGL) { Config::ScreenUseGL = old_gldisplay; - ApplyNewSettings(2); + } + if (old_usegl != new_usegl) + { + apply2 = true; } if (old_threaded3D != Config::Threaded3D) @@ -143,6 +157,8 @@ void OnCancel(uiButton* btn, void* blarg) apply0 = true; } + if (apply2) ApplyNewSettings(2); + else if (apply3) ApplyNewSettings(3); if (apply0) ApplyNewSettings(0); uiControlDestroy(uiControl(win)); -- cgit v1.2.3 From 0bb3321262fcdff4edc3636e7301db70e5ff0533 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 24 May 2019 02:29:16 +0200 Subject: getting somewhere?? --- src/GPU.cpp | 18 ++++++++++++------ src/GPU3D.cpp | 1 + src/libui_sdl/main.cpp | 34 +++++++++++++++++++++------------- 3 files changed, 34 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/GPU.cpp b/src/GPU.cpp index 959129e..a7ea2a4 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -151,12 +151,15 @@ void Reset() VRAMMap_ARM7[0] = 0; VRAMMap_ARM7[1] = 0; - for (int i = 0; i < (256*192); i++) + int fbsize; + if (Accelerated) fbsize = (256*3 + 2) * 192; + else fbsize = 256 * 192; + for (int i = 0; i < fbsize; i++) { Framebuffer[0][0][i] = 0xFFFFFFFF; Framebuffer[1][0][i] = 0xFFFFFFFF; } - for (int i = 0; i < (256*192); i++) + for (int i = 0; i < fbsize; i++) { Framebuffer[0][1][i] = 0xFFFFFFFF; Framebuffer[1][1][i] = 0xFFFFFFFF; @@ -173,10 +176,13 @@ void Reset() void Stop() { - memset(Framebuffer[0][0], 0, 256*192); - memset(Framebuffer[0][1], 0, 256*192); - memset(Framebuffer[1][0], 0, 256*192); - memset(Framebuffer[1][1], 0, 256*192); + int fbsize; + if (Accelerated) fbsize = (256*3 + 2) * 192; + else fbsize = 256 * 192; + memset(Framebuffer[0][0], 0, fbsize*4); + memset(Framebuffer[0][1], 0, fbsize*4); + memset(Framebuffer[1][0], 0, fbsize*4); + memset(Framebuffer[1][1], 0, fbsize*4); } void DoSavestate(Savestate* file) diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 115b31f..770c874 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -624,6 +624,7 @@ int InitRenderer(bool hasGL) if (renderer == 0) SoftRenderer::Init(); Renderer = renderer; + GPU::SetDisplaySettings(Renderer != 0); return renderer; } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index efebc8d..e17827d 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -374,14 +374,24 @@ void GLScreen_DrawScreen() int frontbuf = GPU::FrontBuffer; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); - /*glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256<Context, 256, 192); ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192); - printf("D2D bitmaps inited\n"); } -if (!ScreenBitmap[0] || !ScreenBitmap[1]) printf("draw but no bitmaps :(\n"); + + int frontbuf = GPU::FrontBuffer; if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; - if (!GPU::Framebuffer[0][0]) return; + if (!GPU::Framebuffer[frontbuf][1]) return; uiRect top = {0, 0, 256, 192}; uiRect bot = {0, 0, 256, 192}; - int frontbuf = GPU::FrontBuffer; uiDrawBitmapUpdate(ScreenBitmap[0], GPU::Framebuffer[frontbuf][0]); uiDrawBitmapUpdate(ScreenBitmap[1], GPU::Framebuffer[frontbuf][1]); -- 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') 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 8a63c76f4face4bf717d646624d63eeb03c3849d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 24 May 2019 02:41:24 +0200 Subject: of course I'm a complete and absolute fucking idiot --- src/libui_sdl/main.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index c302b7e..3a99d95 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -1962,7 +1962,9 @@ void ApplyNewSettings(int type) if (type == 0) // 3D renderer settings { + if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); GPU3D::UpdateRendererConfig(); + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); GL_3DScale = Config::GL_ScaleFactor; // dorp GL_ScreenSizeDirty = true; -- 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') 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') 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') 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') 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') 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') diff --git a/src/GPU.cpp b/src/GPU.cpp index a7ea2a4..fe23a77 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -152,7 +152,7 @@ void Reset() VRAMMap_ARM7[1] = 0; int fbsize; - if (Accelerated) fbsize = (256*3 + 2) * 192; + if (Accelerated) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; for (int i = 0; i < fbsize; i++) { @@ -177,7 +177,7 @@ void Reset() void Stop() { int fbsize; - if (Accelerated) fbsize = (256*3 + 2) * 192; + if (Accelerated) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; memset(Framebuffer[0][0], 0, fbsize*4); memset(Framebuffer[0][1], 0, fbsize*4); @@ -257,7 +257,7 @@ void SetDisplaySettings(bool accel) if (accel != Accelerated) { int fbsize; - if (accel) fbsize = (256*3 + 2) * 192; + if (accel) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 88249ba..4fe2209 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -617,10 +617,78 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) return rb | g | 0xFF000000; } +u32 GPU2D::ColorComposite(int i, u32 val1, u32 val2) +{ + u32 coloreffect = 0; + u32 eva, evb; + + u32 flag1 = val1 >> 24; + u32 flag2 = val2 >> 24; + + u32 target2; + if (flag2 & 0x80) target2 = 0x1000; + else if (flag2 & 0x40) target2 = 0x0100; + else target2 = flag2 << 8; + + if ((flag1 & 0x80) && (BlendCnt & target2)) + { + // sprite blending + + coloreffect = 1; + + if (flag1 & 0x40) + { + eva = flag1 & 0x1F; + evb = 16 - eva; + } + else + { + eva = EVA; + evb = EVB; + } + } + else if ((flag1 & 0x40) && (BlendCnt & target2)) + { + // 3D layer blending + + coloreffect = 4; + } + else + { + if (flag1 & 0x80) flag1 = 0x10; + else if (flag1 & 0x40) flag1 = 0x01; + + if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + { + coloreffect = (BlendCnt >> 6) & 0x3; + + if (coloreffect == 1) + { + if (BlendCnt & target2) + { + eva = EVA; + evb = EVB; + } + else + coloreffect = 0; + } + } + } + + switch (coloreffect) + { + case 0: return val1; + case 1: return ColorBlend4(val1, val2, eva, evb); + case 2: return ColorBrightnessUp(val1, EVY); + case 3: return ColorBrightnessDown(val1, EVY); + case 4: return ColorBlend5(val1, val2); + } +} + void GPU2D::DrawScanline(u32 line) { - int stride = Accelerated ? (256*3 + 2) : 256; + int stride = Accelerated ? (256*3 + 1) : 256; u32* dst = &Framebuffer[stride * line]; int n3dline = line; @@ -648,7 +716,6 @@ void GPU2D::DrawScanline(u32 line) if (Accelerated) { dst[256*3] = 0; - dst[256*3 + 1] = 0; } return; } @@ -747,14 +814,7 @@ void GPU2D::DrawScanline(u32 line) if (Accelerated) { - u32 ctl = (BlendCnt & 0x3FFF); - ctl |= ((DispCnt & 0x30000) >> 2); - ctl |= (EVA << 16); - ctl |= (EVB << 21); - ctl |= (EVY << 26); - - dst[256*3] = ctl; - dst[256*3 + 1] = MasterBrightness; + dst[256*3] = MasterBrightness | (DispCnt & 0x30000); return; } @@ -858,111 +918,57 @@ void GPU2D::DoCapture(u32 line, u32 width) // but when doing display capture, we do need the composited output // so we do it here - u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - for (int i = 0; i < 256; i++) { u32 val1 = BGOBJLine[i]; - u32 val3 = BGOBJLine[256+i]; - u32 val2 = BGOBJLine[512+i]; + u32 val2 = BGOBJLine[256+i]; + u32 val3 = BGOBJLine[512+i]; + + u32 compmode = (val3 >> 24) & 0xF; - if ((val1 >> 30) == 1) + if (compmode == 4) { - u32 _3dval = _3DLine[val1 & 0xFF]; + // 3D on top, blending + + u32 _3dval = _3DLine[val3 & 0xFF]; if ((_3dval >> 24) > 0) - { - val1 = _3dval | 0x40000000; - val2 = val3; - } + val1 = ColorBlend5(_3dval, val1); else - val1 = val3; + val1 = val2; } - else if ((val3 >> 30) == 1) + else if (compmode == 1) { + // 3D on bottom, blending + u32 _3dval = _3DLine[val3 & 0xFF]; if ((_3dval >> 24) > 0) - val2 = _3dval | 0x40000000; - } - else - val2 = val3; - - val1 &= ~0x00800000; - val2 &= ~0x00800000; - - u32 coloreffect, eva, evb; - - u32 flag1 = val1 >> 24; - u32 flag2 = val2 >> 24; - - u32 target2; - if (flag2 & 0x80) target2 = 0x1000; - else if (flag2 & 0x40) target2 = 0x0100; - else target2 = flag2 << 8; - - if ((flag1 & 0x80) && (BlendCnt & target2)) - { - // sprite blending - - coloreffect = 1; - - if (flag1 & 0x40) { - eva = flag1 & 0x1F; - evb = 16 - eva; + u32 eva = (val3 >> 8) & 0x1F; + u32 evb = (val3 >> 16) & 0x1F; + + val1 = ColorBlend4(val1, _3dval, eva, evb); } else - { - eva = EVA; - evb = EVB; - } + val1 = val2; } - else if ((flag1 & 0x40) && (BlendCnt & target2)) + else if (compmode <= 3) { - // 3D layer blending + // 3D on top, normal/fade - BGOBJLine[i] = ColorBlend5(val1, val2); - continue; - } - else - { - if (flag1 & 0x80) flag1 = 0x10; - else if (flag1 & 0x40) flag1 = 0x01; - - if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + u32 _3dval = _3DLine[val3 & 0xFF]; + if ((_3dval >> 24) > 0) { - if ((bldcnteffect == 1) && (BlendCnt & target2)) - { - coloreffect = 1; - eva = EVA; - evb = EVB; - } - else if (bldcnteffect >= 2) - coloreffect = bldcnteffect; - else - coloreffect = 0; + u32 evy = (val3 >> 8) & 0x1F; + + val1 = _3dval; + if (compmode == 2) val1 = ColorBrightnessUp(val1, evy); + else if (compmode == 3) val1 = ColorBrightnessDown(val1, evy); } else - coloreffect = 0; + val1 = val2; } - switch (coloreffect) - { - case 0: - BGOBJLine[i] = val1; - break; - - case 1: - BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); - break; - - case 2: - BGOBJLine[i] = ColorBrightnessUp(val1, EVY); - break; - - case 3: - BGOBJLine[i] = ColorBrightnessDown(val1, EVY); - break; - } + BGOBJLine[i] = val1; } } } @@ -1374,94 +1380,102 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) if (!Accelerated) { - u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - for (int i = 0; i < 256; i++) { u32 val1 = BGOBJLine[i]; u32 val2 = BGOBJLine[256+i]; - u32 coloreffect, eva, evb; + BGOBJLine[i] = ColorComposite(i, val1, val2); + } + } + else + { + if (Num == 0) + { + for (int i = 0; i < 256; i++) + { + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[256+i]; + u32 val3 = BGOBJLine[512+i]; - u32 flag1 = val1 >> 24; - u32 flag2 = val2 >> 24; + u32 flag1 = val1 >> 24; + u32 flag2 = val2 >> 24; - u32 target2; - if (flag2 & 0x80) target2 = 0x1000; - else if (flag2 & 0x40) target2 = 0x0100; - else target2 = flag2 << 8; + u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - if ((flag1 & 0x80) && (BlendCnt & target2)) - { - // sprite blending + u32 target1; + if (flag1 & 0x80) target1 = 0x0010; + else if (flag1 & 0x40) target1 = 0x0001; + else target1 = flag1; - coloreffect = 1; + u32 target2; + if (flag2 & 0x80) target2 = 0x1000; + else if (flag2 & 0x40) target2 = 0x0100; + else target2 = flag2 << 8; - if (flag1 & 0x40) + if (((flag1 & 0xC0) == 0x40) && (BlendCnt & target2)) { - eva = flag1 & 0x1F; - evb = 16 - eva; + // 3D on top, blending + + BGOBJLine[i] = val2; + BGOBJLine[256+i] = ColorComposite(i, val2, val3); + BGOBJLine[512+i] = 0x04000000 | (val1 & 0xFF); } - else + else if ((flag1 & 0xC0) == 0x40) { - eva = EVA; - evb = EVB; - } - } - else if ((flag1 & 0x40) && (BlendCnt & target2)) - { - // 3D layer blending + // 3D on top, normal/fade - BGOBJLine[i] = ColorBlend5(val1, val2); - continue; - } - else - { - if (flag1 & 0x80) flag1 = 0x10; - else if (flag1 & 0x40) flag1 = 0x01; + if (bldcnteffect == 1) bldcnteffect = 0; + if (!(BlendCnt & 0x0001)) bldcnteffect = 0; + if (!(WindowMask[i] & 0x20)) bldcnteffect = 0; - if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + BGOBJLine[i] = val2; + BGOBJLine[256+i] = ColorComposite(i, val2, val3); + BGOBJLine[512+i] = (bldcnteffect << 24) | (EVY << 8) | (val1 & 0xFF); + } + else if (((flag2 & 0xC0) == 0x40) && ((BlendCnt & 0x01C0) == 0x0140)) { - if ((bldcnteffect == 1) && (BlendCnt & target2)) + // 3D on bottom, blending + + u32 eva, evb; + if ((flag1 & 0xC0) == 0xC0) + { + eva = flag1 & 0x1F; + evb = 16 - eva; + } + else if ((BlendCnt & target1) && (WindowMask[i] & 0x20)) { - coloreffect = 1; eva = EVA; evb = EVB; } - else if (bldcnteffect >= 2) - coloreffect = bldcnteffect; else - coloreffect = 0; + bldcnteffect = 7; + + BGOBJLine[i] = val1; + BGOBJLine[256+i] = ColorComposite(i, val1, val3); + BGOBJLine[512+i] = (bldcnteffect << 24) | (EVB << 16) | (EVA << 8) | (val1 & 0xFF); } else - coloreffect = 0; - } - - switch (coloreffect) - { - case 0: - BGOBJLine[i] = val1; - break; - - case 1: - BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); - break; - - case 2: - BGOBJLine[i] = ColorBrightnessUp(val1, EVY); - break; + { + // no potential 3D pixel involved - case 3: - BGOBJLine[i] = ColorBrightnessDown(val1, EVY); - break; + BGOBJLine[i] = ColorComposite(i, val1, val2); + BGOBJLine[256+i] = 0; + BGOBJLine[512+i] = 0x07000000; + } } } - } - else - { - for (int i = 0; i < 256; i++) + else { - BGOBJLine[i] |= ((WindowMask[i] & 0x20) << 18); + for (int i = 0; i < 256; i++) + { + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[256+i]; + + BGOBJLine[i] = ColorComposite(i, val1, val2); + BGOBJLine[256+i] = 0; + BGOBJLine[512+i] = 0x07000000; + } } } diff --git a/src/GPU2D.h b/src/GPU2D.h index 78e62f5..21b43f1 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -127,6 +127,7 @@ private: u32 ColorBlend5(u32 val1, u32 val2); u32 ColorBrightnessUp(u32 val, u32 factor); u32 ColorBrightnessDown(u32 val, u32 factor); + u32 ColorComposite(int i, u32 val1, u32 val2); template void DrawScanlineBGMode(u32 line, u32 nsprites); void DrawScanlineBGMode6(u32 line, u32 nsprites); diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 9144792..c759147 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -890,6 +890,8 @@ void RenderSceneChunk(int y, int h) glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID); glBindVertexArray(ClearVertexArrayID); glDrawArrays(GL_TRIANGLES, 0, 2*3); + + glFlush(); } } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 3a99d95..2e0c271 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -216,7 +216,7 @@ bool GLScreen_Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1024, 1536, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 256*3 + 1, 192*2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); GL_ScreenSizeDirty = true; @@ -317,31 +317,31 @@ void GLScreen_DrawScreen() switch (ScreenRotation) { case 0: - s0 = 0; t0 = 768; - s1 = scwidth; t1 = 768; - s2 = 0; t2 = 768+scheight; - s3 = scwidth; t3 = 768+scheight; + s0 = 0; t0 = 192; + s1 = scwidth; t1 = 192; + s2 = 0; t2 = 192+scheight; + s3 = scwidth; t3 = 192+scheight; break; case 1: - s0 = 0; t0 = 768+scheight; - s1 = 0; t1 = 768; - s2 = scwidth; t2 = 768+scheight; - s3 = scwidth; t3 = 768; + s0 = 0; t0 = 192+scheight; + s1 = 0; t1 = 192; + s2 = scwidth; t2 = 192+scheight; + s3 = scwidth; t3 = 192; break; case 2: - s0 = scwidth; t0 = 768+scheight; - s1 = 0; t1 = 768+scheight; - s2 = scwidth; t2 = 768; - s3 = 0; t3 = 768; + s0 = scwidth; t0 = 192+scheight; + s1 = 0; t1 = 192+scheight; + s2 = scwidth; t2 = 192; + s3 = 0; t3 = 192; break; case 3: - s0 = scwidth; t0 = 768; - s1 = scwidth; t1 = 768+scheight; - s2 = 0; t2 = 768; - s3 = 0; t3 = 768+scheight; + s0 = scwidth; t0 = 192; + s1 = scwidth; t1 = 192+scheight; + s2 = 0; t2 = 192; + s3 = 0; t3 = 192+scheight; break; } @@ -381,14 +381,14 @@ void GLScreen_DrawScreen() { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256, 192, GL_RGBA_INTEGER, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3 + 2, 192, GL_RGBA_INTEGER, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3 + 1, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256*3 + 2, 192, GL_RGBA_INTEGER, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256*3 + 1, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); } } @@ -2241,11 +2241,13 @@ void DestroyMainWindow() void RecreateMainWindow(bool opengl) { - int winX, winY; + int winX, winY, maxi; uiWindowPosition(MainWindow, &winX, &winY); + maxi = uiWindowMaximized(MainWindow); DestroyMainWindow(); CreateMainWindow(opengl); uiWindowSetPosition(MainWindow, winX, winY); + uiWindowSetMaximized(MainWindow, maxi); } diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h index d6d898d..a855f1b 100644 --- a/src/libui_sdl/main_shaders.h +++ b/src/libui_sdl/main_shaders.h @@ -66,121 +66,81 @@ void main() { ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); - // bit0-13: BLDCNT - // bit14-15: DISPCNT display mode - // bit16-20: EVA - // bit21-25: EVB - // bit26-30: EVY - ivec4 ctl = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); - ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3 + 1, int(fTexcoord.y)), 0)); - int dispmode = (ctl.g >> 6) & 0x3; + ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); + int dispmode = mbright.b & 0x3; if (dispmode == 1) { - int eva = ctl.b & 0x1F; - int evb = (ctl.b >> 5) | ((ctl.a & 0x03) << 3); - int evy = ctl.a >> 2; + ivec4 val1 = pixel; + ivec4 val2 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0)); + ivec4 val3 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0)); - ivec4 top = pixel; - ivec4 mid = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0)); - ivec4 bot = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0)); + int compmode = val3.a & 0xF; + int eva, evb, evy; - int winmask = top.b >> 7; - - if ((top.a & 0xC0) == 0x40) + if (compmode == 4) { - float xpos = top.r + fract(fTexcoord.x); - float ypos = mod(fTexcoord.y, 768); - ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra - * vec4(63,63,63,31)); + // 3D on top, blending - if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } - else top = mid; - } - else if ((mid.a & 0xC0) == 0x40) - { - float xpos = mid.r + fract(fTexcoord.x); - float ypos = mod(fTexcoord.y, 768); + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra * vec4(63,63,63,31)); - if (_3dpix.a > 0) { bot = _3dpix; bot.a |= 0x40; } - } - else - { - // conditional texture fetch no good for performance, apparently - //texelFetch(_3DTex, ivec2(0, fTexcoord.y*2), 0); - bot = mid; - } - - top.b &= 0x3F; - bot.b &= 0x3F; - - int target2; - if ((bot.a & 0x80) != 0) target2 = 0x10; - else if ((bot.a & 0x40) != 0) target2 = 0x01; - else target2 = bot.a; - bool t2pass = ((ctl.g & target2) != 0); - - int coloreffect = 0; + if (_3dpix.a > 0) + { + eva = (_3dpix.a & 0x1F) + 1; + evb = 32 - eva; - if ((top.a & 0x80) != 0 && t2pass) + val1 = ((_3dpix * eva) + (val1 * evb)) >> 5; + if (eva <= 16) val1 += ivec4(1,1,1,0); + val1 = min(val1, 0x3F); + } + else + val1 = val2; + } + else if (compmode == 1) { - // sprite blending + // 3D on bottom, blending - coloreffect = 1; + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + * vec4(63,63,63,31)); - if ((top.a & 0x40) != 0) + if (_3dpix.a > 0) { - eva = top.a & 0x1F; - evb = 16 - eva; + eva = val3.g; + evb = val3.b; + + val1 = ((val1 * eva) + (_3dpix * evb)) >> 4; + val1 = min(val1, 0x3F); } + else + val1 = val2; } - else if ((top.a & 0x40) != 0 && t2pass) + else if (compmode <= 3) { - // 3D layer blending + // 3D on top, normal/fade - coloreffect = 4; - eva = (top.a & 0x1F) + 1; - evb = 32 - eva; - } - else - { - if ((top.a & 0x80) != 0) top.a = 0x10; - else if ((top.a & 0x40) != 0) top.a = 0x01; + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + * vec4(63,63,63,31)); - if ((ctl.r & top.a) != 0 && winmask != 0) + if (_3dpix.a > 0) { - int effect = ctl.r >> 6; - if ((effect != 1) || t2pass) coloreffect = effect; + evy = val3.g; + + val1 = _3dpix; + if (compmode == 2) val1 += ((ivec4(0x3F,0x3F,0x3F,0) - val1) * evy) >> 4; + else if (compmode == 3) val1 -= (val1 * evy) >> 4; } + else + val1 = val2; } - if (coloreffect == 0) - { - pixel = top; - } - else if (coloreffect == 1) - { - pixel = ((top * eva) + (bot * evb)) >> 4; - pixel = min(pixel, 0x3F); - } - else if (coloreffect == 2) - { - pixel = top; - pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; - } - else if (coloreffect == 3) - { - pixel = top; - pixel -= (pixel * evy) >> 4; - } - else - { - pixel = ((top * eva) + (bot * evb)) >> 5; - if (eva <= 16) pixel += ivec4(1,1,1,0); - pixel = min(pixel, 0x3F); - } + pixel = val1; } if (dispmode != 0) -- cgit v1.2.3 From 956c2c5d86a19e8aa5b51b95a4b5cd46f794df58 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 19:47:19 +0200 Subject: finalize the GL/software switch --- src/libui_sdl/main.cpp | 48 +++++++++++++++++++++++++++++--------------- src/libui_sdl/main_shaders.h | 25 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 2e0c271..f6ef397 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -109,6 +109,7 @@ bool ScreenDrawInited = false; uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; GLuint GL_ScreenShader[3]; +GLuint GL_ScreenShaderAccel[3]; struct { float uScreenSize[2]; @@ -169,29 +170,45 @@ void RecreateMainWindow(bool opengl); +bool GLScreen_InitShader(GLuint* shader, const char* fs) +{ + if (!OpenGL_BuildShaderProgram(kScreenVS, fs, shader, "ScreenShader")) + return false; + + GLuint uni_id; + + uni_id = glGetUniformBlockIndex(shader[2], "uConfig"); + glUniformBlockBinding(shader[2], uni_id, 16); + + glUseProgram(shader[2]); + uni_id = glGetUniformLocation(shader[2], "ScreenTex"); + glUniform1i(uni_id, 0); + uni_id = glGetUniformLocation(shader[2], "_3DTex"); + glUniform1i(uni_id, 1); + + glBindAttribLocation(shader[2], 0, "vPosition"); + glBindAttribLocation(shader[2], 1, "vTexcoord"); + glBindFragDataLocation(shader[2], 0, "oColor"); + + return true; +} + bool GLScreen_Init() { if (!OpenGL_Init()) return false; - if (!OpenGL_BuildShaderProgram(kScreenVS, kScreenFS, GL_ScreenShader, "ScreenShader")) + if (!GLScreen_InitShader(GL_ScreenShader, kScreenFS)) + return false; + if (!GLScreen_InitShader(GL_ScreenShaderAccel, kScreenFS_Accel)) return false; - GLuint uni_id; memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig)); glGenBuffers(1, &GL_ShaderConfigUBO); glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO); glBufferData(GL_UNIFORM_BUFFER, sizeof(GL_ShaderConfig), &GL_ShaderConfig, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, 16, GL_ShaderConfigUBO); - uni_id = glGetUniformBlockIndex(GL_ScreenShader[2], "uConfig"); - glUniformBlockBinding(GL_ScreenShader[2], uni_id, 16); - - glUseProgram(GL_ScreenShader[2]); - uni_id = glGetUniformLocation(GL_ScreenShader[2], "ScreenTex"); - glUniform1i(uni_id, 0); - uni_id = glGetUniformLocation(GL_ScreenShader[2], "_3DTex"); - glUniform1i(uni_id, 1); glGenBuffers(1, &GL_ScreenVertexBufferID); glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); @@ -204,11 +221,6 @@ bool GLScreen_Init() glEnableVertexAttribArray(1); // texcoord glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(2*4)); - glBindAttribLocation(GL_ScreenShader[2], 0, "vPosition"); - glBindAttribLocation(GL_ScreenShader[2], 1, "vTexcoord"); - glBindFragDataLocation(GL_ScreenShader[2], 0, "oColor"); - - // TODO: consider reallocating the texture when changing screen sizes glGenTextures(1, &GL_ScreenTexture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); @@ -231,6 +243,7 @@ void GLScreen_DeInit() glDeleteBuffers(1, &GL_ScreenVertexBufferID); OpenGL_DeleteShaderProgram(GL_ScreenShader); + OpenGL_DeleteShaderProgram(GL_ScreenShaderAccel); } void GLScreen_DrawScreen() @@ -365,7 +378,10 @@ void GLScreen_DrawScreen() glViewport(0, 0, WindowWidth, WindowHeight); - OpenGL_UseShaderProgram(GL_ScreenShader); + if (GPU3D::Renderer == 0) + OpenGL_UseShaderProgram(GL_ScreenShader); + else + OpenGL_UseShaderProgram(GL_ScreenShaderAccel); glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(0, 1, 0, 1); diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h index a855f1b..f03931c 100644 --- a/src/libui_sdl/main_shaders.h +++ b/src/libui_sdl/main_shaders.h @@ -55,6 +55,31 @@ layout(std140) uniform uConfig uint uFilterMode; }; +uniform usampler2D ScreenTex; + +smooth in vec2 fTexcoord; + +out vec4 oColor; + +void main() +{ + ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); + + // TODO: filters + + oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0); +} +)"; + +const char* kScreenFS_Accel = R"(#version 140 + +layout(std140) uniform uConfig +{ + vec2 uScreenSize; + uint u3DScale; + uint uFilterMode; +}; + uniform usampler2D ScreenTex; uniform sampler2D _3DTex; -- cgit v1.2.3 From 9ed1dda9ca18e571fc6613885ac944bbb938cd9a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 19:52:56 +0200 Subject: fix possible crash --- src/GPU.cpp | 41 +++++++++++++++++++---------------------- src/libui_sdl/main.cpp | 2 +- 2 files changed, 20 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/GPU.cpp b/src/GPU.cpp index fe23a77..d1870fd 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -150,7 +150,7 @@ void Reset() VRAMMap_ARM7[0] = 0; VRAMMap_ARM7[1] = 0; - +printf("RESET: ACCEL=%d FRAMEBUFFER=%p\n", Accelerated, Framebuffer[0][0]); int fbsize; if (Accelerated) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; @@ -254,27 +254,24 @@ void AssignFramebuffers() void SetDisplaySettings(bool accel) { - if (accel != Accelerated) - { - int fbsize; - 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]; - if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; - if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; - Framebuffer[0][0] = new u32[fbsize]; - Framebuffer[1][0] = new u32[fbsize]; - Framebuffer[0][1] = new u32[fbsize]; - Framebuffer[1][1] = new u32[fbsize]; - - memset(Framebuffer[0][0], 0, fbsize*4); - memset(Framebuffer[1][0], 0, fbsize*4); - memset(Framebuffer[0][1], 0, fbsize*4); - memset(Framebuffer[1][1], 0, fbsize*4); - - AssignFramebuffers(); - } + int fbsize; + 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]; + if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; + if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; + Framebuffer[0][0] = new u32[fbsize]; + Framebuffer[1][0] = new u32[fbsize]; + Framebuffer[0][1] = new u32[fbsize]; + Framebuffer[1][1] = new u32[fbsize]; + + memset(Framebuffer[0][0], 0, fbsize*4); + memset(Framebuffer[1][0], 0, fbsize*4); + memset(Framebuffer[0][1], 0, fbsize*4); + memset(Framebuffer[1][1], 0, fbsize*4); + + AssignFramebuffers(); GPU2D_A->SetDisplaySettings(accel); GPU2D_B->SetDisplaySettings(accel); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index f6ef397..874d8ff 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -384,7 +384,7 @@ void GLScreen_DrawScreen() OpenGL_UseShaderProgram(GL_ScreenShaderAccel); glBindFramebuffer(GL_FRAMEBUFFER, 0); - glClearColor(0, 1, 0, 1); + glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); int frontbuf = GPU::FrontBuffer; -- cgit v1.2.3 From af581513fb98e37b6c8b3d856ad7f63d4d905040 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 20:51:26 +0200 Subject: * remove old 'threaded 3D' setting from emu settings dialog * remove 'antialiasing' for now --- src/libui_sdl/DlgEmuSettings.cpp | 8 -------- src/libui_sdl/DlgVideoSettings.cpp | 16 ++++++++-------- 2 files changed, 8 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/DlgEmuSettings.cpp b/src/libui_sdl/DlgEmuSettings.cpp index 7d774a0..ad8c047 100644 --- a/src/libui_sdl/DlgEmuSettings.cpp +++ b/src/libui_sdl/DlgEmuSettings.cpp @@ -37,7 +37,6 @@ bool opened; uiWindow* win; uiCheckbox* cbDirectBoot; -uiCheckbox* cbThreaded3D; int OnCloseWindow(uiWindow* window, void* blarg) @@ -55,14 +54,11 @@ void OnCancel(uiButton* btn, void* blarg) void OnOk(uiButton* btn, void* blarg) { Config::DirectBoot = uiCheckboxChecked(cbDirectBoot); - Config::Threaded3D = uiCheckboxChecked(cbThreaded3D); Config::Save(); uiControlDestroy(uiControl(win)); opened = false; - - ApplyNewSettings(0); } void Open() @@ -87,9 +83,6 @@ void Open() cbDirectBoot = uiNewCheckbox("Boot game directly"); uiBoxAppend(in_ctrl, uiControl(cbDirectBoot), 0); - - cbThreaded3D = uiNewCheckbox("Threaded 3D renderer"); - uiBoxAppend(in_ctrl, uiControl(cbThreaded3D), 0); } { @@ -110,7 +103,6 @@ void Open() } uiCheckboxSetChecked(cbDirectBoot, Config::DirectBoot); - uiCheckboxSetChecked(cbThreaded3D, Config::Threaded3D); uiControlShow(uiControl(win)); } diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index 329c79e..69e5ac5 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -59,14 +59,14 @@ void UpdateControls() uiControlEnable(uiControl(cbGLDisplay)); uiControlEnable(uiControl(cbThreaded3D)); uiControlDisable(uiControl(cbResolution)); - uiControlDisable(uiControl(cbAntialias)); + //uiControlDisable(uiControl(cbAntialias)); } else { uiControlDisable(uiControl(cbGLDisplay)); uiControlDisable(uiControl(cbThreaded3D)); uiControlEnable(uiControl(cbResolution)); - uiControlEnable(uiControl(cbAntialias)); + //uiControlEnable(uiControl(cbAntialias)); } } @@ -260,12 +260,12 @@ void Open() } uiBoxAppend(in_ctrl, uiControl(cbResolution), 0); - lbl = uiNewLabel(""); - uiBoxAppend(in_ctrl, uiControl(lbl), 0); + //lbl = uiNewLabel(""); + //uiBoxAppend(in_ctrl, uiControl(lbl), 0); - cbAntialias = uiNewCheckbox("Antialiasing"); - uiCheckboxOnToggled(cbAntialias, OnAntialiasChanged, NULL); - uiBoxAppend(in_ctrl, uiControl(cbAntialias), 0); + //cbAntialias = uiNewCheckbox("Antialiasing"); + //uiCheckboxOnToggled(cbAntialias, OnAntialiasChanged, NULL); + //uiBoxAppend(in_ctrl, uiControl(cbAntialias), 0); } { @@ -299,7 +299,7 @@ void Open() uiCheckboxSetChecked(cbGLDisplay, Config::ScreenUseGL); uiCheckboxSetChecked(cbThreaded3D, Config::Threaded3D); uiComboboxSetSelected(cbResolution, Config::GL_ScaleFactor-1); - uiCheckboxSetChecked(cbAntialias, Config::GL_Antialias); + //uiCheckboxSetChecked(cbAntialias, Config::GL_Antialias); uiRadioButtonsSetSelected(rbRenderer, Config::_3DRenderer); UpdateControls(); -- cgit v1.2.3 From eb6fe823f8196373906916b47fbeecf5d7a63e8a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 20:58:32 +0200 Subject: close any opened dialogs when closing the main window --- src/libui_sdl/DlgAudioSettings.cpp | 7 +++++++ src/libui_sdl/DlgAudioSettings.h | 1 + src/libui_sdl/DlgEmuSettings.cpp | 7 +++++++ src/libui_sdl/DlgEmuSettings.h | 1 + src/libui_sdl/DlgInputConfig.cpp | 8 ++++++++ src/libui_sdl/DlgInputConfig.h | 1 + src/libui_sdl/DlgVideoSettings.cpp | 7 +++++++ src/libui_sdl/DlgVideoSettings.h | 1 + src/libui_sdl/DlgWifiSettings.cpp | 7 +++++++ src/libui_sdl/DlgWifiSettings.h | 1 + src/libui_sdl/main.cpp | 13 +++++++++++++ 11 files changed, 54 insertions(+) (limited to 'src') diff --git a/src/libui_sdl/DlgAudioSettings.cpp b/src/libui_sdl/DlgAudioSettings.cpp index 66bdf61..385128c 100644 --- a/src/libui_sdl/DlgAudioSettings.cpp +++ b/src/libui_sdl/DlgAudioSettings.cpp @@ -180,4 +180,11 @@ void Open() uiControlShow(uiControl(win)); } +void Close() +{ + if (!opened) return; + uiControlDestroy(uiControl(win)); + opened = false; +} + } diff --git a/src/libui_sdl/DlgAudioSettings.h b/src/libui_sdl/DlgAudioSettings.h index 30a5d53..f058c25 100644 --- a/src/libui_sdl/DlgAudioSettings.h +++ b/src/libui_sdl/DlgAudioSettings.h @@ -23,6 +23,7 @@ namespace DlgAudioSettings { void Open(); +void Close(); } diff --git a/src/libui_sdl/DlgEmuSettings.cpp b/src/libui_sdl/DlgEmuSettings.cpp index ad8c047..768560d 100644 --- a/src/libui_sdl/DlgEmuSettings.cpp +++ b/src/libui_sdl/DlgEmuSettings.cpp @@ -107,4 +107,11 @@ void Open() uiControlShow(uiControl(win)); } +void Close() +{ + if (!opened) return; + uiControlDestroy(uiControl(win)); + opened = false; +} + } diff --git a/src/libui_sdl/DlgEmuSettings.h b/src/libui_sdl/DlgEmuSettings.h index 126497a..baff7ce 100644 --- a/src/libui_sdl/DlgEmuSettings.h +++ b/src/libui_sdl/DlgEmuSettings.h @@ -23,6 +23,7 @@ namespace DlgEmuSettings { void Open(); +void Close(); } diff --git a/src/libui_sdl/DlgInputConfig.cpp b/src/libui_sdl/DlgInputConfig.cpp index 513bd90..98cdf8c 100644 --- a/src/libui_sdl/DlgInputConfig.cpp +++ b/src/libui_sdl/DlgInputConfig.cpp @@ -450,5 +450,13 @@ void Open(int type) uiControlShow(uiControl(dlg->win)); } +void Close(int type) +{ + if (openedmask & (1< Date: Sat, 25 May 2019 21:03:39 +0200 Subject: for config dialogs that reflect changes instantly, make behavior of window close button consistent with that of Cancel button --- src/libui_sdl/DlgAudioSettings.cpp | 9 +++- src/libui_sdl/DlgVideoSettings.cpp | 84 ++++++++++++++++++++------------------ 2 files changed, 53 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/DlgAudioSettings.cpp b/src/libui_sdl/DlgAudioSettings.cpp index 385128c..d649321 100644 --- a/src/libui_sdl/DlgAudioSettings.cpp +++ b/src/libui_sdl/DlgAudioSettings.cpp @@ -44,8 +44,15 @@ uiEntry* txMicWavPath; int oldvolume; +void RevertSettings() +{ + Config::AudioVolume = oldvolume; +} + + int OnCloseWindow(uiWindow* window, void* blarg) { + RevertSettings(); opened = false; return 1; } @@ -69,7 +76,7 @@ void OnMicWavBrowse(uiButton* btn, void* blarg) void OnCancel(uiButton* btn, void* blarg) { - Config::AudioVolume = oldvolume; + RevertSettings(); uiControlDestroy(uiControl(win)); opened = false; diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index 8749dc5..5c5d5f9 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -70,9 +70,53 @@ void UpdateControls() } } +void RevertSettings() +{ + bool apply0 = false; + bool apply2 = false; + bool apply3 = false; + + bool old_usegl = (old_gldisplay != 0) || (old_renderer != 0); + bool new_usegl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); + + if (old_renderer != Config::_3DRenderer) + { + Config::_3DRenderer = old_renderer; + apply3 = true; + } + + if (old_gldisplay != Config::ScreenUseGL) + { + Config::ScreenUseGL = old_gldisplay; + } + if (old_usegl != new_usegl) + { + apply2 = true; + } + + if (old_threaded3D != Config::Threaded3D) + { + Config::Threaded3D = old_threaded3D; + apply0 = true; + } + + if (old_resolution != Config::GL_ScaleFactor || + old_antialias != Config::GL_Antialias) + { + Config::GL_ScaleFactor = old_resolution; + Config::GL_Antialias = old_antialias; + apply0 = true; + } + + if (apply2) ApplyNewSettings(2); + else if (apply3) ApplyNewSettings(3); + if (apply0) ApplyNewSettings(0); +} + int OnCloseWindow(uiWindow* window, void* blarg) { + RevertSettings(); opened = false; return 1; } @@ -121,45 +165,7 @@ void OnAntialiasChanged(uiCheckbox* cb, void* blarg) void OnCancel(uiButton* btn, void* blarg) { - bool apply0 = false; - bool apply2 = false; - bool apply3 = false; - - bool old_usegl = (old_gldisplay != 0) || (old_renderer != 0); - bool new_usegl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); - - if (old_renderer != Config::_3DRenderer) - { - Config::_3DRenderer = old_renderer; - apply3 = true; - } - - if (old_gldisplay != Config::ScreenUseGL) - { - Config::ScreenUseGL = old_gldisplay; - } - if (old_usegl != new_usegl) - { - apply2 = true; - } - - if (old_threaded3D != Config::Threaded3D) - { - Config::Threaded3D = old_threaded3D; - apply0 = true; - } - - if (old_resolution != Config::GL_ScaleFactor || - old_antialias != Config::GL_Antialias) - { - Config::GL_ScaleFactor = old_resolution; - Config::GL_Antialias = old_antialias; - apply0 = true; - } - - if (apply2) ApplyNewSettings(2); - else if (apply3) ApplyNewSettings(3); - if (apply0) ApplyNewSettings(0); + RevertSettings(); uiControlDestroy(uiControl(win)); opened = false; -- 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') 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 31e0f15797d0b6545ddc1a361252f267bf5d793d Mon Sep 17 00:00:00 2001 From: PoroCYon Date: Sun, 26 May 2019 00:37:51 +0200 Subject: fix oudated CMake compile settings, add OpenGL dependency for Linux --- .gitignore | 1 + src/CMakeLists.txt | 5 +++++ src/OpenGLSupport.cpp | 2 ++ src/libui_sdl/CMakeLists.txt | 2 ++ 4 files changed, 10 insertions(+) (limited to 'src') diff --git a/.gitignore b/.gitignore index 2d5b5f4..f63e239 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ obj *.o melon_grc.c melon_grc.h +cmake-build diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4b1149f..72ae4bf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,8 +22,13 @@ add_library(core STATIC SPU.cpp Wifi.cpp WifiAP.cpp + # opengl backend stuff + GPU3D_OpenGL.cpp + OpenGLSupport.cpp ) if (WIN32) target_link_libraries(core ole32 comctl32 ws2_32) +else() + target_link_libraries(core OpenGL) endif() diff --git a/src/OpenGLSupport.cpp b/src/OpenGLSupport.cpp index 0204835..bb9e180 100644 --- a/src/OpenGLSupport.cpp +++ b/src/OpenGLSupport.cpp @@ -18,6 +18,8 @@ #include "OpenGLSupport.h" +#include + DO_PROCLIST(DECLPROC); diff --git a/src/libui_sdl/CMakeLists.txt b/src/libui_sdl/CMakeLists.txt index 40019db..0b7545b 100644 --- a/src/libui_sdl/CMakeLists.txt +++ b/src/libui_sdl/CMakeLists.txt @@ -10,6 +10,8 @@ SET(SOURCES_LIBUI DlgEmuSettings.cpp DlgInputConfig.cpp DlgWifiSettings.cpp + # opengl backend stuff + DlgVideoSettings.cpp ) option(BUILD_SHARED_LIBS "Whether to build libui as a shared library or a static library" ON) -- cgit v1.2.3 From 38f61a24fcdf5a78cbabc9184f55ded3b496f1d4 Mon Sep 17 00:00:00 2001 From: PoroCYon Date: Sun, 26 May 2019 00:38:24 +0200 Subject: 'port' libui GL stuff to Linux Only implemented the functions needed by melonDS, and only tested using a very recent mesa+libglvnd+nouveau. Will most likely bork using proprietary nvidia or old(er) drivers (see gl.c) --- src/libui_sdl/libui/unix/CMakeLists.txt | 1 + src/libui_sdl/libui/unix/area.c | 41 ++++++++++++++++++++++++++++ src/libui_sdl/libui/unix/gl.c | 47 +++++++++++++++++++++++++++++++++ src/libui_sdl/libui/unix/uipriv_unix.h | 6 ++++- src/libui_sdl/libui/unix/window.c | 18 +++++++++++++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 src/libui_sdl/libui/unix/gl.c (limited to 'src') diff --git a/src/libui_sdl/libui/unix/CMakeLists.txt b/src/libui_sdl/libui/unix/CMakeLists.txt index 9300bcb..ec9ab75 100644 --- a/src/libui_sdl/libui/unix/CMakeLists.txt +++ b/src/libui_sdl/libui/unix/CMakeLists.txt @@ -43,6 +43,7 @@ list(APPEND _LIBUI_SOURCES unix/text.c unix/util.c unix/window.c + unix/gl.c ) set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE) diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c index 2da9bab..e518ae5 100644 --- a/src/libui_sdl/libui/unix/area.c +++ b/src/libui_sdl/libui/unix/area.c @@ -38,7 +38,10 @@ struct uiArea { GtkWidget *areaWidget; GtkDrawingArea *drawingArea; + GtkGLArea *glArea; areaWidget *area; + + GdkGLContext *glContext; int bgR, bgG, bgB; @@ -730,6 +733,44 @@ uiArea *uiNewArea(uiAreaHandler *ah) return a; } +uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions) +{ + uiArea *a; + + uiUnixNewControl(uiArea, a); + + a->ah = ah; + a->scrolling = FALSE; + + GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new(); + GdkGLContext* ctx = NULL; + + 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); + } + + a->glContext = ctx; + a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType, "libui-area", + a, NULL)); + a->glArea = gla; + a->area = areaWidget(a->areaWidget); + + a->widget = a->areaWidget; + + uiAreaSetBackgroundColor(a, -1, -1, -1); + + return a; +} + +uiGLContext *uiAreaGetGLContext(uiArea* a) +{ + if (!a) return NULL; + return a->glContext; +} + uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height) { uiArea *a; diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c new file mode 100644 index 0000000..da41437 --- /dev/null +++ b/src/libui_sdl/libui/unix/gl.c @@ -0,0 +1,47 @@ +// 26 may 2019 +#include "uipriv_unix.h" + +/* + *(melonDS:17013): Gtk-CRITICAL **: 00:28:09.095: gtk_gl_area_set_required_version: assertion 'GTK_IS_GL_AREA (area)' failed + +(melonDS:17013): GLib-GObject-WARNING **: 00:28:09.096: invalid cast from 'GtkGLArea' to 'areaWidget' + */ + +struct uiGLContext { + GtkGLArea *gla; + GdkGLContext *gctx; + int vermaj, vermin; +}; + +uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min) +{ + uiGLContext *ret = uiAlloc(sizeof(uiGLContext), "uiGLContext"); + ret->gla = gla; + ret->gctx = gtk_gl_area_get_context(gla); + ret->vermaj = maj; ret->vermin = min; + return ret; +} + +void uiGLSwapBuffers(uiGLContext* ctx) +{ + if (!ctx) return; + gtk_gl_area_attach_buffers(ctx->gla); +} + +void uiGLMakeContextCurrent(uiGLContext* ctx) +{ + if (!ctx) return; + gtk_gl_area_make_current(ctx->gla); +} +void *uiGLGetProcAddress(const char* proc) +{ + // this *will* break for older systems that don't have libglvnd! + // TODO: use a real solution + return dlsym(NULL /* RTLD_DEFAULT */, proc); +} +unsigned int uiGLGetVersion(uiGLContext* ctx) +{ + if (!ctx) return 0; + return uiGLVersion(ctx->vermaj, ctx->vermin); +} + diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h index 33ff1e3..42d5d76 100644 --- a/src/libui_sdl/libui/unix/uipriv_unix.h +++ b/src/libui_sdl/libui/unix/uipriv_unix.h @@ -5,7 +5,7 @@ #define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_10 #include #include -#include // see drawtext.c +#include // see drawtext.c, gl.c #include #include #include @@ -63,3 +63,7 @@ extern GtkCellRenderer *newCellRendererButton(void); extern void loadFutures(void); extern PangoAttribute *FUTURE_pango_attr_foreground_alpha_new(guint16 alpha); extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, gint pos, const char *name); + +// gl.c +extern uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min); + diff --git a/src/libui_sdl/libui/unix/window.c b/src/libui_sdl/libui/unix/window.c index 7da1134..6d5e2de 100644 --- a/src/libui_sdl/libui/unix/window.c +++ b/src/libui_sdl/libui/unix/window.c @@ -102,6 +102,23 @@ static void uiWindowDestroy(uiControl *c) uiFreeControl(uiControl(w)); } +void uiWindowSetPosition(uiWindow *w, int x, int y) +{ + if (!w) return; + + gtk_window_move(w->window, x, y); +} + +void uiWindowPosition(uiWindow *w, int *x, int *y) +{ + if (!w) return; + + int xx, yy; + gtk_window_get_position(w->window, &xx, &yy); + if (x) *x = xx; + if (y) *y = yy; +} + uiUnixControlDefaultHandle(uiWindow) uiControl *uiWindowParent(uiControl *c) @@ -442,3 +459,4 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int maximized, i return w; } + -- cgit v1.2.3 From ebad773a3881f31ab668cc0cbea89cc34f5cd2b7 Mon Sep 17 00:00:00 2001 From: PoroCYon Date: Sun, 26 May 2019 00:46:35 +0200 Subject: apply tgsm's changes (see PR #411 ) --- src/CMakeLists.txt | 2 +- src/libui_sdl/libui/windows/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 72ae4bf..702edf5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,7 +28,7 @@ add_library(core STATIC ) if (WIN32) - target_link_libraries(core ole32 comctl32 ws2_32) + target_link_libraries(core ole32 comctl32 ws2_32 opengl32) else() target_link_libraries(core OpenGL) endif() diff --git a/src/libui_sdl/libui/windows/CMakeLists.txt b/src/libui_sdl/libui/windows/CMakeLists.txt index 4695eb4..9d5313a 100644 --- a/src/libui_sdl/libui/windows/CMakeLists.txt +++ b/src/libui_sdl/libui/windows/CMakeLists.txt @@ -29,6 +29,7 @@ list(APPEND _LIBUI_SOURCES windows/fontbutton.cpp windows/fontdialog.cpp windows/form.cpp + windows/gl.cpp windows/graphemes.cpp windows/grid.cpp windows/group.cpp -- 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') 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 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') 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 ce9d728fb6fe97a36eba5294a793f0d451c8fd6d Mon Sep 17 00:00:00 2001 From: StapleButter Date: Thu, 30 May 2019 17:29:41 +0200 Subject: fix cleanup of libui objects when closing melonDS fixes to Cmake shito attempt shit --- src/libui_sdl/CMakeLists.txt | 5 +- src/libui_sdl/libui/ui.h | 2 + src/libui_sdl/libui/unix/CMakeLists.txt | 1 + src/libui_sdl/libui/unix/area.c | 67 ++++++++--- src/libui_sdl/libui/unix/gl.c | 201 ++++++++++++++++++++++++++++---- src/libui_sdl/libui/unix/main.c | 31 +++++ src/libui_sdl/libui/unix/uipriv_unix.h | 20 +++- src/libui_sdl/main.cpp | 31 +++-- 8 files changed, 304 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/CMakeLists.txt b/src/libui_sdl/CMakeLists.txt index 61e0981..e9a54e2 100644 --- a/src/libui_sdl/CMakeLists.txt +++ b/src/libui_sdl/CMakeLists.txt @@ -9,9 +9,8 @@ SET(SOURCES_LIBUI DlgAudioSettings.cpp DlgEmuSettings.cpp DlgInputConfig.cpp - DlgWifiSettings.cpp - # opengl backend stuff DlgVideoSettings.cpp + DlgWifiSettings.cpp ) option(BUILD_SHARED_LIBS "Whether to build libui as a shared library or a static library" ON) @@ -47,7 +46,7 @@ if (UNIX) --generate-header "${CMAKE_SOURCE_DIR}/melon_grc.xml") if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - target_link_libraries(melonDS dl X11) + target_link_libraries(melonDS dl) 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 0c89d90..47da54b 100644 --- a/src/libui_sdl/libui/ui.h +++ b/src/libui_sdl/libui/ui.h @@ -613,6 +613,8 @@ typedef struct uiGLContext uiGLContext; _UI_EXTERN uiGLContext *uiAreaGetGLContext(uiArea* a); _UI_EXTERN void uiGLMakeContextCurrent(uiGLContext* ctx); +_UI_EXTERN void uiGLBegin(uiGLContext* ctx); +_UI_EXTERN void uiGLEnd(uiGLContext* ctx); _UI_EXTERN unsigned int uiGLGetVersion(uiGLContext* ctx); _UI_EXTERN void *uiGLGetProcAddress(const char* proc); _UI_EXTERN int uiGLGetFramebuffer(uiGLContext* ctx); diff --git a/src/libui_sdl/libui/unix/CMakeLists.txt b/src/libui_sdl/libui/unix/CMakeLists.txt index ec9ab75..c69081e 100644 --- a/src/libui_sdl/libui/unix/CMakeLists.txt +++ b/src/libui_sdl/libui/unix/CMakeLists.txt @@ -63,6 +63,7 @@ macro(_handle_static) set(_oname libui-combined.o) add_custom_command( OUTPUT ${_oname} + DEPENDS ${_LIBUINAME} COMMAND ld -r --whole-archive ${_aname} -o ${_oname} COMMAND diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c index bf92ddf..62a4cb0 100644 --- a/src/libui_sdl/libui/unix/area.c +++ b/src/libui_sdl/libui/unix/area.c @@ -3,18 +3,6 @@ extern GThread* gtkthread; -// notes: -// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14) -#define areaWidgetType (areaWidget_get_type()) -#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget)) -#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType)) -#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass)) -#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget)) -#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass)) - -typedef struct areaWidget areaWidget; -typedef struct areaWidgetClass areaWidgetClass; - struct areaWidget { GtkDrawingArea parent_instance; uiArea *a; @@ -45,6 +33,7 @@ struct uiArea { gboolean opengl; uiGLContext *glContext; + gboolean drawreq; int bgR, bgG, bgB; @@ -63,6 +52,21 @@ struct uiArea { G_DEFINE_TYPE(areaWidget, areaWidget, GTK_TYPE_DRAWING_AREA) +int boub(GtkWidget* w) { return isAreaWidget(w); } +void baba(GtkWidget* w) +{ + if (!isAreaWidget(w)) return; + + areaWidget *aw = areaWidget(w); + uiArea *a = aw->a; + if (!a->opengl) return; + + GdkGLContext* oldctx = gdk_gl_context_get_current(); + uiGLMakeContextCurrent(a->glContext); + glFinish(); + gdk_gl_context_make_current(oldctx); +} + static void areaWidget_init(areaWidget *aw) { // for events @@ -130,6 +134,22 @@ static void loadAreaSize(uiArea *a, double *width, double *height) void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx); +void areaPreRedraw(areaWidget* widget) +{ + uiArea* a = widget->a; + if (!a->opengl) return; + + areaPreRedrawGL(a->glContext); +} + +void areaPostRedraw(areaWidget* widget) +{ + uiArea* a = widget->a; + if (!a->opengl) return; + + areaPostRedrawGL(a->glContext); +} + static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) { areaWidget *aw = areaWidget(w); @@ -161,6 +181,8 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) else { areaDrawGL(w, &dp, cr, a->glContext); + //if (a->drawreq) uiGLEnd(a->glContext); + a->drawreq = FALSE; } freeContext(dp.Context); @@ -613,7 +635,15 @@ static void areaWidget_class_init(areaWidgetClass *class) // control implementation -uiUnixControlAllDefaults(uiArea) +uiUnixControlAllDefaultsExceptDestroy(uiArea) + +static void uiAreaDestroy(uiControl *c) +{ + uiArea* a = uiArea(c); + if (a->opengl && a->glContext) freeGLContext(a->glContext); + g_object_unref(uiArea(c)->widget); + uiFreeControl(c); +} void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b) { @@ -634,6 +664,8 @@ void uiAreaSetSize(uiArea *a, int width, int height) gboolean _threadsaferefresh(gpointer data) { uiArea* a = (uiArea*)data; + a->drawreq = TRUE; + //if (a->opengl) uiGLBegin(a->glContext); gtk_widget_queue_draw(a->areaWidget); return FALSE; } @@ -644,7 +676,11 @@ void uiAreaQueueRedrawAll(uiArea *a) if (g_thread_self() != gtkthread) g_idle_add(_threadsaferefresh, a); else + { + a->drawreq = TRUE; + //if (a->opengl) uiGLBegin(a->glContext); gtk_widget_queue_draw(a->areaWidget); + } } void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height) @@ -767,10 +803,12 @@ printf("create glarea\n"); a->ah = ah; a->scrolling = FALSE; a->opengl = TRUE; + a->drawreq = FALSE; //GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new(); uiGLContext* ctx = NULL; printf("create sdfsf\n"); + // TODO: move this elsewhere!! so we can actually try all possible versions for (int i = 0; req_versions[i] && !ctx; i++) { int major = uiGLVerMajor(req_versions[i]); int minor = uiGLVerMinor(req_versions[i]); @@ -792,8 +830,7 @@ printf("create jfghjjgh: %p\n", ctx); 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; } diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c index 3504d3a..3861cda 100644 --- a/src/libui_sdl/libui/unix/gl.c +++ b/src/libui_sdl/libui/unix/gl.c @@ -6,12 +6,35 @@ #include extern GThread* gtkthread; +extern GMutex glmutex; /* *(melonDS:17013): Gtk-CRITICAL **: 00:28:09.095: gtk_gl_area_set_required_version: assertion 'GTK_IS_GL_AREA (area)' failed (melonDS:17013): GLib-GObject-WARNING **: 00:28:09.096: invalid cast from 'GtkGLArea' to 'areaWidget' */ + +// MISERABLE LITTLE PILE OF HACKS +#define HAX_GDK_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GL_CONTEXT, HAX_GdkGLContextClass)) +#define HAX_GDK_IS_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GL_CONTEXT)) +#define HAX_GDK_GL_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GL_CONTEXT, HAX_GdkGLContextClass)) + +typedef struct _HAX_GdkGLContextClass HAX_GdkGLContextClass; + +struct _HAX_GdkGLContextClass +{ + GObjectClass parent_class; + + gboolean (* realize) (GdkGLContext *context, + GError **error); + + void (* end_frame) (GdkGLContext *context, + cairo_region_t *painted, + cairo_region_t *damage); + gboolean (* texture_from_surface) (GdkGLContext *context, + cairo_surface_t *surface, + cairo_region_t *region); +}; struct uiGLContext { GtkGLArea *gla; @@ -19,6 +42,11 @@ struct uiGLContext { GdkWindow* window; GdkGLContext *gctx; + GMutex mutex; + GLsync sync; + GLsync sync2; + int zog; + Display* xdisp; GLXPixmap glxpm; GLXContext glxctx; @@ -26,8 +54,8 @@ struct uiGLContext { int width, height; int scale; - GLuint renderbuffer[2]; - GLuint framebuffer; + GLuint renderbuffer[2][2]; + GLuint framebuffer[2]; }; static PFNGLGENRENDERBUFFERSPROC _glGenRenderbuffers; @@ -45,7 +73,16 @@ static PFNGLCHECKFRAMEBUFFERSTATUSPROC _glCheckFramebufferStatus; static int _procsLoaded = 0; -static void _loadGLProcs() +static void (*vniorp)(GdkGLContext*, cairo_region_t*, cairo_region_t*); + +static void class_hax(GdkGLContext* glctx, cairo_region_t* painted, cairo_region_t* damage) +{ + //printf("END FRAME HIJACK\n"); + //glClearColor(0, 1, 0, 1); + vniorp(glctx, painted, damage); +} + +static void _loadGLProcs(GdkGLContext* glctx) { if (_procsLoaded) return; @@ -63,17 +100,25 @@ static void _loadGLProcs() _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)uiGLGetProcAddress("glCheckFramebufferStatus"); _procsLoaded = 1; + + HAX_GdkGLContextClass* class = HAX_GDK_GL_CONTEXT_GET_CLASS(glctx); + printf("HAX class = %p\n", class); + printf("class end_frame = %p\n", class->end_frame); + vniorp = class->end_frame; + class->end_frame = class_hax; } Display* derp; -uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min) +int nswaps = 0; + +uiGLContext *createGLContext(GtkWidget* widget, int maj, int min) { printf("barp\n"); uiGLContext *ret = uiNew(uiGLContext);//uiAlloc(sizeof(uiGLContext), "uiGLContext"); // herp - ret->gla = gla; + ret->gla = widget; ret->gctx = NULL; //while (!ret->gctx) /*{ @@ -111,6 +156,14 @@ uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min) return ret; } +void freeGLContext(uiGLContext* glctx) +{ + if (glctx == NULL) return; + gdk_gl_context_clear_current(); + g_object_unref(glctx->gctx); + uiFree(glctx); +} + static void areaAllocRenderbuffer(uiGLContext* glctx); void databotte(GtkWidget* widget, uiGLContext* ctx) @@ -150,7 +203,7 @@ void databotte(GtkWidget* widget, uiGLContext* ctx) ctx->scale = window_scale; gdk_gl_context_make_current(glctx); - _loadGLProcs(); + _loadGLProcs(glctx); areaAllocRenderbuffer(ctx); ctx->widget = widget; @@ -160,10 +213,10 @@ void databotte(GtkWidget* widget, uiGLContext* ctx) static void areaAllocRenderbuffer(uiGLContext* glctx) { - _glGenRenderbuffers(2, &glctx->renderbuffer[0]);printf("ylarg0 %04X, %d %d\n", glGetError(), glctx->width, glctx->height); + _glGenRenderbuffers(4, &glctx->renderbuffer[0][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); + _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); @@ -176,37 +229,91 @@ static void areaAllocRenderbuffer(uiGLContext* glctx) 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()); + _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]); + + + _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]);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);printf("ylarg2 %04X\n", glGetError()); + _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[0]);printf("ylarg3 %04X\n", glGetError()); - _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1]);printf("ylarg4 %04X\n", glGetError()); + _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]); 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]); + _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); } static void areaRellocRenderbuffer(uiGLContext* glctx) { - _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[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[1]); + _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); } +void areaPreRedrawGL(uiGLContext* glctx) +{ + g_mutex_lock(&glctx->mutex); + + /*gdk_gl_context_make_current(glctx->gctx); + //glClientWaitSync(glctx->sync, 0, GL_TIMEOUT_IGNORED); + glDeleteSync(glctx->sync); + glFinish(); + gdk_gl_context_clear_current();*/ + /*GdkGLContext* oldctx = gdk_gl_context_get_current(); + gdk_gl_context_make_current(glctx->gctx); + printf("[%p] PRE DRAW\n", gdk_gl_context_get_current()); + + gdk_gl_context_make_current(oldctx);*/ + //glClearColor(0,1,0,1); glClear(GL_COLOR_BUFFER_BIT); + //glWaitSync(glctx->sync, 0, GL_TIMEOUT_IGNORED); + /*int ret = glClientWaitSync(glctx->sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000*50); + printf("PRE-DRAW: SYNC %p, %04X, %04X\n", glctx->sync, ret, glGetError()); + glDeleteSync(glctx->sync); + glctx->sync = NULL;*/ + //glFlush(); + if (nswaps > 1) printf("MISSED %d FRAMES\n", nswaps-1); + nswaps = 0; + //glctx->zog ^= 1; +} + +void areaPostRedrawGL(uiGLContext* glctx) +{ + //glctx->sync2 = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + //glFlush(); + //printf("[%p] POST DRAW\n", gdk_gl_context_get_current()); + g_mutex_unlock(&glctx->mutex); +} + void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx) { + //uiGLBegin(glctx); + int window_scale = gdk_window_get_scale_factor(glctx->window); if (glctx->width != dp->AreaWidth || glctx->height != dp->AreaHeight || glctx->scale != window_scale) @@ -218,8 +325,10 @@ void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContex } gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), - glctx->renderbuffer[0], GL_RENDERBUFFER, + glctx->renderbuffer[glctx->zog][0], GL_RENDERBUFFER, 1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale); + + //uiGLEnd(glctx); } uiGLContext* FARTOMATIC(int major, int minor) @@ -229,9 +338,15 @@ uiGLContext* FARTOMATIC(int major, int minor) _ret->vermin = minor; _ret->width = -1; _ret->height = -1; - _ret->renderbuffer[0] = 0; - _ret->renderbuffer[1] = 0; - _ret->framebuffer = 0; + _ret->renderbuffer[0][0] = 0; + _ret->renderbuffer[0][1] = 0; + _ret->framebuffer[0] = 0; + _ret->renderbuffer[1][0] = 0; + _ret->renderbuffer[1][1] = 0; + _ret->framebuffer[1] = 0; + _ret->zog = 0; + + g_mutex_init(&_ret->mutex); return _ret; @@ -348,7 +463,7 @@ uiGLContext* FARTOMATIC(int major, int minor) int uiGLGetFramebuffer(uiGLContext* ctx) { - return ctx->framebuffer; + return ctx->framebuffer[ctx->zog];// ? 0:1]; } float uiGLGetFramebufferScale(uiGLContext* ctx) @@ -358,8 +473,18 @@ float uiGLGetFramebufferScale(uiGLContext* ctx) void uiGLSwapBuffers(uiGLContext* ctx) { - if (!ctx) return; - //gtk_gl_area_attach_buffers(ctx->gla); + /*ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + //gdk_gl_context_clear_current(); + glWaitSync(ctx->sync, 0, GL_TIMEOUT_IGNORED); + glDeleteSync(ctx->sync);*/ + /*printf("[%p] SWAPBUFFERS\n", gdk_gl_context_get_current()); + glClearColor(0,1,0,1); glClear(GL_COLOR_BUFFER_BIT); + glFinish();*/ + //ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + //glFlush(); + //printf("SWAP: SYNC=%p\n", ctx->sync); + //glFinish(); + nswaps++; } static volatile int _ctxset_done; @@ -398,7 +523,7 @@ void uiGLMakeContextCurrent(uiGLContext* ctx) } printf("WE MAED IT CURRENT: %d\n", ret);*/ - printf("[%p] MAKE CONTEXT CURRENT %p, %p\n", g_thread_self(), ctx, ctx?ctx->gctx:NULL); + //printf("[%p] MAKE CONTEXT CURRENT %p, %p\n", g_thread_self(), ctx, ctx?ctx->gctx:NULL); if (!ctx) { gdk_gl_context_clear_current(); @@ -410,6 +535,32 @@ void uiGLMakeContextCurrent(uiGLContext* ctx) //gtk_gl_area_attach_buffers(ctx->gla); //printf("burp = %p / %p\n", burp, ctx->gctx); } + +void uiGLBegin(uiGLContext* ctx) +{ + //g_mutex_lock(&ctx->mutex); + if (g_thread_self() != gtkthread) + { + g_mutex_lock(&glmutex); + + //int ret = glClientWaitSync(ctx->sync2, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000*50); + //printf("GLBEGIN: SYNC %p, %04X, %04X\n", ctx->sync2, ret, glGetError()); + //glDeleteSync(ctx->sync2); + } +} + +void uiGLEnd(uiGLContext* ctx) +{ + //g_mutex_unlock(&ctx->mutex); + if (g_thread_self() != gtkthread) + { + g_mutex_unlock(&glmutex); + + //ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + //glFlush(); + } +} + void *uiGLGetProcAddress(const char* proc) { printf("get: %s - ", proc); diff --git a/src/libui_sdl/libui/unix/main.c b/src/libui_sdl/libui/unix/main.c index 409b659..66bd335 100644 --- a/src/libui_sdl/libui/unix/main.c +++ b/src/libui_sdl/libui/unix/main.c @@ -6,6 +6,33 @@ uiInitOptions options; // kind of a hack GThread* gtkthread; +GMutex glmutex; +int boub(GtkWidget* w); +void baba(GtkWidget* w); + +static void _eventfilter(GdkEvent* evt, gpointer data) +{ + if (evt->type == GDK_EXPOSE) + { + GtkWidget* widget = gtk_get_event_widget(evt); + if (isAreaWidget(widget)) + { + areaWidget* area = areaWidget(widget); + areaPreRedraw(area); + gtk_main_do_event(evt); + areaPostRedraw(area); + return; + } + } + + gtk_main_do_event(evt); +} + +static void _eventfilterdestroy(gpointer data) +{ + printf("DELET\n"); +} + const char *uiInit(uiInitOptions *o) { GError *err = NULL; @@ -31,6 +58,10 @@ const char *uiInit(uiInitOptions *o) gtk_window_set_default_icon_list(iconlist); + g_mutex_init(&glmutex); + + gdk_event_handler_set(_eventfilter, NULL, _eventfilterdestroy); + return NULL; } diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h index 42d5d76..7a7b208 100644 --- a/src/libui_sdl/libui/unix/uipriv_unix.h +++ b/src/libui_sdl/libui/unix/uipriv_unix.h @@ -65,5 +65,23 @@ extern PangoAttribute *FUTURE_pango_attr_foreground_alpha_new(guint16 alpha); extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, gint pos, const char *name); // gl.c -extern uiGLContext *createGLContext(GtkGLArea* gla, int maj, int min); +extern uiGLContext *createGLContext(GtkWidget* widget, int maj, int min); +extern void freeGLContext(uiGLContext* glctx); +extern void areaPreRedrawGL(uiGLContext* glctx); +extern void areaPostRedrawGL(uiGLContext* glctx); + +// notes: +// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14) +#define areaWidgetType (areaWidget_get_type()) +#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget)) +#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType)) +#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass)) +#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget)) +#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass)) + +typedef struct areaWidget areaWidget; +typedef struct areaWidgetClass areaWidgetClass; + +extern void areaPreRedraw(areaWidget* widget); +extern void areaPostRedraw(areaWidget* widget); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index e2686f9..fa6a2b5 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -379,26 +379,24 @@ 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*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); -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); @@ -424,11 +422,11 @@ printf("rarp5 %04X\n", glGetError()); 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); } @@ -826,7 +824,11 @@ int EmuThreadFunc(void* burp) // microphone input FeedMicInput(); - if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); + if (Screen_UseGL) + { + uiGLBegin(GLContext); + uiGLMakeContextCurrent(GLContext); + } // auto screen layout { @@ -862,7 +864,11 @@ int EmuThreadFunc(void* burp) if (EmuRunning == 0) break; - if (Screen_UseGL) GLScreen_DrawScreen(); + if (Screen_UseGL) + { + GLScreen_DrawScreen(); + uiGLEnd(GLContext); + } uiAreaQueueRedrawAll(MainDrawArea); // framerate limiter based off SDL2_gfx @@ -917,8 +923,10 @@ int EmuThreadFunc(void* burp) { if (Screen_UseGL) { + uiGLBegin(GLContext); uiGLMakeContextCurrent(GLContext); GLScreen_DrawScreen(); + uiGLEnd(GLContext); //uiGLMakeContextCurrent(NULL); //uiQueueMain(norp, NULL); } @@ -2537,6 +2545,9 @@ 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]); Config::ScreenRotation = ScreenRotation; Config::ScreenGap = ScreenGap; -- cgit v1.2.3 From ea669190aa5084a699590d2f2fed92e848a9fd53 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Thu, 30 May 2019 18:05:52 +0200 Subject: fix crash when using -O3. gcc will try to optimize the memfill with MMX opcodes, but those seem to crash if the memory isn't aligned to a 8-byte boundary. --- CMakeLists.txt | 2 +- src/GPU2D.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index 7daf1a5..38d4707 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ else() endif() if(ENABLE_LTO) - add_compile_options(-O2 -flto) + add_compile_options(-O3 -flto) endif() add_compile_options(-fno-pic) diff --git a/src/GPU2D.h b/src/GPU2D.h index 21b43f1..57436c7 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -71,11 +71,11 @@ private: bool Accelerated; - u32 BGOBJLine[256*3]; + u32 BGOBJLine[256*3] __attribute__((aligned (8))); u32* _3DLine; - u8 WindowMask[256]; - u32 OBJLine[256]; + u8 WindowMask[256] __attribute__((aligned (8))); + u32 OBJLine[256] __attribute__((aligned (8))); u16 DispFIFO[16]; u32 DispFIFOReadPtr; -- cgit v1.2.3 From 27d451d07a398a79cedef8040dfb6a612672b06c Mon Sep 17 00:00:00 2001 From: StapleButter Date: Fri, 31 May 2019 01:46:47 +0200 Subject: clean up code, attempt at shit --- src/libui_sdl/libui/unix/area.c | 61 ++--- src/libui_sdl/libui/unix/gl.c | 399 ++++----------------------------- src/libui_sdl/libui/unix/uipriv_unix.h | 1 + src/libui_sdl/main.cpp | 2 +- 4 files changed, 67 insertions(+), 396 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c index 62a4cb0..62fe512 100644 --- a/src/libui_sdl/libui/unix/area.c +++ b/src/libui_sdl/libui/unix/area.c @@ -28,12 +28,11 @@ struct uiArea { GtkWidget *areaWidget; GtkDrawingArea *drawingArea; - GtkGLArea *glArea; areaWidget *area; gboolean opengl; uiGLContext *glContext; - gboolean drawreq; + unsigned int* req_versions; int bgR, bgG, bgB; @@ -132,8 +131,6 @@ static void loadAreaSize(uiArea *a, double *width, double *height) } } -void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx); - void areaPreRedraw(areaWidget* widget) { uiArea* a = widget->a; @@ -181,8 +178,6 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) else { areaDrawGL(w, &dp, cr, a->glContext); - //if (a->drawreq) uiGLEnd(a->glContext); - a->drawreq = FALSE; } freeContext(dp.Context); @@ -664,8 +659,6 @@ void uiAreaSetSize(uiArea *a, int width, int height) gboolean _threadsaferefresh(gpointer data) { uiArea* a = (uiArea*)data; - a->drawreq = TRUE; - //if (a->opengl) uiGLBegin(a->glContext); gtk_widget_queue_draw(a->areaWidget); return FALSE; } @@ -676,11 +669,7 @@ void uiAreaQueueRedrawAll(uiArea *a) if (g_thread_self() != gtkthread) g_idle_add(_threadsaferefresh, a); else - { - a->drawreq = TRUE; - //if (a->opengl) uiGLBegin(a->glContext); gtk_widget_queue_draw(a->areaWidget); - } } void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height) @@ -762,7 +751,7 @@ void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge) uiArea *uiNewArea(uiAreaHandler *ah) { uiArea *a; -printf("create regular area\n"); + uiUnixNewControl(uiArea, a); a->ah = ah; @@ -782,44 +771,38 @@ printf("create regular area\n"); return a; } -uiGLContext* FARTOMATIC(int major, int minor); -void databotte(GtkWidget* gla, uiGLContext* ctx); -void majoricc(GtkWidget* widget, gpointer data) +void _areaCreateGLContext(GtkWidget* widget, gpointer data) { - printf("ACTUALLY CREATE CONTEXT\n"); - uiArea* a = (uiArea*)data; - uiGLContext* ctx = a->glContext; - databotte(a->widget, ctx); + uiGLContext* ctx = NULL; + for (int i = 0; a->req_versions[i] && !ctx; i++) + { + int major = uiGLVerMajor(a->req_versions[i]); + int minor = uiGLVerMinor(a->req_versions[i]); + + // we cannot support any version older than 3.2 via GDK + if ((major < 3) || (major == 3 && minor < 2)) + break; + + ctx = createGLContext(widget, major, minor); + } + + a->glContext = 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; - a->drawreq = FALSE; - - //GtkGLArea* gla = (GtkGLArea*)gtk_gl_area_new(); - uiGLContext* ctx = NULL; -printf("create sdfsf\n"); - // TODO: move this elsewhere!! so we can actually try all possible versions - 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); - ctx = FARTOMATIC(major, minor); - } -printf("create jfghjjgh: %p\n", ctx); - a->glContext = ctx; - //a->areaWidget = GTK_WIDGET(gla); - //a->glArea = gla; + + a->glContext = NULL; + a->req_versions = req_versions; a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType, "libui-area", a, NULL)); @@ -827,7 +810,7 @@ printf("create jfghjjgh: %p\n", ctx); a->widget = a->areaWidget; - g_signal_connect(a->widget, "realize", G_CALLBACK(majoricc), a); + g_signal_connect(a->widget, "realize", G_CALLBACK(_areaCreateGLContext), a); uiAreaSetBackgroundColor(a, -1, -1, -1); diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c index 3861cda..ab29abb 100644 --- a/src/libui_sdl/libui/unix/gl.c +++ b/src/libui_sdl/libui/unix/gl.c @@ -1,63 +1,29 @@ // 26 may 2019 #include "uipriv_unix.h" -#include #include -#include extern GThread* gtkthread; -extern GMutex glmutex; -/* - *(melonDS:17013): Gtk-CRITICAL **: 00:28:09.095: gtk_gl_area_set_required_version: assertion 'GTK_IS_GL_AREA (area)' failed - -(melonDS:17013): GLib-GObject-WARNING **: 00:28:09.096: invalid cast from 'GtkGLArea' to 'areaWidget' - */ - -// MISERABLE LITTLE PILE OF HACKS -#define HAX_GDK_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GL_CONTEXT, HAX_GdkGLContextClass)) -#define HAX_GDK_IS_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GL_CONTEXT)) -#define HAX_GDK_GL_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GL_CONTEXT, HAX_GdkGLContextClass)) - -typedef struct _HAX_GdkGLContextClass HAX_GdkGLContextClass; - -struct _HAX_GdkGLContextClass +struct uiGLContext { - GObjectClass parent_class; - - gboolean (* realize) (GdkGLContext *context, - GError **error); - - void (* end_frame) (GdkGLContext *context, - cairo_region_t *painted, - cairo_region_t *damage); - gboolean (* texture_from_surface) (GdkGLContext *context, - cairo_surface_t *surface, - cairo_region_t *region); -}; - -struct uiGLContext { - GtkGLArea *gla; GtkWidget* widget; GdkWindow* window; + GdkGLContext *gctx; + int vermaj, vermin; GMutex mutex; - GLsync sync; - GLsync sync2; - int zog; - - Display* xdisp; - GLXPixmap glxpm; - GLXContext glxctx; - int vermaj, vermin; int width, height; int scale; GLuint renderbuffer[2][2]; GLuint framebuffer[2]; + int backbuffer; }; +static void areaAllocRenderbuffer(uiGLContext* glctx); + static PFNGLGENRENDERBUFFERSPROC _glGenRenderbuffers; static PFNGLDELETERENDERBUFFERSPROC _glDeleteRenderbuffers; static PFNGLBINDRENDERBUFFERPROC _glBindRenderbuffer; @@ -73,15 +39,6 @@ static PFNGLCHECKFRAMEBUFFERSTATUSPROC _glCheckFramebufferStatus; static int _procsLoaded = 0; -static void (*vniorp)(GdkGLContext*, cairo_region_t*, cairo_region_t*); - -static void class_hax(GdkGLContext* glctx, cairo_region_t* painted, cairo_region_t* damage) -{ - //printf("END FRAME HIJACK\n"); - //glClearColor(0, 1, 0, 1); - vniorp(glctx, painted, damage); -} - static void _loadGLProcs(GdkGLContext* glctx) { if (_procsLoaded) return; @@ -100,101 +57,31 @@ static void _loadGLProcs(GdkGLContext* glctx) _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)uiGLGetProcAddress("glCheckFramebufferStatus"); _procsLoaded = 1; - - HAX_GdkGLContextClass* class = HAX_GDK_GL_CONTEXT_GET_CLASS(glctx); - printf("HAX class = %p\n", class); - printf("class end_frame = %p\n", class->end_frame); - vniorp = class->end_frame; - class->end_frame = class_hax; } -Display* derp; - -int nswaps = 0; - uiGLContext *createGLContext(GtkWidget* widget, int maj, int min) { - printf("barp\n"); - uiGLContext *ret = uiNew(uiGLContext);//uiAlloc(sizeof(uiGLContext), "uiGLContext"); - - // herp - ret->gla = widget; - 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); + GdkWindow* gdkwin = gtk_widget_get_window(widget); - 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; -} - -void freeGLContext(uiGLContext* glctx) -{ - if (glctx == NULL) return; - gdk_gl_context_clear_current(); - g_object_unref(glctx->gctx); - uiFree(glctx); -} - -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) + GdkGLContext* gctx = gdk_window_create_gl_context(gdkwin, &err); + if (err != NULL || gctx == NULL) { - printf("CONTEXT SHAT ITSELF\n"); - return; + return NULL; } - gdk_gl_context_set_use_es(glctx, FALSE); - gdk_gl_context_set_required_version(glctx, 3, 2); + // TODO: make the set_use_es call conditional (#ifdef or smth) for older versions of gdk? + gdk_gl_context_set_use_es(gctx, FALSE); + gdk_gl_context_set_required_version(gctx, maj, min); - gdk_gl_context_realize(glctx, &err); - if (err != NULL) + gboolean res = gdk_gl_context_realize(gctx, &err); + if (err != NULL || res == FALSE) { - printf("CONTEXT REALIZE SHAT ITSELF\n"); - return; + return NULL; } + uiGLContext* ctx = uiNew(uiGLContext); + GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int window_scale = gdk_window_get_scale_factor(gdkwin); @@ -202,13 +89,26 @@ void databotte(GtkWidget* widget, uiGLContext* ctx) ctx->height = allocation.height; ctx->scale = window_scale; - gdk_gl_context_make_current(glctx); - _loadGLProcs(glctx); + gdk_gl_context_make_current(gctx); + _loadGLProcs(gctx); areaAllocRenderbuffer(ctx); + ctx->backbuffer = 0; + + g_mutex_init(&ctx->mutex); ctx->widget = widget; ctx->window = gdkwin; - ctx->gctx = glctx; + ctx->gctx = gctx; + + return ctx; +} + +void freeGLContext(uiGLContext* glctx) +{ + if (glctx == NULL) return; + gdk_gl_context_clear_current(); + g_object_unref(glctx->gctx); + uiFree(glctx); } static void areaAllocRenderbuffer(uiGLContext* glctx) @@ -279,41 +179,16 @@ static void areaRellocRenderbuffer(uiGLContext* glctx) void areaPreRedrawGL(uiGLContext* glctx) { g_mutex_lock(&glctx->mutex); - - /*gdk_gl_context_make_current(glctx->gctx); - //glClientWaitSync(glctx->sync, 0, GL_TIMEOUT_IGNORED); - glDeleteSync(glctx->sync); - glFinish(); - gdk_gl_context_clear_current();*/ - /*GdkGLContext* oldctx = gdk_gl_context_get_current(); - gdk_gl_context_make_current(glctx->gctx); - printf("[%p] PRE DRAW\n", gdk_gl_context_get_current()); - - gdk_gl_context_make_current(oldctx);*/ - //glClearColor(0,1,0,1); glClear(GL_COLOR_BUFFER_BIT); - //glWaitSync(glctx->sync, 0, GL_TIMEOUT_IGNORED); - /*int ret = glClientWaitSync(glctx->sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000*50); - printf("PRE-DRAW: SYNC %p, %04X, %04X\n", glctx->sync, ret, glGetError()); - glDeleteSync(glctx->sync); - glctx->sync = NULL;*/ - //glFlush(); - if (nswaps > 1) printf("MISSED %d FRAMES\n", nswaps-1); - nswaps = 0; - //glctx->zog ^= 1; + glctx->backbuffer = glctx->backbuffer ? 0 : 1; } void areaPostRedrawGL(uiGLContext* glctx) { - //glctx->sync2 = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - //glFlush(); - //printf("[%p] POST DRAW\n", gdk_gl_context_get_current()); g_mutex_unlock(&glctx->mutex); } void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx) { - //uiGLBegin(glctx); - int window_scale = gdk_window_get_scale_factor(glctx->window); if (glctx->width != dp->AreaWidth || glctx->height != dp->AreaHeight || glctx->scale != window_scale) @@ -325,145 +200,13 @@ void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContex } gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), - glctx->renderbuffer[glctx->zog][0], GL_RENDERBUFFER, + glctx->renderbuffer[glctx->backbuffer][0], GL_RENDERBUFFER, 1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale); - - //uiGLEnd(glctx); -} - -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] = 0; - _ret->renderbuffer[0][1] = 0; - _ret->framebuffer[0] = 0; - _ret->renderbuffer[1][0] = 0; - _ret->renderbuffer[1][1] = 0; - _ret->framebuffer[1] = 0; - _ret->zog = 0; - - g_mutex_init(&_ret->mutex); - - 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[ctx->zog];// ? 0:1]; + return ctx->framebuffer[ctx->backbuffer];// ? 0 : 1]; } float uiGLGetFramebufferScale(uiGLContext* ctx) @@ -473,91 +216,35 @@ float uiGLGetFramebufferScale(uiGLContext* ctx) void uiGLSwapBuffers(uiGLContext* ctx) { - /*ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - //gdk_gl_context_clear_current(); - glWaitSync(ctx->sync, 0, GL_TIMEOUT_IGNORED); - glDeleteSync(ctx->sync);*/ - /*printf("[%p] SWAPBUFFERS\n", gdk_gl_context_get_current()); - glClearColor(0,1,0,1); glClear(GL_COLOR_BUFFER_BIT); - glFinish();*/ - //ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - //glFlush(); - //printf("SWAP: SYNC=%p\n", ctx->sync); + // nothing to do here, GTK will take care of this //glFinish(); - nswaps++; -} - -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; - /*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); + + if (ctx->gctx == gdk_gl_context_get_current()) return; 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 uiGLBegin(uiGLContext* ctx) { - //g_mutex_lock(&ctx->mutex); if (g_thread_self() != gtkthread) { - g_mutex_lock(&glmutex); - - //int ret = glClientWaitSync(ctx->sync2, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000*50); - //printf("GLBEGIN: SYNC %p, %04X, %04X\n", ctx->sync2, ret, glGetError()); - //glDeleteSync(ctx->sync2); + g_mutex_lock(&ctx->mutex); } } void uiGLEnd(uiGLContext* ctx) { - //g_mutex_unlock(&ctx->mutex); if (g_thread_self() != gtkthread) { - g_mutex_unlock(&glmutex); - - //ctx->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - //glFlush(); + g_mutex_unlock(&ctx->mutex); } } @@ -568,7 +255,7 @@ void* a = dlsym(NULL, proc); void* b = glXGetProcAddress(proc); void* c = glXGetProcAddressARB(proc); printf("%p / %p / %p\n", a, b, c); -return c; +return a; // 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/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h index 7a7b208..6f14091 100644 --- a/src/libui_sdl/libui/unix/uipriv_unix.h +++ b/src/libui_sdl/libui/unix/uipriv_unix.h @@ -68,6 +68,7 @@ extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, extern uiGLContext *createGLContext(GtkWidget* widget, int maj, int min); extern void freeGLContext(uiGLContext* glctx); extern void areaPreRedrawGL(uiGLContext* glctx); +extern void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx); extern void areaPostRedrawGL(uiGLContext* glctx); // notes: diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index fa6a2b5..a686cb4 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -66,7 +66,7 @@ uiWindow* MainWindow; uiArea* MainDrawArea; uiAreaHandler MainDrawAreaHandler; -const u32 kGLVersions[] = {uiGLVersion(3,1), 0}; +const u32 kGLVersions[] = {uiGLVersion(3,2), uiGLVersion(3,1), 0}; uiGLContext* GLContext; int WindowWidth, WindowHeight; -- cgit v1.2.3 From 3ef00f8fa628dbc0d04c045d8736044afc929d97 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Fri, 31 May 2019 02:21:41 +0200 Subject: attempt at fixing THE FLICKERING without making everything shitty. also, clean up code --- src/libui_sdl/libui/unix/gl.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c index ab29abb..dbb30fa 100644 --- a/src/libui_sdl/libui/unix/gl.c +++ b/src/libui_sdl/libui/unix/gl.c @@ -3,6 +3,8 @@ #include +void* glXGetProcAddressARB(const GLubyte* name); + extern GThread* gtkthread; struct uiGLContext @@ -179,7 +181,6 @@ static void areaRellocRenderbuffer(uiGLContext* glctx) void areaPreRedrawGL(uiGLContext* glctx) { g_mutex_lock(&glctx->mutex); - glctx->backbuffer = glctx->backbuffer ? 0 : 1; } void areaPostRedrawGL(uiGLContext* glctx) @@ -206,7 +207,7 @@ void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContex int uiGLGetFramebuffer(uiGLContext* ctx) { - return ctx->framebuffer[ctx->backbuffer];// ? 0 : 1]; + return ctx->framebuffer[ctx->backbuffer]; } float uiGLGetFramebufferScale(uiGLContext* ctx) @@ -216,8 +217,7 @@ float uiGLGetFramebufferScale(uiGLContext* ctx) void uiGLSwapBuffers(uiGLContext* ctx) { - // nothing to do here, GTK will take care of this - //glFinish(); + ctx->backbuffer = ctx->backbuffer ? 0 : 1; } void uiGLMakeContextCurrent(uiGLContext* ctx) @@ -250,15 +250,15 @@ void uiGLEnd(uiGLContext* ctx) 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 a; - // this *will* break for older systems that don't have libglvnd! - // TODO: use a real solution - return dlsym(NULL /* RTLD_DEFAULT */, proc); + // TODO: consider using epoxy or something funny + + void* ptr = dlsym(NULL /* RTLD_DEFAULT */, proc); + if (ptr) return ptr; + + ptr = glXGetProcAddressARB((const GLubyte*)proc); + if (ptr) return ptr; + + return NULL; } unsigned int uiGLGetVersion(uiGLContext* ctx) { -- 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') 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 d8d7ba9251042fbef425509831fe5b642cf083f1 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Fri, 31 May 2019 03:18:09 +0200 Subject: fix potential crash when switching video output methods --- src/libui_sdl/DlgVideoSettings.cpp | 4 +++- src/libui_sdl/main.cpp | 7 +++---- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index 5c5d5f9..7d876e2 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -134,13 +134,15 @@ void OnRendererChanged(uiRadioButtons* rb, void* blarg) ApplyNewSettings(2); else ApplyNewSettings(3); + + uiControlSetFocus(uiControl(win)); } void OnGLDisplayChanged(uiCheckbox* cb, void* blarg) { Config::ScreenUseGL = uiCheckboxChecked(cb); ApplyNewSettings(2); - uiControlSetFocus(uiControl(cb)); + uiControlSetFocus(uiControl(win)); } void OnThreaded3DChanged(uiCheckbox* cb, void* blarg) diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 986a809..74d3fc9 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -2043,15 +2043,14 @@ void ApplyNewSettings(int type) bool usegl = Config::ScreenUseGL || (Config::_3DRenderer != 0); if (usegl != Screen_UseGL) { - Screen_UseGL = usegl; - if (RunningSomething) { - if (usegl) uiGLMakeContextCurrent(GLContext); + if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); GPU3D::DeInitRenderer(); - if (usegl) uiGLMakeContextCurrent(NULL); + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); } + Screen_UseGL = usegl; RecreateMainWindow(usegl); if (RunningSomething) -- cgit v1.2.3 From 464b1169165b2e4d866c033e4c3288c9742539a8 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Fri, 31 May 2019 04:15:37 +0200 Subject: fix the whole mutex shito fixes potential crash when resizing window --- src/libui_sdl/libui/unix/area.c | 28 ++++++++++++---------------- src/libui_sdl/libui/unix/gl.c | 33 +++++++++++---------------------- src/libui_sdl/libui/unix/main.c | 17 +++++------------ src/libui_sdl/libui/unix/uipriv_unix.h | 17 ----------------- src/libui_sdl/main.cpp | 6 ------ 5 files changed, 28 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c index 62fe512..5734b4b 100644 --- a/src/libui_sdl/libui/unix/area.c +++ b/src/libui_sdl/libui/unix/area.c @@ -3,6 +3,18 @@ extern GThread* gtkthread; +// notes: +// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14) +#define areaWidgetType (areaWidget_get_type()) +#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget)) +#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType)) +#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass)) +#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget)) +#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass)) + +typedef struct areaWidget areaWidget; +typedef struct areaWidgetClass areaWidgetClass; + struct areaWidget { GtkDrawingArea parent_instance; uiArea *a; @@ -131,22 +143,6 @@ static void loadAreaSize(uiArea *a, double *width, double *height) } } -void areaPreRedraw(areaWidget* widget) -{ - uiArea* a = widget->a; - if (!a->opengl) return; - - areaPreRedrawGL(a->glContext); -} - -void areaPostRedraw(areaWidget* widget) -{ - uiArea* a = widget->a; - if (!a->opengl) return; - - areaPostRedrawGL(a->glContext); -} - static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr) { areaWidget *aw = areaWidget(w); diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c index 0511639..6965969 100644 --- a/src/libui_sdl/libui/unix/gl.c +++ b/src/libui_sdl/libui/unix/gl.c @@ -6,6 +6,7 @@ void* glXGetProcAddressARB(const GLubyte* name); extern GThread* gtkthread; +extern GMutex glmutex; struct uiGLContext { @@ -15,8 +16,6 @@ struct uiGLContext GdkGLContext *gctx; int vermaj, vermin; - GMutex mutex; - int width, height; int scale; GLuint renderbuffer[2][2]; @@ -96,8 +95,6 @@ uiGLContext *createGLContext(GtkWidget* widget, int maj, int min) areaAllocRenderbuffer(ctx); ctx->backbuffer = 0; - g_mutex_init(&ctx->mutex); - ctx->widget = widget; ctx->window = gdkwin; ctx->gctx = gctx; @@ -144,7 +141,7 @@ static void areaAllocRenderbuffer(uiGLContext* glctx) // printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER)); } -static void areaRellocRenderbuffer(uiGLContext* glctx) +static void areaReallocRenderbuffer(uiGLContext* glctx) { _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]); _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale); @@ -157,16 +154,6 @@ static void areaRellocRenderbuffer(uiGLContext* glctx) //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale); } -void areaPreRedrawGL(uiGLContext* glctx) -{ - g_mutex_lock(&glctx->mutex); -} - -void areaPostRedrawGL(uiGLContext* glctx) -{ - g_mutex_unlock(&glctx->mutex); -} - void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx) { int window_scale = gdk_window_get_scale_factor(glctx->window); @@ -176,12 +163,14 @@ void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContex glctx->width = dp->AreaWidth; glctx->height = dp->AreaHeight; glctx->scale = window_scale; - areaRellocRenderbuffer(glctx); + areaReallocRenderbuffer(glctx); + } + else + { + gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), + glctx->renderbuffer[glctx->backbuffer][0], GL_RENDERBUFFER, + 1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale); } - - gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), - glctx->renderbuffer[glctx->backbuffer][0], GL_RENDERBUFFER, - 1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale); } int uiGLGetFramebuffer(uiGLContext* ctx) @@ -215,7 +204,7 @@ void uiGLBegin(uiGLContext* ctx) { if (g_thread_self() != gtkthread) { - g_mutex_lock(&ctx->mutex); + g_mutex_lock(&glmutex); } } @@ -223,7 +212,7 @@ void uiGLEnd(uiGLContext* ctx) { if (g_thread_self() != gtkthread) { - g_mutex_unlock(&ctx->mutex); + g_mutex_unlock(&glmutex); } } diff --git a/src/libui_sdl/libui/unix/main.c b/src/libui_sdl/libui/unix/main.c index 66bd335..516bd76 100644 --- a/src/libui_sdl/libui/unix/main.c +++ b/src/libui_sdl/libui/unix/main.c @@ -5,24 +5,16 @@ uiInitOptions options; // kind of a hack GThread* gtkthread; - GMutex glmutex; -int boub(GtkWidget* w); -void baba(GtkWidget* w); static void _eventfilter(GdkEvent* evt, gpointer data) { if (evt->type == GDK_EXPOSE) { - GtkWidget* widget = gtk_get_event_widget(evt); - if (isAreaWidget(widget)) - { - areaWidget* area = areaWidget(widget); - areaPreRedraw(area); - gtk_main_do_event(evt); - areaPostRedraw(area); - return; - } + g_mutex_lock(&glmutex); + gtk_main_do_event(evt); + g_mutex_unlock(&glmutex); + return; } gtk_main_do_event(evt); @@ -48,6 +40,7 @@ const char *uiInit(uiInitOptions *o) loadFutures(); gtkthread = g_thread_self(); + g_mutex_init(&glmutex); GList* iconlist = NULL; iconlist = g_list_append(iconlist, gdk_pixbuf_new_from_resource("/org/kuriboland/melonDS/icon/melon_16x16.png", NULL)); diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h index 6f14091..9b77188 100644 --- a/src/libui_sdl/libui/unix/uipriv_unix.h +++ b/src/libui_sdl/libui/unix/uipriv_unix.h @@ -67,22 +67,5 @@ extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, // gl.c extern uiGLContext *createGLContext(GtkWidget* widget, int maj, int min); extern void freeGLContext(uiGLContext* glctx); -extern void areaPreRedrawGL(uiGLContext* glctx); extern void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx); -extern void areaPostRedrawGL(uiGLContext* glctx); - -// notes: -// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14) -#define areaWidgetType (areaWidget_get_type()) -#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget)) -#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType)) -#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass)) -#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget)) -#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass)) - -typedef struct areaWidget areaWidget; -typedef struct areaWidgetClass areaWidgetClass; - -extern void areaPreRedraw(areaWidget* widget); -extern void areaPostRedraw(areaWidget* widget); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 74d3fc9..6cc6c50 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -430,12 +430,6 @@ void GLScreen_DrawScreen() uiGLSwapBuffers(GLContext); } -void norp(void* data) -{ - uiGLMakeContextCurrent(GLContext); - GLScreen_DrawScreen(); -} - void MicLoadWav(char* name) { SDL_AudioSpec format; -- cgit v1.2.3 From 1a3314f0bdda811ee6db43f3fb467401b4f69d55 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Fri, 31 May 2019 12:25:16 +0200 Subject: GL: don't draw the screens when nothing is running --- src/libui_sdl/main.cpp | 51 ++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 6cc6c50..c351a04 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -396,35 +396,38 @@ void GLScreen_DrawScreen() glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); - int frontbuf = GPU::FrontBuffer; - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); - - if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) + if (RunningSomething) { - if (GPU3D::Renderer == 0) - { - 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, 192, 256, 192, GL_RGBA_INTEGER, - GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); - } - else + int frontbuf = GPU::FrontBuffer; + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); + + if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) { - 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, 192, 256*3 + 1, 192, GL_RGBA_INTEGER, - GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); + if (GPU3D::Renderer == 0) + { + 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, 192, 256, 192, GL_RGBA_INTEGER, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); + } + else + { + 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, 192, 256*3 + 1, 192, GL_RGBA_INTEGER, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); + } } - } - glActiveTexture(GL_TEXTURE1); - if (GPU3D::Renderer != 0) - GPU3D::GLRenderer::SetupAccelFrame(); + glActiveTexture(GL_TEXTURE1); + if (GPU3D::Renderer != 0) + GPU3D::GLRenderer::SetupAccelFrame(); - glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); - glBindVertexArray(GL_ScreenVertexArrayID); - glDrawArrays(GL_TRIANGLES, 0, 4*3); + glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); + glBindVertexArray(GL_ScreenVertexArrayID); + glDrawArrays(GL_TRIANGLES, 0, 4*3); + } glFlush(); uiGLSwapBuffers(GLContext); -- 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') 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 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') 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 5d5e8ceced2d865500f4031502015f789b6746c3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 31 May 2019 21:57:11 +0200 Subject: BAHAHAHAHAHHAHHHHH-~*+ --- README.md | 3 +-- melon.rc | 8 ++++---- src/version.h | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/README.md b/README.md index 30b2052..60215a1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

melonDS

- +

@@ -78,7 +78,6 @@ If everything went well, melonDS and the libraries it needs should now be in the ## TODO LIST * improve libui and the emulator UI - * hardware renderer for 3D (w/ upscaling and fancy shit) * support for rendering screens to separate windows * emulating some fancy addons * other non-core shit (debugger, graphics viewers, cheat crapo, etc) diff --git a/melon.rc b/melon.rc index 6ff0c1e..493dd6d 100644 --- a/melon.rc +++ b/melon.rc @@ -6,8 +6,8 @@ //include version information in .exe, modify these values to match your needs 1 VERSIONINFO -FILEVERSION 0,7,4,0 -PRODUCTVERSION 0,7,4,0 +FILEVERSION 0,8,0,0 +PRODUCTVERSION 0,8,0,0 FILETYPE VFT_APP { BLOCK "StringFileInfo" @@ -15,14 +15,14 @@ FILETYPE VFT_APP BLOCK "040904E4" { VALUE "CompanyName", "Melon Factory of Kuribo64" - VALUE "FileVersion", "0.7.4" + VALUE "FileVersion", "0.8" VALUE "FileDescription", "DS emulator, sorta. also 1st quality melon." VALUE "InternalName", "SDnolem" VALUE "LegalCopyright", "2016-2019 Arisotura & co." VALUE "LegalTrademarks", "" VALUE "OriginalFilename", "zafkflzdasd.exe" VALUE "ProductName", "melonDS" - VALUE "ProductVersion", "0.7.4" + VALUE "ProductVersion", "0.8" } } BLOCK "VarFileInfo" diff --git a/src/version.h b/src/version.h index 6dbce1b..5b43d36 100644 --- a/src/version.h +++ b/src/version.h @@ -19,7 +19,7 @@ #ifndef VERSION_H #define VERSION_H -#define MELONDS_VERSION "0.7.4" +#define MELONDS_VERSION "0.8" #define MELONDS_URL "http://melonds.kuribo64.net/" -- cgit v1.2.3 From b9529e83619f1e2b725ea86508b546d72e072a0c Mon Sep 17 00:00:00 2001 From: StapleButter Date: Sat, 1 Jun 2019 00:27:54 +0200 Subject: Linux: fix uiGLGetProcAddress() --- src/CMakeLists.txt | 2 +- src/libui_sdl/libui/unix/gl.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d096c02..a1110f1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,5 +29,5 @@ add_library(core STATIC if (WIN32) target_link_libraries(core ole32 comctl32 ws2_32 opengl32) else() - target_link_libraries(core GL) + target_link_libraries(core GL EGL) endif() diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c index 6965969..4a180ef 100644 --- a/src/libui_sdl/libui/unix/gl.c +++ b/src/libui_sdl/libui/unix/gl.c @@ -2,8 +2,8 @@ #include "uipriv_unix.h" #include - -void* glXGetProcAddressARB(const GLubyte* name); +#include +#include extern GThread* gtkthread; extern GMutex glmutex; @@ -220,10 +220,15 @@ void *uiGLGetProcAddress(const char* proc) { // TODO: consider using epoxy or something funny - void* ptr = dlsym(NULL /* RTLD_DEFAULT */, proc); + void* ptr; + + ptr = glXGetProcAddressARB((const GLubyte*)proc); + if (ptr) return ptr; + + ptr = eglGetProcAddress(proc); if (ptr) return ptr; - ptr = glXGetProcAddressARB((const GLubyte*)proc); + ptr = dlsym(NULL /* RTLD_DEFAULT */, proc); if (ptr) return ptr; return NULL; -- cgit v1.2.3 From 6f5e45ef2cb451249bf160141fccc0f2a0262357 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Thu, 30 May 2019 23:16:56 +0200 Subject: also, properly delete glarea framebuffers on exit --- src/libui_sdl/libui/unix/gl.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c index 4a180ef..e1665ee 100644 --- a/src/libui_sdl/libui/unix/gl.c +++ b/src/libui_sdl/libui/unix/gl.c @@ -105,6 +105,11 @@ uiGLContext *createGLContext(GtkWidget* widget, int maj, int min) void freeGLContext(uiGLContext* glctx) { if (glctx == NULL) return; + + gdk_gl_context_make_current(glctx->gctx); + _glDeleteRenderbuffers(4, &glctx->renderbuffer[0][0]); + _glDeleteFramebuffers(2, &glctx->framebuffer[0]); + gdk_gl_context_clear_current(); g_object_unref(glctx->gctx); uiFree(glctx); -- 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') 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 27d21e06df8d24ab6c4e53ba5305af533b09f6f2 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 1 Jun 2019 02:54:38 +0200 Subject: use regular slash instead of backslash in config file name. fixes #413 --- src/libui_sdl/Platform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libui_sdl/Platform.cpp b/src/libui_sdl/Platform.cpp index e3035b3..94b3791 100644 --- a/src/libui_sdl/Platform.cpp +++ b/src/libui_sdl/Platform.cpp @@ -167,7 +167,7 @@ FILE* OpenLocalFile(const char* path, const char* mode) int len = emudirlen + 1 + pathlen + 1; emudirpath = new char[len]; strncpy(&emudirpath[0], EmuDirectory, emudirlen); - emudirpath[emudirlen] = '\\'; + emudirpath[emudirlen] = '/'; strncpy(&emudirpath[emudirlen+1], path, pathlen); emudirpath[emudirlen+1+pathlen] = '\0'; } -- cgit v1.2.3 From 78208a9728bab7b381c8eac570ff42a1936161ba Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 1 Jun 2019 03:39:35 +0200 Subject: OpenGL: fix cases of layers/sprites blending over the 3D layer --- src/GPU2D.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 4fe2209..212372c 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -1443,7 +1443,8 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) eva = flag1 & 0x1F; evb = 16 - eva; } - else if ((BlendCnt & target1) && (WindowMask[i] & 0x20)) + else if (((BlendCnt & target1) && (WindowMask[i] & 0x20)) || + ((flag1 & 0xC0) == 0x80)) { eva = EVA; evb = EVB; @@ -1453,7 +1454,7 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) BGOBJLine[i] = val1; BGOBJLine[256+i] = ColorComposite(i, val1, val3); - BGOBJLine[512+i] = (bldcnteffect << 24) | (EVB << 16) | (EVA << 8) | (val1 & 0xFF); + BGOBJLine[512+i] = (bldcnteffect << 24) | (EVB << 16) | (EVA << 8) | (val2 & 0xFF); } else { -- cgit v1.2.3 From 3aa971403bdf3ebd21082025a6b9d9e181f9816a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 2 Jun 2019 14:33:20 +0200 Subject: lay base for OSD --- src/libui_sdl/CMakeLists.txt | 1 + src/libui_sdl/OSD.cpp | 305 +++++++++++++++++++++++++++++++++++++++++++ src/libui_sdl/OSD.h | 36 +++++ src/libui_sdl/font.h | 135 +++++++++++++++++++ src/libui_sdl/main.cpp | 4 + 5 files changed, 481 insertions(+) create mode 100644 src/libui_sdl/OSD.cpp create mode 100644 src/libui_sdl/OSD.h create mode 100644 src/libui_sdl/font.h (limited to 'src') diff --git a/src/libui_sdl/CMakeLists.txt b/src/libui_sdl/CMakeLists.txt index e9a54e2..63e9f48 100644 --- a/src/libui_sdl/CMakeLists.txt +++ b/src/libui_sdl/CMakeLists.txt @@ -11,6 +11,7 @@ SET(SOURCES_LIBUI DlgInputConfig.cpp DlgVideoSettings.cpp DlgWifiSettings.cpp + OSD.cpp ) option(BUILD_SHARED_LIBS "Whether to build libui as a shared library or a static library" ON) diff --git a/src/libui_sdl/OSD.cpp b/src/libui_sdl/OSD.cpp new file mode 100644 index 0000000..7e8c8f7 --- /dev/null +++ b/src/libui_sdl/OSD.cpp @@ -0,0 +1,305 @@ +/* + 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 +#include +#include "types.h" +#include "OSD.h" + +#include "libui/ui.h" +#include "../OpenGLSupport.h" + +#include "font.h" + +extern int WindowWidth, WindowHeight; + +namespace OSD +{ + +const u32 kOSDMargin = 6; + +typedef struct +{ + Uint32 Timestamp; + u32 Width, Height; + u32* Bitmap; + + bool DrawBitmapLoaded; + uiDrawBitmap* DrawBitmap; + + bool GLTextureLoaded; + GLuint GLTexture; + +} Item; + +std::queue CurrentItems; + + +bool Init() +{ +} + +void DeInit() +{ +} + + +int FindBreakPoint(const char* text, int i) +{ + // i = character that went out of bounds + + for (int j = i; j >= 0; j--) + { + if (text[j] == ' ') + return j; + } + + return i; +} + +void LayoutText(const char* text, u32* width, u32* height, int* breaks) +{ + u32 w = 0; + u32 h = 14; + u32 totalw = 0; + u32 maxw = WindowWidth - (kOSDMargin*2); + int lastbreak = -1; + int numbrk = 0; + u16* ptr; + + memset(breaks, 0, sizeof(int)*64); + + for (int i = 0; text[i] != '\0'; ) + { + int glyphsize; + if (text[i] == ' ') + { + glyphsize = 6; + } + else + { + u32 ch = text[i]; + if (ch < 0x10 || ch > 0x7E) ch = 0x7F; + + ptr = &font[(ch-0x10) << 4]; + glyphsize = ptr[0]; + if (!glyphsize) glyphsize = 6; + else glyphsize += 2; // space around the character + } + + w += glyphsize; + if (w > maxw) + { + // wrap shit as needed + if (text[i] == ' ') + { + if (numbrk >= 64) break; + breaks[numbrk++] = i; + i++; + } + else + { + int brk = FindBreakPoint(text, i); + if (brk != lastbreak) i = brk; + + if (numbrk >= 64) break; + breaks[numbrk++] = i; + + lastbreak = brk; + } + + w = 0; + h += 14; + } + else + i++; + + if (w > totalw) totalw = w; + } + + *width = totalw; + *height = h; +} + +u32 RainbowColor(u32 inc) +{ + // inspired from Acmlmboard + + if (inc < 100) return 0xFFFF9BFF + (inc << 8); + else if (inc < 200) return 0xFFFFFF9B - ((inc-100) << 16); + else if (inc < 300) return 0xFF9BFF9B + (inc-200); + else if (inc < 400) return 0xFF9BFFFF - ((inc-300) << 8); + else if (inc < 500) return 0xFF9B9BFF + ((inc-400) << 16); + else return 0xFFFF9BFF - (inc-500); +} + +void RenderText(u32 color, const char* text, Item* item) +{ + u32 w, h; + int breaks[64]; + + bool rainbow = (color == 0); + u32 rainbowinc = rand() % 600; + + color |= 0xFF000000; + const u32 shadow = 0xC0000000; + + LayoutText(text, &w, &h, breaks); + + item->Width = w; + item->Height = h; + item->Bitmap = new u32[w*h]; + memset(item->Bitmap, 0, w*h*sizeof(u32)); + + u32 x = 0, y = 1; + u32 maxw = WindowWidth - (kOSDMargin*2); + int curline = 0; + u16* ptr; + + for (int i = 0; text[i] != '\0'; ) + { + int glyphsize; + if (text[i] == ' ') + { + x += 6; + } + else + { + u32 ch = text[i]; + if (ch < 0x10 || ch > 0x7E) ch = 0x7F; + + ptr = &font[(ch-0x10) << 4]; + int glyphsize = ptr[0]; + if (!glyphsize) x += 6; + else + { + x++; + + if (rainbow) + { + color = RainbowColor(rainbowinc); + rainbowinc = (rainbowinc + 30) % 600; + } + + // draw character + for (int cy = 0; cy < 12; cy++) + { + u16 val = ptr[4+cy]; + + for (int cx = 0; cx < glyphsize; cx++) + { + if (val & (1<Bitmap[((y+cy) * w) + x+cx] = color; + } + } + + x += glyphsize; + x++; + } + } + + i++; + if (breaks[curline] && i >= breaks[curline]) + { + i = breaks[curline++]; + if (text[i] == ' ') i++; + + x = 0; + y += 14; + } + } + + // shadow + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + u32 val; + + val = item->Bitmap[(y * w) + x]; + if ((val >> 24) == 0xFF) continue; + + if (x > 0) val = item->Bitmap[(y * w) + x-1]; + if (x < w-1) val |= item->Bitmap[(y * w) + x+1]; + if (y > 0) + { + if (x > 0) val |= item->Bitmap[((y-1) * w) + x-1]; + val |= item->Bitmap[((y-1) * w) + x]; + if (x < w-1) val |= item->Bitmap[((y-1) * w) + x+1]; + } + if (y < h-1) + { + if (x > 0) val |= item->Bitmap[((y+1) * w) + x-1]; + val |= item->Bitmap[((y+1) * w) + x]; + if (x < w-1) val |= item->Bitmap[((y+1) * w) + x+1]; + } + + if ((val >> 24) == 0xFF) + item->Bitmap[(y * w) + x] = shadow; + } + } +} + +void test(u32* berp) +{ + Item barp; + RenderText(0x000000, "This is a test of OSD, it can display really long messages, like thiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis. Also, pancakes are the best thing ever.", &barp); + + for (int y = 0; y < barp.Height; y++) + { + for (int x = 0; x < barp.Width; x++) + { + u32 src = barp.Bitmap[(y*barp.Width)+x]; + u32 dst = berp[((y+6)*256)+x+6]; + + u32 sR = (src >> 16) & 0xFF; + u32 sG = (src >> 8) & 0xFF; + u32 sB = (src ) & 0xFF; + u32 sA = (src >> 24) & 0xFF; + + u32 dR = (dst >> 16) & 0xFF; + u32 dG = (dst >> 8) & 0xFF; + u32 dB = (dst ) & 0xFF; + + dR = ((sR * sA) + (dR * (255-sA))) >> 8; + dG = ((sG * sA) + (dG * (255-sA))) >> 8; + dB = ((sB * sA) + (dB * (255-sA))) >> 8; + + dst = (dR << 16) | (dG << 8) | dB; + + berp[((y+6)*256)+x+6] = dst | 0xFF000000; + } + } + + delete[] barp.Bitmap; +} + + +void AddMessage(u32 color, const char* text) +{ + // +} + +void Update(bool opengl) +{ + // +} + +} diff --git a/src/libui_sdl/OSD.h b/src/libui_sdl/OSD.h new file mode 100644 index 0000000..ed38490 --- /dev/null +++ b/src/libui_sdl/OSD.h @@ -0,0 +1,36 @@ +/* + 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 OSD_H +#define OSD_H + +namespace OSD +{ + +bool Init(); +void DeInit(); + +void test(u32* berp); + +void AddMessage(u32 color, const char* text); + +void Update(bool opengl); + +} + +#endif // OSD_H diff --git a/src/libui_sdl/font.h b/src/libui_sdl/font.h new file mode 100644 index 0000000..8647b7a --- /dev/null +++ b/src/libui_sdl/font.h @@ -0,0 +1,135 @@ +/* + 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 FONT_H +#define FONT_H +unsigned short font[] = { + 12, 0, 0, 0,0x0C03, 0x0E07, 0x070E, 0x039C, 0x01F8, 0x00F0, 0x00F0, 0x01F8, 0x039C, 0x070E, 0x0E07, 0x0C03, + 12, 0, 0, 0,0x01C0, 0x00E0, 0x0060, 0x0860, 0x0C60, 0x0FE0, 0x07F0, 0x0038, 0x001C, 0x000E, 0x0007, 0x0003, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, 0x0003, 0x0003, 0x0000, 0x0000, + 9, 0, 0, 0,0x01EF, 0x01EF, 0x018C, 0x01CE, 0x00E7, 0x0063, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 10, 0, 0, 0,0x00CC, 0x00CC, 0x03FF, 0x03FF, 0x00CC, 0x00CC, 0x03FF, 0x03FF, 0x00CC, 0x00CC, 0x0000, 0x0000, + 8, 0, 0, 0,0x0018, 0x00FE, 0x00FF, 0x001B, 0x007F, 0x00FE, 0x00D8, 0x00FF, 0x007F, 0x0018, 0x0000, 0x0000, + 10, 0, 0, 0,0x0306, 0x038F, 0x01CF, 0x00E6, 0x0070, 0x0038, 0x019C, 0x03CE, 0x03C7, 0x0183, 0x0000, 0x0000, + 10, 0, 0, 0,0x007C, 0x00FE, 0x00C6, 0x00EE, 0x007C, 0x037E, 0x03E7, 0x01F3, 0x03BF, 0x031E, 0x0000, 0x0000, + 4, 0, 0, 0,0x000F, 0x000F, 0x000C, 0x000E, 0x0007, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 4, 0, 0, 0,0x000C, 0x000E, 0x0007, 0x0003, 0x0003, 0x0003, 0x0003, 0x0007, 0x000E, 0x000C, 0x0000, 0x0000, + 4, 0, 0, 0,0x0003, 0x0007, 0x000E, 0x000C, 0x000C, 0x000C, 0x000C, 0x000E, 0x0007, 0x0003, 0x0000, 0x0000, + 10, 0, 0, 0,0x0030, 0x0333, 0x03B7, 0x01FE, 0x00FC, 0x00FC, 0x01FE, 0x03B7, 0x0333, 0x0030, 0x0000, 0x0000, + 10, 0, 0, 0,0x0030, 0x0030, 0x0030, 0x0030, 0x03FF, 0x03FF, 0x0030, 0x0030, 0x0030, 0x0030, 0x0000, 0x0000, + 4, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000F, 0x000F, 0x000C, 0x000E, 0x0007, 0x0003, + 10, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x03FF, 0x03FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 3, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0007, 0x0007, 0x0007, 0x0000, 0x0000, + 10, 0, 0, 0,0x0300, 0x0380, 0x01C0, 0x00E0, 0x0070, 0x0038, 0x001C, 0x000E, 0x0007, 0x0003, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x00FF, 0x00C3, 0x00C3, 0x00C3, 0x00C3, 0x00C3, 0x00C3, 0x00FF, 0x007E, 0x0000, 0x0000, + 4, 0, 0, 0,0x0006, 0x0007, 0x0007, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x000F, 0x000F, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x00FF, 0x00C3, 0x00C0, 0x00FE, 0x007F, 0x0003, 0x0003, 0x00FF, 0x00FF, 0x0000, 0x0000, + 8, 0, 0, 0,0x007F, 0x00FF, 0x00C0, 0x00C0, 0x007C, 0x00FC, 0x00C0, 0x00C0, 0x00FF, 0x007F, 0x0000, 0x0000, + 8, 0, 0, 0,0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x00FF, 0x00FE, 0x0060, 0x0060, 0x0000, 0x0000, + 8, 0, 0, 0,0x00FF, 0x00FF, 0x0003, 0x0003, 0x007F, 0x00FF, 0x00C0, 0x00C0, 0x00FF, 0x007F, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x007F, 0x0003, 0x0003, 0x007F, 0x00FF, 0x00C3, 0x00C3, 0x00FF, 0x007E, 0x0000, 0x0000, + 8, 0, 0, 0,0x00FF, 0x00FF, 0x00C0, 0x00E0, 0x0070, 0x0038, 0x001C, 0x000C, 0x000C, 0x000C, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x00FF, 0x00C3, 0x00C3, 0x007E, 0x00FF, 0x00C3, 0x00C3, 0x00FF, 0x007E, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x00FF, 0x00C3, 0x00C3, 0x00FF, 0x00FE, 0x00C0, 0x00C0, 0x00FE, 0x007E, 0x0000, 0x0000, + 3, 0, 0, 0,0x0000, 0x0000, 0x0007, 0x0007, 0x0000, 0x0000, 0x0000, 0x0007, 0x0007, 0x0000, 0x0000, 0x0000, + 4, 0, 0, 0,0x0000, 0x0000, 0x000E, 0x000E, 0x0000, 0x0000, 0x000C, 0x000E, 0x0007, 0x0003, 0x0000, 0x0000, + 6, 0, 0, 0,0x0030, 0x0038, 0x001C, 0x000E, 0x0007, 0x0007, 0x000E, 0x001C, 0x0038, 0x0030, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x007F, 0x007F, 0x0000, 0x0000, 0x007F, 0x007F, 0x0000, 0x0000, 0x0000, + 6, 0, 0, 0,0x0003, 0x0007, 0x000E, 0x001C, 0x0038, 0x0038, 0x001C, 0x000E, 0x0007, 0x0003, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x00FF, 0x00C3, 0x00C3, 0x00F0, 0x0078, 0x0018, 0x0000, 0x0018, 0x0018, 0x0000, 0x0000, + 10, 0, 0, 0,0x00FC, 0x01FE, 0x0387, 0x0333, 0x037B, 0x03FB, 0x01F3, 0x0007, 0x03FE, 0x03FC, 0x0000, 0x0000, + 9, 0, 0, 0,0x00FE, 0x01FF, 0x0183, 0x0183, 0x0183, 0x01FF, 0x01FF, 0x0183, 0x0183, 0x0183, 0x0000, 0x0000, + 9, 0, 0, 0,0x00FF, 0x01FF, 0x0183, 0x0183, 0x00FF, 0x01FF, 0x0183, 0x0183, 0x01FF, 0x00FF, 0x0000, 0x0000, + 8, 0, 0, 0,0x00FE, 0x00FF, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x00FF, 0x00FE, 0x0000, 0x0000, + 9, 0, 0, 0,0x007F, 0x00FF, 0x01C3, 0x0183, 0x0183, 0x0183, 0x0183, 0x01C3, 0x00FF, 0x007F, 0x0000, 0x0000, + 9, 0, 0, 0,0x01FF, 0x01FF, 0x0003, 0x0003, 0x00FF, 0x00FF, 0x0003, 0x0003, 0x01FF, 0x01FF, 0x0000, 0x0000, + 9, 0, 0, 0,0x01FF, 0x01FF, 0x0003, 0x0003, 0x00FF, 0x00FF, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, + 9, 0, 0, 0,0x01FE, 0x01FF, 0x0003, 0x0003, 0x01F3, 0x01F3, 0x0183, 0x0183, 0x01FF, 0x00FE, 0x0000, 0x0000, + 9, 0, 0, 0,0x0183, 0x0183, 0x0183, 0x0183, 0x01FF, 0x01FF, 0x0183, 0x0183, 0x0183, 0x0183, 0x0000, 0x0000, + 6, 0, 0, 0,0x003F, 0x003F, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x003F, 0x003F, 0x0000, 0x0000, + 9, 0, 0, 0,0x01F0, 0x01F0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C3, 0x00C3, 0x00FF, 0x007E, 0x0000, 0x0000, + 9, 0, 0, 0,0x0183, 0x01C3, 0x00E3, 0x0073, 0x003F, 0x003F, 0x0073, 0x00E3, 0x01C3, 0x0183, 0x0000, 0x0000, + 7, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x007F, 0x007F, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0387, 0x03CF, 0x03FF, 0x037B, 0x0333, 0x0303, 0x0303, 0x0303, 0x0303, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0307, 0x030F, 0x031F, 0x033B, 0x0373, 0x03E3, 0x03C3, 0x0383, 0x0303, 0x0000, 0x0000, + 10, 0, 0, 0,0x01FE, 0x03FF, 0x0303, 0x0303, 0x0303, 0x0303, 0x0303, 0x0303, 0x03FF, 0x01FE, 0x0000, 0x0000, + 9, 0, 0, 0,0x00FF, 0x01FF, 0x0183, 0x0183, 0x01FF, 0x00FF, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, + 10, 0, 0, 0,0x01FE, 0x03FF, 0x0303, 0x0303, 0x0333, 0x0373, 0x03E3, 0x01C3, 0x03FF, 0x037E, 0x0000, 0x0000, + 9, 0, 0, 0,0x00FF, 0x01FF, 0x0183, 0x0183, 0x01FF, 0x00FF, 0x0073, 0x00E3, 0x01C3, 0x0183, 0x0000, 0x0000, + 10, 0, 0, 0,0x01FE, 0x01FF, 0x0003, 0x0003, 0x01FF, 0x03FE, 0x0300, 0x0300, 0x03FE, 0x01FE, 0x0000, 0x0000, + 10, 0, 0, 0,0x03FF, 0x03FF, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0000, 0x0000, + 9, 0, 0, 0,0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x01FF, 0x00FE, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0303, 0x0303, 0x0303, 0x0303, 0x0387, 0x01CE, 0x00FC, 0x0078, 0x0030, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0303, 0x0303, 0x0303, 0x0333, 0x037B, 0x03FF, 0x03CF, 0x0387, 0x0303, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0387, 0x01CE, 0x00FC, 0x0078, 0x0078, 0x00FC, 0x01CE, 0x0387, 0x0303, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0387, 0x01CE, 0x00FC, 0x0078, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0000, 0x0000, + 10, 0, 0, 0,0x03FF, 0x03FF, 0x01C0, 0x00E0, 0x0070, 0x0038, 0x001C, 0x000E, 0x03FF, 0x03FF, 0x0000, 0x0000, + 4, 0, 0, 0,0x000F, 0x000F, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x000F, 0x000F, 0x0000, 0x0000, + 10, 0, 0, 0,0x0003, 0x0007, 0x000E, 0x001C, 0x0038, 0x0070, 0x00E0, 0x01C0, 0x0380, 0x0300, 0x0000, 0x0000, + 4, 0, 0, 0,0x000F, 0x000F, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000F, 0x000F, 0x0000, 0x0000, + 8, 0, 0, 0,0x0018, 0x003C, 0x007E, 0x00E7, 0x00C3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03FF, 0x03FF, + 4, 0, 0, 0,0x000F, 0x000F, 0x0003, 0x0007, 0x000E, 0x000C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x003E, 0x007E, 0x0060, 0x007E, 0x007F, 0x0063, 0x007F, 0x007E, 0x0000, 0x0000, + 7, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x003F, 0x007F, 0x0063, 0x0063, 0x0063, 0x007F, 0x003F, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x007E, 0x007F, 0x0003, 0x0003, 0x0003, 0x0003, 0x007F, 0x007E, 0x0000, 0x0000, + 7, 0, 0, 0,0x0060, 0x0060, 0x0060, 0x007E, 0x007F, 0x0063, 0x0063, 0x0063, 0x007F, 0x007E, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x003E, 0x007F, 0x0063, 0x007F, 0x003F, 0x0003, 0x003F, 0x003E, 0x0000, 0x0000, + 6, 0, 0, 0,0x003C, 0x003E, 0x0006, 0x0006, 0x001F, 0x001F, 0x0006, 0x0006, 0x0006, 0x0006, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x007E, 0x007F, 0x0063, 0x0063, 0x007F, 0x007E, 0x0060, 0x0060, 0x007E, 0x003E, + 7, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x003F, 0x007F, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x0000, 0x0000, + 2, 0, 0, 0,0x0003, 0x0003, 0x0000, 0x0000, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, + 7, 0, 0, 0,0x0060, 0x0060, 0x0000, 0x0000, 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, 0x0063, 0x007F, 0x003E, + 8, 0, 0, 0,0x0003, 0x0003, 0x00E3, 0x0073, 0x003B, 0x001F, 0x001F, 0x003B, 0x0073, 0x00E3, 0x0000, 0x0000, + 4, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x000F, 0x000E, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x01FF, 0x03FF, 0x0333, 0x0333, 0x0333, 0x0333, 0x0333, 0x0333, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x003F, 0x007F, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x0000, 0x0000, + 8, 0, 0, 0,0x0000, 0x0000, 0x007E, 0x00FF, 0x00C3, 0x00C3, 0x00C3, 0x00C3, 0x00FF, 0x007E, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x003F, 0x007F, 0x0063, 0x0063, 0x007F, 0x003F, 0x0003, 0x0003, 0x0003, 0x0003, + 7, 0, 0, 0,0x0000, 0x0000, 0x007E, 0x007F, 0x0063, 0x0063, 0x007F, 0x007E, 0x0060, 0x0060, 0x0060, 0x0060, + 7, 0, 0, 0,0x0000, 0x0000, 0x003B, 0x007F, 0x0067, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, + 8, 0, 0, 0,0x0000, 0x0000, 0x007E, 0x007F, 0x0003, 0x007F, 0x00FE, 0x00C0, 0x00FE, 0x007E, 0x0000, 0x0000, + 6, 0, 0, 0,0x0006, 0x0006, 0x003F, 0x003F, 0x0006, 0x0006, 0x0006, 0x0006, 0x003E, 0x003C, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x007F, 0x007E, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x0303, 0x0303, 0x0303, 0x0387, 0x01CE, 0x00FC, 0x0078, 0x0030, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x0303, 0x0303, 0x0333, 0x037B, 0x03FF, 0x03CF, 0x0387, 0x0303, 0x0000, 0x0000, + 8, 0, 0, 0,0x0000, 0x0000, 0x00C3, 0x00E7, 0x007E, 0x003C, 0x003C, 0x007E, 0x00E7, 0x00C3, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x0303, 0x0307, 0x038E, 0x01DC, 0x00F8, 0x0070, 0x0038, 0x001C, 0x000E, 0x0006, + 8, 0, 0, 0,0x0000, 0x0000, 0x00FF, 0x00FF, 0x0070, 0x0038, 0x001C, 0x000E, 0x00FF, 0x00FF, 0x0000, 0x0000, + 6, 0, 0, 0,0x0038, 0x003C, 0x000C, 0x000C, 0x000F, 0x000F, 0x000C, 0x000C, 0x003C, 0x0038, 0x0000, 0x0000, + 2, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, + 6, 0, 0, 0,0x0007, 0x000F, 0x000C, 0x000C, 0x003C, 0x003C, 0x000C, 0x000C, 0x000F, 0x0007, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x031C, 0x03BE, 0x01F7, 0x00E3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 11, 0, 0, 0,0x0555, 0x0000, 0x0401, 0x0000, 0x0401, 0x0000, 0x0401, 0x0000, 0x0401, 0x0000, 0x0555, 0x0000, +}; +#endif diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 5408586..fe1b745 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -46,6 +46,8 @@ #include "../Savestate.h" +#include "OSD.h" + // savestate slot mapping // 1-8: regular slots (quick access) @@ -972,6 +974,8 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) uiRect top = {0, 0, 256, 192}; uiRect bot = {0, 0, 256, 192}; + //OSD::test(GPU::Framebuffer[frontbuf][0]); + uiDrawBitmapUpdate(ScreenBitmap[0], GPU::Framebuffer[frontbuf][0]); uiDrawBitmapUpdate(ScreenBitmap[1], GPU::Framebuffer[frontbuf][1]); -- cgit v1.2.3 From 6de19645f8fdd309cdf9f53d846b70f45ed66e62 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 2 Jun 2019 14:57:59 +0200 Subject: fix potential crash when running the software renderer (oops) --- melonDS.cbp | 2 ++ src/GPU2D.cpp | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/melonDS.cbp b/melonDS.cbp index b517353..3003b84 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -143,6 +143,8 @@ + + diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 212372c..c51b252 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -882,10 +882,12 @@ void GPU2D::VBlankEnd() OBJMosaicY = 0; OBJMosaicYMax = OBJMosaicSize[1]; - // TODO: make optional - if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) + if (GPU3D::Renderer != 0) { - GPU3D::GLRenderer::PrepareCaptureFrame(); + if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) + { + GPU3D::GLRenderer::PrepareCaptureFrame(); + } } } -- cgit v1.2.3 From 5487a4e71cf03c15637bcb3d02a39ba64a66f149 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 2 Jun 2019 15:22:37 +0200 Subject: fix bugs when changing 3D renderer with no game loaded --- src/libui_sdl/main.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index fe1b745..73666cd 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -709,7 +709,6 @@ int EmuThreadFunc(void* burp) else { GPU3D::InitRenderer(false); - GPU::SetDisplaySettings(false); } Touching = false; @@ -1389,6 +1388,14 @@ void OnAreaResize(uiAreaHandler* handler, uiArea* area, int width, int height) void Run() { + if (GPU3D::Renderer != Config::_3DRenderer) + { + if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); + GPU3D::DeInitRenderer(); + GPU3D::InitRenderer(Screen_UseGL); + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + } + EmuRunning = 1; RunningSomething = true; -- 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') 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 4a4415fc2ec067fb79881e17e14953b69ef80e0c Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 3 Jun 2019 15:00:49 +0200 Subject: more work on OSD --- src/libui_sdl/OSD.cpp | 132 +++++++++++++++++++++++++---------- src/libui_sdl/OSD.h | 9 ++- src/libui_sdl/libui/ui.h | 2 +- src/libui_sdl/libui/unix/draw.c | 4 +- src/libui_sdl/libui/windows/draw.cpp | 5 +- src/libui_sdl/main.cpp | 39 ++++++++--- 6 files changed, 133 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/OSD.cpp b/src/libui_sdl/OSD.cpp index bce14c1..a13ff44 100644 --- a/src/libui_sdl/OSD.cpp +++ b/src/libui_sdl/OSD.cpp @@ -18,14 +18,14 @@ #include #include -#include +#include #include #include "../types.h" -#include "OSD.h" #include "libui/ui.h" #include "../OpenGLSupport.h" +#include "OSD.h" #include "font.h" extern int WindowWidth, WindowHeight; @@ -38,6 +38,9 @@ const u32 kOSDMargin = 6; typedef struct { Uint32 Timestamp; + char Text[256]; + u32 Color; + u32 Width, Height; u32* Bitmap; @@ -49,15 +52,28 @@ typedef struct } Item; -std::queue CurrentItems; +std::deque ItemQueue; -bool Init() +bool Init(bool opengl) { + return true; } -void DeInit() +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; + + delete item; + + ItemQueue.erase(it); + } } @@ -142,7 +158,7 @@ u32 RainbowColor(u32 inc) { // inspired from Acmlmboard - if (inc < 100) return 0xFFFF9BFF + (inc << 8); + if (inc < 100) return 0xFFFF9B9B + (inc << 8); else if (inc < 200) return 0xFFFFFF9B - ((inc-100) << 16); else if (inc < 300) return 0xFF9BFF9B + (inc-200); else if (inc < 400) return 0xFF9BFFFF - ((inc-300) << 8); @@ -156,10 +172,10 @@ void RenderText(u32 color, const char* text, Item* item) int breaks[64]; bool rainbow = (color == 0); - u32 rainbowinc = rand() % 600; + u32 rainbowinc = (text[0] * 17) % 600; color |= 0xFF000000; - const u32 shadow = 0xC0000000; + const u32 shadow = 0xFE000000; LayoutText(text, &w, &h, breaks); @@ -257,49 +273,89 @@ void RenderText(u32 color, const char* text, Item* item) } } -void test(u32* berp) + +void AddMessage(u32 color, const char* text) { - Item barp; - RenderText(0x000000, "This is a test of OSD, it can display really long messages, like thiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis. Also, pancakes are the best thing ever.", &barp); + Item* item = new Item; + + item->Timestamp = SDL_GetTicks(); + strncpy(item->Text, text, 255); item->Text[255] = '\0'; + item->Color = color; + item->Bitmap = NULL; - for (int y = 0; y < barp.Height; y++) + item->DrawBitmapLoaded = false; + item->GLTextureLoaded = false; + + ItemQueue.push_back(item); +} + +void WindowResized(bool opengl) +{ + /*for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) { - for (int x = 0; x < barp.Width; x++) - { - u32 src = barp.Bitmap[(y*barp.Width)+x]; - u32 dst = berp[((y+6)*256)+x+6]; + Item* item = *it; - u32 sR = (src >> 16) & 0xFF; - u32 sG = (src >> 8) & 0xFF; - u32 sB = (src ) & 0xFF; - u32 sA = (src >> 24) & 0xFF; + if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap); + //if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture); - u32 dR = (dst >> 16) & 0xFF; - u32 dG = (dst >> 8) & 0xFF; - u32 dB = (dst ) & 0xFF; + item->DrawBitmapLoaded = false; + item->GLTextureLoaded = false; - dR = ((sR * sA) + (dR * (255-sA))) >> 8; - dG = ((sG * sA) + (dG * (255-sA))) >> 8; - dB = ((sB * sA) + (dB * (255-sA))) >> 8; + if (item->Bitmap) delete[] item->Bitmap; - dst = (dR << 16) | (dG << 8) | dB; + it++; + }*/ +} + +void Update(bool opengl, uiAreaDrawParams* params) +{ + Uint32 tick_now = SDL_GetTicks(); + Uint32 tick_min = tick_now - 2500; + u32 y = kOSDMargin; + + for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) + { + Item* item = *it; - berp[((y+6)*256)+x+6] = dst | 0xFF000000; + 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; + + ItemQueue.erase(it); + continue; } - } - delete[] barp.Bitmap; -} + if (!item->Bitmap) + { + RenderText(item->Color, item->Text, item); + } + + if (opengl) + { + // + } + else + { + if (!item->DrawBitmapLoaded) + { + 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}; -void AddMessage(u32 color, const char* text) -{ - // -} + uiDrawBitmapDraw(params->Context, item->DrawBitmap, &rc_src, &rc_dst, 0); + } -void Update(bool opengl) -{ - // + y += item->Height; + it++; + } } } diff --git a/src/libui_sdl/OSD.h b/src/libui_sdl/OSD.h index ed38490..afe403f 100644 --- a/src/libui_sdl/OSD.h +++ b/src/libui_sdl/OSD.h @@ -22,14 +22,13 @@ namespace OSD { -bool Init(); -void DeInit(); - -void test(u32* berp); +bool Init(bool opengl); +void DeInit(bool opengl); void AddMessage(u32 color, const char* text); -void Update(bool opengl); +void WindowResized(bool opengl); +void Update(bool opengl, uiAreaDrawParams* params); } diff --git a/src/libui_sdl/libui/ui.h b/src/libui_sdl/libui/ui.h index 47da54b..e15c127 100644 --- a/src/libui_sdl/libui/ui.h +++ b/src/libui_sdl/libui/ui.h @@ -516,7 +516,7 @@ _UI_EXTERN void uiDrawSave(uiDrawContext *c); _UI_EXTERN void uiDrawRestore(uiDrawContext *c); // bitmap API -_UI_EXTERN uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height); +_UI_EXTERN uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height, int alpha); _UI_EXTERN void uiDrawBitmapUpdate(uiDrawBitmap* bmp, const void* data); _UI_EXTERN void uiDrawBitmapDraw(uiDrawContext* c, uiDrawBitmap* bmp, uiRect* srcrect, uiRect* dstrect, int filter); _UI_EXTERN void uiDrawFreeBitmap(uiDrawBitmap* bmp); diff --git a/src/libui_sdl/libui/unix/draw.c b/src/libui_sdl/libui/unix/draw.c index e55397e..5befcd3 100644 --- a/src/libui_sdl/libui/unix/draw.c +++ b/src/libui_sdl/libui/unix/draw.c @@ -143,13 +143,13 @@ void uiDrawRestore(uiDrawContext *c) // bitmap API -uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height) +uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height, int alpha) { uiDrawBitmap* bmp; bmp = uiNew(uiDrawBitmap); - bmp->bmp = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height); + bmp->bmp = cairo_image_surface_create(alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, width, height); if (cairo_surface_status(bmp->bmp) != CAIRO_STATUS_SUCCESS) implbug("error creating bitmap: %s", cairo_status_to_string(cairo_surface_status(bmp->bmp))); diff --git a/src/libui_sdl/libui/windows/draw.cpp b/src/libui_sdl/libui/windows/draw.cpp index 11a777d..9a815b9 100644 --- a/src/libui_sdl/libui/windows/draw.cpp +++ b/src/libui_sdl/libui/windows/draw.cpp @@ -522,7 +522,7 @@ void uiDrawRestore(uiDrawContext *c) // bitmap API -uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height) +uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height, int alpha) { uiDrawBitmap* bmp; HRESULT hr; @@ -532,7 +532,8 @@ uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height) D2D1_BITMAP_PROPERTIES bp2 = D2D1::BitmapProperties(); bp2.dpiX = 0; bp2.dpiY = 0; - bp2.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE); + bp2.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, + alpha ? D2D1_ALPHA_MODE_PREMULTIPLIED : D2D1_ALPHA_MODE_IGNORE); //c->rt->BeginDraw(); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 73666cd..5407403 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -434,6 +434,8 @@ void GLScreen_DrawScreen() glDrawArrays(GL_TRIANGLES, 0, 4*3); } + OSD::Update(true, NULL); + glFlush(); uiGLSwapBuffers(GLContext); } @@ -948,7 +950,15 @@ int EmuThreadFunc(void* burp) NDS::DeInit(); Platform::LAN_DeInit(); - if (Screen_UseGL) GLScreen_DeInit(); + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + OSD::DeInit(true); + GLScreen_DeInit(); + uiGLMakeContextCurrent(NULL); + } + else + OSD::DeInit(false); return 44203; } @@ -962,8 +972,8 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); ScreenDrawInited = true; - ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256, 192); - ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192); + ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256, 192, 0); + ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192, 0); } int frontbuf = GPU::FrontBuffer; @@ -973,8 +983,6 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) uiRect top = {0, 0, 256, 192}; uiRect bot = {0, 0, 256, 192}; - //OSD::test(GPU::Framebuffer[frontbuf][0]); - uiDrawBitmapUpdate(ScreenBitmap[0], GPU::Framebuffer[frontbuf][0]); uiDrawBitmapUpdate(ScreenBitmap[1], GPU::Framebuffer[frontbuf][1]); @@ -987,6 +995,8 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) uiDrawTransform(params->Context, &BottomScreenTrans); uiDrawBitmapDraw(params->Context, ScreenBitmap[1], &bot, &BottomScreenRect, Config::ScreenFilter==1); uiDrawRestore(params->Context); + + OSD::Update(false, params); } void OnAreaMouseEvent(uiAreaHandler* handler, uiArea* area, uiAreaMouseEvent* evt) @@ -1118,7 +1128,8 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt) MicCommand |= 1; if (evt->Scancode == 0x57) // F11 - NDS::debug(0); + OSD::AddMessage(0, "OSD test"); + //NDS::debug(0); } return 1; @@ -1374,15 +1385,17 @@ void OnAreaResize(uiAreaHandler* handler, uiArea* area, int width, int height) WindowWidth = width; WindowHeight = height; - int max = uiWindowMaximized(MainWindow); - int min = uiWindowMinimized(MainWindow); + int ismax = uiWindowMaximized(MainWindow); + int ismin = uiWindowMinimized(MainWindow); - Config::WindowMaximized = max; - if (!max && !min) + Config::WindowMaximized = ismax; + if (!ismax && !ismin) { Config::WindowWidth = width; Config::WindowHeight = height; } + + OSD::WindowResized(Screen_UseGL); } @@ -2061,6 +2074,10 @@ void ApplyNewSettings(int type) if (Screen_UseGL) uiGLMakeContextCurrent(NULL); } + if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); + OSD::DeInit(Screen_UseGL); + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + Screen_UseGL = usegl; RecreateMainWindow(usegl); @@ -2294,6 +2311,8 @@ void CreateMainWindow(bool opengl) RecreateMainWindow(false); Screen_UseGL = false; } + + OSD::Init(opengl); } void DestroyMainWindow() -- 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') 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 From e3dc4e122a6ba822c860c09290925f98cc623532 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 3 Jun 2019 17:01:53 +0200 Subject: use OSD for some actual purposes --- src/libui_sdl/OSD.cpp | 2 +- src/libui_sdl/main.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/libui_sdl/OSD.cpp b/src/libui_sdl/OSD.cpp index 851f9c5..c8d5f83 100644 --- a/src/libui_sdl/OSD.cpp +++ b/src/libui_sdl/OSD.cpp @@ -205,7 +205,7 @@ void RenderText(u32 color, const char* text, Item* item) u32 rainbowinc = (text[0] * 17) % 600; color |= 0xFF000000; - const u32 shadow = 0xFE000000; + const u32 shadow = 0xE0000000; LayoutText(text, &w, &h, breaks); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 073c8ac..cb93294 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -1591,6 +1591,11 @@ void LoadState(int slot) if (!Platform::FileExists(filename)) { + char msg[64]; + if (slot > 0) sprintf(msg, "State slot %d is empty", slot); + else sprintf(msg, "State file does not exist"); + OSD::AddMessage(0xFFA0A0, msg); + EmuRunning = prevstatus; return; } @@ -1631,6 +1636,11 @@ void LoadState(int slot) NDS::RelocateSave(SRAMPath, false); } + char msg[64]; + if (slot > 0) sprintf(msg, "State loaded from slot %d", slot); + else sprintf(msg, "State loaded from file"); + OSD::AddMessage(0, msg); + SavestateLoaded = true; uiMenuItemEnable(MenuItem_UndoStateLoad); } @@ -1690,6 +1700,11 @@ void SaveState(int slot) } } + char msg[64]; + if (slot > 0) sprintf(msg, "State saved to slot %d", slot); + else sprintf(msg, "State saved to file"); + OSD::AddMessage(0, msg); + EmuRunning = prevstatus; } @@ -1714,6 +1729,8 @@ void UndoStateLoad() NDS::RelocateSave(SRAMPath, false); } + OSD::AddMessage(0, "State load undone"); + EmuRunning = prevstatus; } -- cgit v1.2.3 From 3134c8fc66d1fbd5706930a3e3e64ce118406fe5 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 4 Jun 2019 15:44:40 +0200 Subject: add support for setting key mappings to none --- src/libui_sdl/DlgInputConfig.cpp | 37 ++++++++++++++++++++++++++++--------- src/libui_sdl/PlatformConfig.cpp | 2 +- 2 files changed, 29 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/libui_sdl/DlgInputConfig.cpp b/src/libui_sdl/DlgInputConfig.cpp index 98cdf8c..b77f8fe 100644 --- a/src/libui_sdl/DlgInputConfig.cpp +++ b/src/libui_sdl/DlgInputConfig.cpp @@ -64,6 +64,21 @@ int openedmask; InputDlgData inputdlg[2]; +void KeyMappingName(int id, char* str) +{ + if (id < 0) + { + strcpy(str, "None"); + return; + } + + char* keyname = uiKeyName(id); + strncpy(str, keyname, 31); + uiFreeText(keyname); + + str[31] = '\0'; +} + void JoyMappingName(int id, char* str) { if (id < 0) @@ -134,7 +149,7 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt) return 1; } - char keyname[16]; + char keyname[32]; JoyMappingName(dlg->joymap[id], keyname); uiButtonSetText(dlg->pollbtn, keyname); uiControlEnable(uiControl(dlg->pollbtn)); @@ -150,12 +165,17 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt) { // set key. if (evt->Scancode != 0x1) // ESC - dlg->keymap[dlg->pollid] = evt->Scancode; + { + if (evt->Scancode == 0xE) // backspace + dlg->keymap[dlg->pollid] = -1; + else + dlg->keymap[dlg->pollid] = evt->Scancode; + } - char* keyname = uiKeyName(dlg->keymap[dlg->pollid]); + char keyname[32]; + KeyMappingName(dlg->keymap[dlg->pollid], keyname); uiButtonSetText(dlg->pollbtn, keyname); uiControlEnable(uiControl(dlg->pollbtn)); - uiFreeText(keyname); dlg->pollid = -1; @@ -170,7 +190,7 @@ void FinishJoyMapping(void* param) InputDlgData* dlg = (InputDlgData*)param; int id = dlg->pollid & 0xFF; - char keyname[16]; + char keyname[32]; JoyMappingName(dlg->joymap[id], keyname); uiButtonSetText(dlg->pollbtn, keyname); uiControlEnable(uiControl(dlg->pollbtn)); @@ -386,15 +406,14 @@ void Open(int type) uiGridAppend(b_key, uiControl(label), 0, i, 1, 1, 1, uiAlignStart, 1, uiAlignCenter); uiControlSetMinSize(uiControl(label), width, 1); - char* keyname = uiKeyName(dlg->keymap[j]); + char keyname[32]; + KeyMappingName(dlg->keymap[j], keyname); uiButton* btn = uiNewButton(keyname); uiControl(btn)->UserData = dlg; uiGridAppend(b_key, uiControl(btn), 1, i, 1, 1, 1, uiAlignFill, 1, uiAlignCenter); uiButtonOnClicked(btn, OnKeyStartConfig, (type==0) ? &dskeyorder[i] : &identity[i]); uiControlSetMinSize(uiControl(btn), width, 1); - - uiFreeText(keyname); } uiGroup* g_joy = uiNewGroup("Joystick"); @@ -410,7 +429,7 @@ void Open(int type) uiGridAppend(b_joy, uiControl(label), 0, i, 1, 1, 1, uiAlignStart, 1, uiAlignCenter); uiControlSetMinSize(uiControl(label), width, 1); - char keyname[16]; + char keyname[32]; JoyMappingName(dlg->joymap[j], keyname); uiButton* btn = uiNewButton(keyname); diff --git a/src/libui_sdl/PlatformConfig.cpp b/src/libui_sdl/PlatformConfig.cpp index f700ecb..46e502d 100644 --- a/src/libui_sdl/PlatformConfig.cpp +++ b/src/libui_sdl/PlatformConfig.cpp @@ -88,7 +88,7 @@ ConfigEntry PlatformConfigFile[] = {"Joy_X", 0, &JoyMapping[10], -1, NULL, 0}, {"Joy_Y", 0, &JoyMapping[11], -1, NULL, 0}, - {"HKKey_Lid", 0, &HKKeyMapping[HK_Lid], 0x0E, NULL, 0}, + {"HKKey_Lid", 0, &HKKeyMapping[HK_Lid], 0x0D, NULL, 0}, {"HKKey_Mic", 0, &HKKeyMapping[HK_Mic], 0x35, NULL, 0}, {"HKJoy_Lid", 0, &HKJoyMapping[HK_Lid], -1, NULL, 0}, -- cgit v1.2.3