I'm working on a personal OpenGL project. I want my project to not rely on any libraries including CRT. I
I have absolutely no experience in shipping software and I want to prepare my code for release. The
The code below sets up an OpenGL Core Profile context. I want to know if the current code is "production quality" and if it's not, I would like to know what should I add/remove/change to make the code safe and ready for release.
I want to know if the current code is "production quality" and if it's not, I would like to know what should I add/remove/change to make the code safe and ready for release.
#pragma once
#include <Windows.h>
void ErrorMessage(const char *Message)
{
MessageBox(0, Message, 0, MB_OK | MB_ICONERROR);
}
#include <gl\GL.h>
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
typedef HGLRC WINAPI wglCreateContextAttribsARB_type(HDC hdc, HGLRC hShareContext,
const int *attribList);
wglCreateContextAttribsARB_type *wglCreateContextAttribsARB = 0;
typedef BOOL WINAPI wglChoosePixelFormatARB_type(HDC hdc, const int *piAttribIList,
const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
wglChoosePixelFormatARB_type *wglChoosePixelFormatARB = 0;
typedef BOOL WINAPI wglSwapIntervalEXT_type(int interval);
wglSwapIntervalEXT_type *SwapInterval = 0;
bool SetupProxyOpenGL(HINSTANCE Instance)
{
bool Result = false;
WNDCLASS WindowClass = {};
WindowClass.style = CS_OWNDC;
WindowClass.hInstance = Instance;
WindowClass.hCursor = LoadCursor(0, IDC_ARROW);
WindowClass.lpszClassName = "ProxyOpenGLClass";
WindowClass.lpfnWndProc = DefWindowProc;
if (!RegisterClass(&WindowClass))
{
ErrorMessage("RegisterClass() -> SetupProxyOpenGL() failed!");
return Result;
}
HWND Window = CreateWindowEx(0, "ProxyOpenGLClass", 0, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, Instance, 0);
if (!Window)
{
ErrorMessage("CreateWindowEx() - > SetupProxyOpenGL() failed!");
return Result;
}
HDC DeviceContext = GetDC(Window);
int Format = 0;
PIXELFORMATDESCRIPTOR Pfd = {};
Pfd.nSize = sizeof(Pfd);
Pfd.nVersion = 1;
Pfd.iPixelType = PFD_TYPE_RGBA;
Pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
Pfd.cColorBits = 32;
Pfd.cAlphaBits = 8;
Pfd.iLayerType = PFD_MAIN_PLANE;
Pfd.cDepthBits = 24;
Pfd.cStencilBits = 8;
Format = ChoosePixelFormat(DeviceContext, &Pfd);
if (!Format)
{
ErrorMessage("ChoosePixelFormat() -> SetupProxyOpenGL() failed!");
return Result;
}
BOOL Success = SetPixelFormat(DeviceContext, Format, &Pfd);
if (!Success)
{
ErrorMessage("SetPixelFormat() -> SetupProxyOpenGL() failed!");
return Result;
}
HGLRC GraphicContext = wglCreateContext(DeviceContext);
if (!GraphicContext)
{
ErrorMessage("wglCreateContext() -> SetupProxyOpenGL() failed!");
return Result;
}
if (!wglMakeCurrent(DeviceContext, GraphicContext))
{
ErrorMessage("wglMakeCurrent() -> SetupProxyOpenGL() failed!");
return Result;
}
wglCreateContextAttribsARB = (wglCreateContextAttribsARB_type*)wglGetProcAddress("wglCreateContextAttribsARB");
wglChoosePixelFormatARB = (wglChoosePixelFormatARB_type*)wglGetProcAddress("wglChoosePixelFormatARB");
SwapInterval = (wglSwapIntervalEXT_type*)wglGetProcAddress("wglSwapIntervalEXT");
if (!wglCreateContextAttribsARB)
{
ErrorMessage("wglCreateContextAttribsARB is NULL!");
return Result;
}
if (!wglChoosePixelFormatARB)
{
ErrorMessage("wglChoosePixelFormatARB is NULL!");
return Result;
}
if (!SwapInterval)
{
ErrorMessage("SwapInterval is NULL!");
return Result;
}
Result = true;
SwapInterval(1);
LoadFunctions(); // Not related
wglMakeCurrent(DeviceContext, 0);
wglDeleteContext(GraphicContext);
ReleaseDC(Window, DeviceContext);
DestroyWindow(Window);
UnregisterClass("ProxyOpenGLClass", Instance);
return Result;
}
struct GLContext
{
HDC DeviceContext;
HGLRC OpenGLContext;
};
GLContext SetupOpenGL(HINSTANCE Instance, HWND Window)
{
GLContext Context = {};
int Attribs[] = {
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
0
};
Context.DeviceContext = GetDC(Window);
int PixelFormat = 0;
UINT NumFormats = 0;
if (!wglChoosePixelFormatARB(Context.DeviceContext, Attribs, 0, 1, &PixelFormat, &NumFormats))
{
ErrorMessage("wglChoosePixelFormatARB() -> SetupOpenGL() failed!");
ReleaseDC(Window, Context.DeviceContext);
return {};
}
PIXELFORMATDESCRIPTOR Pfd{};
if (!DescribePixelFormat(Context.DeviceContext, PixelFormat, sizeof(Pfd), &Pfd))
{
ErrorMessage("DescribePixelFormat() -> SetupOpenGL() failed!");
ReleaseDC(Window, Context.DeviceContext);
return {};
}
if (!SetPixelFormat(Context.DeviceContext, PixelFormat, &Pfd))
{
ErrorMessage("SetPixelFormat() -> SetupOpenGL() failed!");
ReleaseDC(Window, Context.DeviceContext);
return {};
}
int GL33Attribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0,
};
Context.OpenGLContext = wglCreateContextAttribsARB(Context.DeviceContext, 0, GL33Attribs);
if (!Context.OpenGLContext)
{
ErrorMessage("wglCreateContextAttribsARB() -> SetupOpenGL() failed!");
ReleaseDC(Window, Context.DeviceContext);
return {};
}
if (!wglMakeCurrent(Context.DeviceContext, Context.OpenGLContext))
{
ErrorMessage("wglMakeCurreont() -> SetupOpenGL() failed!");
wglDeleteContext(Context.OpenGLContext);
ReleaseDC(Window, Context.DeviceContext);
return {};
}
return Context;
}
```