/*========================================================================= 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 }; WNDCLASSA wc = { 0 }; wc.lpfnWndProc = DefWindowProc; wc.hInstance = hInstance; wc.hbrBackground = reinterpret_cast(COLOR_BACKGROUND); wc.lpszClassName = "oglversioncheck"; wc.style = CS_OWNDC; if (!RegisterClass(&wc)) { return; } HWND windowHandle = CreateWindowA(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(glGetString(GL_VERSION))); this->renderer = std::string(reinterpret_cast(glGetString(GL_RENDERER))); this->vendor = std::string(reinterpret_cast(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); }