“Great” news : OpenGL 3.0 is out! Well, after skimming over the new specs there’s really no new stuff – besindes of some manufacturer specific extensions going EXT or ARB and the deprecated markings sig. NVIDIA announced full GL3.0 support on G80 series with driver version 181.00+ so I tried to play around with the new context type – here’s some code 🙂
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 #define WGL_CONTEXT_FLAGS_ARB 0x2094 typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int* attribList); void GLWindow::CreateGL() { if(m_hWnd == NULL) { throw std::exception("Window handle cannot be NULL"); } // If we have no window, we cannot continue // If any of the following steps fail, we shutdown any OpenGL elements that have been started and exit if (!(m_hDC=GetDC(m_hWnd))) { // Retrieve the Device Context for this window ShutdownGL(); throw std::exception("Could not get window Device Context"); } //Create the PixelFormatDescriptor, which describes to OpenGL the pixel properties such as depth, color, and alpha channels PIXELFORMATDESCRIPTOR pfd; ZeroMemory( &pfd, sizeof(PIXELFORMATDESCRIPTOR) ); pfd.nVersion = 1; // The PFD version, always 1 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; // The properties of the PFD, in this case OpenGL support and double buffering pfd.iPixelType = PFD_TYPE_RGBA; // The type of Pixels we're dealing with pfd.cColorBits = m_displaySettings.colorBits; // The color depth of the window pfd.cAlphaBits = m_displaySettings.alphaBits; // The alpha depth of the window pfd.cDepthBits = m_displaySettings.depthBits; // The number of bits to use for the depth buffer pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // The size of this structure int pixelFormat; if (!(pixelFormat = ChoosePixelFormat(m_hDC,&pfd))) { ShutdownGL(); throw std::exception("Could not find a suitable Pixel Format"); } if(!SetPixelFormat(m_hDC,pixelFormat,&pfd)) { // Set the format of the Device Context ShutdownGL(); throw std::exception("Could not set the Pixel Format"); } // NV GL 3.0 HGLRC tempContext = NULL; if(!(tempContext = wglCreateContext(m_hDC))) { // Bind the render context for drawing ShutdownGL(); throw std::exception("Could not create temp. Render Context"); } if(!wglMakeCurrent(m_hDC, tempContext)) { // Bind the render context for drawing wglDeleteContext(tempContext); ShutdownGL(); throw std::exception("Could not make temp. Render Context current"); } int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3,//we want a 3.0 context WGL_CONTEXT_MINOR_VERSION_ARB, 0,//and it shall be forward compatible so that we can only use up to date functionality WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, 0 //zero indicates the end of the array }; PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL; //pointer to the method wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB"); if(wglCreateContextAttribsARB == NULL) { //OpenGL 3.0 is not supported // Bind the render context for drawing wglDeleteContext(tempContext); ShutdownGL(); throw std::exception("Cannot get Proc Adress for GL 3.0 CreateContextAttribs"); } if (!(m_hRC=wglCreateContextAttribsARB(m_hDC,0, attribs))) { wglDeleteContext(tempContext); ShutdownGL(); throw std::exception("Can't Create A GL 3.0 Rendering Context."); } wglDeleteContext(tempContext); if(!wglMakeCurrent(m_hDC,m_hRC)) { // Try To Activate The Rendering Context ShutdownGL(); throw std::exception("Could not make Render Context current"); } }
The key is the PFNWGLCREATECONTEXTATTRIBSARBPROC function pointer that is supplied by the opengl dll (see its declation on line 5). Using this layout we can fetch the function using a casted wglGetProcAddress() to the new function “wglCreateContextAttribsARB”. So the difference with GL3.0 here is to use a different method when creating a GL-context. The former method would still create an GL2 context. Alternatively one may use a new version of a utility/ext wrapper (glut, glew, glext, etc.) which supplies the new function directly.
Here’s the complete test project: gl30context_sample_code.