Pārlūkot izejas kodu

Added forward rendering multisample support for OpenGL.
Added OpenGL context delete/recreate mechanism.

Lasse Öörni 14 gadi atpakaļ
vecāks
revīzija
3db2c154e5

+ 5 - 0
Engine/Graphics/OpenGL/OGLGPUObject.cpp

@@ -40,3 +40,8 @@ GPUObject::~GPUObject()
     if (graphics_)
         graphics_->RemoveGPUObject(this);
 }
+
+void GPUObject::OnDeviceLost()
+{
+    Release();
+}

+ 3 - 1
Engine/Graphics/OpenGL/OGLGPUObject.h

@@ -36,7 +36,9 @@ public:
     /// Destruct. Remove from the Graphics
     virtual ~GPUObject();
     
-    /// Screen mode has been changed. React to it if necessary
+    /// OpenGL context will be destroyed. Save data if necessary and release the GPU resource
+    virtual void OnDeviceLost();
+    /// Screen mode change or OpenGL context recreation is complete. Recreate the GPU resource and restore data
     virtual void OnDeviceReset() {}
     /// Unconditionally release the GPU resource
     virtual void Release() {}

+ 171 - 51
Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -174,6 +174,15 @@ bool Graphics::SetMode(RenderMode mode, int width, int height, bool fullscreen,
 {
     PROFILE(SetScreenMode);
     
+    // If OpenGL extensions not yet initialized, initialize now
+    InitializeExtensions();
+    
+    if (!_GLEE_VERSION_2_0)
+    {
+        LOGERROR("OpenGL 2.0 is required");
+        return false;
+    }
+    
     // If zero dimensions, use the desktop default
     if ((width <= 0) || (height <= 0))
     {
@@ -212,29 +221,44 @@ bool Graphics::SetMode(RenderMode mode, int width, int height, bool fullscreen,
         }
     }
     
-    // Create OpenGL context
-    if (!impl_->renderContext_)
+    // Choose pixel format
+    int pixelFormat = GetPixelFormat(mode, multiSample);
+    if (!pixelFormat)
+    {
+        LOGERROR("Failed to choose pixel format");
+        return false;
+    }
+    
+    // Create context if not created yet, or if the pixel format changed
+    if ((!impl_->renderContext_) || (pixelFormat != impl_->pixelFormat_))
     {
         // Mimic Direct3D way of setting FPU into round-to-nearest, single precision mode
-        #ifdef _MSC_VER
-        _controlfp(_RC_NEAR | _PC_24, _MCW_RC | _MCW_PC);
-        #endif
-        
-        impl_->renderContext_ = wglCreateContext(impl_->deviceContext_);
-        wglMakeCurrent(impl_->deviceContext_, impl_->renderContext_);
-        
-        // Query for extensions now. Needs to happen under lock as the function pointers are static
+        if (!impl_->renderContext_)
         {
-            MutexLock lock(GetStaticMutex());
-            GLeeInit();
+            #ifdef _MSC_VER
+            _controlfp(_RC_NEAR | _PC_24, _MCW_RC | _MCW_PC);
+            #endif
+        }
+        else
+        {
+            // Existing context needs to be destroyed, and the window closed and reopened
+            Release();
+            if (!OpenWindow(width, height))
+                return false;
         }
         
-        if (!_GLEE_VERSION_2_0)
+        if (SetPixelFormat(impl_->deviceContext_, pixelFormat, 0) == FALSE)
         {
-            LOGERROR("OpenGL 2.0 is required");
+            LOGERROR("Failed to set pixel format");
             return false;
         }
         
+        impl_->pixelFormat_ = pixelFormat;
+        impl_->renderContext_ = wglCreateContext(impl_->deviceContext_);
+        wglMakeCurrent(impl_->deviceContext_, impl_->renderContext_);
+        
+        LOGINFO("Created OpenGL context");
+        
         // Create the FBO if fully supported
         if ((_GLEE_EXT_framebuffer_object) && (_GLEE_EXT_packed_depth_stencil))
         {
@@ -292,13 +316,13 @@ bool Graphics::SetMode(RenderMode mode, int width, int height, bool fullscreen,
     // Get the system depth buffer's bit depth
     glGetIntegerv(GL_DEPTH_BITS, &impl_->depthBits_);
     
-    // Create rendering buffers
-    CreateRenderTargets();
-    
-    // Let screen mode dependent GPU objects update themselves
+    // Let GPU objects restore themselves
     for (Vector<GPUObject*>::Iterator i = gpuObjects_.Begin(); i != gpuObjects_.End(); ++i)
         (*i)->OnDeviceReset();
     
+    // Create rendering buffers
+    CreateRenderTargets();
+    
     if (!multiSample)
         LOGINFO("Set screen mode " + String(width_) + "x" + String(height_) + " " + (fullscreen_ ? "fullscreen" : "windowed"));
     else
@@ -338,26 +362,7 @@ void Graphics::Close()
         (*i)->Release();
     gpuObjects_.Clear();
     
-    if (impl_->renderContext_)
-    {
-        if (impl_->fbo_)
-            glDeleteFramebuffersEXT(1, &impl_->fbo_);
-        
-        wglMakeCurrent(NULL, NULL);
-        wglDeleteContext(impl_->renderContext_);
-        impl_->renderContext_ = 0;
-    }
-    if (impl_->deviceContext_)
-    {
-        ReleaseDC(impl_->window_, impl_->deviceContext_);
-        impl_->deviceContext_ = 0;
-    }
-    if (impl_->window_)
-    {
-        RestoreScreenMode();
-        DestroyWindow(impl_->window_);
-        impl_->window_ = 0;
-    }
+    Release();
 }
 
 bool Graphics::TakeScreenShot(Image& destImage)
@@ -2032,9 +2037,15 @@ bool Graphics::OpenWindow(int width, int height)
         windowPosY_ = wndpl.rcNormalPosition.top;
     }
     
-    // Save the device context, then set the pixel format
+    // Save the device context
     impl_->deviceContext_ = GetDC(impl_->window_);
     
+    LOGINFO("Created application window");
+    return true;
+}
+
+int Graphics::GetPixelFormat(RenderMode mode, int multiSample)
+{
     PIXELFORMATDESCRIPTOR pfd;
     ZeroMemory(&pfd, sizeof(pfd));
     
@@ -2046,20 +2057,33 @@ bool Graphics::OpenWindow(int width, int height)
     pfd.cDepthBits = 24;
     pfd.cStencilBits = 8;
     
-    int iFormat = ChoosePixelFormat(impl_->deviceContext_, &pfd);
-    if (!iFormat)
-    {
-        LOGERROR("Failed to choose pixel format");
-        return false;
-    }
-    if (SetPixelFormat(impl_->deviceContext_, iFormat, &pfd) == FALSE)
-    {
-        LOGERROR("Failed to set pixel format");
-        return false;
+    int pixelFormat = 0;
+    unsigned numFormats;
+    
+    // Use the extended pixel format if multisampling requested in forward rendering mode
+    if ((_GLEE_WGL_ARB_pixel_format) && (multiSample > 1) && (mode == RENDER_FORWARD))
+    {
+        int attributes[] = {
+            WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
+            WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
+            WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
+            WGL_COLOR_BITS_ARB, 24,
+            WGL_DEPTH_BITS_ARB, 24,
+            WGL_STENCIL_BITS_ARB, 8,
+            WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
+            WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
+            WGL_SAMPLES_ARB, multiSample,
+            0, 0
+        };
+        
+        // If multisample fails, switch to non-multisampled pixel format
+        if ((!wglChoosePixelFormatARB(impl_->deviceContext_, attributes, 0, 1, &pixelFormat, &numFormats)) || (!pixelFormat))
+            pixelFormat = ChoosePixelFormat(impl_->deviceContext_, &pfd);
     }
+    else
+        pixelFormat = ChoosePixelFormat(impl_->deviceContext_, &pfd);
     
-    LOGINFO("Created application window");
-    return true;
+    return pixelFormat;
 }
 
 bool Graphics::SetScreenMode(int newWidth, int newHeight)
@@ -2205,6 +2229,12 @@ void Graphics::ResetCachedState()
     stencilZFail_ = OP_KEEP;
     stencilRef_ = 0;
     stencilMask_ = M_MAX_UNSIGNED;
+    
+    impl_->activeTexture_ = 0;
+    impl_->drawBuffers_ = M_MAX_UNSIGNED;
+    impl_->enabledAttributes_ = 0;
+    impl_->fbo_ = 0;
+    impl_->fboBound_ = false;
 }
 
 void Graphics::SetDrawBuffers()
@@ -2239,6 +2269,96 @@ void Graphics::SetDrawBuffers()
     glReadBuffer(GL_NONE);
 }
 
+void Graphics::Release()
+{
+    diffBuffer_.Reset();
+    normalBuffer_.Reset();
+    depthBuffer_.Reset();
+    screenBuffer_.Reset();
+    
+    // If GPU objects exist ie. it's a context delete/recreate, not Close(), tell the GPU objects to save and release themselves
+    for (Vector<GPUObject*>::Iterator i = gpuObjects_.Begin(); i != gpuObjects_.End(); ++i)
+        (*i)->OnDeviceLost();
+    
+    if (impl_->renderContext_)
+    {
+        if (impl_->fbo_)
+            glDeleteFramebuffersEXT(1, &impl_->fbo_);
+        
+        wglMakeCurrent(NULL, NULL);
+        wglDeleteContext(impl_->renderContext_);
+        impl_->renderContext_ = 0;
+    }
+    if (impl_->deviceContext_)
+    {
+        ReleaseDC(impl_->window_, impl_->deviceContext_);
+        impl_->deviceContext_ = 0;
+    }
+    if (impl_->window_)
+    {
+        RestoreScreenMode();
+        DestroyWindow(impl_->window_);
+        impl_->window_ = 0;
+    }
+    
+    // When the new context is initialized, it will have default state again
+    ResetCachedState();
+    ClearParameterSources();
+}
+
+void Graphics::InitializeExtensions()
+{
+    // Query for extensions needs to happen under lock as the function pointers are static
+    MutexLock lock(GetStaticMutex());
+    
+    if (GLeeInitialized())
+        return;
+    
+    WNDCLASS wc;
+    wc.style         = CS_OWNDC;
+    wc.lpfnWndProc   = wndProc;
+    wc.cbClsExtra    = 0;
+    wc.cbWndExtra    = 0;
+    wc.hInstance     = impl_->instance_;
+    wc.hIcon         = NULL;
+    wc.hCursor       = NULL;
+    wc.hbrBackground = 0;
+    wc.lpszMenuName  = 0;
+    wc.lpszClassName = "DummyOpenGL";
+    
+    RegisterClass(&wc);
+    
+    HWND dummyWindow = CreateWindow("DummyOpenGL", "Urho3D", WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
+        32, 32, 0, 0, impl_->instance_, 0);
+    
+    SetWindowLongPtr(dummyWindow, GWLP_USERDATA, 0);
+    
+    // Save the device context, then set the pixel format
+    HDC deviceContext = GetDC(dummyWindow);
+    
+    PIXELFORMATDESCRIPTOR pfd;
+    ZeroMemory(&pfd, sizeof(pfd));
+    
+    pfd.nSize = sizeof(pfd);
+    pfd.nVersion = 1;
+    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+    pfd.iPixelType = PFD_TYPE_RGBA;
+    pfd.cColorBits = 16;
+    pfd.cDepthBits = 15;
+    
+    int iFormat = ChoosePixelFormat(deviceContext, &pfd);
+    SetPixelFormat(deviceContext, iFormat, &pfd);
+    HGLRC renderContext = wglCreateContext(deviceContext);
+    wglMakeCurrent(deviceContext, renderContext);
+    
+    GLeeInit();
+    
+    wglMakeCurrent(NULL, NULL);
+    wglDeleteContext(renderContext);
+    ReleaseDC(dummyWindow, deviceContext);
+    DestroyWindow(dummyWindow);
+}
+
 void Graphics::InitializeShaderParameters()
 {
     // Map parameter names

+ 6 - 0
Engine/Graphics/OpenGL/OGLGraphics.h

@@ -361,6 +361,8 @@ public:
 private:
     /// Create the application window. Return true if successful
     bool OpenWindow(int width, int height);
+    /// Get the pixel format for a given multisample level. Return nonzero if successful
+    int GetPixelFormat(RenderMode mode, int multiSample);
     /// Change to a fullscreen mode. Return true if successful
     bool SetScreenMode(int newWidth, int newHeight);
     /// Restore desktop mode
@@ -373,6 +375,10 @@ private:
     void ResetCachedState();
     /// Set draw buffer(s) on the FBO
     void SetDrawBuffers();
+    /// Destroy the OpenGL rendering context and the window
+    void Release();
+    /// Initialize OpenGL extensions. Creates a dummy window and OpenGL context
+    void InitializeExtensions();
     /// Initialize shader parameter and texture unit mappings
     void InitializeShaderParameters();
     /// Handle operating system window message

+ 1 - 0
Engine/Graphics/OpenGL/OGLGraphicsImpl.cpp

@@ -37,6 +37,7 @@ GraphicsImpl::GraphicsImpl() :
     drawBuffers_(M_MAX_UNSIGNED),
     fbo_(0),
     enabledAttributes_(0),
+    pixelFormat_(0),
     depthBits_(0),
     windowDepthBits_(0),
     fboBound_(false)

+ 2 - 0
Engine/Graphics/OpenGL/OGLGraphicsImpl.h

@@ -61,6 +61,8 @@ private:
     unsigned fbo_;
     /// Vertex attributes in use
     unsigned enabledAttributes_;
+    /// Current pixel format
+    int pixelFormat_;
     /// Current depth bits
     int depthBits_;
     /// Backbuffer depth bits

+ 30 - 0
Engine/Graphics/OpenGL/OGLIndexBuffer.cpp

@@ -28,6 +28,7 @@
 #include "Log.h"
 
 #include <GLee.h>
+#include <cstring>
 
 #include "DebugNew.h"
 
@@ -48,6 +49,34 @@ IndexBuffer::~IndexBuffer()
     Release();
 }
 
+void IndexBuffer::OnDeviceLost()
+{
+    if (object_)
+    {
+        void* hwData = Lock(0, indexCount_, LOCK_READONLY);
+        if (hwData)
+        {
+            saveData_ = new unsigned char[indexCount_ * indexSize_];
+            memcpy(saveData_.GetPtr(), hwData, indexCount_ * indexSize_);
+        }
+        Unlock();
+        Release();
+    }
+}
+
+void IndexBuffer::OnDeviceReset()
+{
+    if (!object_)
+    {
+        Create();
+        if (saveData_)
+        {
+            SetData(saveData_.GetPtr());
+            saveData_.Reset();
+        }
+    }
+}
+
 void IndexBuffer::Release()
 {
     if (object_)
@@ -59,6 +88,7 @@ void IndexBuffer::Release()
             graphics_->SetIndexBuffer(0);
         
         glDeleteBuffers(1, &object_);
+        object_ = 0;
     }
     
     fallbackData_.Reset();

+ 7 - 1
Engine/Graphics/OpenGL/OGLIndexBuffer.h

@@ -39,7 +39,11 @@ public:
     /// Destruct
     virtual ~IndexBuffer();
     
-    /// Release buffer
+    /// Save data and release the buffer
+    virtual void OnDeviceLost();
+    /// Recreate the buffer from saved data
+    virtual void OnDeviceReset();
+    /// Release the buffer
     virtual void Release();
     
     /// Set buffer size and dynamic mode. Previous data will be lost
@@ -74,6 +78,8 @@ private:
     
     /// Fallback data when operating with a null graphics subsystem
     SharedArrayPtr<unsigned char> fallbackData_;
+    /// Save data when OpenGL context needs to be destroyed and recreated
+    SharedArrayPtr<unsigned char> saveData_;
     /// Number of indices
     unsigned indexCount_;
     /// Index size

+ 2 - 1
Engine/Graphics/OpenGL/OGLShaderProgram.h

@@ -49,8 +49,9 @@ public:
     /// Destruct
     ~ShaderProgram();
     
-    /// Release the shader program object
+    /// Release shader program
     virtual void Release();
+    
     /// Link the shaders and examine the uniforms and samplers used. Return true if successful
     bool Link();
     /// Check whether needs a parameter update

+ 3 - 3
Engine/Graphics/OpenGL/OGLShaderVariation.h

@@ -40,11 +40,11 @@ public:
     /// Destruct
     virtual ~ShaderVariation();
     
-    /// Create the shader program. Return true if successful
-    bool Create();
-    /// Release shader
+    /// Release the shader
     virtual void Release();
     
+    /// Compile the shader. Return true if successful
+    bool Create();
     /// Set name
     void SetName(const String& name);
     /// Set source code

+ 4 - 2
Engine/Graphics/OpenGL/OGLTexture.cpp

@@ -70,6 +70,7 @@ Texture::Texture(Context* context) :
     depthBits_(0),
     width_(0),
     height_(0),
+    dataLost_(false),
     dynamic_(false),
     shadowCompare_(false),
     parametersDirty_(true),
@@ -126,14 +127,15 @@ void Texture::SetParametersDirty()
 
 void Texture::ClearDataLost()
 {
-}    
+    dataLost_ = false;
+}
 
 void Texture::UpdateParameters()
 {
     if ((!object_) || (!graphics_))
         return;
     
-   // Wrapping
+    // Wrapping
     glTexParameteri(target_, GL_TEXTURE_WRAP_S, glWrapModes[addressMode_[0]]);
     glTexParameteri(target_, GL_TEXTURE_WRAP_T, glWrapModes[addressMode_[1]]);
     

+ 5 - 3
Engine/Graphics/OpenGL/OGLTexture.h

@@ -56,7 +56,7 @@ public:
     void SetBackupTexture(Texture* texture);
     /// Dirty the parameters
     void SetParametersDirty();
-    /// Clear data lost flag. No-op on OpenGL
+    /// Clear data lost flag
     void ClearDataLost();
     /// Update changed parameters to OpenGL. Called by Graphics when binding the texture
     void UpdateParameters();
@@ -75,8 +75,8 @@ public:
     int GetWidth() const { return width_; }
     /// Return height
     int GetHeight() const { return height_; }
-    /// Return whether data is lost. Always false on OpenGL
-    bool IsDataLost() const { return false; }
+    /// Return whether data is lost
+    bool IsDataLost() const { return dataLost_; }
     /// Return whether parameters are dirty
     bool GetParametersDirty() const { return parametersDirty_; }
     /// Return filtering mode
@@ -118,6 +118,8 @@ protected:
     int width_;
     /// Texture height
     int height_;
+    /// Data lost flag
+    bool dataLost_;
     /// Dynamic flag
     bool dynamic_;
     /// Shadow compare mode, OpenGL only

+ 12 - 0
Engine/Graphics/OpenGL/OGLTexture2D.cpp

@@ -77,6 +77,16 @@ void Texture2D::OnDeviceReset()
 {
     if (followWindowSize_)
         Create();
+    else if (!object_)
+    {
+        // Reload from the original file if possible
+        ResourceCache* cache = GetSubsystem<ResourceCache>();
+        const String& name = GetName();
+        if ((cache) && (!name.Empty()) && (cache->Exists(name)))
+            cache->ReloadResource(this);
+        else
+            Create();
+    }
 }
 
 void Texture2D::Release()
@@ -97,6 +107,7 @@ void Texture2D::Release()
         
         glDeleteTextures(1, &object_);
         object_ = 0;
+        dataLost_ = true;
     }
     else
     {
@@ -250,6 +261,7 @@ bool Texture2D::Load(SharedPtr<Image> image, bool useAlpha)
     }
     
     SetMemoryUse(memoryUse);
+    ClearDataLost();
     return true;
 }
 

+ 3 - 4
Engine/Graphics/OpenGL/OGLTexture2D.h

@@ -23,12 +23,11 @@
 
 #pragma once
 
+#include "Image.h"
 #include "RenderSurface.h"
 #include "SharedPtr.h"
 #include "Texture.h"
 
-class Image;
-
 /// 2D texture resource
 class Texture2D : public Texture
 {
@@ -44,9 +43,9 @@ public:
     
     /// Load resource. Return true if successful
     virtual bool Load(Deserializer& source);
-    /// React to screen mode change
+    /// Recreate the texture from the original file if necessary and possible
     virtual void OnDeviceReset();
-    /// Release texture
+    /// Release the texture
     virtual void Release();
     
     /// Set size, format and usage. Zero size will follow application window size. Return true if successful

+ 14 - 0
Engine/Graphics/OpenGL/OGLTextureCube.cpp

@@ -61,6 +61,18 @@ void TextureCube::RegisterObject(Context* context)
     context->RegisterFactory<TextureCube>();
 }
 
+void TextureCube::OnDeviceReset()
+{
+    if (!object_)
+    {
+        // Reload from the original file if possible
+        ResourceCache* cache = GetSubsystem<ResourceCache>();
+        const String& name = GetName();
+        if ((cache) && (!name.Empty()) && (cache->Exists(name)))
+            cache->ReloadResource(this);
+    }
+}
+
 void TextureCube::Release()
 {
     if (object_)
@@ -82,6 +94,7 @@ void TextureCube::Release()
         
         glDeleteTextures(1, &object_);
         object_ = 0;
+        dataLost_ = true;
     }
 }
 
@@ -171,6 +184,7 @@ bool TextureCube::Load(Deserializer& source)
         faceElem = faceElem.GetNextElement("face");
     }
     
+    ClearDataLost();
     return true;
 }
 

+ 3 - 1
Engine/Graphics/OpenGL/OGLTextureCube.h

@@ -45,7 +45,9 @@ public:
     
     /// Load resource. Return true if successful
     virtual bool Load(Deserializer& source);
-    /// Release texture
+    /// Recreate the texture from the original file if necessary and possible
+    virtual void OnDeviceReset();
+    /// Release the texture
     virtual void Release();
     
     /// Set size, format and usage. Return true if successful

+ 29 - 0
Engine/Graphics/OpenGL/OGLVertexBuffer.cpp

@@ -27,6 +27,7 @@
 #include "VertexBuffer.h"
 
 #include <GLee.h>
+#include <cstring>
 
 #include "DebugNew.h"
 
@@ -135,6 +136,34 @@ VertexBuffer::~VertexBuffer()
     Release();
 }
 
+void VertexBuffer::OnDeviceLost()
+{
+    if (object_)
+    {
+        void* hwData = Lock(0, vertexCount_, LOCK_NORMAL);
+        if (hwData)
+        {
+            saveData_ = new unsigned char[vertexCount_ * vertexSize_];
+            memcpy(saveData_.GetPtr(), hwData, vertexCount_ * vertexSize_);
+        }
+        Unlock();
+        Release();
+    }
+}
+
+void VertexBuffer::OnDeviceReset()
+{
+    if (!object_)
+    {
+        Create();
+        if (saveData_)
+        {
+            SetData(saveData_.GetPtr());
+            saveData_.Reset();
+        }
+    }
+}
+
 void VertexBuffer::Release()
 {
     if (object_)

+ 7 - 1
Engine/Graphics/OpenGL/OGLVertexBuffer.h

@@ -38,7 +38,11 @@ public:
     /// Destruct
     virtual ~VertexBuffer();
     
-    /// Release buffer
+    /// Save data and release the buffer
+    virtual void OnDeviceLost();
+    /// Recreate the buffer from saved data
+    virtual void OnDeviceReset();
+    /// Release the buffer
     virtual void Release();
     
     /// Set size and vertex elements and dynamic mode. Previous data will be lost
@@ -109,6 +113,8 @@ private:
     SharedArrayPtr<unsigned char> fallbackData_;
     /// Morph vertex range reset data
     SharedArrayPtr<unsigned char> morphRangeResetData_;
+    /// Save data when OpenGL context needs to be destroyed and recreated
+    SharedArrayPtr<unsigned char> saveData_;
     /// Number of vertices
     unsigned vertexCount_;
     /// Vertex size

+ 5 - 1
Engine/UI/Font.cpp

@@ -112,7 +112,11 @@ const FontFace* Font::GetFace(int pointSize)
 {
     Map<int, FontFace>::ConstIterator i = faces_.Find(pointSize);
     if (i != faces_.End())
-        return &i->second_;
+    {
+        // Check if the font texture has lost its data, and recreate in that case
+        if (!i->second_.texture_->IsDataLost())
+            return &i->second_;
+    }
     
     PROFILE(GetFontFace);
     

+ 46 - 3
ThirdParty/GLee/GLee.c

@@ -1193,12 +1193,14 @@ int __GLeeGLNumExtensions=7;
 /* Extension querying variables */
 
 GLboolean _GLEE_WGL_ARB_extensions_string = GL_FALSE;
+GLboolean _GLEE_WGL_ARB_pixel_format = GL_FALSE;
 GLboolean _GLEE_WGL_EXT_swap_control = GL_FALSE;
 
 /*  WGL Extension names */
 
-char __GLeeWGLExtensionNames[2][26]={
+char __GLeeWGLExtensionNames[3][26]={
     "WGL_ARB_extensions_string",
+    "WGL_ARB_pixel_format",
     "WGL_EXT_swap_control"
 };
 int __GLeeWGLNumExtensions=2;
@@ -1212,6 +1214,23 @@ int __GLeeWGLNumExtensions=2;
 #endif
 #endif
 
+/* WGL_ARB_pixel_format */
+
+#ifdef __GLEE_WGL_ARB_pixel_format
+#ifndef GLEE_C_DEFINED_wglGetPixelFormatAttribivARB
+#define GLEE_C_DEFINED_wglGetPixelFormatAttribivARB
+  GLEEPFNWGLGETPIXELFORMATATTRIBIVARBPROC GLeeFuncPtr_wglGetPixelFormatAttribivARB = 0;
+#endif
+#ifndef GLEE_C_DEFINED_wglGetPixelFormatAttribfvARB
+#define GLEE_C_DEFINED_wglGetPixelFormatAttribfvARB
+  GLEEPFNWGLGETPIXELFORMATATTRIBFVARBPROC GLeeFuncPtr_wglGetPixelFormatAttribfvARB = 0;
+#endif
+#ifndef GLEE_C_DEFINED_wglChoosePixelFormatARB
+#define GLEE_C_DEFINED_wglChoosePixelFormatARB
+  GLEEPFNWGLCHOOSEPIXELFORMATARBPROC GLeeFuncPtr_wglChoosePixelFormatARB = 0;
+#endif
+#endif 
+
 /* WGL_EXT_swap_control */
 
 #ifdef __GLEE_WGL_EXT_swap_control
@@ -1603,6 +1622,19 @@ GLuint __GLeeLink_WGL_ARB_extensions_string(void)
     return GLEE_LINK_PARTIAL;
 }
 
+GLuint __GLeeLink_WGL_ARB_pixel_format(void)
+{
+    GLint nLinked=0;
+#ifdef __GLEE_WGL_ARB_pixel_format
+    if ((GLeeFuncPtr_wglGetPixelFormatAttribivARB = (GLEEPFNWGLGETPIXELFORMATATTRIBIVARBPROC) __GLeeGetProcAddress("wglGetPixelFormatAttribivARB"))!=0) nLinked++;
+    if ((GLeeFuncPtr_wglGetPixelFormatAttribfvARB = (GLEEPFNWGLGETPIXELFORMATATTRIBFVARBPROC) __GLeeGetProcAddress("wglGetPixelFormatAttribfvARB"))!=0) nLinked++;
+    if ((GLeeFuncPtr_wglChoosePixelFormatARB = (GLEEPFNWGLCHOOSEPIXELFORMATARBPROC) __GLeeGetProcAddress("wglChoosePixelFormatARB"))!=0) nLinked++;
+#endif
+    if (nLinked==3) return GLEE_LINK_COMPLETE;
+    if (nLinked==0) return GLEE_LINK_FAIL;
+    return GLEE_LINK_PARTIAL;
+}
+
 GLuint __GLeeLink_WGL_EXT_swap_control(void)
 {
     GLint nLinked=0;
@@ -1615,12 +1647,13 @@ GLuint __GLeeLink_WGL_EXT_swap_control(void)
     return GLEE_LINK_PARTIAL;
 }
 
-GLEE_LINK_FUNCTION __GLeeWGLLoadFunction[2];
+GLEE_LINK_FUNCTION __GLeeWGLLoadFunction[3];
 
 void initWGLLoadFunctions(void)
 {
     __GLeeWGLLoadFunction[0]=__GLeeLink_WGL_ARB_extensions_string;
-    __GLeeWGLLoadFunction[1]=__GLeeLink_WGL_EXT_swap_control;
+    __GLeeWGLLoadFunction[1]=__GLeeLink_WGL_ARB_pixel_format;
+    __GLeeWGLLoadFunction[2]=__GLeeLink_WGL_EXT_swap_control;
 }
 
 #elif defined(__APPLE__) || defined(__APPLE_CC__)
@@ -1923,6 +1956,11 @@ GLEE_EXTERN GLboolean GLeeEnabled(GLboolean * extensionQueryingVariable)
 	return *extensionQueryingVariable;	
 }
 
+GLEE_EXTERN GLboolean GLeeInitialized( void )
+{
+    return __GLeeInited;
+}
+
 GLEE_EXTERN GLboolean GLeeInit( void )
 {
 	int version;
@@ -1996,6 +2034,11 @@ GLEE_EXTERN GLboolean GLeeInit( void )
         _GLEE_WGL_ARB_extensions_string = GL_TRUE;
         __GLeeLink_WGL_ARB_extensions_string();
     }
+    if (__GLeeCheckExtension("WGL_ARB_pixel_format", &extensionNames) )
+    {
+        _GLEE_WGL_ARB_pixel_format = GL_TRUE;
+        __GLeeLink_WGL_ARB_pixel_format();
+    }
     if (__GLeeCheckExtension("WGL_EXT_swap_control", &extensionNames) )
     {
         _GLEE_WGL_EXT_swap_control = GL_TRUE;

+ 81 - 0
ThirdParty/GLee/GLee.h

@@ -2220,11 +2220,13 @@ GLEE_EXTERN GLboolean _GLEE_EXT_packed_depth_stencil;
 /* Extension querying variables */
 
 GLEE_EXTERN GLboolean _GLEE_WGL_ARB_extensions_string;
+GLEE_EXTERN GLboolean _GLEE_WGL_ARB_pixel_format;
 GLEE_EXTERN GLboolean _GLEE_WGL_EXT_swap_control;
 
 /* Aliases for extension querying variables */
 
 #define GLEE_WGL_ARB_extensions_string     GLeeEnabled(&_GLEE_WGL_ARB_extensions_string)
+#define GLEE_WGL_ARB_pixel_format     GLeeEnabled(&_GLEE_WGL_ARB_pixel_format)
 #define GLEE_WGL_EXT_swap_control     GLeeEnabled(&_GLEE_WGL_EXT_swap_control)
 
 /* WGL_ARB_extensions_string */
@@ -2241,6 +2243,81 @@ GLEE_EXTERN GLboolean _GLEE_WGL_EXT_swap_control;
 #endif
 #endif
 
+/* WGL_ARB_pixel_format */
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_ARB_pixel_format 1
+#define __GLEE_WGL_ARB_pixel_format 1
+/* Constants */
+#define WGL_NUMBER_PIXEL_FORMATS_ARB                       0x2000
+#define WGL_DRAW_TO_WINDOW_ARB                             0x2001
+#define WGL_DRAW_TO_BITMAP_ARB                             0x2002
+#define WGL_ACCELERATION_ARB                               0x2003
+#define WGL_NEED_PALETTE_ARB                               0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB                        0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB                         0x2006
+#define WGL_SWAP_METHOD_ARB                                0x2007
+#define WGL_NUMBER_OVERLAYS_ARB                            0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB                           0x2009
+#define WGL_TRANSPARENT_ARB                                0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB                      0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB                    0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB                     0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB                    0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB                    0x203B
+#define WGL_SHARE_DEPTH_ARB                                0x200C
+#define WGL_SHARE_STENCIL_ARB                              0x200D
+#define WGL_SHARE_ACCUM_ARB                                0x200E
+#define WGL_SUPPORT_GDI_ARB                                0x200F
+#define WGL_SUPPORT_OPENGL_ARB                             0x2010
+#define WGL_DOUBLE_BUFFER_ARB                              0x2011
+#define WGL_STEREO_ARB                                     0x2012
+#define WGL_PIXEL_TYPE_ARB                                 0x2013
+#define WGL_COLOR_BITS_ARB                                 0x2014
+#define WGL_RED_BITS_ARB                                   0x2015
+#define WGL_RED_SHIFT_ARB                                  0x2016
+#define WGL_GREEN_BITS_ARB                                 0x2017
+#define WGL_GREEN_SHIFT_ARB                                0x2018
+#define WGL_BLUE_BITS_ARB                                  0x2019
+#define WGL_BLUE_SHIFT_ARB                                 0x201A
+#define WGL_ALPHA_BITS_ARB                                 0x201B
+#define WGL_ALPHA_SHIFT_ARB                                0x201C
+#define WGL_ACCUM_BITS_ARB                                 0x201D
+#define WGL_ACCUM_RED_BITS_ARB                             0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB                           0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB                            0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB                           0x2021
+#define WGL_DEPTH_BITS_ARB                                 0x2022
+#define WGL_STENCIL_BITS_ARB                               0x2023
+#define WGL_AUX_BUFFERS_ARB                                0x2024
+#define WGL_NO_ACCELERATION_ARB                            0x2025
+#define WGL_GENERIC_ACCELERATION_ARB                       0x2026
+#define WGL_FULL_ACCELERATION_ARB                          0x2027
+#define WGL_SWAP_EXCHANGE_ARB                              0x2028
+#define WGL_SWAP_COPY_ARB                                  0x2029
+#define WGL_SWAP_UNDEFINED_ARB                             0x202A
+#define WGL_TYPE_RGBA_ARB                                  0x202B
+#define WGL_TYPE_COLORINDEX_ARB                            0x202C
+#ifndef GLEE_H_DEFINED_wglGetPixelFormatAttribivARB
+#define GLEE_H_DEFINED_wglGetPixelFormatAttribivARB
+  typedef BOOL (APIENTRYP GLEEPFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int * piAttributes, int * piValues);
+  GLEE_EXTERN GLEEPFNWGLGETPIXELFORMATATTRIBIVARBPROC GLeeFuncPtr_wglGetPixelFormatAttribivARB;
+  #define wglGetPixelFormatAttribivARB GLeeFuncPtr_wglGetPixelFormatAttribivARB
+#endif
+#ifndef GLEE_H_DEFINED_wglGetPixelFormatAttribfvARB
+#define GLEE_H_DEFINED_wglGetPixelFormatAttribfvARB
+  typedef BOOL (APIENTRYP GLEEPFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int * piAttributes, FLOAT * pfValues);
+  GLEE_EXTERN GLEEPFNWGLGETPIXELFORMATATTRIBFVARBPROC GLeeFuncPtr_wglGetPixelFormatAttribfvARB;
+  #define wglGetPixelFormatAttribfvARB GLeeFuncPtr_wglGetPixelFormatAttribfvARB
+#endif
+#ifndef GLEE_H_DEFINED_wglChoosePixelFormatARB
+#define GLEE_H_DEFINED_wglChoosePixelFormatARB
+  typedef BOOL (APIENTRYP GLEEPFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int * piAttribIList, const FLOAT * pfAttribFList, UINT nMaxFormats, int * piFormats, UINT * nNumFormats);
+  GLEE_EXTERN GLEEPFNWGLCHOOSEPIXELFORMATARBPROC GLeeFuncPtr_wglChoosePixelFormatARB;
+  #define wglChoosePixelFormatARB GLeeFuncPtr_wglChoosePixelFormatARB
+#endif
+#endif 
+
 /* WGL_EXT_swap_control */
 
 #ifndef WGL_EXT_swap_control
@@ -2261,6 +2338,9 @@ GLEE_EXTERN GLboolean _GLEE_WGL_EXT_swap_control;
 #endif
 #endif
 
+#define WGL_SAMPLE_BUFFERS_ARB                             0x2041
+#define WGL_SAMPLES_ARB                                    0x2042
+
 #elif defined(__APPLE__) || defined(__APPLE_CC__)
 #else /* GLX */
 
@@ -2292,6 +2372,7 @@ GLEE_EXTERN GLboolean _GLEE_GLX_SGI_swap_control;
  * GLee functions
  *****************************************************************/
  
+GLEE_EXTERN GLboolean GLeeInitialized( void ); // Added for Urho3D
 GLEE_EXTERN GLboolean GLeeInit( void );
 GLEE_EXTERN GLint GLeeForceLink(const char * extensionName);
 GLEE_EXTERN const char * GLeeGetErrorString( void );