mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +00:00
Add DisplayWindow class to replace OGLVideo
This commit is contained in:
parent
07fae53ed4
commit
3bbb871fc6
|
@ -279,6 +279,7 @@
|
|||
<ClCompile Include="..\..\src\DepthBuffer.cpp" />
|
||||
<ClCompile Include="..\..\src\DepthBufferRender\ClipPolygon.cpp" />
|
||||
<ClCompile Include="..\..\src\DepthBufferRender\DepthBufferRender.cpp" />
|
||||
<ClCompile Include="..\..\src\DisplayWindow.cpp" />
|
||||
<ClCompile Include="..\..\src\F3DEX2CBFD.cpp" />
|
||||
<ClCompile Include="..\..\src\F3DEX2MM.cpp" />
|
||||
<ClCompile Include="..\..\src\F3DGOLDEN.cpp" />
|
||||
|
@ -300,6 +301,10 @@
|
|||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_ShaderStorage.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_SpecialShadersFactory.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_Utils.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\mupen64plus\mupen64plus_DisplayWindow.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_Attributes.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_BufferManipulationObjectFactory.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_CachedFunctions.cpp" />
|
||||
|
@ -308,6 +313,11 @@
|
|||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_Parameters.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_TextureManipulationObjectFactory.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_Utils.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\windows\windows_DisplayWindow.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_mupenplus|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus_uniformset|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\gSP.cpp" />
|
||||
<ClCompile Include="..\..\src\Keys.cpp" />
|
||||
<ClCompile Include="..\..\src\Log.cpp" />
|
||||
|
@ -408,6 +418,7 @@
|
|||
<ClInclude Include="..\..\src\DepthBuffer.h" />
|
||||
<ClInclude Include="..\..\src\DepthBufferRender\ClipPolygon.h" />
|
||||
<ClInclude Include="..\..\src\DepthBufferRender\DepthBufferRender.h" />
|
||||
<ClInclude Include="..\..\src\DisplayWindow.h" />
|
||||
<ClInclude Include="..\..\src\F3DEX2CBFD.h" />
|
||||
<ClInclude Include="..\..\src\F3DEX2MM.h" />
|
||||
<ClInclude Include="..\..\src\F3DGOLDEN.h" />
|
||||
|
|
|
@ -63,6 +63,15 @@
|
|||
<Filter Include="Source Files\Graphics\OpenGL\GLSL">
|
||||
<UniqueIdentifier>{e67eafa1-5cea-4267-bc12-715e06c744db}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\Graphics\OpenGL\windows">
|
||||
<UniqueIdentifier>{dfff6885-c7e7-4b77-863e-7eeea6753d5a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Graphics\OpenGL\windows">
|
||||
<UniqueIdentifier>{e8b5c80f-51ec-45c2-bcdb-5e18868073df}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Graphics\OpenGL\mupen64plus">
|
||||
<UniqueIdentifier>{77259791-9942-4601-a63f-5a0468e69e49}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\Combiner.cpp">
|
||||
|
@ -323,6 +332,15 @@
|
|||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_ShaderStorage.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\DisplayWindow.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\windows\windows_DisplayWindow.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\mupen64plus\mupen64plus_DisplayWindow.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\mupen64plus</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\3DMath.h">
|
||||
|
@ -601,5 +619,8 @@
|
|||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_ShaderStorage.h">
|
||||
<Filter>Header Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\DisplayWindow.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
164
src/DisplayWindow.cpp
Normal file
164
src/DisplayWindow.cpp
Normal file
|
@ -0,0 +1,164 @@
|
|||
#include <assert.h>
|
||||
#include "Config.h"
|
||||
#include "VI.h"
|
||||
#include "DisplayWindow.h"
|
||||
#include "Graphics/Context.h"
|
||||
|
||||
void DisplayWindow::start()
|
||||
{
|
||||
_start(); // TODO: process initialization error
|
||||
gfxContext.init();
|
||||
// m_render._initData();
|
||||
m_buffersSwapCount = 0;
|
||||
}
|
||||
|
||||
void DisplayWindow::stop()
|
||||
{
|
||||
// m_render._destroyData();
|
||||
gfxContext.destroy();
|
||||
_stop();
|
||||
}
|
||||
|
||||
void DisplayWindow::restart()
|
||||
{
|
||||
m_bResizeWindow = true;
|
||||
}
|
||||
|
||||
void DisplayWindow::swapBuffers()
|
||||
{
|
||||
// m_render.drawOSD();
|
||||
_swapBuffers();
|
||||
gDP.otherMode.l = 0;
|
||||
if ((config.generalEmulation.hacks & hack_doNotResetTLUTmode) == 0)
|
||||
gDPSetTextureLUT(G_TT_NONE);
|
||||
++m_buffersSwapCount;
|
||||
}
|
||||
|
||||
void DisplayWindow::setCaptureScreen(const char * const _strDirectory)
|
||||
{
|
||||
::mbstowcs(m_strScreenDirectory, _strDirectory, PLUGIN_PATH_SIZE - 1);
|
||||
m_bCaptureScreen = true;
|
||||
}
|
||||
|
||||
void DisplayWindow::saveScreenshot()
|
||||
{
|
||||
if (!m_bCaptureScreen)
|
||||
return;
|
||||
_saveScreenshot();
|
||||
m_bCaptureScreen = false;
|
||||
}
|
||||
|
||||
bool DisplayWindow::changeWindow()
|
||||
{
|
||||
if (!m_bToggleFullscreen)
|
||||
return false;
|
||||
// m_render._destroyData();
|
||||
_changeWindow();
|
||||
updateScale();
|
||||
// m_render._initData();
|
||||
m_bToggleFullscreen = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DisplayWindow::setWindowSize(u32 _width, u32 _height)
|
||||
{
|
||||
if (m_width != _width || m_height != _height) {
|
||||
m_resizeWidth = _width;
|
||||
m_resizeHeight = _height;
|
||||
m_bResizeWindow = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool DisplayWindow::resizeWindow()
|
||||
{
|
||||
if (!m_bResizeWindow)
|
||||
return false;
|
||||
// m_render._destroyData();
|
||||
if (!_resizeWindow())
|
||||
_start();
|
||||
updateScale();
|
||||
// m_render._initData();
|
||||
m_bResizeWindow = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DisplayWindow::updateScale()
|
||||
{
|
||||
if (VI.width == 0 || VI.height == 0)
|
||||
return;
|
||||
m_scaleX = m_width / (float)VI.width;
|
||||
m_scaleY = m_height / (float)VI.height;
|
||||
}
|
||||
|
||||
void DisplayWindow::_setBufferSize()
|
||||
{
|
||||
m_bAdjustScreen = false;
|
||||
if (config.frameBufferEmulation.enable) {
|
||||
switch (config.frameBufferEmulation.aspect) {
|
||||
case Config::aStretch: // stretch
|
||||
m_width = m_screenWidth;
|
||||
m_height = m_screenHeight;
|
||||
break;
|
||||
case Config::a43: // force 4/3
|
||||
if (m_screenWidth * 3 / 4 > m_screenHeight) {
|
||||
m_height = m_screenHeight;
|
||||
m_width = m_screenHeight * 4 / 3;
|
||||
}
|
||||
else if (m_screenHeight * 4 / 3 > m_screenWidth) {
|
||||
m_width = m_screenWidth;
|
||||
m_height = m_screenWidth * 3 / 4;
|
||||
}
|
||||
else {
|
||||
m_width = m_screenWidth;
|
||||
m_height = m_screenHeight;
|
||||
}
|
||||
break;
|
||||
case Config::a169: // force 16/9
|
||||
if (m_screenWidth * 9 / 16 > m_screenHeight) {
|
||||
m_height = m_screenHeight;
|
||||
m_width = m_screenHeight * 16 / 9;
|
||||
}
|
||||
else if (m_screenHeight * 16 / 9 > m_screenWidth) {
|
||||
m_width = m_screenWidth;
|
||||
m_height = m_screenWidth * 9 / 16;
|
||||
}
|
||||
else {
|
||||
m_width = m_screenWidth;
|
||||
m_height = m_screenHeight;
|
||||
}
|
||||
break;
|
||||
case Config::aAdjust: // adjust
|
||||
m_width = m_screenWidth;
|
||||
m_height = m_screenHeight;
|
||||
if (m_screenWidth * 3 / 4 > m_screenHeight) {
|
||||
f32 width43 = m_screenHeight * 4.0f / 3.0f;
|
||||
m_adjustScale = width43 / m_screenWidth;
|
||||
m_bAdjustScreen = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false && "Unknown aspect ratio");
|
||||
m_width = m_screenWidth;
|
||||
m_height = m_screenHeight;
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_width = m_screenWidth;
|
||||
m_height = m_screenHeight;
|
||||
if (config.frameBufferEmulation.aspect == Config::aAdjust && (m_screenWidth * 3 / 4 > m_screenHeight)) {
|
||||
f32 width43 = m_screenHeight * 4.0f / 3.0f;
|
||||
m_adjustScale = width43 / m_screenWidth;
|
||||
m_bAdjustScreen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayWindow::readScreen(void **_pDest, long *_pWidth, long *_pHeight)
|
||||
{
|
||||
_readScreen(_pDest, _pWidth, _pHeight);
|
||||
}
|
||||
|
||||
void DisplayWindow::readScreen2(void * _dest, int * _width, int * _height, int _front)
|
||||
{
|
||||
_readScreen2(_dest, _width, _height, _front);
|
||||
}
|
78
src/DisplayWindow.h
Normal file
78
src/DisplayWindow.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
#pragma once
|
||||
#include "Types.h"
|
||||
|
||||
namespace graphics {
|
||||
class VideoImpl;
|
||||
}
|
||||
|
||||
class DisplayWindow
|
||||
{
|
||||
public:
|
||||
virtual ~DisplayWindow() {}
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void restart();
|
||||
void swapBuffers();
|
||||
void saveScreenshot();
|
||||
bool changeWindow();
|
||||
bool resizeWindow();
|
||||
void setWindowSize(u32 _width, u32 _height);
|
||||
void setCaptureScreen(const char * const _strDirectory);
|
||||
void setToggleFullscreen() { m_bToggleFullscreen = true; }
|
||||
void readScreen(void **_pDest, long *_pWidth, long *_pHeight);
|
||||
void readScreen2(void * _dest, int * _width, int * _height, int _front);
|
||||
|
||||
void updateScale();
|
||||
f32 getScaleX() const { return m_scaleX; }
|
||||
f32 getScaleY() const { return m_scaleY; }
|
||||
f32 getAdjustScale() const { return m_adjustScale; }
|
||||
u32 getBuffersSwapCount() const { return m_buffersSwapCount; }
|
||||
u32 getWidth() const { return m_width; }
|
||||
u32 getHeight() const { return m_height; }
|
||||
u32 getScreenWidth() const { return m_screenWidth; }
|
||||
u32 getScreenHeight() const { return m_screenHeight; }
|
||||
u32 getHeightOffset() const { return m_heightOffset; }
|
||||
bool isFullscreen() const { return m_bFullscreen; }
|
||||
bool isAdjustScreen() const { return m_bAdjustScreen; }
|
||||
bool isResizeWindow() const { return m_bResizeWindow; }
|
||||
|
||||
static DisplayWindow & get();
|
||||
|
||||
protected:
|
||||
DisplayWindow() = default;
|
||||
|
||||
void _setBufferSize();
|
||||
|
||||
bool m_bCaptureScreen = false;
|
||||
bool m_bToggleFullscreen = false;
|
||||
bool m_bResizeWindow = false;
|
||||
bool m_bFullscreen = false;
|
||||
bool m_bAdjustScreen = false;
|
||||
|
||||
u32 m_buffersSwapCount = 0;
|
||||
u32 m_width = 0;
|
||||
u32 m_height = 0;
|
||||
u32 m_heightOffset = 0;
|
||||
u32 m_screenWidth = 0;
|
||||
u32 m_screenHeight = 0;
|
||||
u32 m_resizeWidth = 0;
|
||||
u32 m_resizeHeight = 0;
|
||||
f32 m_scaleX = 0;
|
||||
f32 m_scaleY = 0;
|
||||
f32 m_adjustScale = 0;
|
||||
|
||||
wchar_t m_strScreenDirectory[PLUGIN_PATH_SIZE];
|
||||
|
||||
private:
|
||||
// OGLRender m_render;
|
||||
|
||||
virtual bool _start() = 0;
|
||||
virtual void _stop() = 0;
|
||||
virtual void _swapBuffers() = 0;
|
||||
virtual void _saveScreenshot() = 0;
|
||||
virtual void _changeWindow() = 0;
|
||||
virtual bool _resizeWindow() = 0;
|
||||
virtual void _readScreen(void **_pDest, long *_pWidth, long *_pHeight) = 0;
|
||||
virtual void _readScreen2(void * _dest, int * _width, int * _height, int _front) = 0;
|
||||
};
|
|
@ -0,0 +1,225 @@
|
|||
#include <stdio.h>
|
||||
#include <Graphics/OpenGLContext/GLFunctions.h>
|
||||
#include <Graphics/OpenGLContext/opengl_Utils.h>
|
||||
#include <mupenplus/GLideN64_mupenplus.h>
|
||||
#include <GLideN64.h>
|
||||
#include <Config.h>
|
||||
#include <N64.h>
|
||||
#include <gSP.h>
|
||||
#include <Log.h>
|
||||
#include <Revision.h>
|
||||
#include <FrameBuffer.h>
|
||||
#include <GLideNUI/GLideNUI.h>
|
||||
#include <DisplayWindow.h>
|
||||
|
||||
#ifdef VC
|
||||
#include <bcm_host.h>
|
||||
#endif
|
||||
|
||||
class DisplayWindowMupen64plus : public DisplayWindow
|
||||
{
|
||||
public:
|
||||
DisplayWindowMupen64plus() {}
|
||||
|
||||
private:
|
||||
void _setAttributes();
|
||||
void _getDisplaySize();
|
||||
|
||||
bool _start() override;
|
||||
void _stop() override;
|
||||
void _swapBuffers() override;
|
||||
void _saveScreenshot() override;
|
||||
bool _resizeWindow() override;
|
||||
void _changeWindow() override;
|
||||
void _readScreen(void **_pDest, long *_pWidth, long *_pHeight) override {}
|
||||
void _readScreen2(void * _dest, int * _width, int * _height, int _front) override;
|
||||
};
|
||||
|
||||
DisplayWindow & DisplayWindow::get()
|
||||
{
|
||||
static DisplayWindowMupen64plus video;
|
||||
return video;
|
||||
}
|
||||
|
||||
void DisplayWindowMupen64plus::_setAttributes()
|
||||
{
|
||||
|
||||
#ifdef GLES2
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
LOG(LOG_VERBOSE, "[gles2GlideN64]: _setAttributes\n");
|
||||
#elif defined(GLES3)
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
#elif defined(GLES3_1)
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 1);
|
||||
#elif defined(OS_MAC_OS_X)
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 2);
|
||||
#else
|
||||
// Do nothing
|
||||
#endif
|
||||
|
||||
#ifndef GLES2
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_RED_SIZE, 8);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_GREEN_SIZE, 8);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_BLUE_SIZE, 8);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_ALPHA_SIZE, 8);
|
||||
#endif
|
||||
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_DOUBLEBUFFER, 1);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_SWAP_CONTROL, config.video.verticalSync);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_BUFFER_SIZE, 32);
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_DEPTH_SIZE, 16);
|
||||
if (config.video.multisampling > 0 && config.frameBufferEmulation.enable == 0) {
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLEBUFFERS, 1);
|
||||
if (config.video.multisampling <= 2)
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 2);
|
||||
else if (config.video.multisampling <= 4)
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 4);
|
||||
else if (config.video.multisampling <= 8)
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 8);
|
||||
else
|
||||
CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 16);
|
||||
}
|
||||
}
|
||||
|
||||
bool DisplayWindowMupen64plus::_start()
|
||||
{
|
||||
CoreVideo_Init();
|
||||
_setAttributes();
|
||||
|
||||
m_bFullscreen = config.video.fullscreen > 0;
|
||||
m_screenWidth = config.video.windowedWidth;
|
||||
m_screenHeight = config.video.windowedHeight;
|
||||
_getDisplaySize();
|
||||
_setBufferSize();
|
||||
|
||||
printf("(II) Setting video mode %dx%d...\n", m_screenWidth, m_screenHeight);
|
||||
const m64p_video_flags flags = M64VIDEOFLAG_SUPPORT_RESIZING;
|
||||
if (CoreVideo_SetVideoMode(m_screenWidth, m_screenHeight, 0, m_bFullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED, flags) != M64ERR_SUCCESS) {
|
||||
//printf("(EE) Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight);
|
||||
LOG(LOG_ERROR, "[gles2GlideN64]: Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight);
|
||||
CoreVideo_Quit();
|
||||
return false;
|
||||
}
|
||||
LOG(LOG_VERBOSE, "[gles2GlideN64]: Create setting videomode %dx%d\n", m_screenWidth, m_screenHeight);
|
||||
|
||||
char caption[128];
|
||||
# ifdef _DEBUG
|
||||
sprintf(caption, "%s debug. Revision %s", pluginName, PLUGIN_REVISION);
|
||||
# else // _DEBUG
|
||||
sprintf(caption, "%s. Revision %s", pluginName, PLUGIN_REVISION);
|
||||
# endif // _DEBUG
|
||||
CoreVideo_SetCaption(caption);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DisplayWindowMupen64plus::_stop()
|
||||
{
|
||||
CoreVideo_Quit();
|
||||
}
|
||||
|
||||
void DisplayWindowMupen64plus::_swapBuffers()
|
||||
{
|
||||
// if emulator defined a render callback function, call it before buffer swap
|
||||
if (renderCallback != nullptr) {
|
||||
glUseProgram(0);
|
||||
if (config.frameBufferEmulation.N64DepthCompare == 0) {
|
||||
glViewport(0, getHeightOffset(), getScreenWidth(), getScreenHeight());
|
||||
gSP.changed |= CHANGED_VIEWPORT;
|
||||
}
|
||||
gDP.changed |= CHANGED_COMBINE;
|
||||
(*renderCallback)((gDP.changed&CHANGED_CPU_FB_WRITE) == 0 ? 1 : 0);
|
||||
}
|
||||
CoreVideo_GL_SwapBuffers();
|
||||
}
|
||||
|
||||
void DisplayWindowMupen64plus::_saveScreenshot()
|
||||
{
|
||||
}
|
||||
|
||||
bool DisplayWindowMupen64plus::_resizeWindow()
|
||||
{
|
||||
_setAttributes();
|
||||
|
||||
m_bFullscreen = false;
|
||||
m_width = m_screenWidth = m_resizeWidth;
|
||||
m_height = m_screenHeight = m_resizeHeight;
|
||||
if (CoreVideo_ResizeWindow(m_screenWidth, m_screenHeight) != M64ERR_SUCCESS) {
|
||||
printf("(EE) Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight);
|
||||
m_width = m_screenWidth = config.video.windowedWidth;
|
||||
m_height = m_screenHeight = config.video.windowedHeight;
|
||||
CoreVideo_Quit();
|
||||
return false;
|
||||
}
|
||||
_setBufferSize();
|
||||
opengl::Utils::isGLError(); // reset GL error.
|
||||
return true;
|
||||
}
|
||||
|
||||
void DisplayWindowMupen64plus::_changeWindow()
|
||||
{
|
||||
CoreVideo_ToggleFullScreen();
|
||||
}
|
||||
|
||||
void DisplayWindowMupen64plus::_getDisplaySize()
|
||||
{
|
||||
#ifdef VC
|
||||
if( m_bFullscreen ) {
|
||||
// Use VC get_display_size function to get the current screen resolution
|
||||
u32 fb_width;
|
||||
u32 fb_height;
|
||||
if (graphics_get_display_size(0 /* LCD */, &fb_width, &fb_height) < 0)
|
||||
printf("ERROR: Failed to get display size\n");
|
||||
else {
|
||||
m_screenWidth = fb_width;
|
||||
m_screenHeight = fb_height;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DisplayWindowMupen64plus::_readScreen2(void * _dest, int * _width, int * _height, int _front)
|
||||
{
|
||||
if (_width == nullptr || _height == nullptr)
|
||||
return;
|
||||
|
||||
*_width = m_screenWidth;
|
||||
*_height = m_screenHeight;
|
||||
|
||||
if (_dest == nullptr)
|
||||
return;
|
||||
|
||||
u8 *pBufferData = (u8*)malloc((*_width)*(*_height) * 4);
|
||||
u8 *pDest = (u8*)_dest;
|
||||
|
||||
#ifndef GLES2
|
||||
GLint oldMode;
|
||||
glGetIntegerv(GL_READ_BUFFER, &oldMode);
|
||||
if (_front != 0)
|
||||
glReadBuffer(GL_FRONT);
|
||||
else
|
||||
glReadBuffer(GL_BACK);
|
||||
glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBufferData);
|
||||
glReadBuffer(oldMode);
|
||||
#else
|
||||
glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBufferData);
|
||||
#endif
|
||||
|
||||
//Convert RGBA to RGB
|
||||
for (u32 y = 0; y < *_height; ++y) {
|
||||
u8 *ptr = pBufferData + ((*_width) * 4 * y);
|
||||
for (u32 x = 0; x < *_width; ++x) {
|
||||
pDest[x * 3] = ptr[0]; // red
|
||||
pDest[x * 3 + 1] = ptr[1]; // green
|
||||
pDest[x * 3 + 2] = ptr[2]; // blue
|
||||
ptr += 4;
|
||||
}
|
||||
pDest += (*_width) * 3;
|
||||
}
|
||||
|
||||
free(pBufferData);
|
||||
}
|
260
src/Graphics/OpenGLContext/windows/windows_DisplayWindow.cpp
Normal file
260
src/Graphics/OpenGLContext/windows/windows_DisplayWindow.cpp
Normal file
|
@ -0,0 +1,260 @@
|
|||
#include <stdio.h>
|
||||
#include <Graphics/OpenGLContext/GLFunctions.h>
|
||||
#include <windows/GLideN64_Windows.h>
|
||||
#include <GLideN64.h>
|
||||
#include <Config.h>
|
||||
#include <N64.h>
|
||||
#include <RSP.h>
|
||||
#include <FrameBuffer.h>
|
||||
#include <GLideNUI/GLideNUI.h>
|
||||
#include <DisplayWindow.h>
|
||||
|
||||
class DisplayWindowWindows : public DisplayWindow
|
||||
{
|
||||
public:
|
||||
DisplayWindowWindows() : hRC(NULL), hDC(NULL) {}
|
||||
|
||||
private:
|
||||
bool _start() override;
|
||||
void _stop() override;
|
||||
void _swapBuffers() override;
|
||||
void _saveScreenshot() override;
|
||||
bool _resizeWindow() override;
|
||||
void _changeWindow() override;
|
||||
void _readScreen(void **_pDest, long *_pWidth, long *_pHeight) override;
|
||||
void _readScreen2(void * _dest, int * _width, int * _height, int _front) override {}
|
||||
|
||||
HGLRC hRC;
|
||||
HDC hDC;
|
||||
};
|
||||
|
||||
DisplayWindow & DisplayWindow::get()
|
||||
{
|
||||
static DisplayWindowWindows video;
|
||||
return video;
|
||||
}
|
||||
|
||||
bool DisplayWindowWindows::_start()
|
||||
{
|
||||
int pixelFormat;
|
||||
|
||||
PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
|
||||
1, // version number
|
||||
PFD_DRAW_TO_WINDOW | // support window
|
||||
PFD_SUPPORT_OPENGL | // support OpenGL
|
||||
PFD_DOUBLEBUFFER, // double buffered
|
||||
PFD_TYPE_RGBA, // RGBA type
|
||||
32, // color depth
|
||||
0, 0, 0, 0, 0, 0, // color bits ignored
|
||||
0, // no alpha buffer
|
||||
0, // shift bit ignored
|
||||
0, // no accumulation buffer
|
||||
0, 0, 0, 0, // accum bits ignored
|
||||
32, // z-buffer
|
||||
0, // no stencil buffer
|
||||
0, // no auxiliary buffer
|
||||
PFD_MAIN_PLANE, // main layer
|
||||
0, // reserved
|
||||
0, 0, 0 // layer masks ignored
|
||||
};
|
||||
|
||||
if (hWnd == NULL)
|
||||
hWnd = GetActiveWindow();
|
||||
|
||||
if ((hDC = GetDC( hWnd )) == NULL) {
|
||||
MessageBox( hWnd, L"Error while getting a device context!", pluginNameW, MB_ICONERROR | MB_OK );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pixelFormat = ChoosePixelFormat(hDC, &pfd )) == 0) {
|
||||
MessageBox( hWnd, L"Unable to find a suitable pixel format!", pluginNameW, MB_ICONERROR | MB_OK );
|
||||
_stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((SetPixelFormat(hDC, pixelFormat, &pfd )) == FALSE) {
|
||||
MessageBox( hWnd, L"Error while setting pixel format!", pluginNameW, MB_ICONERROR | MB_OK );
|
||||
_stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((hRC = wglCreateContext(hDC)) == NULL) {
|
||||
MessageBox( hWnd, L"Error while creating OpenGL context!", pluginNameW, MB_ICONERROR | MB_OK );
|
||||
_stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((wglMakeCurrent(hDC, hRC)) == FALSE) {
|
||||
MessageBox( hWnd, L"Error while making OpenGL context current!", pluginNameW, MB_ICONERROR | MB_OK );
|
||||
_stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
return _resizeWindow();
|
||||
}
|
||||
|
||||
void DisplayWindowWindows::_stop()
|
||||
{
|
||||
wglMakeCurrent( NULL, NULL );
|
||||
|
||||
if (hRC != NULL) {
|
||||
wglDeleteContext(hRC);
|
||||
hRC = NULL;
|
||||
}
|
||||
|
||||
if (hDC != NULL) {
|
||||
ReleaseDC(hWnd, hDC);
|
||||
hDC = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayWindowWindows::_swapBuffers()
|
||||
{
|
||||
if (hDC == NULL)
|
||||
SwapBuffers( wglGetCurrentDC() );
|
||||
else
|
||||
SwapBuffers( hDC );
|
||||
}
|
||||
|
||||
void DisplayWindowWindows::_saveScreenshot()
|
||||
{
|
||||
unsigned char * pixelData = NULL;
|
||||
FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN);
|
||||
if (pBuffer == nullptr) {
|
||||
GLint oldMode;
|
||||
glGetIntegerv(GL_READ_BUFFER, &oldMode);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glReadBuffer(GL_FRONT);
|
||||
pixelData = (unsigned char*)malloc(m_screenWidth * m_screenHeight * 3);
|
||||
glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
|
||||
glReadBuffer(oldMode);
|
||||
SaveScreenshot(m_strScreenDirectory, RSP.romname, m_screenWidth, m_screenHeight, pixelData);
|
||||
}
|
||||
else {
|
||||
if (config.video.multisampling != 0) {
|
||||
pBuffer->resolveMultisampledTexture();
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_resolveFBO);
|
||||
} else
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO);
|
||||
pixelData = (unsigned char*)malloc(pBuffer->m_pTexture->realWidth * pBuffer->m_pTexture->realHeight * 3);
|
||||
glReadPixels(0, 0, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
|
||||
SaveScreenshot(m_strScreenDirectory, RSP.romname, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight, pixelData);
|
||||
}
|
||||
free( pixelData );
|
||||
}
|
||||
|
||||
void DisplayWindowWindows::_changeWindow()
|
||||
{
|
||||
static LONG windowedStyle;
|
||||
static LONG windowedExStyle;
|
||||
static RECT windowedRect;
|
||||
static HMENU windowedMenu;
|
||||
|
||||
if (!m_bFullscreen) {
|
||||
DEVMODE fullscreenMode;
|
||||
memset( &fullscreenMode, 0, sizeof(DEVMODE) );
|
||||
fullscreenMode.dmSize = sizeof(DEVMODE);
|
||||
fullscreenMode.dmPelsWidth = config.video.fullscreenWidth;
|
||||
fullscreenMode.dmPelsHeight = config.video.fullscreenHeight;
|
||||
fullscreenMode.dmBitsPerPel = 32;
|
||||
fullscreenMode.dmDisplayFrequency = config.video.fullscreenRefresh;
|
||||
fullscreenMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
|
||||
|
||||
if (ChangeDisplaySettings( &fullscreenMode, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL) {
|
||||
MessageBox( NULL, L"Failed to change display mode", pluginNameW, MB_ICONERROR | MB_OK );
|
||||
return;
|
||||
}
|
||||
|
||||
ShowCursor( FALSE );
|
||||
|
||||
windowedMenu = GetMenu( hWnd );
|
||||
|
||||
if (windowedMenu)
|
||||
SetMenu( hWnd, NULL );
|
||||
|
||||
if (hStatusBar)
|
||||
ShowWindow( hStatusBar, SW_HIDE );
|
||||
|
||||
windowedExStyle = GetWindowLong( hWnd, GWL_EXSTYLE );
|
||||
windowedStyle = GetWindowLong( hWnd, GWL_STYLE );
|
||||
|
||||
SetWindowLong( hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST );
|
||||
SetWindowLong( hWnd, GWL_STYLE, WS_POPUP );
|
||||
|
||||
GetWindowRect( hWnd, &windowedRect );
|
||||
|
||||
m_bFullscreen = true;
|
||||
_resizeWindow();
|
||||
} else {
|
||||
ChangeDisplaySettings( NULL, 0 );
|
||||
|
||||
ShowCursor( TRUE );
|
||||
|
||||
if (windowedMenu)
|
||||
SetMenu( hWnd, windowedMenu );
|
||||
|
||||
if (hStatusBar)
|
||||
ShowWindow( hStatusBar, SW_SHOW );
|
||||
|
||||
SetWindowLong( hWnd, GWL_STYLE, windowedStyle );
|
||||
SetWindowLong( hWnd, GWL_EXSTYLE, windowedExStyle );
|
||||
SetWindowPos( hWnd, NULL, windowedRect.left, windowedRect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE );
|
||||
|
||||
m_bFullscreen = false;
|
||||
_resizeWindow();
|
||||
}
|
||||
}
|
||||
|
||||
bool DisplayWindowWindows::_resizeWindow()
|
||||
{
|
||||
RECT windowRect, statusRect, toolRect;
|
||||
|
||||
if (m_bFullscreen) {
|
||||
m_screenWidth = config.video.fullscreenWidth;
|
||||
m_screenHeight = config.video.fullscreenHeight;
|
||||
m_heightOffset = 0;
|
||||
_setBufferSize();
|
||||
|
||||
return (SetWindowPos(hWnd, NULL, 0, 0, m_screenWidth, m_screenHeight, SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW) == TRUE);
|
||||
} else {
|
||||
m_screenWidth = m_width = config.video.windowedWidth;
|
||||
m_screenHeight = config.video.windowedHeight;
|
||||
_setBufferSize();
|
||||
|
||||
GetClientRect( hWnd, &windowRect );
|
||||
GetWindowRect( hStatusBar, &statusRect );
|
||||
|
||||
if (hToolBar)
|
||||
GetWindowRect( hToolBar, &toolRect );
|
||||
else
|
||||
toolRect.bottom = toolRect.top = 0;
|
||||
|
||||
m_heightOffset = (statusRect.bottom - statusRect.top);
|
||||
windowRect.right = windowRect.left + config.video.windowedWidth - 1;
|
||||
windowRect.bottom = windowRect.top + config.video.windowedHeight - 1 + m_heightOffset;
|
||||
|
||||
AdjustWindowRect( &windowRect, GetWindowLong( hWnd, GWL_STYLE ), GetMenu( hWnd ) != NULL );
|
||||
|
||||
return (SetWindowPos( hWnd, NULL, 0, 0, windowRect.right - windowRect.left + 1,
|
||||
windowRect.bottom - windowRect.top + 1 + toolRect.bottom - toolRect.top + 1, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE ) == TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayWindowWindows::_readScreen(void **_pDest, long *_pWidth, long *_pHeight)
|
||||
{
|
||||
*_pWidth = m_width;
|
||||
*_pHeight = m_height;
|
||||
|
||||
*_pDest = malloc(m_height * m_width * 3);
|
||||
if (*_pDest == nullptr)
|
||||
return;
|
||||
|
||||
#ifndef GLESX
|
||||
const GLenum format = GL_BGR_EXT;
|
||||
glReadBuffer(GL_FRONT);
|
||||
#else
|
||||
const GLenum format = GL_RGB;
|
||||
#endif
|
||||
glReadPixels(0, m_heightOffset, m_width, m_height, format, GL_UNSIGNED_BYTE, *_pDest);
|
||||
}
|
Loading…
Reference in New Issue
Block a user