I thought this might be helpful to some people.
HGLRC glInitialize(hwnd)
This function creates a basic OpenGL context. You must use this before creating an advanced context.
HGLRC glCreateContext(HWND hwnd, HGLRC sharedcontext, const int& majorversion, const int& minorversion, const int& multisamplemode)
This function creates an advanced OpenGL context. You must create a basic OpenGL context before using this. You can specify an OpenGL version and multisampling mode. If OpenGL 3.3+ is used, a forward-compatible context will be created.
Win32.OpenGL.h:
#pragma once
#include <windows.h>
#include <glew.h>
#include <wglew.h>
namespace le3
{
HGLRC glInitialize(HWND hwnd);
HGLRC glCreateContext(HWND hwnd, HGLRC sharedcontext, const int& majorversion, const int& minorversion, const int& multisamplemode=0);
}
Win32.OpenGL.cpp:
#include "Win32.OpenGL.h"
namespace le3
{
//This function creates minimal OpenGL context.
//This is required to get the wgl functions to create any more advanced styles of contexts
HGLRC glInitialize(HWND hwnd)
{
int ipixelformat;
HDC hdc = GetDC(hwnd);
PIXELFORMATDESCRIPTOR pfd;
GLenum err;
//Create pixel format descriptor
memset(&pfd,0,sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
//Choose pixel format and attempt to set it
ipixelformat = ChoosePixelFormat(hdc,&pfd);
SetPixelFormat(hdc,ipixelformat,&pfd);
//Create the OpenGL context
HGLRC hrc = wglCreateContext(hdc);
if (hrc==NULL)
{
//ReleaseDC(hdc);//Not sure if this is needed?
return NULL;
}
wglMakeCurrent(hdc,hrc);
//Initialize GLEW
err = glewInit();
if (err!=GLEW_OK)
{
wglDeleteContext(hrc);
//ReleaseDC(hdc);//Not sure if this is needed?
return NULL;
}
return hrc;
}
//This function will create a more advanced OpenGL context with more options.
//It requires an active OpenGL context to already be created.
HGLRC glCreateContext(HWND hwnd, HGLRC sharedcontext, const int& majorversion, const int& minorversion, const int& multisamplemode)
{
int ipixelformat;
int contextflags = 0;
PIXELFORMATDESCRIPTOR pfd;
float fAttributes[] = {0,0};
unsigned int countformats = 0;
HDC hdc = GetDC(hwnd);
HGLRC hrc = NULL;
//Create pixel format descriptor
memset(&pfd,0,sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
//Use forward-compatible context for version 3.3+
if ((majorversion>2 && minorversion>2) || majorversion>3)
{
contextflags = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
}
//Choose pixel format and attempt to set it
if (multisamplemode>1)
{
int iAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
WGL_COLOR_BITS_ARB,24,
WGL_ALPHA_BITS_ARB,8,
WGL_DEPTH_BITS_ARB,24,
WGL_STENCIL_BITS_ARB,0,
WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
WGL_SAMPLES_ARB,multisamplemode,
0,0
};
wglChoosePixelFormatARB(hdc,iAttributes,fAttributes,1,&ipixelformat,&countformats);
}
else
{
int iAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
WGL_COLOR_BITS_ARB,24,
WGL_ALPHA_BITS_ARB,8,
WGL_DEPTH_BITS_ARB,24,
WGL_STENCIL_BITS_ARB,0,
WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
WGL_SAMPLE_BUFFERS_ARB,GL_FALSE,
0,0
};
wglChoosePixelFormatARB(hdc,iAttributes,fAttributes,1,&ipixelformat,&countformats);
}
if (countformats==0)
{
//ReleaseDC(hdc);
return NULL;
}
if (!SetPixelFormat(hdc,ipixelformat,&pfd))
{
//ReleaseDC(hdc);
return NULL;
}
//Attributes for the real OpenGL context
int attribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, majorversion,
WGL_CONTEXT_MINOR_VERSION_ARB, minorversion,
WGL_CONTEXT_FLAGS_ARB, contextflags,
0,0
};
//Create context
hrc = wglCreateContextAttribsARB(hdc,sharedcontext,attribs);
if (hrc==NULL)
{
//ReleaseDC(hdc);
return NULL;
}
return hrc;
}
}