156 lines
3.7 KiB
C++
156 lines
3.7 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "StandaloneRendererPrivate.h"
|
|
|
|
#include "OpenGL/SlateOpenGLExtensions.h"
|
|
#include "OpenGL/SlateOpenGLRenderer.h"
|
|
|
|
/**
|
|
* A dummy wndproc.
|
|
*/
|
|
static LRESULT CALLBACK DummyGLWndproc(HWND hWnd, uint32 Message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return DefWindowProc(hWnd, Message, wParam, lParam);
|
|
}
|
|
|
|
/**
|
|
* Create a dummy window used to construct OpenGL contexts.
|
|
*/
|
|
static HWND CreateDummyGLWindow()
|
|
{
|
|
const TCHAR* WindowClassName = TEXT("DummyGLWindow");
|
|
|
|
// Register a dummy window class.
|
|
static bool bInitializedWindowClass = false;
|
|
if (!bInitializedWindowClass)
|
|
{
|
|
WNDCLASS wc;
|
|
|
|
bInitializedWindowClass = true;
|
|
FMemory::Memzero(wc);
|
|
wc.style = CS_OWNDC;
|
|
wc.lpfnWndProc = DummyGLWndproc;
|
|
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 = WindowClassName;
|
|
ATOM ClassAtom = ::RegisterClass(&wc);
|
|
check(ClassAtom);
|
|
}
|
|
|
|
// Create a dummy window.
|
|
HWND WindowHandle = CreateWindowEx(
|
|
WS_EX_WINDOWEDGE,
|
|
WindowClassName,
|
|
NULL,
|
|
WS_POPUP,
|
|
0, 0, 1, 1,
|
|
NULL, NULL, NULL, NULL);
|
|
check(WindowHandle);
|
|
|
|
return WindowHandle;
|
|
}
|
|
|
|
FSlateOpenGLContext::FSlateOpenGLContext()
|
|
: WindowHandle(NULL)
|
|
, WindowDC(NULL)
|
|
, Context(NULL)
|
|
, bReleaseWindowOnDestroy(false)
|
|
{
|
|
}
|
|
|
|
FSlateOpenGLContext::~FSlateOpenGLContext()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
void FSlateOpenGLContext::Initialize( void* InWindow, const FSlateOpenGLContext* SharedContext )
|
|
{
|
|
WindowHandle = (HWND)InWindow;
|
|
|
|
if( WindowHandle == NULL )
|
|
{
|
|
WindowHandle = CreateDummyGLWindow();
|
|
bReleaseWindowOnDestroy = true;
|
|
}
|
|
|
|
// Create a pixel format descriptor for this window
|
|
PIXELFORMATDESCRIPTOR PFD;
|
|
FMemory::Memzero( &PFD, sizeof(PIXELFORMATDESCRIPTOR) );
|
|
|
|
PFD.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
|
PFD.nVersion = 1;
|
|
PFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL| PFD_DOUBLEBUFFER;
|
|
PFD.iPixelType = PFD_TYPE_RGBA;
|
|
PFD.cColorBits = 32;
|
|
PFD.cStencilBits = 0;
|
|
PFD.cDepthBits = 0;
|
|
PFD.iLayerType = PFD_MAIN_PLANE;
|
|
|
|
WindowDC = GetDC( WindowHandle );
|
|
check(WindowDC);
|
|
|
|
// Get the pixel format for this window based on our descriptor
|
|
uint32 PixelFormat = ChoosePixelFormat( WindowDC, &PFD );
|
|
// Ensure a pixel format could be found
|
|
check(PixelFormat);
|
|
|
|
BOOL Result = SetPixelFormat( WindowDC, PixelFormat, &PFD );
|
|
// Ensure the pixel format could be set on this window
|
|
check(Result);
|
|
|
|
Context = wglCreateContext( WindowDC );
|
|
|
|
// Make the new window active for drawing. We can't call any OpenGL functions without an active rendering context
|
|
Result = wglMakeCurrent( WindowDC, Context );
|
|
check( Result );
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable:4191)
|
|
wglCreateContextAttribsARB = ( PFNWGLCREATECONTEXTATTRIBSARBPROC )wglGetProcAddress( "wglCreateContextAttribsARB" );
|
|
#pragma warning(pop)
|
|
check( wglCreateContextAttribsARB );
|
|
|
|
int32 ContextAttribs[] =
|
|
{
|
|
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
|
|
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
|
|
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
|
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
|
0
|
|
};
|
|
|
|
HGLRC OldContext = Context;
|
|
Context = wglCreateContextAttribsARB( WindowDC, SharedContext ? SharedContext->Context : NULL, ContextAttribs );
|
|
wglMakeCurrent( NULL, NULL );
|
|
wglDeleteContext( OldContext );
|
|
wglMakeCurrent( WindowDC, Context );
|
|
}
|
|
|
|
void FSlateOpenGLContext::Destroy()
|
|
{
|
|
if( WindowHandle != NULL )
|
|
{
|
|
wglMakeCurrent( NULL, NULL );
|
|
wglDeleteContext( Context );
|
|
ReleaseDC( WindowHandle, WindowDC );
|
|
WindowDC = NULL;
|
|
Context = NULL;
|
|
|
|
if( bReleaseWindowOnDestroy )
|
|
{
|
|
DestroyWindow( WindowHandle );
|
|
}
|
|
WindowHandle = NULL;
|
|
}
|
|
}
|
|
|
|
void FSlateOpenGLContext::MakeCurrent()
|
|
{
|
|
wglMakeCurrent( WindowDC, Context );
|
|
}
|