inline void *OpenGL_LoadFunction(char *Name)
{
    void *Result = (void *)wglGetProcAddress(Name);
    if((Result == 0) || (Result == (void *)1) || (Result == (void *)2) || (Result == (void *)3))
    {
        HMODULE Module = LoadLibraryA("opengl32.dll");
        Result = (void *)GetProcAddress(Module, Name);
    }
    return(Result);
}

static void *OpenGL_AllocateMemory(umm Size)
{
    void *Result = VirtualAlloc(0, Size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
    return(Result);
}

static void OpenGL_DeallocateMemory(void *Memory)
{
    VirtualFree(Memory, 0, MEM_RELEASE);
}

#define WGL_DRAW_TO_WINDOW_ARB            0x2001
#define WGL_SUPPORT_OPENGL_ARB            0x2010
#define WGL_DOUBLE_BUFFER_ARB             0x2011
#define WGL_PIXEL_TYPE_ARB                0x2013
#define WGL_TYPE_RGBA_ARB                 0x202B
#define WGL_COLOR_BITS_ARB                0x2014
#define WGL_DEPTH_BITS_ARB                0x2022
#define WGL_STENCIL_BITS_ARB              0x2023
#define WGL_CONTEXT_MAJOR_VERSION_ARB     0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB     0x2092
#define WGL_CONTEXT_FLAGS_ARB             0x2094
#define WGL_CONTEXT_DEBUG_BIT_ARB         0x00000001
#define WGL_SAMPLE_BUFFERS_ARB            0x2041
#define WGL_SAMPLES_ARB                   0x2042
#define WGL_CONTEXT_PROFILE_MASK_ARB      0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB  0x00000001

typedef BOOL wgl_choose_pixel_format_arb(HDC hdc,
                                         const int *piAttribIList,
                                         const FLOAT *pfAttribFList,
                                         UINT nMaxFormats,
                                         int *piFormats,
                                         UINT *nNumFormats);

typedef HGLRC wgl_create_context_attribs_arb(HDC hDC, HGLRC hShareContext,
                                             const int *attribList);

typedef BOOL wgl_make_context_current_arb(HDC hDrawDC, HDC hReadDC, HGLRC hglrc);

typedef BOOL wgl_swap_interval_ext(int interval);

static wgl_choose_pixel_format_arb *wglChoosePixelFormatARB;
static wgl_create_context_attribs_arb *wglCreateContextAttribsARB;
static wgl_make_context_current_arb *wglMakeContextCurrentARB;
static wgl_swap_interval_ext *wglSwapIntervalEXT;

#include "opengl_render.h"
#include "opengl_render.cpp"

static void Win32_CreateOpenGLContext(HDC DeviceContext)
{
    PIXELFORMATDESCRIPTOR PixelFormatDesc = {};
    PixelFormatDesc.nSize = sizeof(PixelFormatDesc);
    PixelFormatDesc.nVersion = 1;
    PixelFormatDesc.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER;
    PixelFormatDesc.iPixelType = PFD_TYPE_RGBA;
    PixelFormatDesc.cColorBits = 32;
    PixelFormatDesc.cDepthBits = 24;
    PixelFormatDesc.cStencilBits = 8;
    PixelFormatDesc.iLayerType = PFD_MAIN_PLANE;
    
    int PixelFormat = ChoosePixelFormat(DeviceContext, &PixelFormatDesc);
    Assert(PixelFormat);
    
    SetPixelFormat(DeviceContext, PixelFormat, &PixelFormatDesc);
    
    HGLRC DummyContext = wglCreateContext(DeviceContext);
    wglMakeCurrent(DeviceContext, DummyContext);
    
    wglChoosePixelFormatARB = (wgl_choose_pixel_format_arb *)OpenGL_LoadFunction("wglChoosePixelFormatARB");
    wglCreateContextAttribsARB = (wgl_create_context_attribs_arb *)OpenGL_LoadFunction("wglCreateContextAttribsARB");
    wglMakeContextCurrentARB = (wgl_make_context_current_arb *)OpenGL_LoadFunction("wglMakeContextCurrentARB");
    wglSwapIntervalEXT = (wgl_swap_interval_ext *)OpenGL_LoadFunction("wglSwapIntervalEXT");
    
    int AttribList[] =
    {
        WGL_DRAW_TO_WINDOW_ARB, 1,
        WGL_SUPPORT_OPENGL_ARB, 1,
        WGL_DOUBLE_BUFFER_ARB,  1,
        WGL_PIXEL_TYPE_ARB,     WGL_TYPE_RGBA_ARB,
        WGL_COLOR_BITS_ARB,     32,
        WGL_DEPTH_BITS_ARB,     24,
        WGL_STENCIL_BITS_ARB,   8,
        WGL_SAMPLE_BUFFERS_ARB, true,
        WGL_SAMPLES_ARB,        16,
        0
    };
    
    UINT NumFormats;
    wglChoosePixelFormatARB(DeviceContext, AttribList, 0, 1, &PixelFormat, &NumFormats);
    
    int ContextAttribs[] =
    {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
        WGL_CONTEXT_MINOR_VERSION_ARB, 3,
        WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
        WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
        0
    };
    
    HGLRC RenderContext = wglCreateContextAttribsARB(DeviceContext, DummyContext, ContextAttribs);
    
    wglMakeCurrent(DeviceContext, RenderContext);
    wglDeleteContext(DummyContext);
    wglSwapIntervalEXT(1);
    
    OpenGL_LoadAllFunctions();
}