move/refactor OpenGL code

This commit is contained in:
SuuperW 2018-08-13 11:15:36 -05:00
parent 4c83ec19e9
commit 89fc0a12e3
5 changed files with 205 additions and 120 deletions

View File

@ -372,6 +372,7 @@
<ClCompile Include="main.cpp" />
<ClCompile Include="mic-win.cpp" />
<ClCompile Include="ogl.cpp" />
<ClCompile Include="ogl_display.cpp" />
<ClCompile Include="OpenArchive.cpp" />
<ClCompile Include="pathsettings.cpp" />
<ClCompile Include="recentroms.cpp" />
@ -659,6 +660,7 @@
<ClInclude Include="importSave.h" />
<ClInclude Include="inputdx.h" />
<ClInclude Include="main.h" />
<ClInclude Include="ogl_display.h" />
<ClInclude Include="OpenArchive.h" />
<ClInclude Include="pathsettings.h" />
<ClInclude Include="recentroms.h" />

View File

@ -924,6 +924,9 @@
<ClCompile Include="ddraw.cpp">
<Filter>frontend\Windows</Filter>
</ClCompile>
<ClCompile Include="ogl_display.cpp">
<Filter>frontend\Windows</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\utils\guid.h">
@ -1616,6 +1619,9 @@
<ClInclude Include="ddraw.h">
<Filter>frontend\Windows</Filter>
</ClInclude>
<ClInclude Include="ogl_display.h">
<Filter>frontend\Windows</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="bitmap1.bmp">

View File

@ -92,6 +92,7 @@
#include "winutil.h"
#include "ogl.h"
#include "ddraw.h"
#include "ogl_display.h"
//tools and dialogs
#include "pathsettings.h"
@ -342,6 +343,7 @@ Lock::Lock(CRITICAL_SECTION& cs) : m_cs(&cs) { EnterCriticalSection(m_cs); }
Lock::~Lock() { LeaveCriticalSection(m_cs); }
DDRAW ddraw;
GLDISPLAY gldisplay;
//===================== Input vars
#define WM_CUSTKEYDOWN (WM_USER+50)
@ -1652,125 +1654,6 @@ static void DD_FillRect(LPDIRECTDRAWSURFACE7 surf, int left, int top, int right,
surf->Blt(&r,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&fx);
}
struct GLDISPLAY
{
HGLRC privateContext;
HDC privateDC;
bool init;
bool active;
bool wantVsync, haveVsync;
GLDISPLAY()
: init(false)
, active(false)
, wantVsync(false)
, haveVsync(false)
{
}
bool initialize()
{
//do we need to use another HDC?
if(init) return true;
init = initContext(MainWindow->getHWnd(),&privateContext);
setvsync(!!(GetStyle()&DWS_VSYNC));
return init;
}
void kill()
{
if(!init) return;
wglDeleteContext(privateContext);
privateContext = NULL;
haveVsync = false;
init = false;
}
bool begin()
{
DWORD myThread = GetCurrentThreadId();
//always use another context for display logic
//1. if this is a single threaded process (3d rendering and display in the main thread) then alternating contexts is benign
//2. if this is a multi threaded process (3d rendernig and display in other threads) then the display needs some context
if(!init)
{
if(!initialize()) return false;
}
privateDC = GetDC(MainWindow->getHWnd());
wglMakeCurrent(privateDC,privateContext);
//go ahead and sync the vsync setting while we have the context
if (wantVsync != haveVsync)
_setvsync();
return active = true;
}
void end()
{
wglMakeCurrent(NULL,privateContext);
ReleaseDC(MainWindow->getHWnd(),privateDC);
privateDC = NULL;
active = false;
}
//http://stackoverflow.com/questions/589064/how-to-enable-vertical-sync-in-opengl
bool WGLExtensionSupported(const char *extension_name)
{
// this is pointer to function which returns pointer to string with list of all wgl extensions
PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglGetExtensionsStringEXT = NULL;
// determine pointer to wglGetExtensionsStringEXT function
_wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
if (strstr(_wglGetExtensionsStringEXT(), extension_name) == NULL)
{
// string was not found
return false;
}
// extension is supported
return true;
}
void setvsync(bool vsync)
{
wantVsync = vsync;
}
void _setvsync()
{
//even if it doesn't work, we'll track it
haveVsync = wantVsync;
if (!WGLExtensionSupported("WGL_EXT_swap_control")) return;
//http://stackoverflow.com/questions/589064/how-to-enable-vertical-sync-in-opengl
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = NULL;
{
// Extension is supported, init pointers.
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
// this is another function from WGL_EXT_swap_control extension
wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT");
}
wglSwapIntervalEXT(wantVsync ? 1 : 0);
}
void showPage()
{
SwapBuffers(privateDC);
}
} gldisplay;
static void OGL_DrawTexture(RECT* srcRects, RECT* dstRects)
{
//don't change the original rects
@ -1844,7 +1727,7 @@ static void OGL_DrawTexture(RECT* srcRects, RECT* dstRects)
}
static void OGL_DoDisplay()
{
if(!gldisplay.begin()) return;
if(!gldisplay.begin(MainWindow->getHWnd())) return;
//the ds screen fills the texture entirely, so we dont have garbage at edge to worry about,
//but we need to make sure this is clamped for when filtering is selected

View File

@ -0,0 +1,142 @@
/*
Copyright (C) 2018 DeSmuME team
This file 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 2 of the License, or
(at your option) any later version.
This file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ogl_display.h"
bool GLDISPLAY::initialize(HWND hwnd)
{
//do we need to use another HDC?
if (hwnd == this->hwnd) return true;
else if (this->hwnd) return false;
if (initContext(hwnd, &privateContext))
{
this->hwnd = hwnd;
return true;
}
else
return false;
}
//http://stackoverflow.com/questions/589064/how-to-enable-vertical-sync-in-opengl
bool GLDISPLAY::WGLExtensionSupported(const char *extension_name)
{
// this is pointer to function which returns pointer to string with list of all wgl extensions
PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglGetExtensionsStringEXT = NULL;
// determine pointer to wglGetExtensionsStringEXT function
_wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
if (strstr(_wglGetExtensionsStringEXT(), extension_name) == NULL)
{
// string was not found
return false;
}
// extension is supported
return true;
}
void GLDISPLAY::_setvsync()
{
//even if it doesn't work, we'll track it
haveVsync = wantVsync;
if (!WGLExtensionSupported("WGL_EXT_swap_control")) return;
//http://stackoverflow.com/questions/589064/how-to-enable-vertical-sync-in-opengl
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = NULL;
{
// Extension is supported, init pointers.
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
// this is another function from WGL_EXT_swap_control extension
wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT");
}
wglSwapIntervalEXT(wantVsync ? 1 : 0);
}
GLDISPLAY::GLDISPLAY()
: active(false)
, wantVsync(false)
, haveVsync(false)
{
}
void GLDISPLAY::kill()
{
if (!hwnd) return;
wglDeleteContext(privateContext);
privateContext = NULL;
hwnd = NULL;
haveVsync = false;
}
bool GLDISPLAY::begin(HWND hwnd)
{
DWORD myThread = GetCurrentThreadId();
//always use another context for display logic
//1. if this is a single threaded process (3d rendering and display in the main thread) then alternating contexts is benign
//2. if this is a multi threaded process (3d rendernig and display in other threads) then the display needs some context
if (!this->hwnd)
{
if (!initialize(hwnd)) return false;
}
privateDC = GetDC(hwnd);
wglMakeCurrent(privateDC, privateContext);
//go ahead and sync the vsync setting while we have the context
if (wantVsync != haveVsync)
_setvsync();
if (filter)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
return active = true;
}
void GLDISPLAY::end()
{
wglMakeCurrent(NULL, privateContext);
ReleaseDC(hwnd, privateDC);
privateDC = NULL;
active = false;
}
void GLDISPLAY::setvsync(bool vsync)
{
wantVsync = vsync;
}
void GLDISPLAY::showPage()
{
SwapBuffers(privateDC);
}

View File

@ -0,0 +1,52 @@
/*
Copyright (C) 2018 DeSmuME team
This file 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 2 of the License, or
(at your option) any later version.
This file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _OGL_DISPLAY_H_
#define _OGL_DISPLAY_H_
#include "types.h"
#include "ogl.h"
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/wglext.h>
struct GLDISPLAY
{
private:
HGLRC privateContext;
HDC privateDC;
HWND hwnd;
bool initialize(HWND hwnd);
bool WGLExtensionSupported(const char *extension_name);
void _setvsync();
public:
bool active;
bool wantVsync, haveVsync;
bool filter;
GLDISPLAY();
void kill();
bool begin(HWND hwnd);
void end();
void setvsync(bool vsync);
void showPage();
};
#endif