/*========================================================================= Program: Visualization Toolkit Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. Initial version and concept gratefully provided by Klaus Steinhorst Returns 0 if the system supports OpenGL 3.2 or later. If provided a -v argument then it will display a message box with additional system information. =========================================================================*/ #include #include #include #include #include #include class CheckOpenGLVersion { public: CheckOpenGLVersion( HINSTANCE hInstance ); bool hasVersion_3_2(); std::string version; std::string renderer; std::string vendor; private: HINSTANCE hInstance; PIXELFORMATDESCRIPTOR pixelFormatDescriptor; int glMajorVersion = 1; int glMinorVersion = 0; }; typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int* attribList); #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 #define WGL_CONTEXT_FLAGS_ARB 0x2094 #define GL_MAJOR_VERSION 0x821B #define GL_MINOR_VERSION 0x821C CheckOpenGLVersion::CheckOpenGLVersion( HINSTANCE hInst ) : hInstance( hInst ) { pixelFormatDescriptor = {sizeof( PIXELFORMATDESCRIPTOR ), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. 32, // Colordepth of the framebuffer. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, // Number of bits for the depthbuffer 8, // Number of bits for the stencilbuffer 0, // Number of Aux buffers in the framebuffer. PFD_MAIN_PLANE, 0, 0, 0, 0}; WNDCLASS wc = {0}; wc.lpfnWndProc = DefWindowProc; wc.hInstance = hInstance; wc.hbrBackground = reinterpret_cast< HBRUSH >( COLOR_BACKGROUND ); wc.lpszClassName = "oglversioncheck"; wc.style = CS_OWNDC; if( !RegisterClass( &wc ) ) { return; } HWND windowHandle = CreateWindow( wc.lpszClassName, "openglversioncheck", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, this->hInstance, 0 ); if( windowHandle != nullptr ) { HDC ourWindowHandleToDeviceContext = GetDC( windowHandle ); int letWindowsChooseThisPixelFormat; letWindowsChooseThisPixelFormat = ChoosePixelFormat( ourWindowHandleToDeviceContext, &this->pixelFormatDescriptor ); SetPixelFormat( ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &this->pixelFormatDescriptor ); HGLRC ourOpenGLRenderingContext = wglCreateContext( ourWindowHandleToDeviceContext ); wglMakeCurrent( ourWindowHandleToDeviceContext, ourOpenGLRenderingContext); this->version = std::string( reinterpret_cast< const char* >( glGetString( GL_VERSION ) ) ); this->renderer = std::string( reinterpret_cast< const char* >( glGetString( GL_RENDERER ) ) ); this->vendor = std::string( reinterpret_cast< const char* >( glGetString( GL_VENDOR ) ) ); // create a context PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = reinterpret_cast(wglGetProcAddress("wglCreateContextAttribsARB")); if (wglCreateContextAttribsARB) { // we believe that these later versions are all compatible with // OpenGL 3.2 so get a more recent context if we can. int attemptedVersions[] = {4,5, 4,4, 4,3, 4,2, 4,1, 4,0, 3,3, 3,2}; int iContextAttribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 2, WGL_CONTEXT_FLAGS_ARB, 0, 0 // End of attributes list }; HGLRC contextId = nullptr; for (int i = 0; i < 8 && !contextId; i++) { iContextAttribs[1] = attemptedVersions[i*2]; iContextAttribs[3] = attemptedVersions[i*2+1]; contextId = wglCreateContextAttribsARB(ourWindowHandleToDeviceContext, 0, iContextAttribs); } if (contextId) { wglMakeCurrent( ourWindowHandleToDeviceContext, contextId); glGetIntegerv(GL_MAJOR_VERSION, &this->glMajorVersion); glGetIntegerv(GL_MINOR_VERSION, &this->glMinorVersion); wglDeleteContext(contextId); contextId = nullptr; } } wglDeleteContext( ourOpenGLRenderingContext ); } } bool CheckOpenGLVersion::hasVersion_3_2( ) { // version string should have format "4.5.0 " // so it is enough to parse the 0th and 2nd char int majorCheck = 3; int minorCheck = 2; if( this->glMajorVersion > majorCheck ) { return true; } if( this->glMajorVersion == majorCheck && this->glMinorVersion >= minorCheck ) { return true; } return false; } int CALLBACK WinMain( _In_ HINSTANCE hInstance, _In_ HINSTANCE /*hPrevInstance*/, _In_ LPSTR lpCmdLine, _In_ int /*nCmdShow*/ ) { CheckOpenGLVersion checker( hInstance ); bool result = checker.hasVersion_3_2(); std::string cline = lpCmdLine; if (cline.find("-v") != std::string::npos) { std::ostringstream toString; toString << "A working 3.2 version of OpenGL was " << (!result ? " not" : "") << " found from version " << checker.version << " with renderer " << checker.renderer << " from vendor " << checker.vendor; MessageBox(nullptr, toString.str().c_str(), "VTK OpenGL Version Test", MB_OK); } PostQuitMessage( 0 ); return (result ? 0 : 1); }