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;
}