1
0
Fork 0
spectre/source/Platform/Win32/Win32GLContext.cpp
2016-02-17 13:28:32 +01:00

156 lines
No EOL
3 KiB
C++

#include <GL/glew.h>
#include <GL/wglew.h>
#include <Platform/PlatformDisplay.h>
#include <Spectre/System/Log.h>
#include "Win32Internal.h"
#include "Win32GLContext.h"
// Ensure that OpenGL extensions are loaded.
static void ensureExtensionsLoaded()
{
static bool glewInitOK = false;
if (!glewInitOK) {
GLenum ret = glewInit();
if (ret != GLEW_OK) {
log("Win32: Could not initialize GLEW %s\n",
glewGetErrorString(ret));
return;
}
glewInitOK = true;
}
}
Win32GLContext::Win32GLContext() :
m_wnd (NULL),
m_deviceContext (NULL),
m_renderContext (NULL)
{
}
Win32GLContext::~Win32GLContext()
{
destroy();
}
bool Win32GLContext::create(const PlatformDisplay* display)
{
// If created. destroy old handles.
destroy();
m_wnd = (HWND) display->getHandle();
// Should have a valid handle here. trigger error.
if (!m_wnd) {
log("Win32 - Could not create GL context: Invalid display handle\n");
return false;
}
m_deviceContext = ::GetDC(m_wnd);
createGLContext();
if (!m_deviceContext || !m_renderContext) {
// Make sure we release all handles.
destroy();
log("Win32 - Could not create GL context: %s", Win32GetMessage(GetLastError()));
return false;
}
return true;
}
void Win32GLContext::destroy()
{
if (m_wnd && m_deviceContext) {
::ReleaseDC(m_wnd, m_deviceContext);
m_deviceContext = NULL;
m_wnd = NULL;
}
if (m_renderContext) {
::wglDeleteContext(m_renderContext);
m_renderContext = NULL;
}
}
void Win32GLContext::createGLContext()
{
// First set pixel format.
if (!setPixelFormat()) {
return;
}
m_renderContext = ::wglCreateContext(m_deviceContext);
}
bool Win32GLContext::activate()
{
// Make sure we have dc and rc before calling MakeCurrent.
if (m_deviceContext && m_renderContext) {
return ::wglMakeCurrent(m_deviceContext, m_renderContext);
}
return false;
}
bool Win32GLContext::deactivate()
{
return ::wglMakeCurrent(NULL, NULL);
}
bool Win32GLContext::isActive() const
{
return ::wglGetCurrentContext() == m_renderContext;
}
bool Win32GLContext::setSwapInterval(int interval)
{
ensureExtensionsLoaded();
if (WGLEW_EXT_swap_control) {
return wglSwapIntervalEXT(interval);
}
log("wglSwapInterval: function is not supported\n");
return false;
}
void Win32GLContext::setSize(unsigned int width, unsigned int height)
{
if (activate()) {
glViewport(0, 0, width, height);
}
}
void Win32GLContext::swapBuffers()
{
if (m_deviceContext) {
::SwapBuffers(m_deviceContext);
}
}
bool Win32GLContext::setPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd;
int format;
// For now, always create a RGBA pixel format with double buffer.
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ::ChoosePixelFormat(m_deviceContext, &pfd);
if (format) {
return ::SetPixelFormat(m_deviceContext, format, &pfd);
}
return false;
}