void GraphicsManager::updateTextureFormat() { const int compressionFormat = config.getIntValue("compresstextures"); if (compressionFormat) { // using extensions if can if (supportExtension("GL_ARB_texture_compression")) { if (supportExtension("GL_EXT_texture_compression_s3tc") || supportExtension("3DFX_texture_compression_FXT1")) { GLint num = 0; glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num); logger->log("support %d compressed formats", num); GLint *const formats = new GLint[num > 10 ? num : 10]; glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats); for (int f = 0; f < num; f ++) logger->log(" 0x%x", formats[f]); for (int f = 0; f < num; f ++) { if (formats[f] == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT && compressionFormat == 1) { delete []formats; OpenGLImageHelper::setInternalTextureType( GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); logger->log1("using s3tc texture compression"); return; } else if (formats[f] == GL_COMPRESSED_RGBA_FXT1_3DFX && compressionFormat == 2) { delete []formats; OpenGLImageHelper::setInternalTextureType( GL_COMPRESSED_RGBA_FXT1_3DFX); logger->log1("using fxt1 texture compression"); return; } } delete []formats; if (compressionFormat == 3) { OpenGLImageHelper::setInternalTextureType( GL_COMPRESSED_RGBA_ARB); logger->log1("using ARB texture compression"); return; } } else { if (compressionFormat == 3) { OpenGLImageHelper::setInternalTextureType( GL_COMPRESSED_RGBA_ARB); logger->log1("using ARB texture compression"); return; } } } else { logger->log1("no correct compression format found"); } } // using default formats if (config.getBoolValue("newtextures")) { OpenGLImageHelper::setInternalTextureType(GL_RGBA); logger->log1("using RGBA texture format"); } else { OpenGLImageHelper::setInternalTextureType(4); logger->log1("using 4 texture format"); } }
void GraphicsManager::initOpenGLFunctions() { // Texture sampler if (checkGLVersion(1, 0) && supportExtension("GL_ARB_sampler_objects")) { logger->log1("found GL_ARB_sampler_objects"); assignFunction(glGenSamplers, "glGenSamplers"); assignFunction(glDeleteSamplers, "glDeleteSamplers"); assignFunction(glBindSampler, "glBindSampler"); assignFunction(glSamplerParameteri, "glSamplerParameteri"); if (mglGenSamplers && config.getBoolValue("useTextureSampler")) mUseTextureSampler &= true; else mUseTextureSampler = false; } else { logger->log1("texture sampler not found"); mUseTextureSampler = false; } if (!checkGLVersion(1, 1)) return; if (supportExtension("GL_ARB_framebuffer_object")) { // frame buffer supported logger->log1("found GL_ARB_framebuffer_object"); assignFunction(glGenRenderbuffers, "glGenRenderbuffers"); assignFunction(glBindRenderbuffer, "glBindRenderbuffer"); assignFunction(glRenderbufferStorage, "glRenderbufferStorage"); assignFunction(glGenFramebuffers, "glGenFramebuffers"); assignFunction(glBindFramebuffer, "glBindFramebuffer"); assignFunction(glFramebufferTexture2D, "glFramebufferTexture2D"); assignFunction(glFramebufferRenderbuffer, "glFramebufferRenderbuffer"); assignFunction(glDeleteFramebuffers, "glDeleteFramebuffers"); assignFunction(glDeleteRenderbuffers, "glDeleteRenderbuffers"); } else if (supportExtension("GL_EXT_framebuffer_object")) { // old frame buffer extension logger->log1("found GL_EXT_framebuffer_object"); assignFunction(glGenRenderbuffers, "glGenRenderbuffersEXT"); assignFunction(glBindRenderbuffer, "glBindRenderbufferEXT"); assignFunction(glRenderbufferStorage, "glRenderbufferStorageEXT"); assignFunction(glGenFramebuffers, "glGenFramebuffersEXT"); assignFunction(glBindFramebuffer, "glBindFramebufferEXT"); assignFunction(glFramebufferTexture2D, "glFramebufferTexture2DEXT"); assignFunction(glFramebufferRenderbuffer, "glFramebufferRenderbufferEXT"); assignFunction(glDeleteFramebuffers, "glDeleteFramebuffersEXT"); assignFunction(glDeleteRenderbuffers, "glDeleteRenderbuffersEXT"); } else { // no frame buffer support logger->log1("frame buffer not found"); config.setValue("usefbo", false); } // debug extensions if (supportExtension("GL_KHR_debug")) { logger->log1("found GL_KHR_debug"); assignFunction(glDebugMessageControl, "glDebugMessageControl"); assignFunction(glDebugMessageCallback, "glDebugMessageCallback"); mSupportDebug = 2; } else if (supportExtension("GL_ARB_debug_output")) { logger->log1("found GL_ARB_debug_output"); assignFunction(glDebugMessageControl, "glDebugMessageControlARB"); assignFunction(glDebugMessageCallback, "glDebugMessageCallbackARB"); mSupportDebug = 1; } else { logger->log1("debug extensions not found"); mSupportDebug = 0; } #ifdef WIN32 assignFunction(wglGetExtensionsString, "wglGetExtensionsStringARB"); #endif }
CPUTResult CPUT_OGL::CreateOGLContext(CPUTContextCreation ContextParams ) { HWND hWnd; hWnd = CreateDummyWindow( GetModuleHandle(NULL)); // Create dummy window to gather information about OpenGL if ( ! hWnd) { return CPUT_ERROR; } // To get list of supported extensions, this // code should be used since OpenGL 3.0 Core: // // uint32 count = 0; // glGetIntegerv(GL_NUM_EXTENSIONS, (GLint*)&count); // for(uint16 i=0; i<count; i++) // support.m_extensions.insert(support.m_extensions.end(),string((char*)glGetStringi(GL_EXTENSIONS,i)); // // But data about gpu, are gathered in dummy // OpenGL context which works in deprecaded // mode. This forces implementation in old // deprecated way: // Creates table of supported extensions strings extensions.clear(); string tmp; sint32 begin, end; tmp = string( (char*)glGetString( GL_EXTENSIONS ) ); begin = 0; end = tmp.find( ' ', 0 ); while( end != string::npos ) { extensions.insert( extensions.end(), tmp.substr( begin, end-begin ) ); begin = end + 1; end = tmp.find( ' ', begin ); } // This extension together with WGL_EXT_swap_interval // should be returned in list of supported extensions // after calling glGetString(GL_EXTENSIONS); // Because NVidia drivers don't follow this rule it's // specification says as follow: // // "Applications should call wglGetProcAddress to see // whether or not wglGetExtensionsStringARB is supported." // ( http://www.opengl.org/registry/specs/ARB/wgl_extensions_string.txt ) // bool wglexts = false; wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress( "wglGetExtensionsStringARB" ); if ( wglGetExtensionsStringARB != NULL ) { tmp = string( (char*)wglGetExtensionsStringARB( mhDC ) ); wglexts = true; } else { wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) wglGetProcAddress( "wglGetExtensionsStringEXT" ); if ( wglGetExtensionsStringEXT != NULL ) { tmp = string( (char*)wglGetExtensionsStringEXT() ); wglexts = true; } } // If it is possible to obtain WGL extensions list add // them to the rest of supported extensions. if ( wglexts ) { begin = 0; end = tmp.find( ' ', 0 ); while( end != string::npos ) { extensions.insert( extensions.end(), tmp.substr( begin, end-begin ) ); begin = end + 1; end = tmp.find( ' ', begin ); } } // Get pointers to WGL specific functions that are required during window creation wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress( "wglCreateContextAttribsARB" ); wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress( "wglChoosePixelFormatARB" ); wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC) wglGetProcAddress( "wglChoosePixelFormatEXT" ); // Set Samples count in Advanced Pixel Format iAttributes[27] = ContextParams.samples; // Choosing advanced Pixel Format in modern way uint32 PixelFormat = 0; bool choosedPixelFormat = false; if ( supportExtension( "WGL_ARB_pixel_format" ) ) { uint32 numFormats; if ( wglChoosePixelFormatARB( mhDC, (const int*)iAttributes, fAttributes, 1, (int*)&PixelFormat, (unsigned int*)&numFormats ) ) if ( numFormats >= 1 ) choosedPixelFormat = true; } // Old way for choosing advanced Pixel Format if ( !choosedPixelFormat && supportExtension( "WGL_EXT_pixel_format" ) ) { uint32 numFormats; if ( wglChoosePixelFormatEXT( mhDC, (const int*)iAttributes, fAttributes, 1, (int*)&PixelFormat, (unsigned int*)&numFormats ) ) if ( numFormats >= 1 ) choosedPixelFormat = true; } // Basic Pixel Format if ( !choosedPixelFormat ) PixelFormat = ChoosePixelFormat( mhDC, &pfdLegacy ); // If couldn't find Pixel Format report error if ( PixelFormat == NULL ) { cerr << "Error! Cannot find aproprieate pixel format." << endl; DestroyOGLContext(); return CPUT_ERROR; } // Data about OpenGL are gathered, proper Pixel Format is choosed. // Destroy Dummy Window and proceed to creation of proper window. // Disabling and deleting all rendering contexts wglMakeCurrent( NULL, NULL ); wglDeleteContext( mhRC ); mhRC = NULL; // Disabling device context ReleaseDC( hWnd, mhDC ); mhDC = 0; // Deleting window DestroyWindow( hWnd ); // Unregistering window class if(TRUE != UnregisterClass( L"DummyWindowClass", GetModuleHandle(NULL) )) { return CPUT_ERROR; } // Clear message queue MSG msg = { 0 }; while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } hWnd = mpWindow->GetHWnd(); // Acquiring Device Context mhDC = GetDC( hWnd ); if ( mhDC == NULL ) { cerr << "Error! Cannot create device context." << endl; DestroyOGLContext(); return CPUT_ERROR; } // Activating Pixel Format if ( !SetPixelFormat( mhDC, PixelFormat, &pfdLegacy ) ) { cerr << "Error! Cannot init pixel format." << endl; DestroyOGLContext(); return CPUT_ERROR; } // OpenGL 4.0 Core profile settings uint32 glAttributes[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MINOR_VERSION_ARB, 0, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, GL_CONTEXT_PROFILE_MASK, GL_CONTEXT_CORE_PROFILE_BIT, 0, 0 }; // GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, // GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, // Debug version supports better debugging #ifdef _DEBUG glAttributes[5] |= WGL_CONTEXT_DEBUG_BIT_ARB; #endif // Try to create OpenGL context in new way mhRC = wglCreateContextAttribsARB( mhDC, 0, (const int *) &glAttributes ); if ( mhRC == NULL ) { cerr << "Error! Cannot create window rendering context." << endl; DestroyOGLContext(); return CPUT_ERROR; } // Activating rendering context if( !wglMakeCurrent( mhDC, mhRC ) ) { std::cerr << "Error! Cannot activate rendering context." << endl; DestroyOGLContext(); return CPUT_ERROR; } // Setting created window as current ShowWindow( hWnd, SW_SHOW ); SetForegroundWindow( hWnd ); SetFocus( hWnd ); // Link all OpenGL function pointers glewExperimental = TRUE; if ( glewInit() != GLEW_OK ) { cerr << "Error! Cannot activate GLEW." << endl; DestroyOGLContext(); return CPUT_ERROR; } // GLEW's problem is that it calls glGetString(GL_EXTENSIONS) which causes // GL_INVALID_ENUM on GL 3.2 core context as soon as glewInit() is called. // Clear errors indicator glGetError(); wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress( "wglSwapIntervalEXT" ); wglSwapIntervalEXT(0); return CPUT_SUCCESS; }