2013-04-18 03:43:35 +00:00
|
|
|
// Copyright 2013 Dolphin Emulator Project
|
|
|
|
// Licensed under GPLv2
|
|
|
|
// Refer to the license.txt file included.
|
2012-12-17 21:01:52 +00:00
|
|
|
|
2014-03-12 19:33:41 +00:00
|
|
|
#include <string>
|
|
|
|
|
2014-02-17 10:18:15 +00:00
|
|
|
#include "Core/Host.h"
|
2012-12-17 21:01:52 +00:00
|
|
|
|
2014-02-17 10:18:15 +00:00
|
|
|
#include "DolphinWX/GLInterface/GLInterface.h"
|
|
|
|
|
|
|
|
#include "VideoCommon/RenderBase.h"
|
|
|
|
#include "VideoCommon/VertexShaderManager.h"
|
|
|
|
#include "VideoCommon/VideoConfig.h"
|
2012-12-17 21:01:52 +00:00
|
|
|
|
2014-03-09 20:14:26 +00:00
|
|
|
static HDC hDC = nullptr; // Private GDI Device Context
|
|
|
|
static HGLRC hRC = nullptr; // Permanent Rendering Context
|
|
|
|
static HINSTANCE dllHandle = nullptr; // Handle to OpenGL32.dll
|
2012-12-17 21:01:52 +00:00
|
|
|
|
2013-12-30 23:03:49 +00:00
|
|
|
// typedef from wglext.h
|
|
|
|
typedef BOOL(WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
|
2014-03-09 20:14:26 +00:00
|
|
|
static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = nullptr;
|
2013-12-30 23:03:49 +00:00
|
|
|
|
2013-01-24 16:31:08 +00:00
|
|
|
void cInterfaceWGL::SwapInterval(int Interval)
|
|
|
|
{
|
2013-12-30 23:03:49 +00:00
|
|
|
if (wglSwapIntervalEXT)
|
2013-01-24 16:31:08 +00:00
|
|
|
wglSwapIntervalEXT(Interval);
|
|
|
|
else
|
|
|
|
ERROR_LOG(VIDEO, "No support for SwapInterval (framerate clamped to monitor refresh rate).");
|
|
|
|
}
|
2012-12-26 06:34:09 +00:00
|
|
|
void cInterfaceWGL::Swap()
|
2012-12-17 21:01:52 +00:00
|
|
|
{
|
|
|
|
SwapBuffers(hDC);
|
|
|
|
}
|
|
|
|
|
2014-03-17 23:17:12 +00:00
|
|
|
void* cInterfaceWGL::GetFuncAddress(const std::string& name)
|
2013-12-30 13:22:50 +00:00
|
|
|
{
|
2014-01-18 14:10:24 +00:00
|
|
|
void* func = (void*)wglGetProcAddress((LPCSTR)name.c_str());
|
2014-03-09 20:14:26 +00:00
|
|
|
if (func == nullptr)
|
2014-01-18 14:10:24 +00:00
|
|
|
func = (void*)GetProcAddress(dllHandle, (LPCSTR)name.c_str());
|
2014-03-09 20:14:26 +00:00
|
|
|
return func;
|
2013-12-30 13:22:50 +00:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:01:52 +00:00
|
|
|
// Draw messages on top of the screen
|
|
|
|
bool cInterfaceWGL::PeekMessages()
|
|
|
|
{
|
|
|
|
// TODO: peekmessage
|
|
|
|
MSG msg;
|
|
|
|
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
|
|
|
{
|
|
|
|
if (msg.message == WM_QUIT)
|
|
|
|
return FALSE;
|
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Show the current FPS
|
2014-03-12 19:33:41 +00:00
|
|
|
void cInterfaceWGL::UpdateFPSDisplay(const std::string& text)
|
2012-12-17 21:01:52 +00:00
|
|
|
{
|
2014-06-14 22:23:43 +00:00
|
|
|
SetWindowTextA((HWND)m_window_handle, text.c_str());
|
2012-12-17 21:01:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create rendering window.
|
2014-02-17 04:51:41 +00:00
|
|
|
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
|
2012-12-26 06:07:43 +00:00
|
|
|
bool cInterfaceWGL::Create(void *&window_handle)
|
2012-12-17 21:01:52 +00:00
|
|
|
{
|
2014-06-14 22:23:43 +00:00
|
|
|
if (window_handle == nullptr)
|
|
|
|
return false;
|
|
|
|
|
2012-12-17 21:01:52 +00:00
|
|
|
int _tx, _ty, _twidth, _theight;
|
|
|
|
Host_GetRenderWindowSize(_tx, _ty, _twidth, _theight);
|
|
|
|
|
|
|
|
// Control window size and picture scaling
|
|
|
|
s_backbuffer_width = _twidth;
|
|
|
|
s_backbuffer_height = _theight;
|
|
|
|
|
2014-06-14 22:23:43 +00:00
|
|
|
m_window_handle = window_handle;
|
|
|
|
|
2014-01-18 14:10:24 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
dllHandle = LoadLibrary(TEXT("OpenGL32.dll"));
|
|
|
|
#endif
|
|
|
|
|
2012-12-17 21:01:52 +00:00
|
|
|
PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
|
|
|
|
{
|
|
|
|
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
|
|
|
|
1, // Version Number
|
|
|
|
PFD_DRAW_TO_WINDOW | // Format Must Support Window
|
|
|
|
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
|
|
|
|
PFD_DOUBLEBUFFER, // Must Support Double Buffering
|
|
|
|
PFD_TYPE_RGBA, // Request An RGBA Format
|
|
|
|
32, // Select Our Color Depth
|
|
|
|
0, 0, 0, 0, 0, 0, // Color Bits Ignored
|
|
|
|
0, // 8bit Alpha Buffer
|
|
|
|
0, // Shift Bit Ignored
|
|
|
|
0, // No Accumulation Buffer
|
|
|
|
0, 0, 0, 0, // Accumulation Bits Ignored
|
2013-10-29 05:23:17 +00:00
|
|
|
0, // 0Bit Z-Buffer (Depth Buffer)
|
2013-10-29 18:19:56 +00:00
|
|
|
0, // 0bit Stencil Buffer
|
2012-12-17 21:01:52 +00:00
|
|
|
0, // No Auxiliary Buffer
|
|
|
|
PFD_MAIN_PLANE, // Main Drawing Layer
|
|
|
|
0, // Reserved
|
|
|
|
0, 0, 0 // Layer Masks Ignored
|
|
|
|
};
|
|
|
|
|
2013-12-30 23:03:49 +00:00
|
|
|
int PixelFormat; // Holds The Results After Searching For A Match
|
2012-12-17 21:01:52 +00:00
|
|
|
|
2014-06-14 22:23:43 +00:00
|
|
|
if (!(hDC = GetDC((HWND)window_handle))) {
|
2012-12-17 21:01:52 +00:00
|
|
|
PanicAlert("(1) Can't create an OpenGL Device context. Fail.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) {
|
|
|
|
PanicAlert("(2) Can't find a suitable PixelFormat.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!SetPixelFormat(hDC, PixelFormat, &pfd)) {
|
|
|
|
PanicAlert("(3) Can't set the PixelFormat.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!(hRC = wglCreateContext(hDC))) {
|
|
|
|
PanicAlert("(4) Can't create an OpenGL rendering context.");
|
|
|
|
return false;
|
|
|
|
}
|
2014-01-23 14:04:33 +00:00
|
|
|
|
2012-12-17 21:01:52 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cInterfaceWGL::MakeCurrent()
|
|
|
|
{
|
|
|
|
return wglMakeCurrent(hDC, hRC) ? true : false;
|
|
|
|
}
|
|
|
|
|
2013-04-11 01:32:07 +00:00
|
|
|
bool cInterfaceWGL::ClearCurrent()
|
|
|
|
{
|
2014-03-09 20:14:26 +00:00
|
|
|
bool success = wglMakeCurrent(hDC, nullptr) ? true : false;
|
2014-02-24 11:45:02 +00:00
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
// Grab the swap interval function pointer
|
|
|
|
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)GLInterface->GetFuncAddress("wglSwapIntervalEXT");
|
|
|
|
}
|
|
|
|
return success;
|
2013-04-11 01:32:07 +00:00
|
|
|
}
|
|
|
|
|
2012-12-17 21:01:52 +00:00
|
|
|
// Update window width, size and etc. Called from Render.cpp
|
|
|
|
void cInterfaceWGL::Update()
|
|
|
|
{
|
|
|
|
RECT rcWindow;
|
2014-06-15 12:59:25 +00:00
|
|
|
GetClientRect((HWND)m_window_handle, &rcWindow);
|
2012-12-17 21:01:52 +00:00
|
|
|
|
|
|
|
// Get the new window width and height
|
2014-06-15 12:59:25 +00:00
|
|
|
s_backbuffer_width = rcWindow.right - rcWindow.left;
|
|
|
|
s_backbuffer_height = rcWindow.bottom - rcWindow.top;
|
2012-12-17 21:01:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Close backend
|
|
|
|
void cInterfaceWGL::Shutdown()
|
|
|
|
{
|
|
|
|
if (hRC)
|
|
|
|
{
|
2014-03-09 20:14:26 +00:00
|
|
|
if (!wglMakeCurrent(nullptr, nullptr))
|
2012-12-17 21:01:52 +00:00
|
|
|
NOTICE_LOG(VIDEO, "Could not release drawing context.");
|
|
|
|
|
|
|
|
if (!wglDeleteContext(hRC))
|
2013-04-01 04:10:54 +00:00
|
|
|
ERROR_LOG(VIDEO, "Attempt to release rendering context failed.");
|
2012-12-17 21:01:52 +00:00
|
|
|
|
2014-03-09 20:14:26 +00:00
|
|
|
hRC = nullptr;
|
2012-12-17 21:01:52 +00:00
|
|
|
}
|
|
|
|
|
2014-06-14 22:23:43 +00:00
|
|
|
if (hDC && !ReleaseDC((HWND)m_window_handle, hDC))
|
2012-12-17 21:01:52 +00:00
|
|
|
{
|
2013-04-01 04:10:54 +00:00
|
|
|
ERROR_LOG(VIDEO, "Attempt to release device context failed.");
|
2014-03-09 20:14:26 +00:00
|
|
|
hDC = nullptr;
|
2012-12-17 21:01:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|