Browse Source

Move API-specific Graphics class member variables to GraphicsImpl. Rename WindowMoved & WindowResized to OnWindow.. to match convention used elsewhere (eg. OnNodeSet) Change windowIcon_ member to WeakPtr to ensure safety in later access. Minor class comment fixes.

Lasse Öörni 9 years ago
parent
commit
bdce4b3dba

+ 140 - 142
Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.cpp

@@ -57,7 +57,6 @@
 #include "../../Graphics/Texture3D.h"
 #include "../../Graphics/TextureCube.h"
 #include "../../Graphics/VertexBuffer.h"
-#include "../../Graphics/VertexDeclaration.h"
 #include "../../Graphics/Zone.h"
 #include "../../IO/File.h"
 #include "../../IO/Log.h"
@@ -242,7 +241,6 @@ Graphics::Graphics(Context* context) :
     numBatches_(0),
     maxScratchBufferRequest_(0),
     defaultTextureFilterMode_(FILTER_TRILINEAR),
-    shaderProgram_(0),
     shaderPath_("Shaders/HLSL/"),
     shaderExtension_(".hlsl"),
     orientations_("LandscapeLeft LandscapeRight"),
@@ -269,8 +267,8 @@ Graphics::~Graphics()
         gpuObjects_.Clear();
     }
 
-    vertexDeclarations_.Clear();
-    constantBuffers_.Clear();
+    impl_->vertexDeclarations_.Clear();
+    impl_->allConstantBuffers_.Clear();
 
     for (HashMap<unsigned, ID3D11BlendState*>::Iterator i = impl_->blendStates_.Begin(); i != impl_->blendStates_.End(); ++i)
     {
@@ -783,7 +781,7 @@ bool Graphics::ResolveToTexture(Texture2D* destination, const IntRect& viewport)
 
 void Graphics::Draw(PrimitiveType type, unsigned vertexStart, unsigned vertexCount)
 {
-    if (!vertexCount || !shaderProgram_)
+    if (!vertexCount || !impl_->shaderProgram_)
         return;
 
     PrepareDraw();
@@ -808,7 +806,7 @@ void Graphics::Draw(PrimitiveType type, unsigned vertexStart, unsigned vertexCou
 
 void Graphics::Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount)
 {
-    if (!vertexCount || !shaderProgram_)
+    if (!vertexCount || !impl_->shaderProgram_)
         return;
 
     PrepareDraw();
@@ -833,7 +831,7 @@ void Graphics::Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount
 
 void Graphics::Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex, unsigned vertexCount)
 {
-    if (!vertexCount || !shaderProgram_)
+    if (!vertexCount || !impl_->shaderProgram_)
         return;
 
     PrepareDraw();
@@ -859,7 +857,7 @@ void Graphics::Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount
 void Graphics::DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount,
     unsigned instanceCount)
 {
-    if (!indexCount || !instanceCount || !shaderProgram_)
+    if (!indexCount || !instanceCount || !impl_->shaderProgram_)
         return;
 
     PrepareDraw();
@@ -885,7 +883,7 @@ void Graphics::DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned i
 void Graphics::DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex, unsigned vertexCount,
     unsigned instanceCount)
 {
-    if (!indexCount || !instanceCount || !shaderProgram_)
+    if (!indexCount || !instanceCount || !impl_->shaderProgram_)
         return;
 
     PrepareDraw();
@@ -957,16 +955,16 @@ bool Graphics::SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, unsigne
 
         if (changed)
         {
-            vertexDeclarationDirty_ = true;
+            impl_->vertexDeclarationDirty_ = true;
 
-            if (firstDirtyVB_ == M_MAX_UNSIGNED)
-                firstDirtyVB_ = lastDirtyVB_ = i;
+            if (impl_->firstDirtyVB_ == M_MAX_UNSIGNED)
+                impl_->firstDirtyVB_ = impl_->lastDirtyVB_ = i;
             else
             {
-                if (i < firstDirtyVB_)
-                    firstDirtyVB_ = i;
-                if (i > lastDirtyVB_)
-                    lastDirtyVB_ = i;
+                if (i < impl_->firstDirtyVB_)
+                    impl_->firstDirtyVB_ = i;
+                if (i > impl_->lastDirtyVB_)
+                    impl_->lastDirtyVB_ = i;
             }
         }
     }
@@ -1029,7 +1027,7 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
 
         impl_->deviceContext_->VSSetShader((ID3D11VertexShader*)(vs ? vs->GetGPUObject() : 0), 0, 0);
         vertexShader_ = vs;
-        vertexDeclarationDirty_ = true;
+        impl_->vertexDeclarationDirty_ = true;
     }
 
     if (ps != pixelShader_)
@@ -1059,13 +1057,13 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
     if (vertexShader_ && pixelShader_)
     {
         Pair<ShaderVariation*, ShaderVariation*> key = MakePair(vertexShader_, pixelShader_);
-        ShaderProgramMap::Iterator i = shaderPrograms_.Find(key);
-        if (i != shaderPrograms_.End())
-            shaderProgram_ = i->second_.Get();
+        ShaderProgramMap::Iterator i = impl_->shaderPrograms_.Find(key);
+        if (i != impl_->shaderPrograms_.End())
+            impl_->shaderProgram_ = i->second_.Get();
         else
         {
-            ShaderProgram* newProgram = shaderPrograms_[key] = new ShaderProgram(this, vertexShader_, pixelShader_);
-            shaderProgram_ = newProgram;
+            ShaderProgram* newProgram = impl_->shaderPrograms_[key] = new ShaderProgram(this, vertexShader_, pixelShader_);
+            impl_->shaderProgram_ = newProgram;
         }
 
         bool vsBuffersChanged = false;
@@ -1073,7 +1071,7 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
 
         for (unsigned i = 0; i < MAX_SHADER_PARAMETER_GROUPS; ++i)
         {
-            ID3D11Buffer* vsBuffer = shaderProgram_->vsConstantBuffers_[i] ? (ID3D11Buffer*)shaderProgram_->vsConstantBuffers_[i]->
+            ID3D11Buffer* vsBuffer = impl_->shaderProgram_->vsConstantBuffers_[i] ? (ID3D11Buffer*)impl_->shaderProgram_->vsConstantBuffers_[i]->
                 GetGPUObject() : 0;
             if (vsBuffer != impl_->constantBuffers_[VS][i])
             {
@@ -1082,7 +1080,7 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
                 vsBuffersChanged = true;
             }
 
-            ID3D11Buffer* psBuffer = shaderProgram_->psConstantBuffers_[i] ? (ID3D11Buffer*)shaderProgram_->psConstantBuffers_[i]->
+            ID3D11Buffer* psBuffer = impl_->shaderProgram_->psConstantBuffers_[i] ? (ID3D11Buffer*)impl_->shaderProgram_->psConstantBuffers_[i]->
                 GetGPUObject() : 0;
             if (psBuffer != impl_->constantBuffers_[PS][i])
             {
@@ -1098,7 +1096,7 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
             impl_->deviceContext_->PSSetConstantBuffers(0, MAX_SHADER_PARAMETER_GROUPS, &impl_->constantBuffers_[PS][0]);
     }
     else
-        shaderProgram_ = 0;
+        impl_->shaderProgram_ = 0;
 
     // Store shader combination if shader dumping in progress
     if (shaderPrecache_)
@@ -1112,120 +1110,120 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
 void Graphics::SetShaderParameter(StringHash param, const float* data, unsigned count)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     ConstantBuffer* buffer = i->second_.bufferPtr_;
     if (!buffer->IsDirty())
-        dirtyConstantBuffers_.Push(buffer);
+        impl_->dirtyConstantBuffers_.Push(buffer);
     buffer->SetParameter(i->second_.offset_, (unsigned)(count * sizeof(float)), data);
 }
 
 void Graphics::SetShaderParameter(StringHash param, float value)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     ConstantBuffer* buffer = i->second_.bufferPtr_;
     if (!buffer->IsDirty())
-        dirtyConstantBuffers_.Push(buffer);
+        impl_->dirtyConstantBuffers_.Push(buffer);
     buffer->SetParameter(i->second_.offset_, sizeof(float), &value);
 }
 
 void Graphics::SetShaderParameter(StringHash param, bool value)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     ConstantBuffer* buffer = i->second_.bufferPtr_;
     if (!buffer->IsDirty())
-        dirtyConstantBuffers_.Push(buffer);
+        impl_->dirtyConstantBuffers_.Push(buffer);
     buffer->SetParameter(i->second_.offset_, sizeof(bool), &value);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Color& color)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     ConstantBuffer* buffer = i->second_.bufferPtr_;
     if (!buffer->IsDirty())
-        dirtyConstantBuffers_.Push(buffer);
+        impl_->dirtyConstantBuffers_.Push(buffer);
     buffer->SetParameter(i->second_.offset_, sizeof(Color), &color);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Vector2& vector)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     ConstantBuffer* buffer = i->second_.bufferPtr_;
     if (!buffer->IsDirty())
-        dirtyConstantBuffers_.Push(buffer);
+        impl_->dirtyConstantBuffers_.Push(buffer);
     buffer->SetParameter(i->second_.offset_, sizeof(Vector2), &vector);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Matrix3& matrix)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     ConstantBuffer* buffer = i->second_.bufferPtr_;
     if (!buffer->IsDirty())
-        dirtyConstantBuffers_.Push(buffer);
+        impl_->dirtyConstantBuffers_.Push(buffer);
     buffer->SetVector3ArrayParameter(i->second_.offset_, 3, &matrix);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Vector3& vector)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     ConstantBuffer* buffer = i->second_.bufferPtr_;
     if (!buffer->IsDirty())
-        dirtyConstantBuffers_.Push(buffer);
+        impl_->dirtyConstantBuffers_.Push(buffer);
     buffer->SetParameter(i->second_.offset_, sizeof(Vector3), &vector);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Matrix4& matrix)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     ConstantBuffer* buffer = i->second_.bufferPtr_;
     if (!buffer->IsDirty())
-        dirtyConstantBuffers_.Push(buffer);
+        impl_->dirtyConstantBuffers_.Push(buffer);
     buffer->SetParameter(i->second_.offset_, sizeof(Matrix4), &matrix);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Vector4& vector)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     ConstantBuffer* buffer = i->second_.bufferPtr_;
     if (!buffer->IsDirty())
-        dirtyConstantBuffers_.Push(buffer);
+        impl_->dirtyConstantBuffers_.Push(buffer);
     buffer->SetParameter(i->second_.offset_, sizeof(Vector4), &vector);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Matrix3x4& matrix)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     ConstantBuffer* buffer = i->second_.bufferPtr_;
     if (!buffer->IsDirty())
-        dirtyConstantBuffers_.Push(buffer);
+        impl_->dirtyConstantBuffers_.Push(buffer);
     buffer->SetParameter(i->second_.offset_, sizeof(Matrix3x4), &matrix);
 }
 
@@ -1296,7 +1294,7 @@ bool Graphics::NeedParameterUpdate(ShaderParameterGroup group, const void* sourc
 
 bool Graphics::HasShaderParameter(StringHash param)
 {
-    return shaderProgram_ && shaderProgram_->parameters_.Find(param) != shaderProgram_->parameters_.End();
+    return impl_->shaderProgram_ && impl_->shaderProgram_->parameters_.Find(param) != impl_->shaderProgram_->parameters_.End();
 }
 
 bool Graphics::HasTextureUnit(TextureUnit unit)
@@ -1341,20 +1339,20 @@ void Graphics::SetTexture(unsigned index, Texture* texture)
 
     if (texture != textures_[index])
     {
-        if (firstDirtyTexture_ == M_MAX_UNSIGNED)
-            firstDirtyTexture_ = lastDirtyTexture_ = index;
+        if (impl_->firstDirtyTexture_ == M_MAX_UNSIGNED)
+            impl_->firstDirtyTexture_ = impl_->lastDirtyTexture_ = index;
         else
         {
-            if (index < firstDirtyTexture_)
-                firstDirtyTexture_ = index;
-            if (index > lastDirtyTexture_)
-                lastDirtyTexture_ = index;
+            if (index < impl_->firstDirtyTexture_)
+                impl_->firstDirtyTexture_ = index;
+            if (index > impl_->lastDirtyTexture_)
+                impl_->lastDirtyTexture_ = index;
         }
 
         textures_[index] = texture;
         impl_->shaderResourceViews_[index] = texture ? (ID3D11ShaderResourceView*)texture->GetShaderResourceView() : 0;
         impl_->samplers_[index] = texture ? (ID3D11SamplerState*)texture->GetSampler() : 0;
-        texturesDirty_ = true;
+        impl_->texturesDirty_ = true;
     }
 }
 
@@ -1414,7 +1412,7 @@ void Graphics::SetRenderTarget(unsigned index, RenderSurface* renderTarget)
     if (renderTarget != renderTargets_[index])
     {
         renderTargets_[index] = renderTarget;
-        renderTargetsDirty_ = true;
+        impl_->renderTargetsDirty_ = true;
 
         // If the rendertarget is also bound as a texture, replace with backup texture or null
         if (renderTarget)
@@ -1444,7 +1442,7 @@ void Graphics::SetDepthStencil(RenderSurface* depthStencil)
     if (depthStencil != depthStencil_)
     {
         depthStencil_ = depthStencil;
-        renderTargetsDirty_ = true;
+        impl_->renderTargetsDirty_ = true;
     }
 }
 
@@ -1456,7 +1454,7 @@ void Graphics::SetDepthStencil(Texture2D* texture)
 
     SetDepthStencil(depthStencil);
     // Constant depth bias depends on the bitdepth
-    rasterizerStateDirty_ = true;
+    impl_->rasterizerStateDirty_ = true;
 }
 
 void Graphics::SetViewport(const IntRect& rect)
@@ -1495,7 +1493,7 @@ void Graphics::SetBlendMode(BlendMode mode)
     if (mode != blendMode_)
     {
         blendMode_ = mode;
-        blendStateDirty_ = true;
+        impl_->blendStateDirty_ = true;
     }
 }
 
@@ -1504,7 +1502,7 @@ void Graphics::SetColorWrite(bool enable)
     if (enable != colorWrite_)
     {
         colorWrite_ = enable;
-        blendStateDirty_ = true;
+        impl_->blendStateDirty_ = true;
     }
 }
 
@@ -1513,7 +1511,7 @@ void Graphics::SetCullMode(CullMode mode)
     if (mode != cullMode_)
     {
         cullMode_ = mode;
-        rasterizerStateDirty_ = true;
+        impl_->rasterizerStateDirty_ = true;
     }
 }
 
@@ -1523,7 +1521,7 @@ void Graphics::SetDepthBias(float constantBias, float slopeScaledBias)
     {
         constantDepthBias_ = constantBias;
         slopeScaledDepthBias_ = slopeScaledBias;
-        rasterizerStateDirty_ = true;
+        impl_->rasterizerStateDirty_ = true;
     }
 }
 
@@ -1532,7 +1530,7 @@ void Graphics::SetDepthTest(CompareMode mode)
     if (mode != depthTestMode_)
     {
         depthTestMode_ = mode;
-        depthStateDirty_ = true;
+        impl_->depthStateDirty_ = true;
     }
 }
 
@@ -1541,9 +1539,9 @@ void Graphics::SetDepthWrite(bool enable)
     if (enable != depthWrite_)
     {
         depthWrite_ = enable;
-        depthStateDirty_ = true;
+        impl_->depthStateDirty_ = true;
         // Also affects whether a read-only version of depth-stencil should be bound, to allow sampling
-        renderTargetsDirty_ = true;
+        impl_->renderTargetsDirty_ = true;
     }
 }
 
@@ -1552,7 +1550,7 @@ void Graphics::SetFillMode(FillMode mode)
     if (mode != fillMode_)
     {
         fillMode_ = mode;
-        rasterizerStateDirty_ = true;
+        impl_->rasterizerStateDirty_ = true;
     }
 }
 
@@ -1587,14 +1585,14 @@ void Graphics::SetScissorTest(bool enable, const Rect& rect, bool borderInclusiv
         if (enable && intRect != scissorRect_)
         {
             scissorRect_ = intRect;
-            scissorRectDirty_ = true;
+            impl_->scissorRectDirty_ = true;
         }
     }
 
     if (enable != scissorTest_)
     {
         scissorTest_ = enable;
-        rasterizerStateDirty_ = true;
+        impl_->rasterizerStateDirty_ = true;
     }
 }
 
@@ -1622,14 +1620,14 @@ void Graphics::SetScissorTest(bool enable, const IntRect& rect)
         if (enable && intRect != scissorRect_)
         {
             scissorRect_ = intRect;
-            scissorRectDirty_ = true;
+            impl_->scissorRectDirty_ = true;
         }
     }
 
     if (enable != scissorTest_)
     {
         scissorTest_ = enable;
-        rasterizerStateDirty_ = true;
+        impl_->rasterizerStateDirty_ = true;
     }
 }
 
@@ -1639,7 +1637,7 @@ void Graphics::SetStencilTest(bool enable, CompareMode mode, StencilOp pass, Ste
     if (enable != stencilTest_)
     {
         stencilTest_ = enable;
-        depthStateDirty_ = true;
+        impl_->depthStateDirty_ = true;
     }
 
     if (enable)
@@ -1647,38 +1645,38 @@ void Graphics::SetStencilTest(bool enable, CompareMode mode, StencilOp pass, Ste
         if (mode != stencilTestMode_)
         {
             stencilTestMode_ = mode;
-            depthStateDirty_ = true;
+            impl_->depthStateDirty_ = true;
         }
         if (pass != stencilPass_)
         {
             stencilPass_ = pass;
-            depthStateDirty_ = true;
+            impl_->depthStateDirty_ = true;
         }
         if (fail != stencilFail_)
         {
             stencilFail_ = fail;
-            depthStateDirty_ = true;
+            impl_->depthStateDirty_ = true;
         }
         if (zFail != stencilZFail_)
         {
             stencilZFail_ = zFail;
-            depthStateDirty_ = true;
+            impl_->depthStateDirty_ = true;
         }
         if (compareMask != stencilCompareMask_)
         {
             stencilCompareMask_ = compareMask;
-            depthStateDirty_ = true;
+            impl_->depthStateDirty_ = true;
         }
         if (writeMask != stencilWriteMask_)
         {
             stencilWriteMask_ = writeMask;
-            depthStateDirty_ = true;
+            impl_->depthStateDirty_ = true;
         }
         if (stencilRef != stencilRef_)
         {
             stencilRef_ = stencilRef;
-            stencilRefDirty_ = true;
-            depthStateDirty_ = true;
+            impl_->stencilRefDirty_ = true;
+            impl_->depthStateDirty_ = true;
         }
     }
 }
@@ -1882,7 +1880,7 @@ IntVector2 Graphics::GetRenderTargetDimensions() const
     return IntVector2(width, height);
 }
 
-void Graphics::WindowResized()
+void Graphics::OnWindowResized()
 {
     if (!impl_->device_ || !impl_->window_)
         return;
@@ -1911,7 +1909,7 @@ void Graphics::WindowResized()
     SendEvent(E_SCREENMODE, eventData);
 }
 
-void Graphics::WindowMoved()
+void Graphics::OnWindowMoved()
 {
     if (!impl_->device_ || !impl_->window_ || fullscreen_)
         return;
@@ -2044,30 +2042,30 @@ void Graphics::CleanupScratchBuffers()
 
 void Graphics::CleanUpShaderPrograms(ShaderVariation* variation)
 {
-    for (ShaderProgramMap::Iterator i = shaderPrograms_.Begin(); i != shaderPrograms_.End();)
+    for (ShaderProgramMap::Iterator i = impl_->shaderPrograms_.Begin(); i != impl_->shaderPrograms_.End();)
     {
         if (i->first_.first_ == variation || i->first_.second_ == variation)
-            i = shaderPrograms_.Erase(i);
+            i = impl_->shaderPrograms_.Erase(i);
         else
             ++i;
     }
 
     if (vertexShader_ == variation || pixelShader_ == variation)
-        shaderProgram_ = 0;
+        impl_->shaderProgram_ = 0;
 }
 
 ConstantBuffer* Graphics::GetOrCreateConstantBuffer(ShaderType type, unsigned index, unsigned size)
 {
     // Ensure that different shader types and index slots get unique buffers, even if the size is same
     unsigned key = type | (index << 1) | (size << 4);
-    HashMap<unsigned, SharedPtr<ConstantBuffer> >::Iterator i = constantBuffers_.Find(key);
-    if (i != constantBuffers_.End())
+    ConstantBufferMap::Iterator i = impl_->allConstantBuffers_.Find(key);
+    if (i != impl_->allConstantBuffers_.End())
         return i->second_.Get();
     else
     {
         SharedPtr<ConstantBuffer> newConstantBuffer(new ConstantBuffer(context_));
         newConstantBuffer->SetSize(size);
-        constantBuffers_[key] = newConstantBuffer;
+        impl_->allConstantBuffers_[key] = newConstantBuffer;
         return newConstantBuffer.Get();
     }
 }
@@ -2373,7 +2371,7 @@ bool Graphics::UpdateSwapChain(int width, int height)
     impl_->depthStencilView_ = 0;
     for (unsigned i = 0; i < MAX_RENDERTARGETS; ++i)
         impl_->renderTargetViews_[i] = 0;
-    renderTargetsDirty_ = true;
+    impl_->renderTargetsDirty_ = true;
 
     impl_->swapChain_->ResizeBuffers(1, (UINT)width, (UINT)height, DXGI_FORMAT_UNKNOWN, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
 
@@ -2489,7 +2487,6 @@ void Graphics::ResetCachedState()
     primitiveType_ = 0;
     vertexShader_ = 0;
     pixelShader_ = 0;
-    shaderProgram_ = 0;
     blendMode_ = BLEND_REPLACE;
     textureAnisotropy_ = 1;
     colorWrite_ = true;
@@ -2510,25 +2507,26 @@ void Graphics::ResetCachedState()
     stencilCompareMask_ = M_MAX_UNSIGNED;
     stencilWriteMask_ = M_MAX_UNSIGNED;
     useClipPlane_ = false;
-    renderTargetsDirty_ = true;
-    texturesDirty_ = true;
-    vertexDeclarationDirty_ = true;
-    blendStateDirty_ = true;
-    depthStateDirty_ = true;
-    rasterizerStateDirty_ = true;
-    scissorRectDirty_ = true;
-    stencilRefDirty_ = true;
-    blendStateHash_ = M_MAX_UNSIGNED;
-    depthStateHash_ = M_MAX_UNSIGNED;
-    rasterizerStateHash_ = M_MAX_UNSIGNED;
-    firstDirtyTexture_ = lastDirtyTexture_ = M_MAX_UNSIGNED;
-    firstDirtyVB_ = lastDirtyVB_ = M_MAX_UNSIGNED;
-    dirtyConstantBuffers_.Clear();
+    impl_->shaderProgram_ = 0;
+    impl_->renderTargetsDirty_ = true;
+    impl_->texturesDirty_ = true;
+    impl_->vertexDeclarationDirty_ = true;
+    impl_->blendStateDirty_ = true;
+    impl_->depthStateDirty_ = true;
+    impl_->rasterizerStateDirty_ = true;
+    impl_->scissorRectDirty_ = true;
+    impl_->stencilRefDirty_ = true;
+    impl_->blendStateHash_ = M_MAX_UNSIGNED;
+    impl_->depthStateHash_ = M_MAX_UNSIGNED;
+    impl_->rasterizerStateHash_ = M_MAX_UNSIGNED;
+    impl_->firstDirtyTexture_ = impl_->lastDirtyTexture_ = M_MAX_UNSIGNED;
+    impl_->firstDirtyVB_ = impl_->lastDirtyVB_ = M_MAX_UNSIGNED;
+    impl_->dirtyConstantBuffers_.Clear();
 }
 
 void Graphics::PrepareDraw()
 {
-    if (renderTargetsDirty_)
+    if (impl_->renderTargetsDirty_)
     {
         impl_->depthStencilView_ =
             (depthStencil_ && depthStencil_->GetUsage() == TEXTURE_DEPTHSTENCIL) ?
@@ -2550,33 +2548,33 @@ void Graphics::PrepareDraw()
             impl_->renderTargetViews_[0] = impl_->defaultRenderTargetView_;
 
         impl_->deviceContext_->OMSetRenderTargets(MAX_RENDERTARGETS, &impl_->renderTargetViews_[0], impl_->depthStencilView_);
-        renderTargetsDirty_ = false;
+        impl_->renderTargetsDirty_ = false;
     }
 
-    if (texturesDirty_ && firstDirtyTexture_ < M_MAX_UNSIGNED)
+    if (impl_->texturesDirty_ && impl_->firstDirtyTexture_ < M_MAX_UNSIGNED)
     {
         // Set also VS textures to enable vertex texture fetch to work the same way as on OpenGL
-        impl_->deviceContext_->VSSetShaderResources(firstDirtyTexture_, lastDirtyTexture_ - firstDirtyTexture_ + 1,
-            &impl_->shaderResourceViews_[firstDirtyTexture_]);
-        impl_->deviceContext_->VSSetSamplers(firstDirtyTexture_, lastDirtyTexture_ - firstDirtyTexture_ + 1,
-            &impl_->samplers_[firstDirtyTexture_]);
-        impl_->deviceContext_->PSSetShaderResources(firstDirtyTexture_, lastDirtyTexture_ - firstDirtyTexture_ + 1,
-            &impl_->shaderResourceViews_[firstDirtyTexture_]);
-        impl_->deviceContext_->PSSetSamplers(firstDirtyTexture_, lastDirtyTexture_ - firstDirtyTexture_ + 1,
-            &impl_->samplers_[firstDirtyTexture_]);
+        impl_->deviceContext_->VSSetShaderResources(impl_->firstDirtyTexture_, impl_->lastDirtyTexture_ - impl_->firstDirtyTexture_ + 1,
+            &impl_->shaderResourceViews_[impl_->firstDirtyTexture_]);
+        impl_->deviceContext_->VSSetSamplers(impl_->firstDirtyTexture_, impl_->lastDirtyTexture_ - impl_->firstDirtyTexture_ + 1,
+            &impl_->samplers_[impl_->firstDirtyTexture_]);
+        impl_->deviceContext_->PSSetShaderResources(impl_->firstDirtyTexture_, impl_->lastDirtyTexture_ - impl_->firstDirtyTexture_ + 1,
+            &impl_->shaderResourceViews_[impl_->firstDirtyTexture_]);
+        impl_->deviceContext_->PSSetSamplers(impl_->firstDirtyTexture_, impl_->lastDirtyTexture_ - impl_->firstDirtyTexture_ + 1,
+            &impl_->samplers_[impl_->firstDirtyTexture_]);
 
-        firstDirtyTexture_ = lastDirtyTexture_ = M_MAX_UNSIGNED;
-        texturesDirty_ = false;
+        impl_->firstDirtyTexture_ = impl_->lastDirtyTexture_ = M_MAX_UNSIGNED;
+        impl_->texturesDirty_ = false;
     }
 
-    if (vertexDeclarationDirty_ && vertexShader_ && vertexShader_->GetByteCode().Size())
+    if (impl_->vertexDeclarationDirty_ && vertexShader_ && vertexShader_->GetByteCode().Size())
     {
-        if (firstDirtyVB_ < M_MAX_UNSIGNED)
+        if (impl_->firstDirtyVB_ < M_MAX_UNSIGNED)
         {
-            impl_->deviceContext_->IASetVertexBuffers(firstDirtyVB_, lastDirtyVB_ - firstDirtyVB_ + 1,
-                &impl_->vertexBuffers_[firstDirtyVB_], &impl_->vertexSizes_[firstDirtyVB_], &impl_->vertexOffsets_[firstDirtyVB_]);
+            impl_->deviceContext_->IASetVertexBuffers(impl_->firstDirtyVB_, impl_->lastDirtyVB_ - impl_->firstDirtyVB_ + 1,
+                &impl_->vertexBuffers_[impl_->firstDirtyVB_], &impl_->vertexSizes_[impl_->firstDirtyVB_], &impl_->vertexOffsets_[impl_->firstDirtyVB_]);
 
-            firstDirtyVB_ = lastDirtyVB_ = M_MAX_UNSIGNED;
+            impl_->firstDirtyVB_ = impl_->lastDirtyVB_ = M_MAX_UNSIGNED;
         }
 
         unsigned long long newVertexDeclarationHash = 0;
@@ -2592,25 +2590,25 @@ void Graphics::PrepareDraw()
             newVertexDeclarationHash += vertexShader_->GetElementHash();
             if (newVertexDeclarationHash != vertexDeclarationHash_)
             {
-                HashMap<unsigned long long, SharedPtr<VertexDeclaration> >::Iterator i =
-                    vertexDeclarations_.Find(newVertexDeclarationHash);
-                if (i == vertexDeclarations_.End())
+                VertexDeclarationMap::Iterator i =
+                    impl_->vertexDeclarations_.Find(newVertexDeclarationHash);
+                if (i == impl_->vertexDeclarations_.End())
                 {
                     SharedPtr<VertexDeclaration> newVertexDeclaration(new VertexDeclaration(this, vertexShader_, vertexBuffers_));
-                    i = vertexDeclarations_.Insert(MakePair(newVertexDeclarationHash, newVertexDeclaration));
+                    i = impl_->vertexDeclarations_.Insert(MakePair(newVertexDeclarationHash, newVertexDeclaration));
                 }
                 impl_->deviceContext_->IASetInputLayout((ID3D11InputLayout*)i->second_->GetInputLayout());
                 vertexDeclarationHash_ = newVertexDeclarationHash;
             }
         }
 
-        vertexDeclarationDirty_ = false;
+        impl_->vertexDeclarationDirty_ = false;
     }
 
-    if (blendStateDirty_)
+    if (impl_->blendStateDirty_)
     {
         unsigned newBlendStateHash = (unsigned)((colorWrite_ ? 1 : 0) | (blendMode_ << 1));
-        if (newBlendStateHash != blendStateHash_)
+        if (newBlendStateHash != impl_->blendStateHash_)
         {
             HashMap<unsigned, ID3D11BlendState*>::Iterator i = impl_->blendStates_.Find(newBlendStateHash);
             if (i == impl_->blendStates_.End())
@@ -2642,19 +2640,19 @@ void Graphics::PrepareDraw()
             }
 
             impl_->deviceContext_->OMSetBlendState(i->second_, 0, M_MAX_UNSIGNED);
-            blendStateHash_ = newBlendStateHash;
+            impl_->blendStateHash_ = newBlendStateHash;
         }
 
-        blendStateDirty_ = false;
+        impl_->blendStateDirty_ = false;
     }
 
-    if (depthStateDirty_)
+    if (impl_->depthStateDirty_)
     {
         unsigned newDepthStateHash =
             (depthWrite_ ? 1 : 0) | (stencilTest_ ? 2 : 0) | (depthTestMode_ << 2) | ((stencilCompareMask_ & 0xff) << 5) |
             ((stencilWriteMask_ & 0xff) << 13) | (stencilTestMode_ << 21) |
             ((stencilFail_ + stencilZFail_ * 5 + stencilPass_ * 25) << 24);
-        if (newDepthStateHash != depthStateHash_ || stencilRefDirty_)
+        if (newDepthStateHash != impl_->depthStateHash_ || impl_->stencilRefDirty_)
         {
             HashMap<unsigned, ID3D11DepthStencilState*>::Iterator i = impl_->depthStates_.Find(newDepthStateHash);
             if (i == impl_->depthStates_.End())
@@ -2690,14 +2688,14 @@ void Graphics::PrepareDraw()
             }
 
             impl_->deviceContext_->OMSetDepthStencilState(i->second_, stencilRef_);
-            depthStateHash_ = newDepthStateHash;
+            impl_->depthStateHash_ = newDepthStateHash;
         }
 
-        depthStateDirty_ = false;
-        stencilRefDirty_ = false;
+        impl_->depthStateDirty_ = false;
+        impl_->stencilRefDirty_ = false;
     }
 
-    if (rasterizerStateDirty_)
+    if (impl_->rasterizerStateDirty_)
     {
         unsigned depthBits = 24;
         if (depthStencil_ && depthStencil_->GetParentTexture()->GetFormat() == DXGI_FORMAT_R16_TYPELESS)
@@ -2707,7 +2705,7 @@ void Graphics::PrepareDraw()
         unsigned newRasterizerStateHash =
             (scissorTest_ ? 1 : 0) | (fillMode_ << 1) | (cullMode_ << 3) | ((scaledDepthBias & 0x1fff) << 5) |
             ((*((unsigned*)&slopeScaledDepthBias_) & 0x1fff) << 18);
-        if (newRasterizerStateHash != rasterizerStateHash_)
+        if (newRasterizerStateHash != impl_->rasterizerStateHash_)
         {
             HashMap<unsigned, ID3D11RasterizerState*>::Iterator i = impl_->rasterizerStates_.Find(newRasterizerStateHash);
             if (i == impl_->rasterizerStates_.End())
@@ -2739,13 +2737,13 @@ void Graphics::PrepareDraw()
             }
 
             impl_->deviceContext_->RSSetState(i->second_);
-            rasterizerStateHash_ = newRasterizerStateHash;
+            impl_->rasterizerStateHash_ = newRasterizerStateHash;
         }
 
-        rasterizerStateDirty_ = false;
+        impl_->rasterizerStateDirty_ = false;
     }
 
-    if (scissorRectDirty_)
+    if (impl_->scissorRectDirty_)
     {
         D3D11_RECT d3dRect;
         d3dRect.left = scissorRect_.left_;
@@ -2753,12 +2751,12 @@ void Graphics::PrepareDraw()
         d3dRect.right = scissorRect_.right_;
         d3dRect.bottom = scissorRect_.bottom_;
         impl_->deviceContext_->RSSetScissorRects(1, &d3dRect);
-        scissorRectDirty_ = false;
+        impl_->scissorRectDirty_ = false;
     }
 
-    for (unsigned i = 0; i < dirtyConstantBuffers_.Size(); ++i)
-        dirtyConstantBuffers_[i]->Apply();
-    dirtyConstantBuffers_.Clear();
+    for (unsigned i = 0; i < impl_->dirtyConstantBuffers_.Size(); ++i)
+        impl_->dirtyConstantBuffers_[i]->Apply();
+    impl_->dirtyConstantBuffers_.Clear();
 }
 
 void Graphics::CreateResolveTexture()

+ 7 - 49
Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.h

@@ -75,8 +75,6 @@ struct ScratchBuffer
     bool reserved_;
 };
 
-typedef HashMap<Pair<ShaderVariation*, ShaderVariation*>, SharedPtr<ShaderProgram> > ShaderProgramMap;
-
 /// %Graphics subsystem. Manages the application window, rendering state and GPU resources.
 class URHO3D_API Graphics : public Object
 {
@@ -308,7 +306,7 @@ public:
     /// Return 24-bit shadow map depth texture format, or 0 if not supported.
     unsigned GetHiresShadowMapFormat() const { return hiresShadowMapFormat_; }
 
-    /// Return whether hardware instancing is supported..
+    /// Return whether hardware instancing is supported.
     bool GetInstancingSupport() const { return instancingSupport_; }
 
     /// Return whether light pre-pass rendering is supported.
@@ -436,9 +434,9 @@ public:
     IntVector2 GetRenderTargetDimensions() const;
 
     /// Window was resized through user interaction. Called by Input subsystem.
-    void WindowResized();
+    void OnWindowResized();
     /// Window was moved through user interaction. Called by Input subsystem.
-    void WindowMoved();
+    void OnWindowMoved();
     /// Maximize the Window.
     void Maximize();
     /// Minimize the Window.
@@ -527,8 +525,8 @@ private:
     GraphicsImpl* impl_;
     /// Window title.
     String windowTitle_;
-    /// Window Icon File Name
-    Image* windowIcon_;
+    /// Window icon image.
+    WeakPtr<Image> windowIcon_;
     /// External window, null if not in use (default.)
     void* externalWindow_;
     /// Window width in pixels.
@@ -605,6 +603,8 @@ private:
     RenderSurface* depthStencil_;
     /// Viewport coordinates.
     IntRect viewport_;
+    /// Default texture filtering mode.
+    TextureFilterMode defaultTextureFilterMode_;
     /// Texture anisotropy level.
     unsigned textureAnisotropy_;
     /// Blending mode.
@@ -647,48 +647,6 @@ private:
     bool stencilTest_;
     /// Custom clip plane enable flag.
     bool useClipPlane_;
-    /// Rendertargets dirty flag.
-    bool renderTargetsDirty_;
-    /// Textures dirty flag.
-    bool texturesDirty_;
-    /// Vertex declaration dirty flag.
-    bool vertexDeclarationDirty_;
-    /// Blend state dirty flag.
-    bool blendStateDirty_;
-    /// Depth state dirty flag.
-    bool depthStateDirty_;
-    /// Rasterizer state dirty flag.
-    bool rasterizerStateDirty_;
-    /// Scissor rect dirty flag.
-    bool scissorRectDirty_;
-    /// Stencil ref dirty flag.
-    bool stencilRefDirty_;
-    /// Hash of current blend state.
-    unsigned blendStateHash_;
-    /// Hash of current depth state.
-    unsigned depthStateHash_;
-    /// Hash of current rasterizer state.
-    unsigned rasterizerStateHash_;
-    /// First dirtied texture unit.
-    unsigned firstDirtyTexture_;
-    /// Last dirtied texture unit.
-    unsigned lastDirtyTexture_;
-    /// First dirtied vertex buffer.
-    unsigned firstDirtyVB_;
-    /// Last dirtied vertex buffer.
-    unsigned lastDirtyVB_;
-    /// Default texture filtering mode.
-    TextureFilterMode defaultTextureFilterMode_;
-    /// Vertex declarations.
-    HashMap<unsigned long long, SharedPtr<VertexDeclaration> > vertexDeclarations_;
-    /// Constant buffers.
-    HashMap<unsigned, SharedPtr<ConstantBuffer> > constantBuffers_;
-    /// Currently dirty constant buffers.
-    PODVector<ConstantBuffer*> dirtyConstantBuffers_;
-    /// Shader programs.
-    ShaderProgramMap shaderPrograms_;
-    /// Shader program in use.
-    ShaderProgram* shaderProgram_;
     /// Remembered shader parameter sources.
     const void* shaderParameterSources_[MAX_SHADER_PARAMETER_GROUPS];
     /// Base directory for shaders.

+ 2 - 1
Source/Urho3D/Graphics/Direct3D11/D3D11GraphicsImpl.cpp

@@ -39,7 +39,8 @@ GraphicsImpl::GraphicsImpl() :
     defaultDepthTexture_(0),
     defaultDepthStencilView_(0),
     depthStencilView_(0),
-    resolveTexture_(0)
+    resolveTexture_(0),
+    shaderProgram_(0)
 {
     for (unsigned i = 0; i < MAX_RENDERTARGETS; ++i)
         renderTargetViews_[i] = 0;

+ 47 - 0
Source/Urho3D/Graphics/Direct3D11/D3D11GraphicsImpl.h

@@ -22,7 +22,10 @@
 
 #pragma once
 
+#include "../../Graphics/ConstantBuffer.h"
 #include "../../Graphics/GraphicsDefs.h"
+#include "../../Graphics/ShaderProgram.h"
+#include "../../Graphics/VertexDeclaration.h"
 #include "../../Math/Color.h"
 
 #include <d3d11.h>
@@ -37,6 +40,10 @@ namespace Urho3D
 
 #define URHO3D_LOGD3DERROR(msg, hr) URHO3D_LOGERRORF("%s (HRESULT %x)", msg, (unsigned)hr)
 
+typedef HashMap<Pair<ShaderVariation*, ShaderVariation*>, SharedPtr<ShaderProgram> > ShaderProgramMap;
+typedef HashMap<unsigned long long, SharedPtr<VertexDeclaration> > VertexDeclarationMap;
+typedef HashMap<unsigned, SharedPtr<ConstantBuffer> > ConstantBufferMap;
+
 /// %Graphics implementation. Holds API-specific objects.
 class URHO3D_API GraphicsImpl
 {
@@ -97,6 +104,46 @@ private:
     unsigned vertexSizes_[MAX_VERTEX_STREAMS];
     /// Vertex stream offsets per buffer.
     unsigned vertexOffsets_[MAX_VERTEX_STREAMS];
+    /// Rendertargets dirty flag.
+    bool renderTargetsDirty_;
+    /// Textures dirty flag.
+    bool texturesDirty_;
+    /// Vertex declaration dirty flag.
+    bool vertexDeclarationDirty_;
+    /// Blend state dirty flag.
+    bool blendStateDirty_;
+    /// Depth state dirty flag.
+    bool depthStateDirty_;
+    /// Rasterizer state dirty flag.
+    bool rasterizerStateDirty_;
+    /// Scissor rect dirty flag.
+    bool scissorRectDirty_;
+    /// Stencil ref dirty flag.
+    bool stencilRefDirty_;
+    /// Hash of current blend state.
+    unsigned blendStateHash_;
+    /// Hash of current depth state.
+    unsigned depthStateHash_;
+    /// Hash of current rasterizer state.
+    unsigned rasterizerStateHash_;
+    /// First dirtied texture unit.
+    unsigned firstDirtyTexture_;
+    /// Last dirtied texture unit.
+    unsigned lastDirtyTexture_;
+    /// First dirtied vertex buffer.
+    unsigned firstDirtyVB_;
+    /// Last dirtied vertex buffer.
+    unsigned lastDirtyVB_;
+    /// Vertex declarations.
+    VertexDeclarationMap vertexDeclarations_;
+    /// Constant buffer search map.
+    ConstantBufferMap allConstantBuffers_;
+    /// Currently dirty constant buffers.
+    PODVector<ConstantBuffer*> dirtyConstantBuffers_;
+    /// Shader programs.
+    ShaderProgramMap shaderPrograms_;
+    /// Shader program in use.
+    ShaderProgram* shaderProgram_;
 };
 
 }

+ 38 - 38
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -286,7 +286,6 @@ Graphics::Graphics(Context* context) :
     numBatches_(0),
     maxScratchBufferRequest_(0),
     defaultTextureFilterMode_(FILTER_TRILINEAR),
-    shaderProgram_(0),
     shaderPath_("Shaders/HLSL/"),
     shaderExtension_(".hlsl"),
     orientations_("LandscapeLeft LandscapeRight"),
@@ -312,7 +311,7 @@ Graphics::~Graphics()
         gpuObjects_.Clear();
     }
 
-    vertexDeclarations_.Clear();
+    impl_->vertexDeclarations_.Clear();
 
     URHO3D_SAFE_RELEASE(impl_->defaultColorSurface_);
     URHO3D_SAFE_RELEASE(impl_->defaultDepthStencilSurface_);
@@ -1022,20 +1021,21 @@ bool Graphics::SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, unsigne
     if (hash)
     {
         // If no previous vertex declaration for that hash, create new
-        if (!vertexDeclarations_.Contains(hash))
+        VertexDeclarationMap::Iterator i = impl_->vertexDeclarations_.Find(hash);
+        if (i == impl_->vertexDeclarations_.End())
         {
             SharedPtr<VertexDeclaration> newDeclaration(new VertexDeclaration(this, buffers));
             if (!newDeclaration->GetDeclaration())
                 return false;
 
-            vertexDeclarations_[hash] = newDeclaration;
+            i = impl_->vertexDeclarations_.Insert(MakePair(hash, newDeclaration));
         }
 
-        VertexDeclaration* declaration = vertexDeclarations_[hash];
-        if (declaration != vertexDeclaration_)
+        VertexDeclaration* declaration = i->second_;
+        if (declaration != impl_->vertexDeclaration_)
         {
             impl_->device_->SetVertexDeclaration(declaration->GetDeclaration());
-            vertexDeclaration_ = declaration;
+            impl_->vertexDeclaration_ = declaration;
         }
     }
 
@@ -1053,7 +1053,7 @@ bool Graphics::SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, unsigne
                 offset = instanceOffset * buffer->GetVertexSize();
         }
 
-        if (buffer != vertexBuffers_[i] || offset != streamOffsets_[i])
+        if (buffer != vertexBuffers_[i] || offset != impl_->streamOffsets_[i])
         {
             if (buffer)
                 impl_->device_->SetStreamSource(i, (IDirect3DVertexBuffer9*)buffer->GetGPUObject(), offset,
@@ -1062,7 +1062,7 @@ bool Graphics::SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, unsigne
                 impl_->device_->SetStreamSource(i, 0, 0, 0);
 
             vertexBuffers_[i] = buffer;
-            streamOffsets_[i] = offset;
+            impl_->streamOffsets_[i] = offset;
         }
     }
 
@@ -1159,17 +1159,17 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
     if (vertexShader_ && pixelShader_)
     {
         Pair<ShaderVariation*, ShaderVariation*> key = MakePair(vertexShader_, pixelShader_);
-        ShaderProgramMap::Iterator i = shaderPrograms_.Find(key);
-        if (i != shaderPrograms_.End())
-            shaderProgram_ = i->second_.Get();
+        ShaderProgramMap::Iterator i = impl_->shaderPrograms_.Find(key);
+        if (i != impl_->shaderPrograms_.End())
+            impl_->shaderProgram_ = i->second_.Get();
         else
         {
-            ShaderProgram* newProgram = shaderPrograms_[key] = new ShaderProgram(vertexShader_, pixelShader_);
-            shaderProgram_ = newProgram;
+            ShaderProgram* newProgram = impl_->shaderPrograms_[key] = new ShaderProgram(vertexShader_, pixelShader_);
+            impl_->shaderProgram_ = newProgram;
         }
     }
     else
-        shaderProgram_ = 0;
+        impl_->shaderProgram_ = 0;
 
     // Store shader combination if shader dumping in progress
     if (shaderPrecache_)
@@ -1179,7 +1179,7 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
 void Graphics::SetShaderParameter(StringHash param, const float* data, unsigned count)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     if (i->second_.type_ == VS)
@@ -1191,7 +1191,7 @@ void Graphics::SetShaderParameter(StringHash param, const float* data, unsigned
 void Graphics::SetShaderParameter(StringHash param, float value)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     static Vector4 data(Vector4::ZERO);
@@ -1207,7 +1207,7 @@ void Graphics::SetShaderParameter(StringHash param, bool value)
 {
     /// \todo Bool constants possibly have no effect on Direct3D9
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     BOOL data = value;
@@ -1221,7 +1221,7 @@ void Graphics::SetShaderParameter(StringHash param, bool value)
 void Graphics::SetShaderParameter(StringHash param, const Color& color)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     if (i->second_.type_ == VS)
@@ -1233,7 +1233,7 @@ void Graphics::SetShaderParameter(StringHash param, const Color& color)
 void Graphics::SetShaderParameter(StringHash param, const Vector2& vector)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     static Vector4 data(Vector4::ZERO);
@@ -1249,7 +1249,7 @@ void Graphics::SetShaderParameter(StringHash param, const Vector2& vector)
 void Graphics::SetShaderParameter(StringHash param, const Matrix3& matrix)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     static Matrix3x4 data(Matrix3x4::ZERO);
@@ -1272,7 +1272,7 @@ void Graphics::SetShaderParameter(StringHash param, const Matrix3& matrix)
 void Graphics::SetShaderParameter(StringHash param, const Vector3& vector)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     static Vector4 data(Vector4::ZERO);
@@ -1289,7 +1289,7 @@ void Graphics::SetShaderParameter(StringHash param, const Vector3& vector)
 void Graphics::SetShaderParameter(StringHash param, const Matrix4& matrix)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     if (i->second_.type_ == VS)
@@ -1301,7 +1301,7 @@ void Graphics::SetShaderParameter(StringHash param, const Matrix4& matrix)
 void Graphics::SetShaderParameter(StringHash param, const Vector4& vector)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     if (i->second_.type_ == VS)
@@ -1313,7 +1313,7 @@ void Graphics::SetShaderParameter(StringHash param, const Vector4& vector)
 void Graphics::SetShaderParameter(StringHash param, const Matrix3x4& matrix)
 {
     HashMap<StringHash, ShaderParameter>::Iterator i;
-    if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
+    if (!impl_->shaderProgram_ || (i = impl_->shaderProgram_->parameters_.Find(param)) == impl_->shaderProgram_->parameters_.End())
         return;
 
     if (i->second_.type_ == VS)
@@ -1389,7 +1389,7 @@ bool Graphics::NeedParameterUpdate(ShaderParameterGroup group, const void* sourc
 
 bool Graphics::HasShaderParameter(StringHash param)
 {
-    return shaderProgram_ && shaderProgram_->parameters_.Find(param) != shaderProgram_->parameters_.End();
+    return impl_->shaderProgram_ && impl_->shaderProgram_->parameters_.Find(param) != impl_->shaderProgram_->parameters_.End();
 }
 
 bool Graphics::HasTextureUnit(TextureUnit unit)
@@ -2097,7 +2097,7 @@ IntVector2 Graphics::GetRenderTargetDimensions() const
     return IntVector2(width, height);
 }
 
-void Graphics::WindowResized()
+void Graphics::OnWindowResized()
 {
     if (!impl_->device_ || !impl_->window_)
         return;
@@ -2131,7 +2131,7 @@ void Graphics::WindowResized()
     SendEvent(E_SCREENMODE, eventData);
 }
 
-void Graphics::WindowMoved()
+void Graphics::OnWindowMoved()
 {
     if (!impl_->device_ || !impl_->window_ || fullscreen_)
         return;
@@ -2264,16 +2264,16 @@ void Graphics::CleanupScratchBuffers()
 
 void Graphics::CleanupShaderPrograms(ShaderVariation* variation)
 {
-    for (ShaderProgramMap::Iterator i = shaderPrograms_.Begin(); i != shaderPrograms_.End();)
+    for (ShaderProgramMap::Iterator i = impl_->shaderPrograms_.Begin(); i != impl_->shaderPrograms_.End();)
     {
         if (i->first_.first_ == variation || i->first_.second_ == variation)
-            i = shaderPrograms_.Erase(i);
+            i = impl_->shaderPrograms_.Erase(i);
         else
             ++i;
     }
 
     if (vertexShader_ == variation || pixelShader_ == variation)
-        shaderProgram_ = 0;
+        impl_->shaderProgram_ = 0;
 }
 
 unsigned Graphics::GetAlphaFormat()
@@ -2398,10 +2398,10 @@ unsigned Graphics::GetFormat(const String& formatName)
 
 void Graphics::SetStreamFrequency(unsigned index, unsigned frequency)
 {
-    if (index < MAX_VERTEX_STREAMS && streamFrequencies_[index] != frequency)
+    if (index < MAX_VERTEX_STREAMS && impl_->streamFrequencies_[index] != frequency)
     {
         impl_->device_->SetStreamSourceFreq(index, frequency);
-        streamFrequencies_[index] = frequency;
+        impl_->streamFrequencies_[index] = frequency;
     }
 }
 
@@ -2409,10 +2409,10 @@ void Graphics::ResetStreamFrequencies()
 {
     for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i)
     {
-        if (streamFrequencies_[i] != 1)
+        if (impl_->streamFrequencies_[i] != 1)
         {
             impl_->device_->SetStreamSourceFreq(i, 1);
-            streamFrequencies_[i] = 1;
+            impl_->streamFrequencies_[i] = 1;
         }
     }
 }
@@ -2704,7 +2704,7 @@ void Graphics::ResetCachedState()
     for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i)
     {
         vertexBuffers_[i] = 0;
-        streamOffsets_[i] = 0;
+        impl_->streamOffsets_[i] = 0;
     }
 
     for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
@@ -2731,10 +2731,9 @@ void Graphics::ResetCachedState()
     impl_->sRGBWrite_ = false;
 
     for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i)
-        streamFrequencies_[i] = 1;
+        impl_->streamFrequencies_[i] = 1;
 
     indexBuffer_ = 0;
-    vertexDeclaration_ = 0;
     vertexShader_ = 0;
     pixelShader_ = 0;
     blendMode_ = BLEND_REPLACE;
@@ -2761,6 +2760,7 @@ void Graphics::ResetCachedState()
     impl_->srcBlend_ = D3DBLEND_ONE;
     impl_->destBlend_ = D3DBLEND_ZERO;
     impl_->blendOp_ = D3DBLENDOP_ADD;
+    impl_->vertexDeclaration_ = 0;
 
     queryIssued_ = false;
 }

+ 6 - 20
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.h

@@ -55,8 +55,6 @@ class VertexDeclaration;
 
 struct ShaderParameter;
 
-typedef HashMap<Pair<ShaderVariation*, ShaderVariation*>, SharedPtr<ShaderProgram> > ShaderProgramMap;
-
 /// CPU-side scratch buffer for vertex data updates.
 struct ScratchBuffer
 {
@@ -431,9 +429,9 @@ public:
     IntVector2 GetRenderTargetDimensions() const;
 
     /// Window was resized through user interaction. Called by Input subsystem.
-    void WindowResized();
+    void OnWindowResized();
     /// Window was moved through user interaction. Called by Input subsystem.
-    void WindowMoved();
+    void OnWindowMoved();
     /// Maximize the Window.
     void Maximize();
     /// Minimize the Window.
@@ -526,8 +524,8 @@ private:
     GraphicsImpl* impl_;
     /// Window title.
     String windowTitle_;
-    /// Window Icon File Name
-    Image* windowIcon_;
+    /// Window icon image.
+    WeakPtr<Image> windowIcon_;
     /// External window, null if not in use (default.)
     void* externalWindow_;
     /// Window width in pixels.
@@ -580,8 +578,6 @@ private:
     PODVector<GPUObject*> gpuObjects_;
     /// Scratch buffers.
     Vector<ScratchBuffer> scratchBuffers_;
-    /// Vertex declarations.
-    HashMap<unsigned long long, SharedPtr<VertexDeclaration> > vertexDeclarations_;
     /// Shadow map dummy color texture format.
     unsigned dummyColorFormat_;
     /// Shadow map depth texture format.
@@ -590,14 +586,8 @@ private:
     unsigned hiresShadowMapFormat_;
     /// Vertex buffers in use.
     VertexBuffer* vertexBuffers_[MAX_VERTEX_STREAMS];
-    /// Stream frequencies by vertex buffer.
-    unsigned streamFrequencies_[MAX_VERTEX_STREAMS];
-    /// Stream offsets by vertex buffer.
-    unsigned streamOffsets_[MAX_VERTEX_STREAMS];
     /// Index buffer in use.
     IndexBuffer* indexBuffer_;
-    /// Vertex declaration in use.
-    VertexDeclaration* vertexDeclaration_;
     /// Vertex shader in use.
     ShaderVariation* vertexShader_;
     /// Pixel shader in use.
@@ -612,6 +602,8 @@ private:
     RenderSurface* depthStencil_;
     /// Viewport coordinates.
     IntRect viewport_;
+    /// Default texture filtering mode.
+    TextureFilterMode defaultTextureFilterMode_;
     /// Texture anisotropy level.
     unsigned textureAnisotropy_;
     /// Blending mode.
@@ -652,12 +644,6 @@ private:
     bool stencilTest_;
     /// Custom clip plane enable flag.
     bool useClipPlane_;
-    /// Default texture filtering mode.
-    TextureFilterMode defaultTextureFilterMode_;
-    /// Shader programs.
-    ShaderProgramMap shaderPrograms_;
-    /// Shader program in use.
-    ShaderProgram* shaderProgram_;
     /// Remembered shader parameter sources.
     const void* shaderParameterSources_[MAX_SHADER_PARAMETER_GROUPS];
     /// Base directory for shaders.

+ 2 - 1
Source/Urho3D/Graphics/Direct3D9/D3D9GraphicsImpl.cpp

@@ -38,7 +38,8 @@ GraphicsImpl::GraphicsImpl() :
     defaultDepthStencilSurface_(0),
     frameQuery_(0),
     adapter_(D3DADAPTER_DEFAULT),
-    deviceType_(D3DDEVTYPE_HAL)
+    deviceType_(D3DDEVTYPE_HAL),
+    shaderProgram_(0)
 {
     memset(&presentParams_, 0, sizeof presentParams_);
 }

+ 18 - 0
Source/Urho3D/Graphics/Direct3D9/D3D9GraphicsImpl.h

@@ -22,6 +22,8 @@
 
 #pragma once
 
+#include "../../Graphics/ShaderProgram.h"
+#include "../../Graphics/VertexDeclaration.h"
 #include "../../Math/Color.h"
 
 #include <d3d9.h>
@@ -35,6 +37,9 @@ namespace Urho3D
 
 #define URHO3D_LOGD3DERROR(msg, hr) URHO3D_LOGERRORF("%s (HRESULT %x)", msg, (unsigned)hr)
 
+typedef HashMap<Pair<ShaderVariation*, ShaderVariation*>, SharedPtr<ShaderProgram> > ShaderProgramMap;
+typedef HashMap<unsigned long long, SharedPtr<VertexDeclaration> > VertexDeclarationMap;
+
 /// %Graphics implementation. Holds API-specific objects.
 class URHO3D_API GraphicsImpl
 {
@@ -110,6 +115,19 @@ private:
     D3DBLEND destBlend_;
     /// Blend operation.
     D3DBLENDOP blendOp_;
+    /// Vertex declarations.
+    VertexDeclarationMap vertexDeclarations_;
+    /// Stream frequencies by vertex buffer.
+    unsigned streamFrequencies_[MAX_VERTEX_STREAMS];
+    /// Stream offsets by vertex buffer.
+    unsigned streamOffsets_[MAX_VERTEX_STREAMS];
+    /// Vertex declaration in use.
+    VertexDeclaration* vertexDeclaration_;
+    /// Shader programs.
+    ShaderProgramMap shaderPrograms_;
+    /// Shader program in use.
+    ShaderProgram* shaderProgram_;
+
 };
 
 }

+ 85 - 80
Source/Urho3D/Graphics/OpenGL/OGLGraphics.cpp

@@ -931,9 +931,9 @@ bool Graphics::SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, unsigne
         return false;
     }
 
-    if (instanceOffset != lastInstanceOffset_)
+    if (instanceOffset != impl_->lastInstanceOffset_)
     {
-        lastInstanceOffset_ = instanceOffset;
+        impl_->lastInstanceOffset_ = instanceOffset;
         impl_->vertexBuffersDirty_ = true;
     }
 
@@ -1015,7 +1015,7 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
         glUseProgram(0);
         vertexShader_ = 0;
         pixelShader_ = 0;
-        shaderProgram_ = 0;
+        impl_->shaderProgram_ = 0;
     }
     else
     {
@@ -1023,20 +1023,20 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
         pixelShader_ = ps;
 
         Pair<ShaderVariation*, ShaderVariation*> combination(vs, ps);
-        ShaderProgramMap::Iterator i = shaderPrograms_.Find(combination);
+        ShaderProgramMap::Iterator i = impl_->shaderPrograms_.Find(combination);
 
-        if (i != shaderPrograms_.End())
+        if (i != impl_->shaderPrograms_.End())
         {
             // Use the existing linked program
             if (i->second_->GetGPUObjectName())
             {
                 glUseProgram(i->second_->GetGPUObjectName());
-                shaderProgram_ = i->second_;
+                impl_->shaderProgram_ = i->second_;
             }
             else
             {
                 glUseProgram(0);
-                shaderProgram_ = 0;
+                impl_->shaderProgram_ = 0;
             }
         }
         else
@@ -1050,35 +1050,35 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
                 URHO3D_LOGDEBUG("Linked vertex shader " + vs->GetFullName() + " and pixel shader " + ps->GetFullName());
                 // Note: Link() calls glUseProgram() to set the texture sampler uniforms,
                 // so it is not necessary to call it again
-                shaderProgram_ = newProgram;
+                impl_->shaderProgram_ = newProgram;
             }
             else
             {
                 URHO3D_LOGERROR("Failed to link vertex shader " + vs->GetFullName() + " and pixel shader " + ps->GetFullName() + ":\n" +
                          newProgram->GetLinkerOutput());
                 glUseProgram(0);
-                shaderProgram_ = 0;
+                impl_->shaderProgram_ = 0;
             }
 
-            shaderPrograms_[combination] = newProgram;
+            impl_->shaderPrograms_[combination] = newProgram;
         }
     }
 
     // Update the clip plane uniform on GL3, and set constant buffers
 #ifndef GL_ES_VERSION_2_0
-    if (gl3Support && shaderProgram_)
+    if (gl3Support && impl_->shaderProgram_)
     {
-        const SharedPtr<ConstantBuffer>* constantBuffers = shaderProgram_->GetConstantBuffers();
+        const SharedPtr<ConstantBuffer>* constantBuffers = impl_->shaderProgram_->GetConstantBuffers();
         for (unsigned i = 0; i < MAX_SHADER_PARAMETER_GROUPS * 2; ++i)
         {
             ConstantBuffer* buffer = constantBuffers[i].Get();
-            if (buffer != currentConstantBuffers_[i])
+            if (buffer != impl_->constantBuffers_[i])
             {
                 unsigned object = buffer ? buffer->GetGPUObjectName() : 0;
                 glBindBufferBase(GL_UNIFORM_BUFFER, i, object);
                 // Calling glBindBufferBase also affects the generic buffer binding point
                 impl_->boundUBO_ = object;
-                currentConstantBuffers_[i] = buffer;
+                impl_->constantBuffers_[i] = buffer;
                 ShaderProgram::ClearGlobalParameterSource((ShaderParameterGroup)(i % MAX_SHADER_PARAMETER_GROUPS));
             }
         }
@@ -1091,10 +1091,10 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
     if (shaderPrecache_)
         shaderPrecache_->StoreShaders(vertexShader_, pixelShader_);
 
-    if (shaderProgram_)
+    if (impl_->shaderProgram_)
     {
-        impl_->usedVertexAttributes_ = shaderProgram_->GetUsedVertexAttributes();
-        impl_->vertexAttributes_ = &shaderProgram_->GetVertexAttributes();
+        impl_->usedVertexAttributes_ = impl_->shaderProgram_->GetUsedVertexAttributes();
+        impl_->vertexAttributes_ = &impl_->shaderProgram_->GetVertexAttributes();
     }
     else
     {
@@ -1107,16 +1107,16 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
 
 void Graphics::SetShaderParameter(StringHash param, const float* data, unsigned count)
 {
-    if (shaderProgram_)
+    if (impl_->shaderProgram_)
     {
-        const ShaderParameter* info = shaderProgram_->GetParameter(param);
+        const ShaderParameter* info = impl_->shaderProgram_->GetParameter(param);
         if (info)
         {
             if (info->bufferPtr_)
             {
                 ConstantBuffer* buffer = info->bufferPtr_;
                 if (!buffer->IsDirty())
-                    dirtyConstantBuffers_.Push(buffer);
+                    impl_->dirtyConstantBuffers_.Push(buffer);
                 buffer->SetParameter(info->offset_, (unsigned)(count * sizeof(float)), data);
                 return;
             }
@@ -1155,16 +1155,16 @@ void Graphics::SetShaderParameter(StringHash param, const float* data, unsigned
 
 void Graphics::SetShaderParameter(StringHash param, float value)
 {
-    if (shaderProgram_)
+    if (impl_->shaderProgram_)
     {
-        const ShaderParameter* info = shaderProgram_->GetParameter(param);
+        const ShaderParameter* info = impl_->shaderProgram_->GetParameter(param);
         if (info)
         {
             if (info->bufferPtr_)
             {
                 ConstantBuffer* buffer = info->bufferPtr_;
                 if (!buffer->IsDirty())
-                    dirtyConstantBuffers_.Push(buffer);
+                    impl_->dirtyConstantBuffers_.Push(buffer);
                 buffer->SetParameter(info->offset_, sizeof(float), &value);
                 return;
             }
@@ -1181,16 +1181,16 @@ void Graphics::SetShaderParameter(StringHash param, const Color& color)
 
 void Graphics::SetShaderParameter(StringHash param, const Vector2& vector)
 {
-    if (shaderProgram_)
+    if (impl_->shaderProgram_)
     {
-        const ShaderParameter* info = shaderProgram_->GetParameter(param);
+        const ShaderParameter* info = impl_->shaderProgram_->GetParameter(param);
         if (info)
         {
             if (info->bufferPtr_)
             {
                 ConstantBuffer* buffer = info->bufferPtr_;
                 if (!buffer->IsDirty())
-                    dirtyConstantBuffers_.Push(buffer);
+                    impl_->dirtyConstantBuffers_.Push(buffer);
                 buffer->SetParameter(info->offset_, sizeof(Vector2), &vector);
                 return;
             }
@@ -1214,16 +1214,16 @@ void Graphics::SetShaderParameter(StringHash param, const Vector2& vector)
 
 void Graphics::SetShaderParameter(StringHash param, const Matrix3& matrix)
 {
-    if (shaderProgram_)
+    if (impl_->shaderProgram_)
     {
-        const ShaderParameter* info = shaderProgram_->GetParameter(param);
+        const ShaderParameter* info = impl_->shaderProgram_->GetParameter(param);
         if (info)
         {
             if (info->bufferPtr_)
             {
                 ConstantBuffer* buffer = info->bufferPtr_;
                 if (!buffer->IsDirty())
-                    dirtyConstantBuffers_.Push(buffer);
+                    impl_->dirtyConstantBuffers_.Push(buffer);
                 buffer->SetVector3ArrayParameter(info->offset_, 3, &matrix);
                 return;
             }
@@ -1235,16 +1235,16 @@ void Graphics::SetShaderParameter(StringHash param, const Matrix3& matrix)
 
 void Graphics::SetShaderParameter(StringHash param, const Vector3& vector)
 {
-    if (shaderProgram_)
+    if (impl_->shaderProgram_)
     {
-        const ShaderParameter* info = shaderProgram_->GetParameter(param);
+        const ShaderParameter* info = impl_->shaderProgram_->GetParameter(param);
         if (info)
         {
             if (info->bufferPtr_)
             {
                 ConstantBuffer* buffer = info->bufferPtr_;
                 if (!buffer->IsDirty())
-                    dirtyConstantBuffers_.Push(buffer);
+                    impl_->dirtyConstantBuffers_.Push(buffer);
                 buffer->SetParameter(info->offset_, sizeof(Vector3), &vector);
                 return;
             }
@@ -1272,16 +1272,16 @@ void Graphics::SetShaderParameter(StringHash param, const Vector3& vector)
 
 void Graphics::SetShaderParameter(StringHash param, const Matrix4& matrix)
 {
-    if (shaderProgram_)
+    if (impl_->shaderProgram_)
     {
-        const ShaderParameter* info = shaderProgram_->GetParameter(param);
+        const ShaderParameter* info = impl_->shaderProgram_->GetParameter(param);
         if (info)
         {
             if (info->bufferPtr_)
             {
                 ConstantBuffer* buffer = info->bufferPtr_;
                 if (!buffer->IsDirty())
-                    dirtyConstantBuffers_.Push(buffer);
+                    impl_->dirtyConstantBuffers_.Push(buffer);
                 buffer->SetParameter(info->offset_, sizeof(Matrix4), &matrix);
                 return;
             }
@@ -1293,16 +1293,16 @@ void Graphics::SetShaderParameter(StringHash param, const Matrix4& matrix)
 
 void Graphics::SetShaderParameter(StringHash param, const Vector4& vector)
 {
-    if (shaderProgram_)
+    if (impl_->shaderProgram_)
     {
-        const ShaderParameter* info = shaderProgram_->GetParameter(param);
+        const ShaderParameter* info = impl_->shaderProgram_->GetParameter(param);
         if (info)
         {
             if (info->bufferPtr_)
             {
                 ConstantBuffer* buffer = info->bufferPtr_;
                 if (!buffer->IsDirty())
-                    dirtyConstantBuffers_.Push(buffer);
+                    impl_->dirtyConstantBuffers_.Push(buffer);
                 buffer->SetParameter(info->offset_, sizeof(Vector4), &vector);
                 return;
             }
@@ -1334,9 +1334,9 @@ void Graphics::SetShaderParameter(StringHash param, const Vector4& vector)
 
 void Graphics::SetShaderParameter(StringHash param, const Matrix3x4& matrix)
 {
-    if (shaderProgram_)
+    if (impl_->shaderProgram_)
     {
-        const ShaderParameter* info = shaderProgram_->GetParameter(param);
+        const ShaderParameter* info = impl_->shaderProgram_->GetParameter(param);
         if (info)
         {
             // Expand to a full Matrix4
@@ -1358,7 +1358,7 @@ void Graphics::SetShaderParameter(StringHash param, const Matrix3x4& matrix)
             {
                 ConstantBuffer* buffer = info->bufferPtr_;
                 if (!buffer->IsDirty())
-                    dirtyConstantBuffers_.Push(buffer);
+                    impl_->dirtyConstantBuffers_.Push(buffer);
                 buffer->SetParameter(info->offset_, sizeof(Matrix4), &fullMatrix);
                 return;
             }
@@ -1424,23 +1424,23 @@ void Graphics::SetShaderParameter(StringHash param, const Variant& value)
 
 bool Graphics::NeedParameterUpdate(ShaderParameterGroup group, const void* source)
 {
-    return shaderProgram_ ? shaderProgram_->NeedParameterUpdate(group, source) : false;
+    return impl_->shaderProgram_ ? impl_->shaderProgram_->NeedParameterUpdate(group, source) : false;
 }
 
 bool Graphics::HasShaderParameter(StringHash param)
 {
-    return shaderProgram_ && shaderProgram_->HasParameter(param);
+    return impl_->shaderProgram_ && impl_->shaderProgram_->HasParameter(param);
 }
 
 bool Graphics::HasTextureUnit(TextureUnit unit)
 {
-    return shaderProgram_ && shaderProgram_->HasTextureUnit(unit);
+    return impl_->shaderProgram_ && impl_->shaderProgram_->HasTextureUnit(unit);
 }
 
 void Graphics::ClearParameterSource(ShaderParameterGroup group)
 {
-    if (shaderProgram_)
-        shaderProgram_->ClearParameterSource(group);
+    if (impl_->shaderProgram_)
+        impl_->shaderProgram_->ClearParameterSource(group);
 }
 
 void Graphics::ClearParameterSources()
@@ -1450,10 +1450,10 @@ void Graphics::ClearParameterSources()
 
 void Graphics::ClearTransformSources()
 {
-    if (shaderProgram_)
+    if (impl_->shaderProgram_)
     {
-        shaderProgram_->ClearParameterSource(SP_CAMERA);
-        shaderProgram_->ClearParameterSource(SP_OBJECT);
+        impl_->shaderProgram_->ClearParameterSource(SP_CAMERA);
+        impl_->shaderProgram_->ClearParameterSource(SP_OBJECT);
     }
 }
 
@@ -1481,18 +1481,18 @@ void Graphics::SetTexture(unsigned index, Texture* texture)
         {
             unsigned glType = texture->GetTarget();
             // Unbind old texture type if necessary
-            if (textureTypes_[index] && textureTypes_[index] != glType)
-                glBindTexture(textureTypes_[index], 0);
+            if (impl_->textureTypes_[index] && impl_->textureTypes_[index] != glType)
+                glBindTexture(impl_->textureTypes_[index], 0);
             glBindTexture(glType, texture->GetGPUObjectName());
-            textureTypes_[index] = glType;
+            impl_->textureTypes_[index] = glType;
 
             if (texture->GetParametersDirty())
                 texture->UpdateParameters();
         }
-        else if (textureTypes_[index])
+        else if (impl_->textureTypes_[index])
         {
-            glBindTexture(textureTypes_[index], 0);
-            textureTypes_[index] = 0;
+            glBindTexture(impl_->textureTypes_[index], 0);
+            impl_->textureTypes_[index] = 0;
         }
 
         textures_[index] = texture;
@@ -1523,10 +1523,10 @@ void Graphics::SetTextureForUpdate(Texture* texture)
 
     unsigned glType = texture->GetTarget();
     // Unbind old texture type if necessary
-    if (textureTypes_[0] && textureTypes_[0] != glType)
-        glBindTexture(textureTypes_[0], 0);
+    if (impl_->textureTypes_[0] && impl_->textureTypes_[0] != glType)
+        glBindTexture(impl_->textureTypes_[0], 0);
     glBindTexture(glType, texture->GetGPUObjectName());
-    textureTypes_[0] = glType;
+    impl_->textureTypes_[0] = glType;
     textures_[0] = texture;
 }
 
@@ -1626,14 +1626,14 @@ void Graphics::SetDepthStencil(RenderSurface* depthStencil)
         if (width <= width_ && height <= height_)
         {
             int searchKey = (width << 16) | height;
-            HashMap<int, SharedPtr<Texture2D> >::Iterator i = depthTextures_.Find(searchKey);
-            if (i != depthTextures_.End())
+            HashMap<int, SharedPtr<Texture2D> >::Iterator i = impl_->depthTextures_.Find(searchKey);
+            if (i != impl_->depthTextures_.End())
                 depthStencil = i->second_->GetRenderSurface();
             else
             {
                 SharedPtr<Texture2D> newDepthTexture(new Texture2D(context_));
                 newDepthTexture->SetSize(width, height, GetDepthStencilFormat(), TEXTURE_DEPTHSTENCIL);
-                depthTextures_[searchKey] = newDepthTexture;
+                impl_->depthTextures_[searchKey] = newDepthTexture;
                 depthStencil = newDepthTexture->GetRenderSurface();
             }
         }
@@ -2110,6 +2110,11 @@ VertexBuffer* Graphics::GetVertexBuffer(unsigned index) const
     return index < MAX_VERTEX_STREAMS ? vertexBuffers_[index] : 0;
 }
 
+ShaderProgram* Graphics::GetShaderProgram() const
+{
+    return impl_->shaderProgram_;
+}
+
 TextureUnit Graphics::GetTextureUnit(const String& name)
 {
     HashMap<String, TextureUnit>::Iterator i = textureUnits_.Find(name);
@@ -2162,7 +2167,7 @@ IntVector2 Graphics::GetRenderTargetDimensions() const
     return IntVector2(width, height);
 }
 
-void Graphics::WindowResized()
+void Graphics::OnWindowResized()
 {
     if (!impl_->window_)
         return;
@@ -2193,7 +2198,7 @@ void Graphics::WindowResized()
     SendEvent(E_SCREENMODE, eventData);
 }
 
-void Graphics::WindowMoved()
+void Graphics::OnWindowMoved()
 {
     if (!impl_->window_ || fullscreen_)
         return;
@@ -2355,25 +2360,25 @@ void Graphics::CleanupRenderSurface(RenderSurface* surface)
 
 void Graphics::CleanupShaderPrograms(ShaderVariation* variation)
 {
-    for (ShaderProgramMap::Iterator i = shaderPrograms_.Begin(); i != shaderPrograms_.End();)
+    for (ShaderProgramMap::Iterator i = impl_->shaderPrograms_.Begin(); i != impl_->shaderPrograms_.End();)
     {
         if (i->second_->GetVertexShader() == variation || i->second_->GetPixelShader() == variation)
-            i = shaderPrograms_.Erase(i);
+            i = impl_->shaderPrograms_.Erase(i);
         else
             ++i;
     }
 
     if (vertexShader_ == variation || pixelShader_ == variation)
-        shaderProgram_ = 0;
+        impl_->shaderProgram_ = 0;
 }
 
 ConstantBuffer* Graphics::GetOrCreateConstantBuffer(unsigned bindingIndex, unsigned size)
 {
     unsigned key = (bindingIndex << 16) | size;
-    HashMap<unsigned, SharedPtr<ConstantBuffer> >::Iterator i = constantBuffers_.Find(key);
-    if (i == constantBuffers_.End())
+    HashMap<unsigned, SharedPtr<ConstantBuffer> >::Iterator i = impl_->allConstantBuffers_.Find(key);
+    if (i == impl_->allConstantBuffers_.End())
     {
-        i = constantBuffers_.Insert(MakePair(key, SharedPtr<ConstantBuffer>(new ConstantBuffer(context_))));
+        i = impl_->allConstantBuffers_.Insert(MakePair(key, SharedPtr<ConstantBuffer>(new ConstantBuffer(context_))));
         i->second_->SetSize(size);
     }
     return i->second_.Get();
@@ -2391,7 +2396,7 @@ void Graphics::Release(bool clearGPUObjects, bool closeWindow)
         {
             // Shutting down: release all GPU objects that still exist
             // Shader programs are also GPU objects; clear them first to avoid list modification during iteration
-            shaderPrograms_.Clear();
+            impl_->shaderPrograms_.Clear();
 
             for (PODVector<GPUObject*>::Iterator i = gpuObjects_.Begin(); i != gpuObjects_.End(); ++i)
                 (*i)->Release();
@@ -2405,14 +2410,14 @@ void Graphics::Release(bool clearGPUObjects, bool closeWindow)
 
             // In this case clear shader programs last so that they do not attempt to delete their OpenGL program
             // from a context that may no longer exist
-            shaderPrograms_.Clear();
+            impl_->shaderPrograms_.Clear();
 
             SendEvent(E_DEVICELOST);
         }
     }
 
     CleanupFramebuffers();
-    depthTextures_.Clear();
+    impl_->depthTextures_.Clear();
 
     // End fullscreen mode first to counteract transition and getting stuck problems on OS X
 #if defined(__APPLE__) && !defined(IOS)
@@ -2884,9 +2889,9 @@ void Graphics::PrepareDraw()
 #ifndef GL_ES_VERSION_2_0
     if (gl3Support)
     {
-        for (PODVector<ConstantBuffer*>::Iterator i = dirtyConstantBuffers_.Begin(); i != dirtyConstantBuffers_.End(); ++i)
+        for (PODVector<ConstantBuffer*>::Iterator i = impl_->dirtyConstantBuffers_.Begin(); i != impl_->dirtyConstantBuffers_.End(); ++i)
             (*i)->Apply();
-        dirtyConstantBuffers_.Clear();
+        impl_->dirtyConstantBuffers_.Clear();
     }
 #endif
 
@@ -3137,7 +3142,7 @@ void Graphics::PrepareDraw()
                     unsigned dataStart = element.offset_;
                     if (element.perInstance_)
                     {
-                        dataStart += lastInstanceOffset_ * buffer->GetVertexSize();
+                        dataStart += impl_->lastInstanceOffset_ * buffer->GetVertexSize();
                         if (!(impl_->instancingVertexAttributes_ & locationMask))
                         {
                             SetVertexAttribDivisor(location, 1);
@@ -3208,7 +3213,7 @@ void Graphics::ResetCachedState()
     for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
     {
         textures_[i] = 0;
-        textureTypes_[i] = 0;
+        impl_->textureTypes_[i] = 0;
     }
 
     for (unsigned i = 0; i < MAX_RENDERTARGETS; ++i)
@@ -3219,7 +3224,6 @@ void Graphics::ResetCachedState()
     indexBuffer_ = 0;
     vertexShader_ = 0;
     pixelShader_ = 0;
-    shaderProgram_ = 0;
     blendMode_ = BLEND_REPLACE;
     textureAnisotropy_ = 1;
     colorWrite_ = true;
@@ -3240,7 +3244,8 @@ void Graphics::ResetCachedState()
     stencilCompareMask_ = M_MAX_UNSIGNED;
     stencilWriteMask_ = M_MAX_UNSIGNED;
     useClipPlane_ = false;
-    lastInstanceOffset_ = 0;
+    impl_->shaderProgram_ = 0;
+    impl_->lastInstanceOffset_ = 0;
     impl_->activeTexture_ = 0;
     impl_->enabledVertexAttributes_ = 0;
     impl_->usedVertexAttributes_ = 0;
@@ -3260,8 +3265,8 @@ void Graphics::ResetCachedState()
     }
 
     for (unsigned i = 0; i < MAX_SHADER_PARAMETER_GROUPS * 2; ++i)
-        currentConstantBuffers_[i] = 0;
-    dirtyConstantBuffers_.Clear();
+        impl_->constantBuffers_[i] = 0;
+    impl_->dirtyConstantBuffers_.Clear();
 }
 
 void Graphics::SetTextureUnitMappings()

+ 9 - 26
Source/Urho3D/Graphics/OpenGL/OGLGraphics.h

@@ -53,8 +53,6 @@ class Vector3;
 class Vector4;
 class VertexBuffer;
 
-typedef HashMap<Pair<ShaderVariation*, ShaderVariation*>, SharedPtr<ShaderProgram> > ShaderProgramMap;
-
 static const unsigned NUM_SCREEN_BUFFERS = 2;
 
 /// CPU-side scratch buffer for vertex data updates.
@@ -360,8 +358,8 @@ public:
     /// Return pixel shader.
     ShaderVariation* GetPixelShader() const { return pixelShader_; }
 
-    /// Return shader program.
-    ShaderProgram* GetShaderProgram() const { return shaderProgram_; }
+    /// Return shader program. This is an API-specific class and should not be used by applications.
+    ShaderProgram* GetShaderProgram() const;
 
     /// Return texture unit index by name.
     TextureUnit GetTextureUnit(const String& name);
@@ -449,9 +447,9 @@ public:
     IntVector2 GetRenderTargetDimensions() const;
 
     /// Window was resized through user interaction. Called by Input subsystem.
-    void WindowResized();
+    void OnWindowResized();
     /// Window was moved through user interaction. Called by Input subsystem.
-    void WindowMoved();
+    void OnWindowMoved();
     /// Add a GPU object to keep track of. Called by GPUObject.
     void AddGPUObject(GPUObject* object);
     /// Remove a GPU object. Called by GPUObject.
@@ -563,8 +561,8 @@ private:
     GraphicsImpl* impl_;
     /// Window title.
     String windowTitle_;
-    /// Window Icon File Name
-    Image* windowIcon_;
+    /// Window icon image.
+    WeakPtr<Image> windowIcon_;
     /// External window, null if not in use (default.)
     void* externalWindow_;
     /// Window width in pixels.
@@ -635,28 +633,19 @@ private:
     ShaderVariation* vertexShader_;
     /// Pixel shader in use.
     ShaderVariation* pixelShader_;
-    /// Shader program in use.
-    ShaderProgram* shaderProgram_;
-    /// Linked shader programs.
-    ShaderProgramMap shaderPrograms_;
     /// Textures in use.
     Texture* textures_[MAX_TEXTURE_UNITS];
-    /// OpenGL texture types in use.
-    unsigned textureTypes_[MAX_TEXTURE_UNITS];
+
     /// Texture unit mappings.
     HashMap<String, TextureUnit> textureUnits_;
-    /// All constant buffers.
-    HashMap<unsigned, SharedPtr<ConstantBuffer> > constantBuffers_;
-    /// Currently bound constant buffers.
-    ConstantBuffer* currentConstantBuffers_[MAX_SHADER_PARAMETER_GROUPS * 2];
-    /// Dirty constant buffers.
-    PODVector<ConstantBuffer*> dirtyConstantBuffers_;
     /// Rendertargets in use.
     RenderSurface* renderTargets_[MAX_RENDERTARGETS];
     /// Depth-stencil surface in use.
     RenderSurface* depthStencil_;
     /// Viewport coordinates.
     IntRect viewport_;
+    /// Default texture filtering mode.
+    TextureFilterMode defaultTextureFilterMode_;
     /// Texture anisotropy level.
     unsigned textureAnisotropy_;
     /// Blending mode.
@@ -699,12 +688,6 @@ private:
     bool stencilTest_;
     /// Custom clip plane enable flag.
     bool useClipPlane_;
-    /// Last used instance data offset.
-    unsigned lastInstanceOffset_;
-    /// Default texture filtering mode.
-    TextureFilterMode defaultTextureFilterMode_;
-    /// Map for additional depth textures, to emulate Direct3D9 ability to mix render texture and backbuffer rendering.
-    HashMap<int, SharedPtr<Texture2D> > depthTextures_;
     /// Base directory for shaders.
     String shaderPath_;
     /// File extension for shaders.

+ 2 - 1
Source/Urho3D/Graphics/OpenGL/OGLGraphicsImpl.cpp

@@ -44,7 +44,8 @@ GraphicsImpl::GraphicsImpl() :
     boundUBO_(0),
     pixelFormat_(0),
     fboDirty_(false),
-    vertexBuffersDirty_(false)
+    vertexBuffersDirty_(false),
+    shaderProgram_(0)
 {
 }
 

+ 22 - 0
Source/Urho3D/Graphics/OpenGL/OGLGraphicsImpl.h

@@ -24,6 +24,9 @@
 
 #include "../../Container/HashMap.h"
 #include "../../Core/Timer.h"
+#include "../../Graphics/ConstantBuffer.h"
+#include "../../Graphics/ShaderProgram.h"
+#include "../../Graphics/Texture2D.h"
 #include "../../Math/Color.h"
 
 #if defined(IOS)
@@ -69,6 +72,9 @@ namespace Urho3D
 
 class Context;
 
+typedef HashMap<unsigned, SharedPtr<ConstantBuffer> > ConstantBufferMap;
+typedef HashMap<Pair<ShaderVariation*, ShaderVariation*>, SharedPtr<ShaderProgram> > ShaderProgramMap;
+
 /// Cached state of a frame buffer object
 struct FrameBufferObject
 {
@@ -135,6 +141,22 @@ private:
     int pixelFormat_;
     /// Map for FBO's per resolution and format.
     HashMap<unsigned long long, FrameBufferObject> frameBuffers_;
+    /// OpenGL texture types in use.
+    unsigned textureTypes_[MAX_TEXTURE_UNITS];
+    /// Constant buffer search map.
+    ConstantBufferMap allConstantBuffers_;
+    /// Currently bound constant buffers.
+    ConstantBuffer* constantBuffers_[MAX_SHADER_PARAMETER_GROUPS * 2];
+    /// Dirty constant buffers.
+    PODVector<ConstantBuffer*> dirtyConstantBuffers_;
+    /// Last used instance data offset.
+    unsigned lastInstanceOffset_;
+    /// Map for additional depth textures, to emulate Direct3D9 ability to mix render texture and backbuffer rendering.
+    HashMap<int, SharedPtr<Texture2D> > depthTextures_;
+    /// Shader program in use.
+    ShaderProgram* shaderProgram_;
+    /// Linked shader programs.
+    ShaderProgramMap shaderPrograms_;
     /// Need FBO commit flag.
     bool fboDirty_;
     /// Need vertex attribute pointer update flag.

+ 2 - 2
Source/Urho3D/Input/Input.cpp

@@ -2292,11 +2292,11 @@ void Input::HandleSDLEvent(void* sdlEvent)
 
             case SDL_WINDOWEVENT_RESIZED:
                 inResize_ = true;
-                graphics_->WindowResized();
+                graphics_->OnWindowResized();
                 inResize_ = false;
                 break;
             case SDL_WINDOWEVENT_MOVED:
-                graphics_->WindowMoved();
+                graphics_->OnWindowMoved();
                 break;
 
             default: break;