3
\$\begingroup\$

I'm working on a personal OpenGL project. I want my project to not rely on any libraries including CRT.

I have absolutely no experience in shipping software and I want to prepare my code for release.

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.

#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;
}
\$\endgroup\$
1
  • \$\begingroup\$ I did not get this part "I want my project to not rely on any libraries including CRT.". Your code works in Windows and have dependencies to Windows API, WGL and OpenGL. \$\endgroup\$
    – Cem Polat
    Oct 12, 2023 at 11:02

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.