Files
FlaxEngine/Source/Engine/GraphicsDevice/OpenGL/Win32/Win32ContextOGL.cpp
2020-12-07 23:40:54 +01:00

127 lines
4.0 KiB
C++

// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "Win32ContextOGL.h"
#if GRAPHICS_API_OPENGL && PLATFORM_WINDOWS
#include "Engine/Platform/Platform.h"
#include "Engine/Core/Log.h"
#include "../AdapterOGL.h"
#include "../GPUDeviceOGL.h"
PFNWGLCREATECONTEXTATTRIBSARBPROC Win32ContextOGL::wglCreateContextAttribsARB = NULL;
HGLRC Win32ContextOGL::OpenGLContext = 0;
HDC Win32ContextOGL::OpenGLContextWin = 0;
Array<Win32GPUSwapChainOGL*, FixedAllocation<32>> Win32ContextOGL::ChildWindows;
// A dummy window procedure (for WinAPI).
static LRESULT CALLBACK PlatformDummyGLWndproc(HWND hWnd, uint32 Message, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hWnd, Message, wParam, lParam);
}
// Initializes a pixel format descriptor for the given window handle.
void Win32ContextOGL::PlatformInitPixelFormatForDevice(HDC context)
{
// Pixel format descriptor for the context
PIXELFORMATDESCRIPTOR PixelFormatDesc;
Platform::MemoryClear(&PixelFormatDesc, sizeof(PixelFormatDesc));
PixelFormatDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
PixelFormatDesc.nVersion = 1;
PixelFormatDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
PixelFormatDesc.iPixelType = PFD_TYPE_RGBA;
PixelFormatDesc.cColorBits = 32;
PixelFormatDesc.cDepthBits = 0;
PixelFormatDesc.cStencilBits = 0;
PixelFormatDesc.iLayerType = PFD_MAIN_PLANE;
// Set the pixel format
int32 PixelFormat = ChoosePixelFormat(context, &PixelFormatDesc);
if (!PixelFormat || !SetPixelFormat(context, PixelFormat, &PixelFormatDesc))
{
LOG(Error, "Failed to set pixel format for device context.");
}
}
// Creates a dummy window used to construct OpenGL contexts.
void Win32ContextOGL::CreateDummyGLWindow(Data* context)
{
const Char* DummyWindowClassName = TEXT("DummyGLWindow");
// Register a dummy window class
{
WNDCLASS wc;
Platform::MemoryClear(&wc, sizeof(wc));
wc.style = CS_OWNDC;
wc.lpfnWndProc = PlatformDummyGLWndproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = NULL;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_MENUTEXT);
wc.lpszMenuName = NULL;
wc.lpszClassName = DummyWindowClassName;
ATOM ClassAtom = ::RegisterClass(&wc);
ASSERT(ClassAtom);
}
// Create a dummy window
context->WindowHandle = CreateWindowEx(
WS_EX_WINDOWEDGE,
DummyWindowClassName,
NULL,
WS_POPUP,
0, 0, 1, 1,
NULL, NULL, NULL, NULL);
ASSERT(context->WindowHandle);
context->bReleaseWindowOnDestroy = true;
// Get the device context.
context->DeviceContext = GetDC(context->WindowHandle);
ASSERT(context->DeviceContext);
PlatformInitPixelFormatForDevice(context->DeviceContext);
}
// Create a core profile OpenGL context.
void Win32ContextOGL::PlatformCreateOpenGLContextCore(Data* result, int majorVersion, int minorVersion, HGLRC parentContext)
{
ASSERT(result);
result->SyncInterval = -1; // invalid value to enforce setup on first buffer swap
result->ViewportFramebuffer = 0;
PlatformCreateOpenGLContextCore(&result->OpenGLContext, result->DeviceContext, majorVersion, minorVersion, parentContext);
}
void Win32ContextOGL::PlatformCreateOpenGLContextCore(HGLRC* result, HDC deviceContext, int majorVersion, int minorVersion, HGLRC parentContext)
{
ASSERT(wglCreateContextAttribsARB);
ASSERT(result && deviceContext);
int debugFlag = 0;
#if GPU_OGL_USE_DEBUG_LAYER
debugFlag = WGL_CONTEXT_DEBUG_BIT_ARB;
#endif
int attributes[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, majorVersion,
WGL_CONTEXT_MINOR_VERSION_ARB, minorVersion,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | debugFlag,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0
};
*result = wglCreateContextAttribsARB(deviceContext, parentContext, attributes);
}
void Win32ContextOGL::PlatformCreateOpenGLContextCore(HGLRC* result, HDC deviceContext, HGLRC parentContext)
{
auto adapter = (AdapterOGL*)GPUDevice::Instance->GetAdapter();
PlatformCreateOpenGLContextCore(result, deviceContext, adapter->VersionMajor, adapter->VersionMinor, parentContext);
}
#endif