Browse Source

Merge branch 'api-agnostic-headers'

Lasse Öörni 9 years ago
parent
commit
2c2c6d26b1
100 changed files with 4600 additions and 11165 deletions
  1. 1 2
      Source/Urho3D/Engine/Application.cpp
  2. 36 29
      Source/Urho3D/Graphics/ConstantBuffer.cpp
  3. 49 5
      Source/Urho3D/Graphics/ConstantBuffer.h
  4. 7 41
      Source/Urho3D/Graphics/Direct3D11/D3D11ConstantBuffer.cpp
  5. 0 71
      Source/Urho3D/Graphics/Direct3D11/D3D11ConstantBuffer.h
  6. 157 341
      Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.cpp
  7. 0 716
      Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.h
  8. 2 2
      Source/Urho3D/Graphics/Direct3D11/D3D11GraphicsImpl.cpp
  9. 47 7
      Source/Urho3D/Graphics/Direct3D11/D3D11GraphicsImpl.h
  10. 17 108
      Source/Urho3D/Graphics/Direct3D11/D3D11IndexBuffer.cpp
  11. 0 114
      Source/Urho3D/Graphics/Direct3D11/D3D11IndexBuffer.h
  12. 5 59
      Source/Urho3D/Graphics/Direct3D11/D3D11RenderSurface.cpp
  13. 0 116
      Source/Urho3D/Graphics/Direct3D11/D3D11RenderSurface.h
  14. 23 34
      Source/Urho3D/Graphics/Direct3D11/D3D11ShaderVariation.cpp
  15. 0 172
      Source/Urho3D/Graphics/Direct3D11/D3D11ShaderVariation.h
  16. 10 256
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture.cpp
  17. 0 191
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture.h
  18. 17 114
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture2D.cpp
  19. 0 82
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture2D.h
  20. 16 160
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture2DArray.cpp
  21. 0 95
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture2DArray.h
  22. 15 133
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture3D.cpp
  23. 0 74
      Source/Urho3D/Graphics/Direct3D11/D3D11Texture3D.h
  24. 17 271
      Source/Urho3D/Graphics/Direct3D11/D3D11TextureCube.cpp
  25. 0 90
      Source/Urho3D/Graphics/Direct3D11/D3D11TextureCube.h
  26. 17 175
      Source/Urho3D/Graphics/Direct3D11/D3D11VertexBuffer.cpp
  27. 0 165
      Source/Urho3D/Graphics/Direct3D11/D3D11VertexBuffer.h
  28. 11 10
      Source/Urho3D/Graphics/Direct3D9/D3D9ConstantBuffer.cpp
  29. 0 76
      Source/Urho3D/Graphics/Direct3D9/D3D9GPUObject.h
  30. 100 336
      Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp
  31. 0 685
      Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.h
  32. 4 2
      Source/Urho3D/Graphics/Direct3D9/D3D9GraphicsImpl.cpp
  33. 22 7
      Source/Urho3D/Graphics/Direct3D9/D3D9GraphicsImpl.h
  34. 20 132
      Source/Urho3D/Graphics/Direct3D9/D3D9IndexBuffer.cpp
  35. 0 120
      Source/Urho3D/Graphics/Direct3D9/D3D9IndexBuffer.h
  36. 5 59
      Source/Urho3D/Graphics/Direct3D9/D3D9RenderSurface.cpp
  37. 0 110
      Source/Urho3D/Graphics/Direct3D9/D3D9RenderSurface.h
  38. 65 69
      Source/Urho3D/Graphics/Direct3D9/D3D9ShaderVariation.cpp
  39. 0 140
      Source/Urho3D/Graphics/Direct3D9/D3D9ShaderVariation.h
  40. 4 217
      Source/Urho3D/Graphics/Direct3D9/D3D9Texture.cpp
  41. 0 160
      Source/Urho3D/Graphics/Direct3D9/D3D9Texture.h
  42. 36 142
      Source/Urho3D/Graphics/Direct3D9/D3D9Texture2D.cpp
  43. 0 86
      Source/Urho3D/Graphics/Direct3D9/D3D9Texture2D.h
  44. 6 160
      Source/Urho3D/Graphics/Direct3D9/D3D9Texture2DArray.cpp
  45. 0 99
      Source/Urho3D/Graphics/Direct3D9/D3D9Texture2DArray.h
  46. 18 156
      Source/Urho3D/Graphics/Direct3D9/D3D9Texture3D.cpp
  47. 0 78
      Source/Urho3D/Graphics/Direct3D9/D3D9Texture3D.h
  48. 35 297
      Source/Urho3D/Graphics/Direct3D9/D3D9TextureCube.cpp
  49. 0 94
      Source/Urho3D/Graphics/Direct3D9/D3D9TextureCube.h
  50. 21 199
      Source/Urho3D/Graphics/Direct3D9/D3D9VertexBuffer.cpp
  51. 0 171
      Source/Urho3D/Graphics/Direct3D9/D3D9VertexBuffer.h
  52. 80 64
      Source/Urho3D/Graphics/GPUObject.cpp
  53. 59 7
      Source/Urho3D/Graphics/GPUObject.h
  54. 310 0
      Source/Urho3D/Graphics/Graphics.cpp
  55. 728 7
      Source/Urho3D/Graphics/Graphics.h
  56. 3 0
      Source/Urho3D/Graphics/GraphicsImpl.h
  57. 137 0
      Source/Urho3D/Graphics/IndexBuffer.cpp
  58. 94 7
      Source/Urho3D/Graphics/IndexBuffer.h
  59. 8 48
      Source/Urho3D/Graphics/OpenGL/OGLConstantBuffer.cpp
  60. 0 73
      Source/Urho3D/Graphics/OpenGL/OGLConstantBuffer.h
  61. 0 76
      Source/Urho3D/Graphics/OpenGL/OGLGPUObject.h
  62. 153 325
      Source/Urho3D/Graphics/OpenGL/OGLGraphics.cpp
  63. 0 732
      Source/Urho3D/Graphics/OpenGL/OGLGraphics.h
  64. 2 2
      Source/Urho3D/Graphics/OpenGL/OGLGraphicsImpl.cpp
  65. 22 5
      Source/Urho3D/Graphics/OpenGL/OGLGraphicsImpl.h
  66. 23 108
      Source/Urho3D/Graphics/OpenGL/OGLIndexBuffer.cpp
  67. 0 112
      Source/Urho3D/Graphics/OpenGL/OGLIndexBuffer.h
  68. 0 70
      Source/Urho3D/Graphics/OpenGL/OGLRenderSurface.cpp
  69. 0 124
      Source/Urho3D/Graphics/OpenGL/OGLRenderSurface.h
  70. 46 52
      Source/Urho3D/Graphics/OpenGL/OGLShaderProgram.cpp
  71. 1 18
      Source/Urho3D/Graphics/OpenGL/OGLShaderProgram.h
  72. 24 33
      Source/Urho3D/Graphics/OpenGL/OGLShaderVariation.cpp
  73. 0 88
      Source/Urho3D/Graphics/OpenGL/OGLShaderVariation.h
  74. 4 223
      Source/Urho3D/Graphics/OpenGL/OGLTexture.cpp
  75. 0 183
      Source/Urho3D/Graphics/OpenGL/OGLTexture.h
  76. 10 135
      Source/Urho3D/Graphics/OpenGL/OGLTexture2D.cpp
  77. 0 88
      Source/Urho3D/Graphics/OpenGL/OGLTexture2D.h
  78. 11 185
      Source/Urho3D/Graphics/OpenGL/OGLTexture2DArray.cpp
  79. 0 97
      Source/Urho3D/Graphics/OpenGL/OGLTexture2DArray.h
  80. 10 160
      Source/Urho3D/Graphics/OpenGL/OGLTexture3D.cpp
  81. 0 78
      Source/Urho3D/Graphics/OpenGL/OGLTexture3D.h
  82. 11 296
      Source/Urho3D/Graphics/OpenGL/OGLTextureCube.cpp
  83. 0 92
      Source/Urho3D/Graphics/OpenGL/OGLTextureCube.h
  84. 26 178
      Source/Urho3D/Graphics/OpenGL/OGLVertexBuffer.cpp
  85. 0 163
      Source/Urho3D/Graphics/OpenGL/OGLVertexBuffer.h
  86. 102 0
      Source/Urho3D/Graphics/RenderSurface.cpp
  87. 123 7
      Source/Urho3D/Graphics/RenderSurface.h
  88. 2 0
      Source/Urho3D/Graphics/ShaderProgram.h
  89. 61 59
      Source/Urho3D/Graphics/ShaderVariation.cpp
  90. 152 7
      Source/Urho3D/Graphics/ShaderVariation.h
  91. 293 0
      Source/Urho3D/Graphics/Texture.cpp
  92. 183 7
      Source/Urho3D/Graphics/Texture.h
  93. 159 0
      Source/Urho3D/Graphics/Texture2D.cpp
  94. 64 7
      Source/Urho3D/Graphics/Texture2D.h
  95. 212 0
      Source/Urho3D/Graphics/Texture2DArray.cpp
  96. 73 7
      Source/Urho3D/Graphics/Texture2DArray.h
  97. 184 0
      Source/Urho3D/Graphics/Texture3D.cpp
  98. 54 7
      Source/Urho3D/Graphics/Texture3D.h
  99. 325 0
      Source/Urho3D/Graphics/TextureCube.cpp
  100. 68 7
      Source/Urho3D/Graphics/TextureCube.h

+ 1 - 2
Source/Urho3D/Engine/Application.cpp

@@ -28,7 +28,6 @@
 
 #ifdef IOS
 #include "../Graphics/Graphics.h"
-#include "../Graphics/GraphicsImpl.h"
 #include <SDL/SDL.h>
 #endif
 
@@ -92,7 +91,7 @@ int Application::Run()
         // support calling the Stop() function, as the application will never stop manually
 #else
 #if defined(IOS)
-        SDL_iPhoneSetAnimationCallback(GetSubsystem<Graphics>()->GetImpl()->GetWindow(), 1, &RunFrame, engine_);
+        SDL_iPhoneSetAnimationCallback(GetSubsystem<Graphics>()->GetWindow(), 1, &RunFrame, engine_);
 #elif defined(__EMSCRIPTEN__)
         emscripten_set_main_loop_arg(RunFrame, engine_, 0, 1);
 #endif

+ 36 - 29
Source/Urho3D/Graphics/Direct3D11/D3D11GPUObject.h → Source/Urho3D/Graphics/ConstantBuffer.cpp

@@ -20,47 +20,54 @@
 // THE SOFTWARE.
 //
 
-#pragma once
+#include "../Precompiled.h"
 
-#include "../../Container/Ptr.h"
+#include "../Graphics/Graphics.h"
+#include "../Graphics/ConstantBuffer.h"
+#include "../IO/Log.h"
+
+#include "../DebugNew.h"
 
 namespace Urho3D
 {
 
-class Graphics;
-
-/// Base class for GPU resources.
-class URHO3D_API GPUObject
+ConstantBuffer::ConstantBuffer(Context* context) :
+    Object(context),
+    GPUObject(GetSubsystem<Graphics>())
 {
-public:
-    /// Construct with graphics subsystem pointer.
-    GPUObject(Graphics* graphics);
-    /// Destruct. Remove from the graphics subsystem.
-    virtual ~GPUObject();
+}
 
-    /// Unconditionally release the GPU resource.
-    virtual void Release() { }
+ConstantBuffer::~ConstantBuffer()
+{
+    Release();
+}
 
-    /// Clear the data lost flag. No-op on D3D11.
-    void ClearDataLost() { }
+void ConstantBuffer::SetParameter(unsigned offset, unsigned size, const void* data)
+{
+    if (offset + size > size_)
+        return; // Would overflow the buffer
 
-    /// Return the graphics subsystem.
-    Graphics* GetGraphics() const;
+    memcpy(&shadowData_[offset], data, size);
+    dirty_ = true;
+}
 
-    /// Return Direct3D object.
-    void* GetGPUObject() const { return object_; }
+void ConstantBuffer::SetVector3ArrayParameter(unsigned offset, unsigned rows, const void* data)
+{
+    if (offset + rows * 4 * sizeof(float) > size_)
+        return; // Would overflow the buffer
 
-    /// Return whether data is lost due to device loss. Always false on D3D11.
-    bool IsDataLost() const { return false; }
+    float* dest = (float*)&shadowData_[offset];
+    const float* src = (const float*)data;
 
-    /// Return whether has pending data assigned while device was lost. Always false on D3D11.
-    bool HasPendingData() const { return false; }
+    while (rows--)
+    {
+        *dest++ = *src++;
+        *dest++ = *src++;
+        *dest++ = *src++;
+        ++dest; // Skip over the w coordinate
+    }
 
-protected:
-    /// Graphics subsystem.
-    WeakPtr<Graphics> graphics_;
-    /// Direct3D object.
-    void* object_;
-};
+    dirty_ = true;
+}
 
 }

+ 49 - 5
Source/Urho3D/Graphics/ConstantBuffer.h

@@ -22,8 +22,52 @@
 
 #pragma once
 
-#if defined(URHO3D_OPENGL)
-#include "OpenGL/OGLConstantBuffer.h"
-#elif defined(URHO3D_D3D11)
-#include "Direct3D11/D3D11ConstantBuffer.h"
-#endif
+#include "../Container/ArrayPtr.h"
+#include "../Core/Object.h"
+#include "../Graphics/GPUObject.h"
+#include "../Graphics/GraphicsDefs.h"
+
+namespace Urho3D
+{
+
+/// Hardware constant buffer.
+class URHO3D_API ConstantBuffer : public Object, public GPUObject
+{
+    URHO3D_OBJECT(ConstantBuffer, Object);
+
+public:
+    /// Construct.
+    ConstantBuffer(Context* context);
+    /// Destruct.
+    virtual ~ConstantBuffer();
+
+    /// Recreate the GPU resource and restore data if applicable.
+    virtual void OnDeviceReset();
+    /// Release the buffer.
+    virtual void Release();
+
+    /// Set size and create GPU-side buffer. Return true on success.
+    bool SetSize(unsigned size);
+    /// Set a generic parameter and mark buffer dirty.
+    void SetParameter(unsigned offset, unsigned size, const void* data);
+    /// Set a Vector3 array parameter and mark buffer dirty.
+    void SetVector3ArrayParameter(unsigned offset, unsigned rows, const void* data);
+    /// Apply to GPU.
+    void Apply();
+
+    /// Return size.
+    unsigned GetSize() const { return size_; }
+
+    /// Return whether has unapplied data.
+    bool IsDirty() const { return dirty_; }
+
+private:
+    /// Shadow data.
+    SharedArrayPtr<unsigned char> shadowData_;
+    /// Buffer byte size.
+    unsigned size_;
+    /// Dirty flag.
+    bool dirty_;
+};
+
+}

+ 7 - 41
Source/Urho3D/Graphics/Direct3D11/D3D11ConstantBuffer.cpp

@@ -32,20 +32,14 @@
 namespace Urho3D
 {
 
-ConstantBuffer::ConstantBuffer(Context* context) :
-    Object(context),
-    GPUObject(GetSubsystem<Graphics>())
+void ConstantBuffer::OnDeviceReset()
 {
-}
-
-ConstantBuffer::~ConstantBuffer()
-{
-    Release();
+    // No-op on Direct3D11
 }
 
 void ConstantBuffer::Release()
 {
-    URHO3D_SAFE_RELEASE(object_);
+    URHO3D_SAFE_RELEASE(object_.ptr_);
 
     shadowData_.Reset();
     size_ = 0;
@@ -80,10 +74,10 @@ bool ConstantBuffer::SetSize(unsigned size)
         bufferDesc.CPUAccessFlags = 0;
         bufferDesc.Usage = D3D11_USAGE_DEFAULT;
 
-        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_);
+        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_.ptr_);
         if (FAILED(hr))
         {
-            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_SAFE_RELEASE(object_.ptr_);
             URHO3D_LOGD3DERROR("Failed to create constant buffer", hr);
             return false;
         }
@@ -92,39 +86,11 @@ bool ConstantBuffer::SetSize(unsigned size)
     return true;
 }
 
-void ConstantBuffer::SetParameter(unsigned offset, unsigned size, const void* data)
-{
-    if (offset + size > size_)
-        return; // Would overflow the buffer
-
-    memcpy(&shadowData_[offset], data, size);
-    dirty_ = true;
-}
-
-void ConstantBuffer::SetVector3ArrayParameter(unsigned offset, unsigned rows, const void* data)
-{
-    if (offset + rows * 4 * sizeof(float) > size_)
-        return; // Would overflow the buffer
-
-    float* dest = (float*)&shadowData_[offset];
-    const float* src = (const float*)data;
-
-    while (rows--)
-    {
-        *dest++ = *src++;
-        *dest++ = *src++;
-        *dest++ = *src++;
-        ++dest; // Skip over the w coordinate
-    }
-
-    dirty_ = true;
-}
-
 void ConstantBuffer::Apply()
 {
-    if (dirty_ && object_)
+    if (dirty_ && object_.ptr_)
     {
-        graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Buffer*)object_, 0, 0, shadowData_.Get(), 0, 0);
+        graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Buffer*)object_.ptr_, 0, 0, shadowData_.Get(), 0, 0);
         dirty_ = false;
     }
 }

+ 0 - 71
Source/Urho3D/Graphics/Direct3D11/D3D11ConstantBuffer.h

@@ -1,71 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/ArrayPtr.h"
-#include "../../Core/Object.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-
-namespace Urho3D
-{
-
-/// Hardware constant buffer.
-class URHO3D_API ConstantBuffer : public Object, public GPUObject
-{
-    URHO3D_OBJECT(ConstantBuffer, Object);
-
-public:
-    /// Construct.
-    ConstantBuffer(Context* context);
-    /// Destruct.
-    virtual ~ConstantBuffer();
-
-    /// Release buffer.
-    virtual void Release();
-
-    /// Set size and create GPU-side buffer. Return true on success.
-    bool SetSize(unsigned size);
-    /// Set a generic parameter and mark buffer dirty.
-    void SetParameter(unsigned offset, unsigned size, const void* data);
-    /// Set a Vector3 array parameter and mark buffer dirty.
-    void SetVector3ArrayParameter(unsigned offset, unsigned rows, const void* data);
-    /// Apply to GPU.
-    void Apply();
-
-    /// Return size.
-    unsigned GetSize() const { return size_; }
-
-    /// Return whether has unapplied data.
-    bool IsDirty() const { return dirty_; }
-
-private:
-    /// Shadow data.
-    SharedArrayPtr<unsigned char> shadowData_;
-    /// Buffer byte size.
-    unsigned size_;
-    /// Dirty flag.
-    bool dirty_;
-};
-
-}

File diff suppressed because it is too large
+ 157 - 341
Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.cpp


+ 0 - 716
Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.h

@@ -1,716 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/ArrayPtr.h"
-#include "../../Container/HashSet.h"
-#include "../../Core/Mutex.h"
-#include "../../Core/Object.h"
-#include "../../Graphics/GraphicsDefs.h"
-#include "../../Graphics/ShaderVariation.h"
-#include "../../Math/Color.h"
-#include "../../Math/Plane.h"
-#include "../../Math/Rect.h"
-#include "../../Resource/Image.h"
-
-namespace Urho3D
-{
-
-class ConstantBuffer;
-class File;
-class Image;
-class IndexBuffer;
-class GPUObject;
-class GraphicsImpl;
-class RenderSurface;
-class Shader;
-class ShaderPrecache;
-class ShaderProgram;
-class ShaderVariation;
-class Texture;
-class Texture2D;
-class Texture2DArray;
-class TextureCube;
-class Vector3;
-class Vector4;
-class VertexBuffer;
-class VertexDeclaration;
-
-struct ShaderParameter;
-
-/// CPU-side scratch buffer for vertex data updates.
-struct ScratchBuffer
-{
-    ScratchBuffer() :
-        size_(0),
-        reserved_(false)
-    {
-    }
-
-    /// Buffer data.
-    SharedArrayPtr<unsigned char> data_;
-    /// Data size.
-    unsigned size_;
-    /// Reserved flag.
-    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
-{
-    URHO3D_OBJECT(Graphics, Object);
-
-public:
-    /// Construct.
-    Graphics(Context* context);
-    /// Destruct. Release the Direct3D11 device and close the window.
-    virtual ~Graphics();
-
-    /// Set external window handle. Only effective before setting the initial screen mode.
-    void SetExternalWindow(void* window);
-    /// Set window title.
-    void SetWindowTitle(const String& windowTitle);
-    /// Set window icon.
-    void SetWindowIcon(Image* windowIcon);
-    /// Set window position. Sets initial position if window is not created yet.
-    void SetWindowPosition(const IntVector2& position);
-    /// Set window position. Sets initial position if window is not created yet.
-    void SetWindowPosition(int x, int y);
-    /// Set screen mode. Return true if successful.
-    bool SetMode
-        (int width, int height, bool fullscreen, bool borderless, bool resizable, bool highDPI, bool vsync, bool tripleBuffer,
-            int multiSample);
-    /// Set screen resolution only. Return true if successful.
-    bool SetMode(int width, int height);
-    /// Set whether the main window uses sRGB conversion on write.
-    void SetSRGB(bool enable);
-    /// Set whether to flush the GPU command buffer to prevent multiple frames being queued and uneven frame timesteps. Default off, may decrease performance if enabled.
-    void SetFlushGPU(bool enable);
-    /// Set allowed screen orientations as a space-separated list of "LandscapeLeft", "LandscapeRight", "Portrait" and "PortraitUpsideDown". Affects currently only iOS platform.
-    void SetOrientations(const String& orientations);
-    /// Toggle between full screen and windowed mode. Return true if successful.
-    bool ToggleFullscreen();
-    /// Close the window.
-    void Close();
-    /// Take a screenshot. Return true if successful.
-    bool TakeScreenShot(Image& destImage);
-    /// Begin frame rendering. Return true if device available and can render.
-    bool BeginFrame();
-    /// End frame rendering and swap buffers.
-    void EndFrame();
-    /// Clear any or all of rendertarget, depth buffer and stencil buffer.
-    void Clear(unsigned flags, const Color& color = Color(0.0f, 0.0f, 0.0f, 0.0f), float depth = 1.0f, unsigned stencil = 0);
-    /// Resolve multisampled backbuffer to a texture rendertarget. The texture's size should match the viewport size.
-    bool ResolveToTexture(Texture2D* destination, const IntRect& viewport);
-    /// Draw non-indexed geometry.
-    void Draw(PrimitiveType type, unsigned vertexStart, unsigned vertexCount);
-    /// Draw indexed geometry.
-    void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount);
-    /// Draw indexed geometry with vertex index offset.
-    void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex, unsigned vertexCount);
-    /// Draw indexed, instanced geometry. An instancing vertex buffer must be set.
-    void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount,
-        unsigned instanceCount);
-    /// Draw indexed, instanced geometry with vertex index offset.
-    void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex,
-        unsigned vertexCount, unsigned instanceCount);
-    /// Set vertex buffer.
-    void SetVertexBuffer(VertexBuffer* buffer);
-    /// Set multiple vertex buffers.
-    bool SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, unsigned instanceOffset = 0);
-    /// Set multiple vertex buffers.
-    bool SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, unsigned instanceOffset = 0);
-    /// Set index buffer.
-    void SetIndexBuffer(IndexBuffer* buffer);
-    /// Set shaders.
-    void SetShaders(ShaderVariation* vs, ShaderVariation* ps);
-    /// Set shader float constants.
-    void SetShaderParameter(StringHash param, const float* data, unsigned count);
-    /// Set shader float constant.
-    void SetShaderParameter(StringHash param, float value);
-    /// Set shader boolean constant.
-    void SetShaderParameter(StringHash param, bool value);
-    /// Set shader color constant.
-    void SetShaderParameter(StringHash param, const Color& color);
-    /// Set shader 2D vector constant.
-    void SetShaderParameter(StringHash param, const Vector2& vector);
-    /// Set shader 3x3 matrix constant.
-    void SetShaderParameter(StringHash param, const Matrix3& matrix);
-    /// Set shader 3D vector constant.
-    void SetShaderParameter(StringHash param, const Vector3& vector);
-    /// Set shader 4x4 matrix constant.
-    void SetShaderParameter(StringHash param, const Matrix4& matrix);
-    /// Set shader 4D vector constant.
-    void SetShaderParameter(StringHash param, const Vector4& vector);
-    /// Set shader 3x4 matrix constant.
-    void SetShaderParameter(StringHash param, const Matrix3x4& matrix);
-    /// Set shader constant from a variant. Supported variant types: bool, float, vector2, vector3, vector4, color.
-    void SetShaderParameter(StringHash param, const Variant& value);
-    /// Check whether a shader parameter group needs update. Does not actually check whether parameters exist in the shaders.
-    bool NeedParameterUpdate(ShaderParameterGroup group, const void* source);
-    /// Check whether a shader parameter exists on the currently set shaders.
-    bool HasShaderParameter(StringHash param);
-    /// Check whether the current vertex or pixel shader uses a texture unit.
-    bool HasTextureUnit(TextureUnit unit);
-    /// Clear remembered shader parameter source group.
-    void ClearParameterSource(ShaderParameterGroup group);
-    /// Clear remembered shader parameter sources.
-    void ClearParameterSources();
-    /// Clear remembered transform shader parameter sources.
-    void ClearTransformSources();
-    /// Set texture.
-    void SetTexture(unsigned index, Texture* texture);
-    /// Set default texture filtering mode.
-    void SetDefaultTextureFilterMode(TextureFilterMode mode);
-    /// Set texture anisotropy.
-    void SetTextureAnisotropy(unsigned level);
-    /// Dirty texture parameters of all textures (when global settings change.)
-    void SetTextureParametersDirty();
-    /// Reset all rendertargets, depth-stencil surface and viewport.
-    void ResetRenderTargets();
-    /// Reset specific rendertarget.
-    void ResetRenderTarget(unsigned index);
-    /// Reset depth-stencil surface.
-    void ResetDepthStencil();
-    /// Set rendertarget.
-    void SetRenderTarget(unsigned index, RenderSurface* renderTarget);
-    /// Set rendertarget.
-    void SetRenderTarget(unsigned index, Texture2D* texture);
-    /// Set depth-stencil surface.
-    void SetDepthStencil(RenderSurface* depthStencil);
-    /// Set depth-stencil surface.
-    void SetDepthStencil(Texture2D* texture);
-    /// Set viewport.
-    void SetViewport(const IntRect& rect);
-    /// Set blending mode.
-    void SetBlendMode(BlendMode mode);
-    /// Set color write on/off.
-    void SetColorWrite(bool enable);
-    /// Set hardware culling mode.
-    void SetCullMode(CullMode mode);
-    /// Set depth bias.
-    void SetDepthBias(float constantBias, float slopeScaledBias);
-    /// Set depth compare.
-    void SetDepthTest(CompareMode mode);
-    /// Set depth write on/off.
-    void SetDepthWrite(bool enable);
-    /// Set polygon fill mode.
-    void SetFillMode(FillMode mode);
-    /// Set scissor test.
-    void SetScissorTest(bool enable, const Rect& rect = Rect::FULL, bool borderInclusive = true);
-    /// Set scissor test.
-    void SetScissorTest(bool enable, const IntRect& rect);
-    /// Set stencil test.
-    void SetStencilTest
-        (bool enable, CompareMode mode = CMP_ALWAYS, StencilOp pass = OP_KEEP, StencilOp fail = OP_KEEP, StencilOp zFail = OP_KEEP,
-            unsigned stencilRef = 0, unsigned compareMask = M_MAX_UNSIGNED, unsigned writeMask = M_MAX_UNSIGNED);
-    /// Set a custom clipping plane. The plane is specified in world space, but is dependent on the view and projection matrices.
-    void SetClipPlane(bool enable, const Plane& clipPlane = Plane::UP, const Matrix3x4& view = Matrix3x4::IDENTITY,
-        const Matrix4& projection = Matrix4::IDENTITY);
-    /// Begin dumping shader variation names to an XML file for precaching.
-    void BeginDumpShaders(const String& fileName);
-    /// End dumping shader variations names.
-    void EndDumpShaders();
-    /// Precache shader variations from an XML file generated with BeginDumpShaders().
-    void PrecacheShaders(Deserializer& source);
-
-    /// Return whether rendering initialized.
-    bool IsInitialized() const;
-
-    /// Return graphics implementation, which holds the actual API-specific resources.
-    GraphicsImpl* GetImpl() const { return impl_; }
-
-    /// Return OS-specific external window handle. Null if not in use.
-    void* GetExternalWindow() const { return externalWindow_; }
-
-    /// Return window title.
-    const String& GetWindowTitle() const { return windowTitle_; }
-
-    /// Return graphics API name.
-    const String& GetApiName() const { return apiName_; }
-
-    /// Return window position.
-    IntVector2 GetWindowPosition() const;
-
-    /// Return window width in pixels.
-    int GetWidth() const { return width_; }
-
-    /// Return window height in pixels.
-    int GetHeight() const { return height_; }
-
-    /// Return multisample mode (1 = no multisampling.)
-    int GetMultiSample() const { return multiSample_; }
-
-    /// Return whether window is fullscreen.
-    bool GetFullscreen() const { return fullscreen_; }
-
-    /// Return whether window is borderless.
-    bool GetBorderless() const { return borderless_; }
-
-    /// Return whether window is resizable.
-    bool GetResizable() const { return resizable_; }
-
-    /// Return whether window is high DPI.
-    bool GetHighDPI() const { return highDPI_; }
-
-    /// Return whether vertical sync is on.
-    bool GetVSync() const { return vsync_; }
-
-    /// Return whether triple buffering is enabled.
-    bool GetTripleBuffer() const { return tripleBuffer_; }
-
-    /// Return whether the main window is using sRGB conversion on write.
-    bool GetSRGB() const { return sRGB_; }
-
-    /// Return whether the GPU command buffer is flushed each frame.
-    bool GetFlushGPU() const { return flushGPU_; }
-
-    /// Return allowed screen orientations.
-    const String& GetOrientations() const { return orientations_; }
-
-    /// Return whether Direct3D device is lost, and can not yet render. Always false on D3D11.
-    bool IsDeviceLost() const { return false; }
-
-    /// Return number of primitives drawn this frame.
-    unsigned GetNumPrimitives() const { return numPrimitives_; }
-
-    /// Return number of batches drawn this frame.
-    unsigned GetNumBatches() const { return numBatches_; }
-
-    /// Return dummy color texture format for shadow maps. Is "NULL" (consume no video memory) if supported.
-    unsigned GetDummyColorFormat() const { return dummyColorFormat_; }
-
-    /// Return shadow map depth texture format, or 0 if not supported.
-    unsigned GetShadowMapFormat() const { return shadowMapFormat_; }
-
-    /// Return 24-bit shadow map depth texture format, or 0 if not supported.
-    unsigned GetHiresShadowMapFormat() const { return hiresShadowMapFormat_; }
-
-    /// Return whether hardware instancing is supported..
-    bool GetInstancingSupport() const { return instancingSupport_; }
-
-    /// Return whether light pre-pass rendering is supported.
-    bool GetLightPrepassSupport() const { return lightPrepassSupport_; }
-
-    /// Return whether deferred rendering is supported.
-    bool GetDeferredSupport() const { return deferredSupport_; }
-
-    /// Return whether shadow map depth compare is done in hardware.
-    bool GetHardwareShadowSupport() const { return hardwareShadowSupport_; }
-
-    /// Return whether a readable hardware depth format is available.
-    bool GetReadableDepthSupport() const { return GetReadableDepthFormat() != 0; }
-
-    /// Return whether sRGB conversion on texture sampling is supported.
-    bool GetSRGBSupport() const { return sRGBSupport_; }
-
-    /// Return whether sRGB conversion on rendertarget writing is supported.
-    bool GetSRGBWriteSupport() const { return sRGBWriteSupport_; }
-
-    /// Return supported fullscreen resolutions. Will be empty if listing the resolutions is not supported on the platform (e.g. Web).
-    PODVector<IntVector2> GetResolutions() const;
-    /// Return supported multisampling levels.
-    PODVector<int> GetMultiSampleLevels() const;
-    /// Return the desktop resolution.
-    IntVector2 GetDesktopResolution() const;
-    /// Return hardware format for a compressed image format, or 0 if unsupported.
-    unsigned GetFormat(CompressedFormat format) const;
-    /// Return a shader variation by name and defines.
-    ShaderVariation* GetShader(ShaderType type, const String& name, const String& defines = String::EMPTY) const;
-    /// Return a shader variation by name and defines.
-    ShaderVariation* GetShader(ShaderType type, const char* name, const char* defines) const;
-    /// Return current vertex buffer by index.
-    VertexBuffer* GetVertexBuffer(unsigned index) const;
-
-    /// Return current index buffer.
-    IndexBuffer* GetIndexBuffer() const { return indexBuffer_; }
-
-    /// Return current vertex shader.
-    ShaderVariation* GetVertexShader() const { return vertexShader_; }
-
-    /// Return current pixel shader.
-    ShaderVariation* GetPixelShader() const { return pixelShader_; }
-
-    /// Return texture unit index by name.
-    TextureUnit GetTextureUnit(const String& name);
-    /// Return texture unit name by index.
-    const String& GetTextureUnitName(TextureUnit unit);
-    /// Return current texture by texture unit index.
-    Texture* GetTexture(unsigned index) const;
-
-    /// Return default texture filtering mode.
-    TextureFilterMode GetDefaultTextureFilterMode() const { return defaultTextureFilterMode_; }
-
-    /// Return current rendertarget by index.
-    RenderSurface* GetRenderTarget(unsigned index) const;
-
-    /// Return current depth-stencil surface.
-    RenderSurface* GetDepthStencil() const { return depthStencil_; }
-
-    /// Return the viewport coordinates.
-    IntRect GetViewport() const { return viewport_; }
-
-    /// Return texture anisotropy.
-    unsigned GetTextureAnisotropy() const { return textureAnisotropy_; }
-
-    /// Return blending mode.
-    BlendMode GetBlendMode() const { return blendMode_; }
-
-    /// Return whether color write is enabled.
-    bool GetColorWrite() const { return colorWrite_; }
-
-    /// Return hardware culling mode.
-    CullMode GetCullMode() const { return cullMode_; }
-
-    /// Return depth constant bias.
-    float GetDepthConstantBias() const { return constantDepthBias_; }
-
-    /// Return depth slope scaled bias.
-    float GetDepthSlopeScaledBias() const { return slopeScaledDepthBias_; }
-
-    /// Return depth compare mode.
-    CompareMode GetDepthTest() const { return depthTestMode_; }
-
-    /// Return whether depth write is enabled.
-    bool GetDepthWrite() const { return depthWrite_; }
-
-    /// Return polygon fill mode.
-    FillMode GetFillMode() const { return fillMode_; }
-
-    /// Return whether stencil test is enabled.
-    bool GetStencilTest() const { return stencilTest_; }
-
-    /// Return whether scissor test is enabled.
-    bool GetScissorTest() const { return scissorTest_; }
-
-    /// Return scissor rectangle coordinates.
-    const IntRect& GetScissorRect() const { return scissorRect_; }
-
-    /// Return stencil compare mode.
-    CompareMode GetStencilTestMode() const { return stencilTestMode_; }
-
-    /// Return stencil operation to do if stencil test passes.
-    StencilOp GetStencilPass() const { return stencilPass_; }
-
-    /// Return stencil operation to do if stencil test fails.
-    StencilOp GetStencilFail() const { return stencilFail_; }
-
-    /// Return stencil operation to do if depth compare fails.
-    StencilOp GetStencilZFail() const { return stencilZFail_; }
-
-    /// Return stencil reference value.
-    unsigned GetStencilRef() const { return stencilRef_; }
-
-    /// Return stencil compare bitmask.
-    unsigned GetStencilCompareMask() const { return stencilCompareMask_; }
-
-    /// Return stencil write bitmask.
-    unsigned GetStencilWriteMask() const { return stencilWriteMask_; }
-
-    /// Return whether a custom clipping plane is in use.
-    bool GetUseClipPlane() const { return useClipPlane_; }
-
-    /// Return rendertarget width and height.
-    IntVector2 GetRenderTargetDimensions() const;
-
-    /// Window was resized through user interaction. Called by Input subsystem.
-    void WindowResized();
-    /// Window was moved through user interaction. Called by Input subsystem.
-    void WindowMoved();
-    /// Maximize the Window.
-    void Maximize();
-    /// Minimize the Window.
-    void Minimize();
-    /// Add a GPU object to keep track of. Called by GPUObject.
-    void AddGPUObject(GPUObject* object);
-    /// Remove a GPU object. Called by GPUObject.
-    void RemoveGPUObject(GPUObject* object);
-    /// Reserve a CPU-side scratch buffer.
-    void* ReserveScratchBuffer(unsigned size);
-    /// Free a CPU-side scratch buffer.
-    void FreeScratchBuffer(void* buffer);
-    /// Clean up too large scratch buffers.
-    void CleanupScratchBuffers();
-    /// Clean up shader parameters when a shader variation is released or destroyed.
-    void CleanUpShaderPrograms(ShaderVariation* variation);
-    /// Get or create a constant buffer. Will be shared between shaders if possible.
-    ConstantBuffer* GetOrCreateConstantBuffer(ShaderType type, unsigned index, unsigned size);
-
-    /// Return the API-specific alpha texture format.
-    static unsigned GetAlphaFormat();
-    /// Return the API-specific luminance texture format.
-    static unsigned GetLuminanceFormat();
-    /// Return the API-specific luminance alpha texture format.
-    static unsigned GetLuminanceAlphaFormat();
-    /// Return the API-specific RGB texture format.
-    static unsigned GetRGBFormat();
-    /// Return the API-specific RGBA texture format.
-    static unsigned GetRGBAFormat();
-    /// Return the API-specific RGBA 16-bit texture format.
-    static unsigned GetRGBA16Format();
-    /// Return the API-specific RGBA 16-bit float texture format.
-    static unsigned GetRGBAFloat16Format();
-    /// Return the API-specific RGBA 32-bit float texture format.
-    static unsigned GetRGBAFloat32Format();
-    /// Return the API-specific RG 16-bit texture format.
-    static unsigned GetRG16Format();
-    /// Return the API-specific RG 16-bit float texture format.
-    static unsigned GetRGFloat16Format();
-    /// Return the API-specific RG 32-bit float texture format.
-    static unsigned GetRGFloat32Format();
-    /// Return the API-specific single channel 16-bit float texture format.
-    static unsigned GetFloat16Format();
-    /// Return the API-specific single channel 32-bit float texture format.
-    static unsigned GetFloat32Format();
-    /// Return the API-specific linear depth texture format.
-    static unsigned GetLinearDepthFormat();
-    /// Return the API-specific hardware depth-stencil texture format.
-    static unsigned GetDepthStencilFormat();
-    /// Return the API-specific readable hardware depth format, or 0 if not supported.
-    static unsigned GetReadableDepthFormat();
-    /// Return the API-specific texture format from a textual description, for example "rgb".
-    static unsigned GetFormat(const String& formatName);
-
-    /// Return UV offset required for pixel perfect rendering.
-    static const Vector2& GetPixelUVOffset() { return pixelUVOffset; }
-
-    /// Return maximum number of supported bones for skinning.
-    static unsigned GetMaxBones() { return 128; }
-
-private:
-    /// Create the application window.
-    bool OpenWindow(int width, int height, bool resizable, bool borderless);
-    /// Create the application window icon.
-    void CreateWindowIcon();
-    /// Adjust the window for new resolution and fullscreen mode.
-    void AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen, bool& newBorderless);
-    /// Create the D3D11 device and swap chain. Requires an open window. Can also be called again to recreate swap chain. Return true on success.
-    bool CreateDevice(int width, int height, int multiSample);
-    /// Update swap chain state for a new mode and create views for the backbuffer & default depth buffer. Return true on success.
-    bool UpdateSwapChain(int width, int height);
-    /// Check supported rendering features.
-    void CheckFeatureSupport();
-    /// Reset cached rendering state.
-    void ResetCachedState();
-    /// Initialize texture unit mappings.
-    void SetTextureUnitMappings();
-    /// Process dirtied state before draw.
-    void PrepareDraw();
-    /// Create intermediate texture for multisampled backbuffer resolve. No-op if already exists.
-    void CreateResolveTexture();
-
-    /// Mutex for accessing the GPU objects vector from several threads.
-    Mutex gpuObjectMutex_;
-    /// Implementation.
-    GraphicsImpl* impl_;
-    /// Window title.
-    String windowTitle_;
-    /// Window Icon File Name
-    Image* windowIcon_;
-    /// External window, null if not in use (default.)
-    void* externalWindow_;
-    /// Window width in pixels.
-    int width_;
-    /// Window height in pixels.
-    int height_;
-    /// Window position.
-    IntVector2 position_;
-    /// Multisampling mode.
-    int multiSample_;
-    /// Fullscreen flag.
-    bool fullscreen_;
-    /// Borderless flag.
-    bool borderless_;
-    /// Resizable flag.
-    bool resizable_;
-    /// High DPI flag.
-    bool highDPI_;
-    /// Vertical sync flag.
-    bool vsync_;
-    /// Triple buffering flag.
-    bool tripleBuffer_;
-    /// Flush GPU command buffer flag.
-    bool flushGPU_;
-    /// sRGB conversion on write flag for the main window.
-    bool sRGB_;
-    /// Light pre-pass rendering support flag.
-    bool lightPrepassSupport_;
-    /// Deferred rendering support flag.
-    bool deferredSupport_;
-    /// Hardware shadow map depth compare support flag.
-    bool hardwareShadowSupport_;
-    /// Instancing support flag.
-    bool instancingSupport_;
-    /// sRGB conversion on read support flag.
-    bool sRGBSupport_;
-    /// sRGB conversion on write support flag.
-    bool sRGBWriteSupport_;
-    /// Number of primitives this frame.
-    unsigned numPrimitives_;
-    /// Number of batches this frame.
-    unsigned numBatches_;
-    /// Largest scratch buffer request this frame.
-    unsigned maxScratchBufferRequest_;
-    /// GPU objects.
-    PODVector<GPUObject*> gpuObjects_;
-    /// Scratch buffers.
-    Vector<ScratchBuffer> scratchBuffers_;
-    /// Shadow map dummy color texture format.
-    unsigned dummyColorFormat_;
-    /// Shadow map depth texture format.
-    unsigned shadowMapFormat_;
-    /// Shadow map 24-bit depth texture format.
-    unsigned hiresShadowMapFormat_;
-    /// Vertex buffers in use.
-    VertexBuffer* vertexBuffers_[MAX_VERTEX_STREAMS];
-    /// Index buffer in use.
-    IndexBuffer* indexBuffer_;
-    /// Current vertex declaration hash.
-    unsigned long long vertexDeclarationHash_;
-    /// Current primitive type.
-    unsigned primitiveType_;
-    /// Vertex shader in use.
-    ShaderVariation* vertexShader_;
-    /// Pixel shader in use.
-    ShaderVariation* pixelShader_;
-    /// Textures in use.
-    Texture* textures_[MAX_TEXTURE_UNITS];
-    /// Texture unit mappings.
-    HashMap<String, TextureUnit> textureUnits_;
-    /// Rendertargets in use.
-    RenderSurface* renderTargets_[MAX_RENDERTARGETS];
-    /// Depth-stencil surface in use.
-    RenderSurface* depthStencil_;
-    /// Viewport coordinates.
-    IntRect viewport_;
-    /// Texture anisotropy level.
-    unsigned textureAnisotropy_;
-    /// Blending mode.
-    BlendMode blendMode_;
-    /// Color write enable.
-    bool colorWrite_;
-    /// Hardware culling mode.
-    CullMode cullMode_;
-    /// Depth constant bias.
-    float constantDepthBias_;
-    /// Depth slope scaled bias.
-    float slopeScaledDepthBias_;
-    /// Depth compare mode.
-    CompareMode depthTestMode_;
-    /// Depth write enable flag.
-    bool depthWrite_;
-    /// Polygon fill mode.
-    FillMode fillMode_;
-    /// Scissor test rectangle.
-    IntRect scissorRect_;
-    /// Scissor test enable flag.
-    bool scissorTest_;
-    /// Stencil test compare mode.
-    CompareMode stencilTestMode_;
-    /// Stencil operation on pass.
-    StencilOp stencilPass_;
-    /// Stencil operation on fail.
-    StencilOp stencilFail_;
-    /// Stencil operation on depth fail.
-    StencilOp stencilZFail_;
-    /// Stencil test reference value.
-    unsigned stencilRef_;
-    /// Stencil compare bitmask.
-    unsigned stencilCompareMask_;
-    /// Stencil write bitmask.
-    unsigned stencilWriteMask_;
-    /// Current custom clip plane in post-projection space.
-    Vector4 clipPlane_;
-    /// Stencil test enable flag.
-    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.
-    String shaderPath_;
-    /// File extension for shaders.
-    String shaderExtension_;
-    /// Last used shader in shader variation query.
-    mutable WeakPtr<Shader> lastShader_;
-    /// Last used shader name in shader variation query.
-    mutable String lastShaderName_;
-    /// Shader precache utility.
-    SharedPtr<ShaderPrecache> shaderPrecache_;
-    /// Allowed screen orientations.
-    String orientations_;
-    /// Graphics API name.
-    String apiName_;
-
-    /// Pixel perfect UV offset.
-    static const Vector2 pixelUVOffset;
-};
-
-/// Register Graphics library objects.
-void URHO3D_API RegisterGraphicsLibrary(Context* context);
-
-}

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

@@ -31,7 +31,6 @@ namespace Urho3D
 {
 
 GraphicsImpl::GraphicsImpl() :
-    window_(0),
     device_(0),
     deviceContext_(0),
     swapChain_(0),
@@ -39,7 +38,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 - 7
Source/Urho3D/Graphics/Direct3D11/D3D11GraphicsImpl.h

@@ -22,14 +22,15 @@
 
 #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>
 #include <dxgi.h>
 
-struct SDL_Window;
-
 namespace Urho3D
 {
 
@@ -37,6 +38,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
 {
@@ -55,12 +60,7 @@ public:
     /// Return swapchain.
     IDXGISwapChain* GetSwapChain() const { return swapChain_; }
 
-    /// Return window.
-    SDL_Window* GetWindow() const { return window_; }
-
 private:
-    /// SDL window.
-    SDL_Window* window_;
     /// Graphics device.
     ID3D11Device* device_;
     /// Immediate device context.
@@ -97,6 +97,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_;
 };
 
 }

+ 17 - 108
Source/Urho3D/Graphics/Direct3D11/D3D11IndexBuffer.cpp

@@ -33,26 +33,14 @@
 namespace Urho3D
 {
 
-IndexBuffer::IndexBuffer(Context* context, bool forceHeadless) :
-    Object(context),
-    GPUObject(forceHeadless ? (Graphics*)0 : GetSubsystem<Graphics>()),
-    indexCount_(0),
-    indexSize_(0),
-    lockState_(LOCK_NONE),
-    lockStart_(0),
-    lockCount_(0),
-    lockScratchData_(0),
-    dynamic_(false),
-    shadowed_(false)
+void IndexBuffer::OnDeviceLost()
 {
-    // Force shadowing mode if graphics subsystem does not exist
-    if (!graphics_)
-        shadowed_ = true;
+    // No-op on Direct3D11
 }
 
-IndexBuffer::~IndexBuffer()
+void IndexBuffer::OnDeviceReset()
 {
-    Release();
+    // No-op on Direct3D11
 }
 
 void IndexBuffer::Release()
@@ -62,40 +50,7 @@ void IndexBuffer::Release()
     if (graphics_ && graphics_->GetIndexBuffer() == this)
         graphics_->SetIndexBuffer(0);
 
-    URHO3D_SAFE_RELEASE(object_);
-}
-
-void IndexBuffer::SetShadowed(bool enable)
-{
-    // If no graphics subsystem, can not disable shadowing
-    if (!graphics_)
-        enable = true;
-
-    if (enable != shadowed_)
-    {
-        if (enable && indexCount_ && indexSize_)
-            shadowData_ = new unsigned char[indexCount_ * indexSize_];
-        else
-            shadowData_.Reset();
-
-        shadowed_ = enable;
-    }
-}
-
-bool IndexBuffer::SetSize(unsigned indexCount, bool largeIndices, bool dynamic)
-{
-    Unlock();
-
-    dynamic_ = dynamic;
-    indexCount_ = indexCount;
-    indexSize_ = (unsigned)(largeIndices ? sizeof(unsigned) : sizeof(unsigned short));
-
-    if (shadowed_ && indexCount_ && indexSize_)
-        shadowData_ = new unsigned char[indexCount_ * indexSize_];
-    else
-        shadowData_.Reset();
-
-    return Create();
+    URHO3D_SAFE_RELEASE(object_.ptr_);
 }
 
 bool IndexBuffer::SetData(const void* data)
@@ -115,7 +70,7 @@ bool IndexBuffer::SetData(const void* data)
     if (shadowData_ && data != shadowData_.Get())
         memcpy(shadowData_.Get(), data, indexCount_ * indexSize_);
 
-    if (object_)
+    if (object_.ptr_)
     {
         if (dynamic_)
         {
@@ -138,7 +93,7 @@ bool IndexBuffer::SetData(const void* data)
             destBox.front = 0;
             destBox.back = 1;
 
-            graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Buffer*)object_, 0, &destBox, data, 0, 0);
+            graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Buffer*)object_.ptr_, 0, &destBox, data, 0, 0);
         }
     }
 
@@ -174,7 +129,7 @@ bool IndexBuffer::SetDataRange(const void* data, unsigned start, unsigned count,
     if (shadowData_ && shadowData_.Get() + start * indexSize_ != data)
         memcpy(shadowData_.Get() + start * indexSize_, data, count * indexSize_);
 
-    if (object_)
+    if (object_.ptr_)
     {
         if (dynamic_)
         {
@@ -197,7 +152,7 @@ bool IndexBuffer::SetDataRange(const void* data, unsigned start, unsigned count,
             destBox.front = 0;
             destBox.back = 1;
 
-            graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Buffer*)object_, 0, &destBox, data, 0, 0);
+            graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Buffer*)object_.ptr_, 0, &destBox, data, 0, 0);
         }
     }
 
@@ -231,7 +186,7 @@ void* IndexBuffer::Lock(unsigned start, unsigned count, bool discard)
     lockCount_ = count;
 
     // Because shadow data must be kept in sync, can only lock hardware buffer if not shadowed
-    if (object_ && !shadowData_ && dynamic_)
+    if (object_.ptr_ && !shadowData_ && dynamic_)
         return MapBuffer(start, count, discard);
     else if (shadowData_)
     {
@@ -273,52 +228,6 @@ void IndexBuffer::Unlock()
     }
 }
 
-bool IndexBuffer::GetUsedVertexRange(unsigned start, unsigned count, unsigned& minVertex, unsigned& vertexCount)
-{
-    if (!shadowData_)
-    {
-        URHO3D_LOGERROR("Used vertex range can only be queried from an index buffer with shadow data");
-        return false;
-    }
-
-    if (start + count > indexCount_)
-    {
-        URHO3D_LOGERROR("Illegal index range for querying used vertices");
-        return false;
-    }
-
-    minVertex = M_MAX_UNSIGNED;
-    unsigned maxVertex = 0;
-
-    if (indexSize_ == sizeof(unsigned))
-    {
-        unsigned* indices = ((unsigned*)shadowData_.Get()) + start;
-
-        for (unsigned i = 0; i < count; ++i)
-        {
-            if (indices[i] < minVertex)
-                minVertex = indices[i];
-            if (indices[i] > maxVertex)
-                maxVertex = indices[i];
-        }
-    }
-    else
-    {
-        unsigned short* indices = ((unsigned short*)shadowData_.Get()) + start;
-
-        for (unsigned i = 0; i < count; ++i)
-        {
-            if (indices[i] < minVertex)
-                minVertex = indices[i];
-            if (indices[i] > maxVertex)
-                maxVertex = indices[i];
-        }
-    }
-
-    vertexCount = maxVertex - minVertex + 1;
-    return true;
-}
-
 bool IndexBuffer::Create()
 {
     Release();
@@ -335,10 +244,10 @@ bool IndexBuffer::Create()
         bufferDesc.Usage = dynamic_ ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
         bufferDesc.ByteWidth = (UINT)(indexCount_ * indexSize_);
 
-        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_);
+        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_.ptr_);
         if (FAILED(hr))
         {
-            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_SAFE_RELEASE(object_.ptr_);
             URHO3D_LOGD3DERROR("Failed to create index buffer", hr);
             return false;
         }
@@ -349,7 +258,7 @@ bool IndexBuffer::Create()
 
 bool IndexBuffer::UpdateToGPU()
 {
-    if (object_ && shadowData_)
+    if (object_.ptr_ && shadowData_)
         return SetData(shadowData_.Get());
     else
         return false;
@@ -359,12 +268,12 @@ void* IndexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
 {
     void* hwData = 0;
 
-    if (object_)
+    if (object_.ptr_)
     {
         D3D11_MAPPED_SUBRESOURCE mappedData;
         mappedData.pData = 0;
 
-        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Buffer*)object_, 0, discard ? D3D11_MAP_WRITE_DISCARD :
+        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Buffer*)object_.ptr_, 0, discard ? D3D11_MAP_WRITE_DISCARD :
             D3D11_MAP_WRITE, 0, &mappedData);
         if (FAILED(hr) || !mappedData.pData)
             URHO3D_LOGD3DERROR("Failed to map index buffer", hr);
@@ -380,9 +289,9 @@ void* IndexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
 
 void IndexBuffer::UnmapBuffer()
 {
-    if (object_ && lockState_ == LOCK_HARDWARE)
+    if (object_.ptr_ && lockState_ == LOCK_HARDWARE)
     {
-        graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Buffer*)object_, 0);
+        graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Buffer*)object_.ptr_, 0);
         lockState_ = LOCK_NONE;
     }
 }

+ 0 - 114
Source/Urho3D/Graphics/Direct3D11/D3D11IndexBuffer.h

@@ -1,114 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Core/Object.h"
-#include "../../Container/ArrayPtr.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-
-namespace Urho3D
-{
-
-/// Hardware index buffer.
-class URHO3D_API IndexBuffer : public Object, public GPUObject
-{
-    URHO3D_OBJECT(IndexBuffer, Object);
-
-public:
-    /// Construct.
-    IndexBuffer(Context* context, bool forceHeadless = false);
-    /// Destruct.
-    virtual ~IndexBuffer();
-
-    /// Release buffer.
-    virtual void Release();
-
-    /// Enable shadowing in CPU memory. Shadowing is forced on if the graphics subsystem does not exist.
-    void SetShadowed(bool enable);
-    /// Set size and vertex elements and dynamic mode. Previous data will be lost.
-    bool SetSize(unsigned indexCount, bool largeIndices, bool dynamic = false);
-    /// Set all data in the buffer.
-    bool SetData(const void* data);
-    /// Set a data range in the buffer. Optionally discard data outside the range.
-    bool SetDataRange(const void* data, unsigned start, unsigned count, bool discard = false);
-    /// Lock the buffer for write-only editing. Return data pointer if successful. Optionally discard data outside the range.
-    void* Lock(unsigned start, unsigned count, bool discard = false);
-    /// Unlock the buffer and apply changes to the GPU buffer.
-    void Unlock();
-
-    /// Return whether CPU memory shadowing is enabled.
-    bool IsShadowed() const { return shadowed_; }
-
-    /// Return whether is dynamic.
-    bool IsDynamic() const { return dynamic_; }
-
-    /// Return whether is currently locked.
-    bool IsLocked() const { return lockState_ != LOCK_NONE; }
-
-    /// Return number of indices.
-    unsigned GetIndexCount() const { return indexCount_; }
-
-    /// Return index size in bytes.
-    unsigned GetIndexSize() const { return indexSize_; }
-
-    /// Return used vertex range from index range.
-    bool GetUsedVertexRange(unsigned start, unsigned count, unsigned& minVertex, unsigned& vertexCount);
-
-    /// Return CPU memory shadow data.
-    unsigned char* GetShadowData() const { return shadowData_.Get(); }
-
-    /// Return shared array pointer to the CPU memory shadow data.
-    SharedArrayPtr<unsigned char> GetShadowDataShared() const { return shadowData_; }
-
-private:
-    /// Create buffer.
-    bool Create();
-    /// Update the shadow data to the GPU buffer.
-    bool UpdateToGPU();
-    /// Map the GPU buffer into CPU memory.
-    void* MapBuffer(unsigned start, unsigned count, bool discard);
-    /// Unmap the GPU buffer.
-    void UnmapBuffer();
-
-    /// Shadow data.
-    SharedArrayPtr<unsigned char> shadowData_;
-    /// Number of indices.
-    unsigned indexCount_;
-    /// Index size.
-    unsigned indexSize_;
-    /// Buffer locking state.
-    LockState lockState_;
-    /// Lock start vertex.
-    unsigned lockStart_;
-    /// Lock number of vertices.
-    unsigned lockCount_;
-    /// Scratch buffer for fallback locking.
-    void* lockScratchData_;
-    /// Dynamic flag.
-    bool dynamic_;
-    /// Shadowed flag.
-    bool shadowed_;
-};
-
-}

+ 5 - 59
Source/Urho3D/Graphics/Direct3D11/D3D11RenderSurface.cpp

@@ -43,51 +43,6 @@ RenderSurface::RenderSurface(Texture* parentTexture) :
 {
 }
 
-RenderSurface::~RenderSurface()
-{
-    Release();
-}
-
-void RenderSurface::SetNumViewports(unsigned num)
-{
-    viewports_.Resize(num);
-}
-
-void RenderSurface::SetViewport(unsigned index, Viewport* viewport)
-{
-    if (index >= viewports_.Size())
-        viewports_.Resize(index + 1);
-
-    viewports_[index] = viewport;
-}
-
-void RenderSurface::SetUpdateMode(RenderSurfaceUpdateMode mode)
-{
-    updateMode_ = mode;
-}
-
-void RenderSurface::SetLinkedRenderTarget(RenderSurface* renderTarget)
-{
-    if (renderTarget != this)
-        linkedRenderTarget_ = renderTarget;
-}
-
-void RenderSurface::SetLinkedDepthStencil(RenderSurface* depthStencil)
-{
-    if (depthStencil != this)
-        linkedDepthStencil_ = depthStencil;
-}
-
-void RenderSurface::QueueUpdate()
-{
-    updateQueued_ = true;
-}
-
-void RenderSurface::ResetUpdateQueued()
-{
-    updateQueued_ = false;
-}
-
 void RenderSurface::Release()
 {
     Graphics* graphics = parentTexture_->GetGraphics();
@@ -107,24 +62,15 @@ void RenderSurface::Release()
     URHO3D_SAFE_RELEASE(readOnlyView_);
 }
 
-int RenderSurface::GetWidth() const
-{
-    return parentTexture_->GetWidth();
-}
-
-int RenderSurface::GetHeight() const
-{
-    return parentTexture_->GetHeight();
-}
-
-TextureUsage RenderSurface::GetUsage() const
+bool RenderSurface::CreateRenderBuffer(unsigned width, unsigned height, unsigned format)
 {
-    return parentTexture_->GetUsage();
+    // Not used on Direct3D
+    return false;
 }
 
-Viewport* RenderSurface::GetViewport(unsigned index) const
+void RenderSurface::OnDeviceLost()
 {
-    return index < viewports_.Size() ? viewports_[index] : (Viewport*)0;
+    // No-op on Direct3D
 }
 
 }

+ 0 - 116
Source/Urho3D/Graphics/Direct3D11/D3D11RenderSurface.h

@@ -1,116 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Graphics/GraphicsDefs.h"
-#include "../../Graphics/Viewport.h"
-
-namespace Urho3D
-{
-
-class Texture;
-
-/// %Color or depth-stencil surface that can be rendered into.
-class URHO3D_API RenderSurface : public RefCounted
-{
-    friend class Texture2D;
-    friend class Texture2DArray;
-    friend class TextureCube;
-
-public:
-    /// Construct with parent texture.
-    RenderSurface(Texture* parentTexture);
-    /// Destruct.
-    ~RenderSurface();
-
-    /// Set number of viewports.
-    void SetNumViewports(unsigned num);
-    /// Set viewport.
-    void SetViewport(unsigned index, Viewport* viewport);
-    /// Set viewport update mode. Default is to update when visible.
-    void SetUpdateMode(RenderSurfaceUpdateMode mode);
-    /// Set linked color rendertarget.
-    void SetLinkedRenderTarget(RenderSurface* renderTarget);
-    /// Set linked depth-stencil surface.
-    void SetLinkedDepthStencil(RenderSurface* depthStencil);
-    /// Queue manual update of the viewport(s).
-    void QueueUpdate();
-    /// Release surface.
-    void Release();
-
-    /// Return parent texture.
-    Texture* GetParentTexture() const { return parentTexture_; }
-
-    /// Return Direct3D rendertarget or depth-stencil view.
-    void* GetRenderTargetView() const { return renderTargetView_; }
-
-    /// Return Direct3D read-only depth-stencil view. May be null if not applicable
-    void* GetReadOnlyView() const { return readOnlyView_; }
-
-    /// Return width.
-    int GetWidth() const;
-    /// Return height.
-    int GetHeight() const;
-    /// Return usage.
-    TextureUsage GetUsage() const;
-
-    /// Return number of viewports.
-    unsigned GetNumViewports() const { return viewports_.Size(); }
-
-    /// Return viewport by index.
-    Viewport* GetViewport(unsigned index) const;
-
-    /// Return viewport update mode.
-    RenderSurfaceUpdateMode GetUpdateMode() const { return updateMode_; }
-
-    /// Return linked color rendertarget.
-    RenderSurface* GetLinkedRenderTarget() const { return linkedRenderTarget_; }
-
-    /// Return linked depth-stencil surface.
-    RenderSurface* GetLinkedDepthStencil() const { return linkedDepthStencil_; }
-
-    /// Return whether manual update queued. Called internally.
-    bool IsUpdateQueued() const { return updateQueued_; }
-    /// Reset update queued flag. Called internally.
-    void ResetUpdateQueued();
-
-private:
-    /// Parent texture.
-    Texture* parentTexture_;
-    /// Direct3D rendertarget or depth-stencil view.
-    void* renderTargetView_;
-    /// Direct3D read-only depth-stencil view. Present only on depth-stencil surfaces.
-    void* readOnlyView_;
-    /// Viewports.
-    Vector<SharedPtr<Viewport> > viewports_;
-    /// Linked color buffer.
-    WeakPtr<RenderSurface> linkedRenderTarget_;
-    /// Linked depth buffer.
-    WeakPtr<RenderSurface> linkedDepthStencil_;
-    /// Update mode for viewports.
-    RenderSurfaceUpdateMode updateMode_;
-    /// Update queued flag.
-    bool updateQueued_;
-};
-
-}

+ 23 - 34
Source/Urho3D/Graphics/Direct3D11/D3D11ShaderVariation.cpp

@@ -51,21 +51,9 @@ const char* ShaderVariation::elementSemanticNames[] =
     "OBJECTINDEX"
 };
 
-ShaderVariation::ShaderVariation(Shader* owner, ShaderType type) :
-    GPUObject(owner->GetSubsystem<Graphics>()),
-    owner_(owner),
-    type_(type),
-    elementHash_(0)
+void ShaderVariation::OnDeviceLost()
 {
-    for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
-        useTextureUnit_[i] = false;
-    for (unsigned i = 0; i < MAX_SHADER_PARAMETER_GROUPS; ++i)
-        constantBufferSizes_[i] = 0;
-}
-
-ShaderVariation::~ShaderVariation()
-{
-    Release();
+    // No-op on Direct3D11
 }
 
 bool ShaderVariation::Create()
@@ -104,10 +92,10 @@ bool ShaderVariation::Create()
     {
         if (device && byteCode_.Size())
         {
-            HRESULT hr = device->CreateVertexShader(&byteCode_[0], byteCode_.Size(), 0, (ID3D11VertexShader**)&object_);
+            HRESULT hr = device->CreateVertexShader(&byteCode_[0], byteCode_.Size(), 0, (ID3D11VertexShader**)&object_.ptr_);
             if (FAILED(hr))
             {
-                URHO3D_SAFE_RELEASE(object_);
+                URHO3D_SAFE_RELEASE(object_.ptr_);
                 compilerOutput_ = "Could not create vertex shader (HRESULT " + ToStringHex((unsigned)hr) + ")";
             }
         }
@@ -118,10 +106,10 @@ bool ShaderVariation::Create()
     {
         if (device && byteCode_.Size())
         {
-            HRESULT hr = device->CreatePixelShader(&byteCode_[0], byteCode_.Size(), 0, (ID3D11PixelShader**)&object_);
+            HRESULT hr = device->CreatePixelShader(&byteCode_[0], byteCode_.Size(), 0, (ID3D11PixelShader**)&object_.ptr_);
             if (FAILED(hr))
             {
-                URHO3D_SAFE_RELEASE(object_);
+                URHO3D_SAFE_RELEASE(object_.ptr_);
                 compilerOutput_ = "Could not create pixel shader (HRESULT " + ToStringHex((unsigned)hr) + ")";
             }
         }
@@ -129,17 +117,17 @@ bool ShaderVariation::Create()
             compilerOutput_ = "Could not create pixel shader, empty bytecode";
     }
 
-    return object_ != 0;
+    return object_.ptr_ != 0;
 }
 
 void ShaderVariation::Release()
 {
-    if (object_)
+    if (object_.ptr_)
     {
         if (!graphics_)
             return;
 
-        graphics_->CleanUpShaderPrograms(this);
+        graphics_->CleanupShaderPrograms(this);
 
         if (type_ == VS)
         {
@@ -152,7 +140,7 @@ void ShaderVariation::Release()
                 graphics_->SetShaders(0, 0);
         }
 
-        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_SAFE_RELEASE(object_.ptr_);
     }
 
     compilerOutput_.Clear();
@@ -166,11 +154,6 @@ void ShaderVariation::Release()
     elementHash_ = 0;
 }
 
-void ShaderVariation::SetName(const String& name)
-{
-    name_ = name;
-}
-
 void ShaderVariation::SetDefines(const String& defines)
 {
     defines_ = defines;
@@ -181,11 +164,6 @@ void ShaderVariation::SetDefines(const String& defines)
         definesClipPlane_ += " CLIPPLANE";
 }
 
-Shader* ShaderVariation::GetOwner() const
-{
-    return owner_;
-}
-
 bool ShaderVariation::LoadByteCode(const String& binaryShaderName)
 {
     ResourceCache* cache = owner_->GetSubsystem<ResourceCache>();
@@ -220,7 +198,12 @@ bool ShaderVariation::LoadByteCode(const String& binaryShaderName)
         unsigned offset = file->ReadUInt();
         unsigned size = file->ReadUInt();
 
-        ShaderParameter parameter(type_, name_, buffer, offset, size);
+        ShaderParameter parameter;
+        parameter.type_ = type_;
+        parameter.name_ = name;
+        parameter.buffer_ = buffer;
+        parameter.offset_ = offset;
+        parameter.size_ = size;
         parameters_[StringHash(name)] = parameter;
     }
 
@@ -416,7 +399,13 @@ void ShaderVariation::ParseParameters(unsigned char* bufData, unsigned bufSize)
             if (varName[0] == 'c')
             {
                 varName = varName.Substring(1); // Strip the c to follow Urho3D constant naming convention
-                parameters_[varName] = ShaderParameter(type_, varName, cbRegister, varDesc.StartOffset, varDesc.Size);
+                ShaderParameter parameter;
+                parameter.type_ = type_;
+                parameter.name_ = varName;
+                parameter.buffer_ = cbRegister;
+                parameter.offset_ = varDesc.StartOffset;
+                parameter.size_ = varDesc.Size;
+                parameters_[varName] = parameter;
             }
         }
     }

+ 0 - 172
Source/Urho3D/Graphics/Direct3D11/D3D11ShaderVariation.h

@@ -1,172 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/HashSet.h"
-#include "../../Container/RefCounted.h"
-#include "../../Container/ArrayPtr.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-
-namespace Urho3D
-{
-
-class ConstantBuffer;
-class Shader;
-
-/// %Shader parameter definition.
-struct ShaderParameter
-{
-    /// Construct with defaults.
-    ShaderParameter() :
-        type_(VS),
-        buffer_(0),
-        offset_(0),
-        size_(0),
-        bufferPtr_(0)
-    {
-    }
-
-    /// Construct with parameters.
-    ShaderParameter(ShaderType type, const String& name, unsigned buffer, unsigned offset, unsigned size, ConstantBuffer* ptr = 0) :
-        type_(type),
-        name_(name),
-        buffer_(buffer),
-        offset_(offset),
-        size_(size),
-        bufferPtr_(ptr)
-    {
-    }
-
-    /// %Shader type.
-    ShaderType type_;
-    /// Name of the parameter.
-    String name_;
-    /// Constant buffer index.
-    unsigned buffer_;
-    /// Offset in constant buffer.
-    unsigned offset_;
-    /// Size of parameter in bytes.
-    unsigned size_;
-    /// Constant buffer pointer. Defined only in shader programs.
-    ConstantBuffer* bufferPtr_;
-};
-
-/// Vertex or pixel shader on the GPU.
-class URHO3D_API ShaderVariation : public RefCounted, public GPUObject
-{
-public:
-    /// Construct.
-    ShaderVariation(Shader* owner, ShaderType type);
-    /// Destruct.
-    virtual ~ShaderVariation();
-
-    /// Release the shader.
-    virtual void Release();
-
-    /// Compile the shader. Return true if successful.
-    bool Create();
-    /// Set name.
-    void SetName(const String& name);
-    /// Set defines.
-    void SetDefines(const String& defines);
-
-    /// Return the owner resource.
-    Shader* GetOwner() const;
-
-    /// Return shader type.
-    ShaderType GetShaderType() const { return type_; }
-
-    /// Return shader name.
-    const String& GetName() const { return name_; }
-
-    /// Return full shader name.
-    String GetFullName() const { return name_ + "(" + defines_ + ")"; }
-
-    /// Return whether uses a parameter.
-    bool HasParameter(StringHash param) const { return parameters_.Contains(param); }
-
-    /// Return whether uses a texture unit (only for pixel shaders.)
-    bool HasTextureUnit(TextureUnit unit) const { return useTextureUnit_[unit]; }
-
-    /// Return all parameter definitions.
-    const HashMap<StringHash, ShaderParameter>& GetParameters() const { return parameters_; }
-
-    /// Return vertex element hash.
-    unsigned long long GetElementHash() const { return elementHash_; }
-
-    /// Return shader bytecode.
-    const PODVector<unsigned char>& GetByteCode() const { return byteCode_; }
-
-    /// Return defines.
-    const String& GetDefines() const { return defines_; }
-
-    /// Return compile error/warning string.
-    const String& GetCompilerOutput() const { return compilerOutput_; }
-
-    /// Return constant buffer data sizes.
-    const unsigned* GetConstantBufferSizes() const { return &constantBufferSizes_[0]; }
-
-    /// Return defines with the CLIPPLANE define appended. Used internally on D3D11 only.
-    const String& GetDefinesClipPlane() { return definesClipPlane_; }
-
-    /// D3D11 vertex semantic names. Used internally.
-    static const char* elementSemanticNames[];
-
-private:
-    /// Load bytecode from a file. Return true if successful.
-    bool LoadByteCode(const String& binaryShaderName);
-    /// Compile from source. Return true if successful.
-    bool Compile();
-    /// Inspect the constant parameters and input layout (if applicable) from the shader bytecode.
-    void ParseParameters(unsigned char* bufData, unsigned bufSize);
-    /// Save bytecode to a file.
-    void SaveByteCode(const String& binaryShaderName);
-    /// Calculate constant buffer sizes from parameters.
-    void CalculateConstantBufferSizes();
-
-    /// Shader this variation belongs to.
-    WeakPtr<Shader> owner_;
-    /// Shader type.
-    ShaderType type_;
-    /// Vertex element hash for vertex shaders. Zero for pixel shaders. Note that hashing is different than vertex buffers.
-    unsigned long long elementHash_;
-    /// Shader parameters.
-    HashMap<StringHash, ShaderParameter> parameters_;
-    /// Texture unit use flags.
-    bool useTextureUnit_[MAX_TEXTURE_UNITS];
-    /// Constant buffer sizes. 0 if a constant buffer slot is not in use.
-    unsigned constantBufferSizes_[MAX_SHADER_PARAMETER_GROUPS];
-    /// Bytecode. Needed for inspecting the input signature and parameters.
-    PODVector<unsigned char> byteCode_;
-    /// Shader name.
-    String name_;
-    /// Defines to use in compiling.
-    String defines_;
-    /// Defines to use in compiling + CLIPPLANE define appended.
-    String definesClipPlane_;
-    /// Shader compile error string.
-    String compilerOutput_;
-};
-
-}

+ 10 - 256
Source/Urho3D/Graphics/Direct3D11/D3D11Texture.cpp

@@ -36,25 +36,6 @@
 namespace Urho3D
 {
 
-static const char* addressModeNames[] =
-{
-    "wrap",
-    "mirror",
-    "clamp",
-    "border",
-    0
-};
-
-static const char* filterModeNames[] =
-{
-    "nearest",
-    "bilinear",
-    "trilinear",
-    "anisotropic",
-    "default",
-    0
-};
-
 static const D3D11_FILTER d3dFilterMode[] =
 {
     D3D11_FILTER_MIN_MAG_MIP_POINT,
@@ -75,136 +56,28 @@ static const D3D11_TEXTURE_ADDRESS_MODE d3dAddressMode[] =
     D3D11_TEXTURE_ADDRESS_BORDER
 };
 
-Texture::Texture(Context* context) :
-    Resource(context),
-    GPUObject(GetSubsystem<Graphics>()),
-    shaderResourceView_(0),
-    sampler_(0),
-    format_(DXGI_FORMAT_UNKNOWN),
-    usage_(TEXTURE_STATIC),
-    levels_(0),
-    requestedLevels_(0),
-    width_(0),
-    height_(0),
-    depth_(0),
-    shadowCompare_(false),
-    filterMode_(FILTER_DEFAULT),
-    sRGB_(false),
-    parametersDirty_(true)
-{
-    for (int i = 0; i < MAX_COORDS; ++i)
-        addressMode_[i] = ADDRESS_WRAP;
-    for (int i = 0; i < MAX_TEXTURE_QUALITY_LEVELS; ++i)
-        mipsToSkip_[i] = (unsigned)(MAX_TEXTURE_QUALITY_LEVELS - 1 - i);
-}
-
-Texture::~Texture()
-{
-}
-
-void Texture::SetNumLevels(unsigned levels)
-{
-    if (usage_ > TEXTURE_RENDERTARGET)
-        requestedLevels_ = 1;
-    else
-        requestedLevels_ = levels;
-}
-
-void Texture::SetFilterMode(TextureFilterMode mode)
-{
-    filterMode_ = mode;
-    parametersDirty_ = true;
-}
-
-void Texture::SetAddressMode(TextureCoordinate coord, TextureAddressMode mode)
-{
-    addressMode_[coord] = mode;
-    parametersDirty_ = true;
-}
-
-void Texture::SetShadowCompare(bool enable)
-{
-    shadowCompare_ = enable;
-    parametersDirty_ = true;
-}
-
-void Texture::SetBorderColor(const Color& color)
-{
-    borderColor_ = color;
-    parametersDirty_ = true;
-}
-
 void Texture::SetSRGB(bool enable)
 {
     if (graphics_)
         enable &= graphics_->GetSRGBSupport();
 
-    // Note: on D3D11 sRGB only affects the texture before creation
-    sRGB_ = enable;
-}
-
-void Texture::SetBackupTexture(Texture* texture)
-{
-    backupTexture_ = texture;
-}
-
-void Texture::SetMipsToSkip(int quality, int toSkip)
-{
-    if (quality >= QUALITY_LOW && quality < MAX_TEXTURE_QUALITY_LEVELS)
+    if (enable != sRGB_)
     {
-        mipsToSkip_[quality] = (unsigned)toSkip;
-
-        // Make sure a higher quality level does not actually skip more mips
-        for (int i = 1; i < MAX_TEXTURE_QUALITY_LEVELS; ++i)
-        {
-            if (mipsToSkip_[i] > mipsToSkip_[i - 1])
-                mipsToSkip_[i] = mipsToSkip_[i - 1];
-        }
+        sRGB_ = enable;
+        // If texture had already been created, must recreate it to set the sRGB texture format
+        if (object_.name_)
+            Create();
     }
 }
 
-bool Texture::IsCompressed() const
-{
-    return format_ == DXGI_FORMAT_BC1_UNORM || format_ == DXGI_FORMAT_BC2_UNORM || format_ == DXGI_FORMAT_BC3_UNORM;
-}
-
-int Texture::GetMipsToSkip(int quality) const
-{
-    return (quality >= QUALITY_LOW && quality < MAX_TEXTURE_QUALITY_LEVELS) ? mipsToSkip_[quality] : 0;
-}
-
-int Texture::GetLevelWidth(unsigned level) const
+bool Texture::GetParametersDirty() const
 {
-    if (level > levels_)
-        return 0;
-    return Max(width_ >> level, 1);
-}
-
-int Texture::GetLevelHeight(unsigned level) const
-{
-    if (level > levels_)
-        return 0;
-    return Max(height_ >> level, 1);
-}
-
-int Texture::GetLevelDepth(unsigned level) const
-{
-    if (level > levels_)
-        return 0;
-    return Max(depth_ >> level, 1);
+    return parametersDirty_ || !sampler_;
 }
 
-unsigned Texture::GetDataSize(int width, int height) const
-{
-    if (IsCompressed())
-        return GetRowDataSize(width) * ((height + 3) >> 2);
-    else
-        return GetRowDataSize(width) * height;
-}
-
-unsigned Texture::GetDataSize(int width, int height, int depth) const
+bool Texture::IsCompressed() const
 {
-    return depth * GetDataSize(width, height);
+    return format_ == DXGI_FORMAT_BC1_UNORM || format_ == DXGI_FORMAT_BC2_UNORM || format_ == DXGI_FORMAT_BC3_UNORM;
 }
 
 unsigned Texture::GetRowDataSize(int width) const
@@ -248,80 +121,9 @@ unsigned Texture::GetRowDataSize(int width) const
     }
 }
 
-unsigned Texture::GetComponents() const
-{
-    if (!width_ || IsCompressed())
-        return 0;
-    else
-        return GetRowDataSize(width_) / width_;
-}
-
-void Texture::SetParameters(XMLFile* file)
-{
-    if (!file)
-        return;
-
-    XMLElement rootElem = file->GetRoot();
-    SetParameters(rootElem);
-}
-
-void Texture::SetParameters(const XMLElement& element)
-{
-    XMLElement paramElem = element.GetChild();
-    while (paramElem)
-    {
-        String name = paramElem.GetName();
-
-        if (name == "address")
-        {
-            String coord = paramElem.GetAttributeLower("coord");
-            if (coord.Length() >= 1)
-            {
-                TextureCoordinate coordIndex = (TextureCoordinate)(coord[0] - 'u');
-                String mode = paramElem.GetAttributeLower("mode");
-                SetAddressMode(coordIndex, (TextureAddressMode)GetStringListIndex(mode.CString(), addressModeNames, ADDRESS_WRAP));
-            }
-        }
-
-        if (name == "border")
-            SetBorderColor(paramElem.GetColor("color"));
-
-        if (name == "filter")
-        {
-            String mode = paramElem.GetAttributeLower("mode");
-            SetFilterMode((TextureFilterMode)GetStringListIndex(mode.CString(), filterModeNames, FILTER_DEFAULT));
-        }
-
-        if (name == "mipmap")
-            SetNumLevels(paramElem.GetBool("enable") ? 0 : 1);
-
-        if (name == "quality")
-        {
-            if (paramElem.HasAttribute("low"))
-                SetMipsToSkip(QUALITY_LOW, paramElem.GetInt("low"));
-            if (paramElem.HasAttribute("med"))
-                SetMipsToSkip(QUALITY_MEDIUM, paramElem.GetInt("med"));
-            if (paramElem.HasAttribute("medium"))
-                SetMipsToSkip(QUALITY_MEDIUM, paramElem.GetInt("medium"));
-            if (paramElem.HasAttribute("high"))
-                SetMipsToSkip(QUALITY_HIGH, paramElem.GetInt("high"));
-        }
-
-        if (name == "srgb")
-            SetSRGB(paramElem.GetBool("enable"));
-
-        paramElem = paramElem.GetNext();
-    }
-}
-
-void Texture::SetParametersDirty()
-{
-    parametersDirty_ = true;
-}
-
 void Texture::UpdateParameters()
 {
-    if ((!parametersDirty_ && sampler_) || !object_)
+    if ((!parametersDirty_ && sampler_) || !object_.ptr_)
         return;
 
     // Release old sampler
@@ -352,40 +154,6 @@ void Texture::UpdateParameters()
     parametersDirty_ = false;
 }
 
-unsigned Texture::CheckMaxLevels(int width, int height, unsigned requestedLevels)
-{
-    unsigned maxLevels = 1;
-    while (width > 1 && height > 1)
-    {
-        ++maxLevels;
-        width >>= 1;
-        height >>= 1;
-    }
-
-    if (!requestedLevels || maxLevels < requestedLevels)
-        return maxLevels;
-    else
-        return requestedLevels;
-}
-
-unsigned Texture::CheckMaxLevels(int width, int height, int depth, unsigned requestedLevels)
-{
-    unsigned maxLevels = 1;
-    while (width > 1 && height > 1 && depth > 1)
-    {
-        ++maxLevels;
-        width >>= 1;
-        height >>= 1;
-        depth >>= 1;
-    }
-
-    if (!requestedLevels || maxLevels < requestedLevels)
-        return maxLevels;
-    else
-        return requestedLevels;
-}
-
-
 unsigned Texture::GetSRVFormat(unsigned format)
 {
     if (format == DXGI_FORMAT_R24G8_TYPELESS)
@@ -424,18 +192,4 @@ unsigned Texture::GetSRGBFormat(unsigned format)
         return format;
 }
 
-void Texture::CheckTextureBudget(StringHash type)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-    unsigned long long textureBudget = cache->GetMemoryBudget(type);
-    unsigned long long textureUse = cache->GetMemoryUse(type);
-    if (!textureBudget)
-        return;
-
-    // If textures are over the budget, they likely can not be freed directly as materials still refer to them.
-    // Therefore free unused materials first
-    if (textureUse > textureBudget)
-        cache->ReleaseResources(Material::GetTypeStatic());
-}
-
 }

+ 0 - 191
Source/Urho3D/Graphics/Direct3D11/D3D11Texture.h

@@ -1,191 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/ArrayPtr.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-#include "../../Math/Color.h"
-#include "../../Resource/Resource.h"
-
-namespace Urho3D
-{
-
-static const int MAX_TEXTURE_QUALITY_LEVELS = 3;
-
-class XMLElement;
-class XMLFile;
-
-/// Base class for texture resources.
-class URHO3D_API Texture : public Resource, public GPUObject
-{
-public:
-    /// Construct.
-    Texture(Context* context);
-    /// Destruct.
-    virtual ~Texture();
-
-    /// Set number of requested mip levels. Needs to be called before setting size.
-    void SetNumLevels(unsigned levels);
-    /// Set filtering mode.
-    void SetFilterMode(TextureFilterMode filter);
-    /// Set addressing mode by texture coordinate.
-    void SetAddressMode(TextureCoordinate coord, TextureAddressMode address);
-    /// Set shadow compare mode.
-    void SetShadowCompare(bool enable);
-    /// Set border color for border addressing mode.
-    void SetBorderColor(const Color& color);
-    /// Set sRGB sampling and writing mode.
-    void SetSRGB(bool enable);
-    /// Set backup texture to use when rendering to this texture.
-    void SetBackupTexture(Texture* texture);
-    /// Set mip levels to skip on a quality setting when loading. Ensures higher quality levels do not skip more.
-    void SetMipsToSkip(int quality, int toSkip);
-
-    /// Return texture format.
-    unsigned GetFormat() const { return format_; }
-
-    /// Return whether the texture format is compressed.
-    bool IsCompressed() const;
-
-    /// Return number of mip levels.
-    unsigned GetLevels() const { return levels_; }
-
-    /// Return width.
-    int GetWidth() const { return width_; }
-
-    /// Return height.
-    int GetHeight() const { return height_; }
-
-    /// Return height.
-    int GetDepth() const { return depth_; }
-
-    /// Return filtering mode.
-    TextureFilterMode GetFilterMode() const { return filterMode_; }
-
-    /// Return addressing mode by texture coordinate.
-    TextureAddressMode GetAddressMode(TextureCoordinate coord) const { return addressMode_[coord]; }
-
-    /// Return whether shadow compare is enabled.
-    bool GetShadowCompare() const { return shadowCompare_; }
-
-    /// Return border color.
-    const Color& GetBorderColor() const { return borderColor_; }
-
-    /// Return whether is using sRGB sampling and writing.
-    bool GetSRGB() const { return sRGB_; }
-
-    /// Return backup texture.
-    Texture* GetBackupTexture() const { return backupTexture_; }
-
-    /// Return mip levels to skip on a quality setting when loading.
-    int GetMipsToSkip(int quality) const;
-    /// Return mip level width, or 0 if level does not exist.
-    int GetLevelWidth(unsigned level) const;
-    /// Return mip level width, or 0 if level does not exist.
-    int GetLevelHeight(unsigned level) const;
-    /// Return mip level depth, or 0 if level does not exist.
-    int GetLevelDepth(unsigned level) const;
-
-    /// Return texture usage type.
-    TextureUsage GetUsage() const { return usage_; }
-
-    /// Return data size in bytes for a rectangular region.
-    unsigned GetDataSize(int width, int height) const;
-    /// Return data size in bytes for a volume region.
-    unsigned GetDataSize(int width, int height, int depth) const;
-    /// Return data size in bytes for a pixel or block row.
-    unsigned GetRowDataSize(int width) const;
-    /// Return number of image components required to receive pixel data from GetData(), or 0 for compressed images.
-    unsigned GetComponents() const;
-
-    /// Return whether the parameters are dirty.
-    bool GetParametersDirty() const { return parametersDirty_ || !sampler_; }
-
-    /// Set additional parameters from an XML file.
-    void SetParameters(XMLFile* xml);
-    /// Set additional parameters from an XML element.
-    void SetParameters(const XMLElement& element);
-    /// Mark parameters dirty. Called by Graphics.
-    void SetParametersDirty();
-    /// Create sampler state object after parameters have been changed. Called by Graphics when assigning the texture.
-    void UpdateParameters();
-
-    /// Return shader resource view.
-    void* GetShaderResourceView() const { return shaderResourceView_; }
-
-    /// Return sampler state object.
-    void* GetSampler() const { return sampler_; }
-
-    /// Check maximum allowed mip levels for a specific texture size.
-    static unsigned CheckMaxLevels(int width, int height, unsigned requestedLevels);
-    /// Check maximum allowed mip levels for a specific 3D texture size.
-    static unsigned CheckMaxLevels(int width, int height, int depth, unsigned requestedLevels);
-    /// Return the shader resource view format corresponding to a texture format. Handles conversion of typeless depth texture formats.
-    static unsigned GetSRVFormat(unsigned format);
-    /// Return the depth-stencil view format corresponding to a texture format. Handles conversion of typeless depth texture formats.
-    static unsigned GetDSVFormat(unsigned format);
-    /// Convert format to sRGB.
-    static unsigned GetSRGBFormat(unsigned format);
-
-protected:
-    /// Check whether texture memory budget has been exceeded. Free unused materials in that case to release the texture references.
-    void CheckTextureBudget(StringHash type);
-
-    /// Shader resource view.
-    void* shaderResourceView_;
-    /// Sampler state object.
-    void* sampler_;
-    /// Texture format.
-    unsigned format_;
-    /// Texture usage type.
-    TextureUsage usage_;
-    /// Current mip levels.
-    unsigned levels_;
-    /// Requested mip levels.
-    unsigned requestedLevels_;
-    /// Texture width.
-    int width_;
-    /// Texture height.
-    int height_;
-    /// Texture depth.
-    int depth_;
-    /// Shadow compare mode.
-    bool shadowCompare_;
-    /// Filtering mode.
-    TextureFilterMode filterMode_;
-    /// Addressing mode.
-    TextureAddressMode addressMode_[MAX_COORDS];
-    /// Mip levels to skip when loading per texture quality setting.
-    unsigned mipsToSkip_[MAX_TEXTURE_QUALITY_LEVELS];
-    /// Border color.
-    Color borderColor_;
-    /// sRGB sampling and writing mode flag.
-    bool sRGB_;
-    /// Parameters dirty flag.
-    bool parametersDirty_;
-    /// Backup texture.
-    SharedPtr<Texture> backupTexture_;
-};
-
-}

+ 17 - 114
Source/Urho3D/Graphics/Direct3D11/D3D11Texture2D.cpp

@@ -39,68 +39,19 @@
 namespace Urho3D
 {
 
-Texture2D::Texture2D(Context* context) :
-    Texture(context)
+void Texture2D::OnDeviceLost()
 {
+    // No-op on Direct3D11
 }
 
-Texture2D::~Texture2D()
+void Texture2D::OnDeviceReset()
 {
-    Release();
-}
-
-void Texture2D::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Texture2D>();
-}
-
-bool Texture2D::BeginLoad(Deserializer& source)
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // Load the image data for EndLoad()
-    loadImage_ = new Image(context_);
-    if (!loadImage_->Load(source))
-    {
-        loadImage_.Reset();
-        return false;
-    }
-
-    // Precalculate mip levels if async loading
-    if (GetAsyncLoadState() == ASYNC_LOADING)
-        loadImage_->PrecalculateLevels();
-
-    // Load the optional parameters file
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-    String xmlName = ReplaceExtension(GetName(), ".xml");
-    loadParameters_ = cache->GetTempResource<XMLFile>(xmlName, false);
-
-    return true;
-}
-
-bool Texture2D::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-    bool success = SetData(loadImage_);
-
-    loadImage_.Reset();
-    loadParameters_.Reset();
-
-    return success;
+    // No-op on Direct3D11
 }
 
 void Texture2D::Release()
 {
-    if (graphics_ && object_)
+    if (graphics_ && object_.ptr_)
     {
         for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
         {
@@ -112,53 +63,16 @@ void Texture2D::Release()
     if (renderSurface_)
         renderSurface_->Release();
 
-    URHO3D_SAFE_RELEASE(object_);
+    URHO3D_SAFE_RELEASE(object_.ptr_);
     URHO3D_SAFE_RELEASE(shaderResourceView_);
     URHO3D_SAFE_RELEASE(sampler_);
 }
 
-bool Texture2D::SetSize(int width, int height, unsigned format, TextureUsage usage)
-{
-    if (width <= 0 || height <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative texture dimensions");
-        return false;
-    }
-
-    // Delete the old rendersurface if any
-    renderSurface_.Reset();
-    usage_ = usage;
-
-    if (usage_ == TEXTURE_RENDERTARGET || usage_ == TEXTURE_DEPTHSTENCIL)
-    {
-        renderSurface_ = new RenderSurface(this);
-
-        // Clamp mode addressing by default, nearest filtering, and mipmaps disabled
-        addressMode_[COORD_U] = ADDRESS_CLAMP;
-        addressMode_[COORD_V] = ADDRESS_CLAMP;
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
-    }
-    else if (usage_ == TEXTURE_DYNAMIC)
-        requestedLevels_ = 1;
-
-    if (usage_ == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(Texture2D, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
-
-    width_ = width;
-    height_ = height;
-    format_ = format;
-
-    return Create();
-}
-
 bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, const void* data)
 {
     URHO3D_PROFILE(SetTextureData);
 
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not set data");
         return false;
@@ -211,7 +125,7 @@ bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, con
         D3D11_MAPPED_SUBRESOURCE mappedData;
         mappedData.pData = 0;
 
-        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
+        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_.ptr_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
             &mappedData);
         if (FAILED(hr) || !mappedData.pData)
         {
@@ -222,7 +136,7 @@ bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, con
         {
             for (int row = 0; row < height; ++row)
                 memcpy((unsigned char*)mappedData.pData + (row + y) * mappedData.RowPitch + rowStart, src + row * rowSize, rowSize);
-            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource);
+            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_.ptr_, subResource);
         }
     }
     else
@@ -235,7 +149,7 @@ bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, con
         destBox.front = 0;
         destBox.back = 1;
 
-        graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Resource*)object_, subResource, &destBox, data,
+        graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Resource*)object_.ptr_, subResource, &destBox, data,
             rowSize, 0);
     }
 
@@ -366,7 +280,7 @@ bool Texture2D::SetData(Image* image, bool useAlpha)
 
 bool Texture2D::GetData(unsigned level, void* dest) const
 {
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not get data");
         return false;
@@ -416,7 +330,7 @@ bool Texture2D::GetData(unsigned level, void* dest) const
     srcBox.bottom = (UINT)levelHeight;
     srcBox.front = 0;
     srcBox.back = 1;
-    graphics_->GetImpl()->GetDeviceContext()->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, (ID3D11Resource*)object_,
+    graphics_->GetImpl()->GetDeviceContext()->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, (ID3D11Resource*)object_.ptr_,
         srcSubResource, &srcBox);
 
     D3D11_MAPPED_SUBRESOURCE mappedData;
@@ -470,7 +384,7 @@ bool Texture2D::Create()
     HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, (ID3D11Texture2D**)&object_);
     if (FAILED(hr))
     {
-        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_SAFE_RELEASE(object_.ptr_);
         URHO3D_LOGD3DERROR("Failed to create texture", hr);
         return false;
     }
@@ -481,7 +395,7 @@ bool Texture2D::Create()
     resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
     resourceViewDesc.Texture2D.MipLevels = (UINT)levels_;
 
-    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_, &resourceViewDesc,
+    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_.ptr_, &resourceViewDesc,
         (ID3D11ShaderResourceView**)&shaderResourceView_);
     if (FAILED(hr))
     {
@@ -497,7 +411,7 @@ bool Texture2D::Create()
         renderTargetViewDesc.Format = textureDesc.Format;
         renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
 
-        hr = graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_, &renderTargetViewDesc,
+        hr = graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_.ptr_, &renderTargetViewDesc,
             (ID3D11RenderTargetView**)&renderSurface_->renderTargetView_);
         if (FAILED(hr))
         {
@@ -513,7 +427,7 @@ bool Texture2D::Create()
         depthStencilViewDesc.Format = (DXGI_FORMAT)GetDSVFormat(textureDesc.Format);
         depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
 
-        hr = graphics_->GetImpl()->GetDevice()->CreateDepthStencilView((ID3D11Resource*)object_, &depthStencilViewDesc,
+        hr = graphics_->GetImpl()->GetDevice()->CreateDepthStencilView((ID3D11Resource*)object_.ptr_, &depthStencilViewDesc,
             (ID3D11DepthStencilView**)&renderSurface_->renderTargetView_);
         if (FAILED(hr))
         {
@@ -524,7 +438,7 @@ bool Texture2D::Create()
 
         // Create also a read-only version of the view for simultaneous depth testing and sampling in shader
         depthStencilViewDesc.Flags = D3D11_DSV_READ_ONLY_DEPTH;
-        hr = graphics_->GetImpl()->GetDevice()->CreateDepthStencilView((ID3D11Resource*)object_, &depthStencilViewDesc,
+        hr = graphics_->GetImpl()->GetDevice()->CreateDepthStencilView((ID3D11Resource*)object_.ptr_, &depthStencilViewDesc,
             (ID3D11DepthStencilView**)&renderSurface_->readOnlyView_);
         if (FAILED(hr))
         {
@@ -536,15 +450,4 @@ bool Texture2D::Create()
     return true;
 }
 
-void Texture2D::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    if (renderSurface_ && (renderSurface_->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurface_->IsUpdateQueued()))
-    {
-        Renderer* renderer = GetSubsystem<Renderer>();
-        if (renderer)
-            renderer->QueueRenderSurface(renderSurface_);
-        renderSurface_->ResetUpdateQueued();
-    }
-}
-
 }

+ 0 - 82
Source/Urho3D/Graphics/Direct3D11/D3D11Texture2D.h

@@ -1,82 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-
-namespace Urho3D
-{
-
-class Image;
-class XMLFile;
-
-/// 2D texture resource.
-class URHO3D_API Texture2D : public Texture
-{
-    URHO3D_OBJECT(Texture2D, Texture);
-
-public:
-    /// Construct.
-    Texture2D(Context* context);
-    /// Destruct.
-    virtual ~Texture2D();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Release texture.
-    virtual void Release();
-
-    /// Set size, format and usage. Zero size will follow application window size. Return true if successful.
-    bool SetSize(int width, int height, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a mip level. Return true if successful.
-    bool SetData(unsigned level, int x, int y, int width, int height, const void* data);
-    /// Set data from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(Image* image, bool useAlpha = false);
-
-    /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(unsigned level, void* dest) const;
-
-    /// Return render surface.
-    RenderSurface* GetRenderSurface() const { return renderSurface_; }
-
-private:
-    /// Create texture.
-    bool Create();
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
-
-    /// Render surface.
-    SharedPtr<RenderSurface> renderSurface_;
-    /// Image file acquired during BeginLoad.
-    SharedPtr<Image> loadImage_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 16 - 160
Source/Urho3D/Graphics/Direct3D11/D3D11Texture2DArray.cpp

@@ -43,93 +43,14 @@
 namespace Urho3D
 {
 
-Texture2DArray::Texture2DArray(Context* context) :
-    Texture(context),
-    layers_(0),
-    lockedLevel_(-1)
+void Texture2DArray::OnDeviceLost()
 {
+    // No-op on Direct3D11
 }
 
-Texture2DArray::~Texture2DArray()
+void Texture2DArray::OnDeviceReset()
 {
-    Release();
-}
-
-void Texture2DArray::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Texture2DArray>();
-}
-
-bool Texture2DArray::BeginLoad(Deserializer& source)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    cache->ResetDependencies(this);
-
-    String texPath, texName, texExt;
-    SplitPath(GetName(), texPath, texName, texExt);
-
-    loadParameters_ = (new XMLFile(context_));
-    if (!loadParameters_->Load(source))
-    {
-        loadParameters_.Reset();
-        return false;
-    }
-
-    loadImages_.Clear();
-
-    XMLElement textureElem = loadParameters_->GetRoot();
-    XMLElement layerElem = textureElem.GetChild("layer");
-    while (layerElem)
-    {
-        String name = layerElem.GetAttribute("name");
-
-        // If path is empty, add the XML file path
-        if (GetPath(name).Empty())
-            name = texPath + name;
-
-        loadImages_.Push(cache->GetTempResource<Image>(name));
-        cache->StoreResourceDependency(this, name);
-
-        layerElem = layerElem.GetNext("layer");
-    }
-
-    // Precalculate mip levels if async loading
-    if (GetAsyncLoadState() == ASYNC_LOADING)
-    {
-        for (unsigned i = 0; i < loadImages_.Size(); ++i)
-        {
-            if (loadImages_[i])
-                loadImages_[i]->PrecalculateLevels();
-        }
-    }
-
-    return true;
-}
-
-bool Texture2DArray::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-    SetLayers(loadImages_.Size());
-
-    for (unsigned i = 0; i < loadImages_.Size(); ++i)
-        SetData(i, loadImages_[i]);
-
-    loadImages_.Clear();
-    loadParameters_.Reset();
-
-    return true;
+    // No-op on Direct3D11
 }
 
 void Texture2DArray::Release()
@@ -146,70 +67,16 @@ void Texture2DArray::Release()
     if (renderSurface_)
         renderSurface_->Release();
 
-    URHO3D_SAFE_RELEASE(object_);
+    URHO3D_SAFE_RELEASE(object_.ptr_);
     URHO3D_SAFE_RELEASE(shaderResourceView_);
     URHO3D_SAFE_RELEASE(sampler_);
 }
 
-void Texture2DArray::SetLayers(unsigned layers)
-{
-    Release();
-
-    layers_ = layers;
-}
-
-bool Texture2DArray::SetSize(unsigned layers, int width, int height, unsigned format, TextureUsage usage)
-{
-    if (width <= 0 || height <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative texture array size");
-        return false;
-    }
-    if (usage == TEXTURE_DEPTHSTENCIL)
-    {
-        URHO3D_LOGERROR("Depth-stencil usage not supported for texture arrays");
-        return false;
-    }
-
-    // Delete the old rendersurfaces if any
-    renderSurface_.Reset();
-
-    usage_ = usage;
-
-    if (usage_ == TEXTURE_RENDERTARGET)
-    {
-        renderSurface_ = new RenderSurface(this);
-
-        // Nearest filtering and mipmaps disabled by default
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
-    }
-    else if (usage_ == TEXTURE_DYNAMIC)
-        requestedLevels_ = 1;
-
-    if (usage_ == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(Texture2DArray, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
-
-    width_ = width;
-    height_ = height;
-    format_ = format;
-    if (layers)
-        layers_ = layers;
-
-    layerMemoryUse_.Resize(layers_);
-    for (unsigned i = 0; i < layers_; ++i)
-        layerMemoryUse_[i] = 0;
-
-    return Create();
-}
-
 bool Texture2DArray::SetData(unsigned layer, unsigned level, int x, int y, int width, int height, const void* data)
 {
     URHO3D_PROFILE(SetTextureData);
 
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("Texture array not created, can not set data");
         return false;
@@ -268,7 +135,7 @@ bool Texture2DArray::SetData(unsigned layer, unsigned level, int x, int y, int w
         D3D11_MAPPED_SUBRESOURCE mappedData;
         mappedData.pData = 0;
 
-        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
+        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_.ptr_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
             &mappedData);
         if (FAILED(hr) || !mappedData.pData)
         {
@@ -279,7 +146,7 @@ bool Texture2DArray::SetData(unsigned layer, unsigned level, int x, int y, int w
         {
             for (int row = 0; row < height; ++row)
                 memcpy((unsigned char*)mappedData.pData + (row + y) * mappedData.RowPitch + rowStart, src + row * rowSize, rowSize);
-            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource);
+            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_.ptr_, subResource);
         }
     }
     else
@@ -292,7 +159,7 @@ bool Texture2DArray::SetData(unsigned layer, unsigned level, int x, int y, int w
         destBox.front = 0;
         destBox.back = 1;
 
-        graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Resource*)object_, subResource, &destBox, data,
+        graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Resource*)object_.ptr_, subResource, &destBox, data,
             rowSize, 0);
     }
 
@@ -384,7 +251,7 @@ bool Texture2DArray::SetData(unsigned layer, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.ptr_)
             {
                 URHO3D_LOGERROR("Texture array layer 0 must be loaded first");
                 return false;
@@ -440,7 +307,7 @@ bool Texture2DArray::SetData(unsigned layer, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.ptr_)
             {
                 URHO3D_LOGERROR("Texture array layer 0 must be loaded first");
                 return false;
@@ -482,7 +349,7 @@ bool Texture2DArray::SetData(unsigned layer, Image* image, bool useAlpha)
 
 bool Texture2DArray::GetData(unsigned layer, unsigned level, void* dest) const
 {
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("Texture array not created, can not get data");
         return false;
@@ -538,7 +405,7 @@ bool Texture2DArray::GetData(unsigned layer, unsigned level, void* dest) const
     srcBox.bottom = (UINT)levelHeight;
     srcBox.front = 0;
     srcBox.back = 1;
-    graphics_->GetImpl()->GetDeviceContext()->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, (ID3D11Resource*)object_,
+    graphics_->GetImpl()->GetDeviceContext()->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, (ID3D11Resource*)object_.ptr_,
         srcSubResource, &srcBox);
 
     D3D11_MAPPED_SUBRESOURCE mappedData;
@@ -592,7 +459,7 @@ bool Texture2DArray::Create()
     HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, (ID3D11Texture2D**)&object_);
     if (FAILED(hr))
     {
-        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_SAFE_RELEASE(object_.ptr_);
         URHO3D_LOGD3DERROR("Failed to create texture array", hr);
         return false;
     }
@@ -615,7 +482,7 @@ bool Texture2DArray::Create()
         srvDesc.Texture2DArray.MostDetailedMip = 0;
     }
 
-    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_, &srvDesc,
+    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_.ptr_, &srvDesc,
         (ID3D11ShaderResourceView**)&shaderResourceView_);
     if (FAILED(hr))
     {
@@ -642,7 +509,7 @@ bool Texture2DArray::Create()
             renderTargetViewDesc.Texture2DArray.FirstArraySlice = 0;
         }
 
-        hr = graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_, &renderTargetViewDesc,
+        hr = graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_.ptr_, &renderTargetViewDesc,
             (ID3D11RenderTargetView**)&renderSurface_->renderTargetView_);
 
         if (FAILED(hr))
@@ -656,15 +523,4 @@ bool Texture2DArray::Create()
     return true;
 }
 
-void Texture2DArray::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    if (renderSurface_ && (renderSurface_->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurface_->IsUpdateQueued()))
-    {
-        Renderer* renderer = GetSubsystem<Renderer>();
-        if (renderer)
-            renderer->QueueRenderSurface(renderSurface_);
-        renderSurface_->ResetUpdateQueued();
-    }
-}
-
 }

+ 0 - 95
Source/Urho3D/Graphics/Direct3D11/D3D11Texture2DArray.h

@@ -1,95 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-
-namespace Urho3D
-{
-
-class Deserializer;
-class Image;
-
-/// 2D texture array resource.
-class URHO3D_API Texture2DArray : public Texture
-{
-    URHO3D_OBJECT(Texture2DArray, Texture)
-
-public:
-    /// Construct.
-    Texture2DArray(Context* context);
-    /// Destruct.
-    virtual ~Texture2DArray();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Release texture.
-    virtual void Release();
-
-    /// Set the number of layers in the texture. To be used before SetData.
-    void SetLayers(unsigned layers);
-    /// Set layers, size, format and usage. Set layers to zero to leave them unchanged. Return true if successful.
-    bool SetSize(unsigned layers, int width, int height, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a face's mip level. Return true if successful.
-    bool SetData(unsigned layer, unsigned level, int x, int y, int width, int height, const void* data);
-    /// Set data of one face from a stream. Return true if successful.
-    bool SetData(unsigned layer, Deserializer& source);
-    /// Set data of one face from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(unsigned layer, Image* image, bool useAlpha = false);
-
-    /// Return number of layers in the texture.
-    unsigned GetLayers() const { return layers_; }
-    /// Get data from a layer's mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(unsigned layer, unsigned level, void* dest) const;
-    /// Return render surface.
-    RenderSurface* GetRenderSurface() const { return renderSurface_; }
-
-private:
-    /// Create texture array.
-    bool Create();
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
-
-    /// Texture array layers number.
-    unsigned layers_;
-    /// Render surfaces.
-    SharedPtr<RenderSurface> renderSurface_;
-    /// Memory use per layer.
-    PODVector<unsigned> layerMemoryUse_;
-    /// Currently locked mip level.
-    int lockedLevel_;
-    /// Currently locked layer.
-    int lockedLayer_;
-    /// Layer image files acquired during BeginLoad.
-    Vector<SharedPtr<Image> > loadImages_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 15 - 133
Source/Urho3D/Graphics/Direct3D11/D3D11Texture3D.cpp

@@ -39,112 +39,19 @@
 namespace Urho3D
 {
 
-Texture3D::Texture3D(Context* context) :
-    Texture(context)
+void Texture3D::OnDeviceLost()
 {
+    // No-op on Direct3D11
 }
 
-Texture3D::~Texture3D()
+void Texture3D::OnDeviceReset()
 {
-    Release();
-}
-
-void Texture3D::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Texture3D>();
-}
-
-bool Texture3D::BeginLoad(Deserializer& source)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    String texPath, texName, texExt;
-    SplitPath(GetName(), texPath, texName, texExt);
-
-    cache->ResetDependencies(this);
-
-    loadParameters_ = new XMLFile(context_);
-    if (!loadParameters_->Load(source))
-    {
-        loadParameters_.Reset();
-        return false;
-    }
-
-    XMLElement textureElem = loadParameters_->GetRoot();
-    XMLElement volumeElem = textureElem.GetChild("volume");
-    XMLElement colorlutElem = textureElem.GetChild("colorlut");
-
-    if (volumeElem)
-    {
-        String name = volumeElem.GetAttribute("name");
-
-        String volumeTexPath, volumeTexName, volumeTexExt;
-        SplitPath(name, volumeTexPath, volumeTexName, volumeTexExt);
-        // If path is empty, add the XML file path
-        if (volumeTexPath.Empty())
-            name = texPath + name;
-
-        loadImage_ = cache->GetTempResource<Image>(name);
-        // Precalculate mip levels if async loading
-        if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING)
-            loadImage_->PrecalculateLevels();
-        cache->StoreResourceDependency(this, name);
-        return true;
-    }
-    else if (colorlutElem)
-    {
-        String name = colorlutElem.GetAttribute("name");
-
-        String colorlutTexPath, colorlutTexName, colorlutTexExt;
-        SplitPath(name, colorlutTexPath, colorlutTexName, colorlutTexExt);
-        // If path is empty, add the XML file path
-        if (colorlutTexPath.Empty())
-            name = texPath + name;
-
-        SharedPtr<File> file = GetSubsystem<ResourceCache>()->GetFile(name);
-        loadImage_ = new Image(context_);
-        if (!loadImage_->LoadColorLUT(*(file.Get())))
-        {
-            loadParameters_.Reset();
-            loadImage_.Reset();
-            return false;
-        }
-        // Precalculate mip levels if async loading
-        if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING)
-            loadImage_->PrecalculateLevels();
-        cache->StoreResourceDependency(this, name);
-        return true;
-    }
-
-    URHO3D_LOGERROR("Texture3D XML data for " + GetName() + " did not contain either volume or colorlut element");
-    return false;
-}
-
-bool Texture3D::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-    bool success = SetData(loadImage_);
-
-    loadImage_.Reset();
-    loadParameters_.Reset();
-
-    return success;
+    // No-op on Direct3D11
 }
 
 void Texture3D::Release()
 {
-    if (graphics_ && object_)
+    if (graphics_ && object_.ptr_)
     {
         for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
         {
@@ -153,41 +60,16 @@ void Texture3D::Release()
         }
     }
 
-    URHO3D_SAFE_RELEASE(object_);
+    URHO3D_SAFE_RELEASE(object_.ptr_);
     URHO3D_SAFE_RELEASE(shaderResourceView_);
     URHO3D_SAFE_RELEASE(sampler_);
 }
 
-bool Texture3D::SetSize(int width, int height, int depth, unsigned format, TextureUsage usage)
-{
-    if (width <= 0 || height <= 0 || depth <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative 3D texture dimensions");
-        return false;
-    }
-    if (usage >= TEXTURE_RENDERTARGET)
-    {
-        URHO3D_LOGERROR("Rendertarget or depth-stencil usage not supported for 3D textures");
-        return false;
-    }
-    if (usage_ == TEXTURE_DYNAMIC)
-        requestedLevels_ = 1;
-
-    usage_ = usage;
-
-    width_ = width;
-    height_ = height;
-    depth_ = depth;
-    format_ = format;
-
-    return Create();
-}
-
 bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data)
 {
     URHO3D_PROFILE(SetTextureData);
 
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not set data");
         return false;
@@ -242,7 +124,7 @@ bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int heig
         D3D11_MAPPED_SUBRESOURCE mappedData;
         mappedData.pData = 0;
 
-        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
+        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_.ptr_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
             &mappedData);
         if (FAILED(hr) || !mappedData.pData)
         {
@@ -260,7 +142,7 @@ bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int heig
                 }
             }
 
-            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource);
+            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_.ptr_, subResource);
         }
     }
     else
@@ -276,7 +158,7 @@ bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int heig
         destBox.front = (UINT)z;
         destBox.back = (UINT)(z + depth);
 
-        graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Resource*)object_, subResource, &destBox, data,
+        graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Resource*)object_.ptr_, subResource, &destBox, data,
             rowSize, levelHeight * rowSize);
     }
 
@@ -412,7 +294,7 @@ bool Texture3D::SetData(Image* image, bool useAlpha)
 
 bool Texture3D::GetData(unsigned level, void* dest) const
 {
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not get data");
         return false;
@@ -461,7 +343,7 @@ bool Texture3D::GetData(unsigned level, void* dest) const
     srcBox.bottom = (UINT)levelHeight;
     srcBox.front = 0;
     srcBox.back = (UINT)levelDepth;
-    graphics_->GetImpl()->GetDeviceContext()->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, (ID3D11Resource*)object_,
+    graphics_->GetImpl()->GetDeviceContext()->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, (ID3D11Resource*)object_.ptr_,
         srcSubResource, &srcBox);
 
     D3D11_MAPPED_SUBRESOURCE mappedData;
@@ -512,10 +394,10 @@ bool Texture3D::Create()
     textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
     textureDesc.CPUAccessFlags = usage_ == TEXTURE_DYNAMIC ? D3D11_CPU_ACCESS_WRITE : 0;
 
-    HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture3D(&textureDesc, 0, (ID3D11Texture3D**)&object_);
+    HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture3D(&textureDesc, 0, (ID3D11Texture3D**)&object_.ptr_);
     if (FAILED(hr))
     {
-        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_SAFE_RELEASE(object_.ptr_);
         URHO3D_LOGD3DERROR("Failed to create texture", hr);
         return false;
     }
@@ -526,7 +408,7 @@ bool Texture3D::Create()
     resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
     resourceViewDesc.Texture3D.MipLevels = (UINT)levels_;
 
-    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_, &resourceViewDesc,
+    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_.ptr_, &resourceViewDesc,
         (ID3D11ShaderResourceView**)&shaderResourceView_);
     if (FAILED(hr))
     {

+ 0 - 74
Source/Urho3D/Graphics/Direct3D11/D3D11Texture3D.h

@@ -1,74 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-
-namespace Urho3D
-{
-
-class Image;
-
-/// 3D texture resource.
-class URHO3D_API Texture3D : public Texture
-{
-    URHO3D_OBJECT(Texture3D, Texture);
-
-public:
-    /// Construct.
-    Texture3D(Context* context);
-    /// Destruct.
-    virtual ~Texture3D();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Release texture.
-    virtual void Release();
-
-    /// Set size, format and usage. Zero size will follow application window size. Return true if successful.
-    bool SetSize(int width, int height, int depth, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a mip level. Return true if successful.
-    bool SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data);
-    /// Set data from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(Image* image, bool useAlpha = false);
-
-    /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(unsigned level, void* dest) const;
-
-private:
-    /// Create texture.
-    bool Create();
-
-    /// Image file acquired during BeginLoad.
-    SharedPtr<Image> loadImage_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 17 - 271
Source/Urho3D/Graphics/Direct3D11/D3D11TextureCube.cpp

@@ -43,208 +43,14 @@
 namespace Urho3D
 {
 
-static const char* cubeMapLayoutNames[] = {
-    "horizontal",
-    "horizontalnvidia",
-    "horizontalcross",
-    "verticalcross",
-    "blender",
-    0
-};
-
-static SharedPtr<Image> GetTileImage(Image* src, int tileX, int tileY, int tileWidth, int tileHeight)
+void TextureCube::OnDeviceLost()
 {
-    return SharedPtr<Image>(
-        src->GetSubimage(IntRect(tileX * tileWidth, tileY * tileHeight, (tileX + 1) * tileWidth, (tileY + 1) * tileHeight)));
+    // No-op on Direct3D11
 }
 
-TextureCube::TextureCube(Context* context) :
-    Texture(context),
-    lockedLevel_(-1)
+void TextureCube::OnDeviceReset()
 {
-    // Default to clamp mode addressing
-    addressMode_[COORD_U] = ADDRESS_CLAMP;
-    addressMode_[COORD_V] = ADDRESS_CLAMP;
-    addressMode_[COORD_W] = ADDRESS_CLAMP;
-
-    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-        faceMemoryUse_[i] = 0;
-}
-
-TextureCube::~TextureCube()
-{
-    Release();
-}
-
-void TextureCube::RegisterObject(Context* context)
-{
-    context->RegisterFactory<TextureCube>();
-}
-
-bool TextureCube::BeginLoad(Deserializer& source)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    cache->ResetDependencies(this);
-
-    String texPath, texName, texExt;
-    SplitPath(GetName(), texPath, texName, texExt);
-
-    loadParameters_ = (new XMLFile(context_));
-    if (!loadParameters_->Load(source))
-    {
-        loadParameters_.Reset();
-        return false;
-    }
-
-    loadImages_.Clear();
-
-    XMLElement textureElem = loadParameters_->GetRoot();
-    XMLElement imageElem = textureElem.GetChild("image");
-    // Single image and multiple faces with layout
-    if (imageElem)
-    {
-        String name = imageElem.GetAttribute("name");
-        // If path is empty, add the XML file path
-        if (GetPath(name).Empty())
-            name = texPath + name;
-
-        SharedPtr<Image> image = cache->GetTempResource<Image>(name);
-        if (!image)
-            return false;
-
-        int faceWidth, faceHeight;
-        loadImages_.Resize(MAX_CUBEMAP_FACES);
-
-        if (image->IsCubemap())
-        {
-            loadImages_[FACE_POSITIVE_X] = image;
-            loadImages_[FACE_NEGATIVE_X] = loadImages_[FACE_POSITIVE_X]->GetNextSibling();
-            loadImages_[FACE_POSITIVE_Y] = loadImages_[FACE_NEGATIVE_X]->GetNextSibling();
-            loadImages_[FACE_NEGATIVE_Y] = loadImages_[FACE_POSITIVE_Y]->GetNextSibling();
-            loadImages_[FACE_POSITIVE_Z] = loadImages_[FACE_NEGATIVE_Y]->GetNextSibling();
-            loadImages_[FACE_NEGATIVE_Z] = loadImages_[FACE_POSITIVE_Z]->GetNextSibling();
-        }
-        else
-        {
-        
-            CubeMapLayout layout =
-                (CubeMapLayout)GetStringListIndex(imageElem.GetAttribute("layout").CString(), cubeMapLayoutNames, CML_HORIZONTAL);
-            
-            switch (layout)
-            {
-            case CML_HORIZONTAL:
-                faceWidth = image->GetWidth() / MAX_CUBEMAP_FACES;
-                faceHeight = image->GetHeight();
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 0, 0, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 2, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 3, 0, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 4, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 5, 0, faceWidth, faceHeight);
-                break;
-
-            case CML_HORIZONTALNVIDIA:
-                faceWidth = image->GetWidth() / MAX_CUBEMAP_FACES;
-                faceHeight = image->GetHeight();
-                for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-                    loadImages_[i] = GetTileImage(image, i, 0, faceWidth, faceHeight);
-                break;
-
-            case CML_HORIZONTALCROSS:
-                faceWidth = image->GetWidth() / 4;
-                faceHeight = image->GetHeight() / 3;
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 3, 1, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 1, 2, faceWidth, faceHeight);
-                break;
-
-            case CML_VERTICALCROSS:
-                faceWidth = image->GetWidth() / 3;
-                faceHeight = image->GetHeight() / 4;
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 1, 2, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 1, 3, faceWidth, faceHeight);
-                if (loadImages_[FACE_NEGATIVE_Z])
-                {
-                    loadImages_[FACE_NEGATIVE_Z]->FlipVertical();
-                    loadImages_[FACE_NEGATIVE_Z]->FlipHorizontal();
-                }
-                break;
-
-            case CML_BLENDER:
-                faceWidth = image->GetWidth() / 3;
-                faceHeight = image->GetHeight() / 2;
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
-                break;
-            }
-        }
-    }
-    // Face per image
-    else
-    {
-        XMLElement faceElem = textureElem.GetChild("face");
-        while (faceElem)
-        {
-            String name = faceElem.GetAttribute("name");
-
-            // If path is empty, add the XML file path
-            if (GetPath(name).Empty())
-                name = texPath + name;
-
-            loadImages_.Push(cache->GetTempResource<Image>(name));
-            cache->StoreResourceDependency(this, name);
-
-            faceElem = faceElem.GetNext("face");
-        }
-    }
-
-    // Precalculate mip levels if async loading
-    if (GetAsyncLoadState() == ASYNC_LOADING)
-    {
-        for (unsigned i = 0; i < loadImages_.Size(); ++i)
-        {
-            if (loadImages_[i])
-                loadImages_[i]->PrecalculateLevels();
-        }
-    }
-
-    return true;
-}
-
-bool TextureCube::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-
-    for (unsigned i = 0; i < loadImages_.Size() && i < MAX_CUBEMAP_FACES; ++i)
-        SetData((CubeMapFace)i, loadImages_[i]);
-
-    loadImages_.Clear();
-    loadParameters_.Reset();
-
-    return true;
+    // No-op on Direct3D11
 }
 
 void TextureCube::Release()
@@ -264,61 +70,16 @@ void TextureCube::Release()
             renderSurfaces_[i]->Release();
     }
 
-    URHO3D_SAFE_RELEASE(object_);
+    URHO3D_SAFE_RELEASE(object_.ptr_);
     URHO3D_SAFE_RELEASE(shaderResourceView_);
     URHO3D_SAFE_RELEASE(sampler_);
 }
 
-bool TextureCube::SetSize(int size, unsigned format, TextureUsage usage)
-{
-    if (size <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative cube texture size");
-        return false;
-    }
-    if (usage == TEXTURE_DEPTHSTENCIL)
-    {
-        URHO3D_LOGERROR("Depth-stencil usage not supported for cube maps");
-        return false;
-    }
-
-    // Delete the old rendersurfaces if any
-    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-    {
-        renderSurfaces_[i].Reset();
-        faceMemoryUse_[i] = 0;
-    }
-
-    usage_ = usage;
-    if (usage_ == TEXTURE_RENDERTARGET)
-    {
-        for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-            renderSurfaces_[i] = new RenderSurface(this);
-
-        // Nearest filtering and mipmaps disabled by default
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
-    }
-    else if (usage_ == TEXTURE_DYNAMIC)
-        requestedLevels_ = 1;
-
-    if (usage_ == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(TextureCube, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
-
-    width_ = size;
-    height_ = size;
-    format_ = format;
-
-    return Create();
-}
-
 bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int width, int height, const void* data)
 {
     URHO3D_PROFILE(SetTextureData);
 
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not set data");
         return false;
@@ -371,7 +132,7 @@ bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int wi
         D3D11_MAPPED_SUBRESOURCE mappedData;
         mappedData.pData = 0;
 
-        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
+        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)object_.ptr_, subResource, D3D11_MAP_WRITE_DISCARD, 0,
             &mappedData);
         if (FAILED(hr) || !mappedData.pData)
         {
@@ -382,7 +143,7 @@ bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int wi
         {
             for (int row = 0; row < height; ++row)
                 memcpy((unsigned char*)mappedData.pData + (row + y) * mappedData.RowPitch + rowStart, src + row * rowSize, rowSize);
-            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_, subResource);
+            graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Resource*)object_.ptr_, subResource);
         }
     }
     else
@@ -395,7 +156,7 @@ bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int wi
         destBox.front = 0;
         destBox.back = 1;
 
-        graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Resource*)object_, subResource, &destBox, data,
+        graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Resource*)object_.ptr_, subResource, &destBox, data,
             rowSize, 0);
     }
 
@@ -482,7 +243,7 @@ bool TextureCube::SetData(CubeMapFace face, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.ptr_)
             {
                 URHO3D_LOGERROR("Cube texture face 0 must be loaded first");
                 return false;
@@ -544,7 +305,7 @@ bool TextureCube::SetData(CubeMapFace face, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.ptr_)
             {
                 URHO3D_LOGERROR("Cube texture face 0 must be loaded first");
                 return false;
@@ -586,7 +347,7 @@ bool TextureCube::SetData(CubeMapFace face, Image* image, bool useAlpha)
 
 bool TextureCube::GetData(CubeMapFace face, unsigned level, void* dest) const
 {
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not get data");
         return false;
@@ -636,7 +397,7 @@ bool TextureCube::GetData(CubeMapFace face, unsigned level, void* dest) const
     srcBox.bottom = (UINT)levelHeight;
     srcBox.front = 0;
     srcBox.back = 1;
-    graphics_->GetImpl()->GetDeviceContext()->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, (ID3D11Resource*)object_,
+    graphics_->GetImpl()->GetDeviceContext()->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, (ID3D11Resource*)object_.ptr_,
         srcSubResource, &srcBox);
 
     D3D11_MAPPED_SUBRESOURCE mappedData;
@@ -688,10 +449,10 @@ bool TextureCube::Create()
     textureDesc.CPUAccessFlags = usage_ == TEXTURE_DYNAMIC ? D3D11_CPU_ACCESS_WRITE : 0;
     textureDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
 
-    HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, (ID3D11Texture2D**)&object_);
+    HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateTexture2D(&textureDesc, 0, (ID3D11Texture2D**)&object_.ptr_);
     if (FAILED(hr))
     {
-        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_SAFE_RELEASE(object_.ptr_);
         URHO3D_LOGD3DERROR("Failed to create texture", hr);
         return false;
     }
@@ -702,7 +463,7 @@ bool TextureCube::Create()
     resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
     resourceViewDesc.Texture2D.MipLevels = (UINT)levels_;
 
-    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_, &resourceViewDesc,
+    hr = graphics_->GetImpl()->GetDevice()->CreateShaderResourceView((ID3D11Resource*)object_.ptr_, &resourceViewDesc,
         (ID3D11ShaderResourceView**)&shaderResourceView_);
     if (FAILED(hr))
     {
@@ -723,7 +484,7 @@ bool TextureCube::Create()
             renderTargetViewDesc.Texture2DArray.FirstArraySlice = i;
             renderTargetViewDesc.Texture2DArray.MipSlice = 0;
 
-            hr = graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_, &renderTargetViewDesc,
+            hr = graphics_->GetImpl()->GetDevice()->CreateRenderTargetView((ID3D11Resource*)object_.ptr_, &renderTargetViewDesc,
                 (ID3D11RenderTargetView**)&renderSurfaces_[i]->renderTargetView_);
 
             if (FAILED(hr))
@@ -738,19 +499,4 @@ bool TextureCube::Create()
     return true;
 }
 
-void TextureCube::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    Renderer* renderer = GetSubsystem<Renderer>();
-
-    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-    {
-        if (renderSurfaces_[i] && (renderSurfaces_[i]->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurfaces_[i]->IsUpdateQueued()))
-        {
-            if (renderer)
-                renderer->QueueRenderSurface(renderSurfaces_[i]);
-            renderSurfaces_[i]->ResetUpdateQueued();
-        }
-    }
-}
-
 }

+ 0 - 90
Source/Urho3D/Graphics/Direct3D11/D3D11TextureCube.h

@@ -1,90 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-
-namespace Urho3D
-{
-
-class Deserializer;
-class Image;
-
-/// Cube texture resource.
-class URHO3D_API TextureCube : public Texture
-{
-    URHO3D_OBJECT(TextureCube, Texture);
-
-public:
-    /// Construct.
-    TextureCube(Context* context);
-    /// Destruct.
-    virtual ~TextureCube();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Release texture.
-    virtual void Release();
-
-    /// Set size, format and usage. Return true if successful.
-    bool SetSize(int size, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a face's mip level. Return true if successful.
-    bool SetData(CubeMapFace face, unsigned level, int x, int y, int width, int height, const void* data);
-    /// Set data of one face from a stream. Return true if successful.
-    bool SetData(CubeMapFace face, Deserializer& source);
-    /// Set data of one face from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(CubeMapFace face, Image* image, bool useAlpha = false);
-
-    /// Get data from a face's mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(CubeMapFace face, unsigned level, void* dest) const;
-
-    /// Return render surface for one face.
-    RenderSurface* GetRenderSurface(CubeMapFace face) const { return renderSurfaces_[face]; }
-
-private:
-    /// Create texture.
-    bool Create();
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
-
-    /// Render surfaces.
-    SharedPtr<RenderSurface> renderSurfaces_[MAX_CUBEMAP_FACES];
-    /// Memory use per face.
-    unsigned faceMemoryUse_[MAX_CUBEMAP_FACES];
-    /// Currently locked mip level.
-    int lockedLevel_;
-    /// Currently locked face.
-    CubeMapFace lockedFace_;
-    /// Face image files acquired during BeginLoad.
-    Vector<SharedPtr<Image> > loadImages_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 17 - 175
Source/Urho3D/Graphics/Direct3D11/D3D11VertexBuffer.cpp

@@ -32,28 +32,14 @@
 namespace Urho3D
 {
 
-VertexBuffer::VertexBuffer(Context* context, bool forceHeadless) :
-    Object(context),
-    GPUObject(forceHeadless ? (Graphics*)0 : GetSubsystem<Graphics>()),
-    vertexCount_(0),
-    elementMask_(0),
-    lockState_(LOCK_NONE),
-    lockStart_(0),
-    lockCount_(0),
-    lockScratchData_(0),
-    dynamic_(false),
-    shadowed_(false)
+void VertexBuffer::OnDeviceLost()
 {
-    UpdateOffsets();
-
-    // Force shadowing mode if graphics subsystem does not exist
-    if (!graphics_)
-        shadowed_ = true;
+    // No-op on Direct3D11
 }
 
-VertexBuffer::~VertexBuffer()
+void VertexBuffer::OnDeviceReset()
 {
-    Release();
+    // No-op on Direct3D11
 }
 
 void VertexBuffer::Release()
@@ -69,47 +55,7 @@ void VertexBuffer::Release()
         }
     }
 
-    URHO3D_SAFE_RELEASE(object_);
-}
-
-void VertexBuffer::SetShadowed(bool enable)
-{
-    // If no graphics subsystem, can not disable shadowing
-    if (!graphics_)
-        enable = true;
-
-    if (enable != shadowed_)
-    {
-        if (enable && vertexSize_ && vertexCount_)
-            shadowData_ = new unsigned char[vertexCount_ * vertexSize_];
-        else
-            shadowData_.Reset();
-
-        shadowed_ = enable;
-    }
-}
-
-bool VertexBuffer::SetSize(unsigned vertexCount, unsigned elementMask, bool dynamic)
-{
-    return SetSize(vertexCount, GetElements(elementMask), dynamic);
-}
-
-bool VertexBuffer::SetSize(unsigned vertexCount, const PODVector<VertexElement>& elements, bool dynamic)
-{
-    Unlock();
-
-    dynamic_ = dynamic;
-    vertexCount_ = vertexCount;
-    elements_ = elements;
-
-    UpdateOffsets();
-
-    if (shadowed_ && vertexCount_ && vertexSize_)
-        shadowData_ = new unsigned char[vertexCount_ * vertexSize_];
-    else
-        shadowData_.Reset();
-
-    return Create();
+    URHO3D_SAFE_RELEASE(object_.ptr_);
 }
 
 bool VertexBuffer::SetData(const void* data)
@@ -129,7 +75,7 @@ bool VertexBuffer::SetData(const void* data)
     if (shadowData_ && data != shadowData_.Get())
         memcpy(shadowData_.Get(), data, vertexCount_ * vertexSize_);
 
-    if (object_)
+    if (object_.ptr_)
     {
         if (dynamic_)
         {
@@ -152,7 +98,7 @@ bool VertexBuffer::SetData(const void* data)
             destBox.front = 0;
             destBox.back = 1;
 
-            graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Buffer*)object_, 0, &destBox, data, 0, 0);
+            graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Buffer*)object_.ptr_, 0, &destBox, data, 0, 0);
         }
     }
 
@@ -188,7 +134,7 @@ bool VertexBuffer::SetDataRange(const void* data, unsigned start, unsigned count
     if (shadowData_ && shadowData_.Get() + start * vertexSize_ != data)
         memcpy(shadowData_.Get() + start * vertexSize_, data, count * vertexSize_);
 
-    if (object_)
+    if (object_.ptr_)
     {
         if (dynamic_)
         {
@@ -211,7 +157,7 @@ bool VertexBuffer::SetDataRange(const void* data, unsigned start, unsigned count
             destBox.front = 0;
             destBox.back = 1;
 
-            graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Buffer*)object_, 0, &destBox, data, 0, 0);
+            graphics_->GetImpl()->GetDeviceContext()->UpdateSubresource((ID3D11Buffer*)object_.ptr_, 0, &destBox, data, 0, 0);
         }
     }
 
@@ -245,7 +191,7 @@ void* VertexBuffer::Lock(unsigned start, unsigned count, bool discard)
     lockCount_ = count;
 
     // Because shadow data must be kept in sync, can only lock hardware buffer if not shadowed
-    if (object_ && !shadowData_ && dynamic_)
+    if (object_.ptr_ && !shadowData_ && dynamic_)
         return MapBuffer(start, count, discard);
     else if (shadowData_)
     {
@@ -287,110 +233,6 @@ void VertexBuffer::Unlock()
     }
 }
 
-void VertexBuffer::UpdateOffsets()
-{
-    unsigned elementOffset = 0;
-    elementHash_ = 0;
-    elementMask_ = 0;
-
-    for (PODVector<VertexElement>::Iterator i = elements_.Begin(); i != elements_.End(); ++i)
-    {
-        i->offset_ = elementOffset;
-        elementOffset += ELEMENT_TYPESIZES[i->type_];
-        elementHash_ <<= 6;
-        elementHash_ += (((int)i->type_ + 1) * ((int)i->semantic_ + 1) + i->index_);
-
-        for (unsigned j = 0; j < MAX_LEGACY_VERTEX_ELEMENTS; ++j)
-        {
-            const VertexElement& legacy = LEGACY_VERTEXELEMENTS[j];
-            if (i->type_ == legacy.type_ && i->semantic_ == legacy.semantic_ && i->index_ == legacy.index_)
-                elementMask_ |= (1 << j);
-        }
-    }
-
-    vertexSize_ = elementOffset;
-}
-
-const VertexElement* VertexBuffer::GetElement(VertexElementSemantic semantic, unsigned char index) const
-{
-    for (PODVector<VertexElement>::ConstIterator i = elements_.Begin(); i != elements_.End(); ++i)
-    {
-        if (i->semantic_ == semantic && i->index_ == index)
-            return &(*i);
-    }
-
-    return 0;
-}
-
-const VertexElement* VertexBuffer::GetElement(VertexElementType type, VertexElementSemantic semantic, unsigned char index) const
-{
-    for (PODVector<VertexElement>::ConstIterator i = elements_.Begin(); i != elements_.End(); ++i)
-    {
-        if (i->type_ == type && i->semantic_ == semantic && i->index_ == index)
-            return &(*i);
-    }
-
-    return 0;
-}
-
-const VertexElement* VertexBuffer::GetElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
-{
-    for (PODVector<VertexElement>::ConstIterator i = elements.Begin(); i != elements.End(); ++i)
-    {
-        if (i->type_ == type && i->semantic_ == semantic && i->index_ == index)
-            return &(*i);
-    }
-
-    return 0;
-}
-
-bool VertexBuffer::HasElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
-{
-    return GetElement(elements, type, semantic, index) != 0;
-}
-
-unsigned VertexBuffer::GetElementOffset(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
-{
-    const VertexElement* element = GetElement(elements, type, semantic, index);
-    return element ? element->offset_ : M_MAX_UNSIGNED;
-}
-
-PODVector<VertexElement> VertexBuffer::GetElements(unsigned elementMask)
-{
-    PODVector<VertexElement> ret;
-
-    for (unsigned i = 0; i < MAX_LEGACY_VERTEX_ELEMENTS; ++i)
-    {
-        if (elementMask & (1 << i))
-            ret.Push(LEGACY_VERTEXELEMENTS[i]);
-    }
-
-    return ret;
-}
-
-unsigned VertexBuffer::GetVertexSize(const PODVector<VertexElement>& elements)
-{
-    unsigned size = 0;
-
-    for (unsigned i = 0; i < elements.Size(); ++i)
-        size += ELEMENT_TYPESIZES[elements[i].type_];
-
-    return size;
-}
-
-unsigned VertexBuffer::GetVertexSize(unsigned elementMask)
-{
-    unsigned size = 0;
-
-    for (unsigned i = 0; i < MAX_LEGACY_VERTEX_ELEMENTS; ++i)
-    {
-        if (elementMask & (1 << i))
-            size += ELEMENT_TYPESIZES[LEGACY_VERTEXELEMENTS[i].type_];
-    }
-
-    return size;
-}
-
 bool VertexBuffer::Create()
 {
     Release();
@@ -407,10 +249,10 @@ bool VertexBuffer::Create()
         bufferDesc.Usage = dynamic_ ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
         bufferDesc.ByteWidth = (UINT)(vertexCount_ * vertexSize_);
 
-        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_);
+        HRESULT hr = graphics_->GetImpl()->GetDevice()->CreateBuffer(&bufferDesc, 0, (ID3D11Buffer**)&object_.ptr_);
         if (FAILED(hr))
         {
-            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_SAFE_RELEASE(object_.ptr_);
             URHO3D_LOGD3DERROR("Failed to create vertex buffer", hr);
             return false;
         }
@@ -421,7 +263,7 @@ bool VertexBuffer::Create()
 
 bool VertexBuffer::UpdateToGPU()
 {
-    if (object_ && shadowData_)
+    if (object_.ptr_ && shadowData_)
         return SetData(shadowData_.Get());
     else
         return false;
@@ -431,12 +273,12 @@ void* VertexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
 {
     void* hwData = 0;
 
-    if (object_)
+    if (object_.ptr_)
     {
         D3D11_MAPPED_SUBRESOURCE mappedData;
         mappedData.pData = 0;
 
-        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Buffer*)object_, 0, discard ? D3D11_MAP_WRITE_DISCARD :
+        HRESULT hr = graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Buffer*)object_.ptr_, 0, discard ? D3D11_MAP_WRITE_DISCARD :
             D3D11_MAP_WRITE, 0, &mappedData);
         if (FAILED(hr) || !mappedData.pData)
             URHO3D_LOGD3DERROR("Failed to map vertex buffer", hr);
@@ -452,9 +294,9 @@ void* VertexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
 
 void VertexBuffer::UnmapBuffer()
 {
-    if (object_ && lockState_ == LOCK_HARDWARE)
+    if (object_.ptr_ && lockState_ == LOCK_HARDWARE)
     {
-        graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Buffer*)object_, 0);
+        graphics_->GetImpl()->GetDeviceContext()->Unmap((ID3D11Buffer*)object_.ptr_, 0);
         lockState_ = LOCK_NONE;
     }
 }

+ 0 - 165
Source/Urho3D/Graphics/Direct3D11/D3D11VertexBuffer.h

@@ -1,165 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/ArrayPtr.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-
-namespace Urho3D
-{
-
-/// Hardware vertex buffer.
-class URHO3D_API VertexBuffer : public Object, public GPUObject
-{
-    URHO3D_OBJECT(VertexBuffer, Object);
-
-public:
-    /// Construct.
-    VertexBuffer(Context* context, bool forceHeadless = false);
-    /// Destruct.
-    virtual ~VertexBuffer();
-
-    /// Release buffer.
-    virtual void Release();
-
-    /// Enable shadowing in CPU memory. Shadowing is forced on if the graphics subsystem does not exist.
-    void SetShadowed(bool enable);
-    /// Set size, vertex elements and dynamic mode. Previous data will be lost.
-    bool SetSize(unsigned vertexCount, const PODVector<VertexElement>& elements, bool dynamic = false);
-    /// Set size and vertex elements and dynamic mode using legacy element bitmask. Previous data will be lost.
-    bool SetSize(unsigned vertexCount, unsigned elementMask, bool dynamic = false);
-    /// Set all data in the buffer.
-    bool SetData(const void* data);
-    /// Set a data range in the buffer. Optionally discard data outside the range.
-    bool SetDataRange(const void* data, unsigned start, unsigned count, bool discard = false);
-    /// Lock the buffer for write-only editing. Return data pointer if successful. Optionally discard data outside the range.
-    void* Lock(unsigned start, unsigned count, bool discard = false);
-    /// Unlock the buffer and apply changes to the GPU buffer.
-    void Unlock();
-
-    /// Return whether CPU memory shadowing is enabled.
-    bool IsShadowed() const { return shadowed_; }
-
-    /// Return whether is dynamic.
-    bool IsDynamic() const { return dynamic_; }
-
-    /// Return whether is currently locked.
-    bool IsLocked() const { return lockState_ != LOCK_NONE; }
-
-    /// Return number of vertices.
-    unsigned GetVertexCount() const { return vertexCount_; }
-
-    /// Return vertex size in bytes.
-    unsigned GetVertexSize() const { return vertexSize_; }
-
-    /// Return vertex elements.
-    const PODVector<VertexElement>& GetElements() const { return elements_; }
-
-    /// Return vertex element, or null if does not exist.
-    const VertexElement* GetElement(VertexElementSemantic semantic, unsigned char index = 0) const;
-
-    /// Return vertex element with specific type, or null if does not exist.
-    const VertexElement* GetElement(VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0) const;
-
-    /// Return whether has a specified element semantic.
-    bool HasElement(VertexElementSemantic semantic, unsigned char index = 0) const { return GetElement(semantic, index) != 0; }
-
-    /// Return whether has an element semantic with specific type.
-    bool HasElement(VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0) const { return GetElement(type, semantic, index) != 0; }
-
-    /// Return offset of a element within vertex, or M_MAX_UNSIGNED if does not exist.
-    unsigned GetElementOffset(VertexElementSemantic semantic, unsigned char index = 0) const { const VertexElement* element = GetElement(semantic, index); return element ? element->offset_ : M_MAX_UNSIGNED; }
-
-    /// Return offset of a element with specific type within vertex, or M_MAX_UNSIGNED if element does not exist.
-    unsigned GetElementOffset(VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0) const { const VertexElement* element = GetElement(type, semantic, index); return element ? element->offset_ : M_MAX_UNSIGNED; }
-
-    /// Return legacy vertex element mask. Note that both semantic and type must match the legacy element for a mask bit to be set.
-    unsigned GetElementMask() const { return elementMask_; }
-
-    /// Return CPU memory shadow data.
-    unsigned char* GetShadowData() const { return shadowData_.Get(); }
-
-    /// Return shared array pointer to the CPU memory shadow data.
-    SharedArrayPtr<unsigned char> GetShadowDataShared() const { return shadowData_; }
-
-    /// Return buffer hash for building vertex declarations. Used internally.
-    unsigned long long GetBufferHash(unsigned streamIndex) { return elementHash_ << (streamIndex * 16); }
-
-    /// Return element with specified type and semantic from a vertex element list, or null if does not exist.
-    static const VertexElement* GetElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0);
-
-    /// Return whether element list has a specified element type and semantic.
-    static bool HasElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0);
-
-    /// Return element offset for specified type and semantic from a vertex element list, or M_MAX_UNSIGNED if does not exist.
-    static unsigned GetElementOffset(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0);
-
-    /// Return a vertex element list from a legacy element bitmask.
-    static PODVector<VertexElement> GetElements(unsigned elementMask);
-
-    /// Return vertex size from an element list.
-    static unsigned GetVertexSize(const PODVector<VertexElement>& elements);
-
-    /// Return vertex size for a legacy vertex element bitmask.
-    static unsigned GetVertexSize(unsigned elementMask);
-
-private:
-    /// Update offsets of vertex elements.
-    void UpdateOffsets();
-    /// Create buffer.
-    bool Create();
-    /// Update the shadow data to the GPU buffer.
-    bool UpdateToGPU();
-    /// Map the GPU buffer into CPU memory.
-    void* MapBuffer(unsigned start, unsigned count, bool discard);
-    /// Unmap the GPU buffer.
-    void UnmapBuffer();
-
-    /// Shadow data.
-    SharedArrayPtr<unsigned char> shadowData_;
-    /// Number of vertices.
-    unsigned vertexCount_;
-    /// Vertex size.
-    unsigned vertexSize_;
-    /// Vertex elements.
-    PODVector<VertexElement> elements_;
-    /// Vertex element hash.
-    unsigned long long elementHash_;
-    /// Vertex element legacy bitmask.
-    unsigned elementMask_;
-    /// Buffer locking state.
-    LockState lockState_;
-    /// Lock start vertex.
-    unsigned lockStart_;
-    /// Lock number of vertices.
-    unsigned lockCount_;
-    /// Scratch buffer for fallback locking.
-    void* lockScratchData_;
-    /// Dynamic flag.
-    bool dynamic_;
-    /// Shadowed flag.
-    bool shadowed_;
-};
-
-}

+ 11 - 10
Source/Urho3D/Graphics/Direct3D11/D3D11GPUObject.cpp → Source/Urho3D/Graphics/Direct3D9/D3D9ConstantBuffer.cpp

@@ -23,29 +23,30 @@
 #include "../../Precompiled.h"
 
 #include "../../Graphics/Graphics.h"
+#include "../../Graphics/ConstantBuffer.h"
+#include "../../IO/Log.h"
 
 #include "../../DebugNew.h"
 
 namespace Urho3D
 {
 
-GPUObject::GPUObject(Graphics* graphics) :
-    graphics_(graphics),
-    object_(0)
+void ConstantBuffer::OnDeviceReset()
 {
-    if (graphics_)
-        graphics->AddGPUObject(this);
 }
 
-GPUObject::~GPUObject()
+void ConstantBuffer::Release()
 {
-    if (graphics_)
-        graphics_->RemoveGPUObject(this);
 }
 
-Graphics* GPUObject::GetGraphics() const
+bool ConstantBuffer::SetSize(unsigned size)
+{
+    URHO3D_LOGERROR("Constant buffers are not supported on Direct3D9");
+    return false;
+}
+
+void ConstantBuffer::Apply()
 {
-    return graphics_;
 }
 
 }

+ 0 - 76
Source/Urho3D/Graphics/Direct3D9/D3D9GPUObject.h

@@ -1,76 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-
-namespace Urho3D
-{
-
-class Graphics;
-
-/// Base class for GPU resources.
-class URHO3D_API GPUObject
-{
-public:
-    /// Construct with graphics subsystem pointer.
-    GPUObject(Graphics* graphics);
-    /// Destruct. Remove from the graphics subsystem.
-    virtual ~GPUObject();
-
-    /// Release default pool resources.
-    virtual void OnDeviceLost() { }
-
-    /// Recreate default pool resources.
-    virtual void OnDeviceReset() { }
-
-    /// Unconditionally release the GPU resource.
-    virtual void Release() { }
-
-    /// Clear the data lost flag.
-    void ClearDataLost();
-
-    /// Return the graphics subsystem.
-    Graphics* GetGraphics() const;
-
-    /// Return Direct3D object.
-    void* GetGPUObject() const { return object_; }
-
-    /// Return whether data is lost due to device loss.
-    bool IsDataLost() const { return dataLost_; }
-
-    /// Return whether has pending data assigned while device was lost.
-    bool HasPendingData() const { return dataPending_; }
-
-protected:
-    /// Graphics subsystem.
-    WeakPtr<Graphics> graphics_;
-    /// Direct3D object.
-    void* object_;
-    /// Data lost flag.
-    bool dataLost_;
-    /// Data pending flag.
-    bool dataPending_;
-};
-
-}

+ 100 - 336
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -25,37 +25,17 @@
 #include "../../Core/Context.h"
 #include "../../Core/ProcessUtils.h"
 #include "../../Core/Profiler.h"
-#include "../../Graphics/AnimatedModel.h"
-#include "../../Graphics/Animation.h"
-#include "../../Graphics/AnimationController.h"
-#include "../../Graphics/Camera.h"
-#include "../../Graphics/CustomGeometry.h"
-#include "../../Graphics/DebugRenderer.h"
-#include "../../Graphics/DecalSet.h"
 #include "../../Graphics/Graphics.h"
 #include "../../Graphics/GraphicsEvents.h"
 #include "../../Graphics/GraphicsImpl.h"
 #include "../../Graphics/IndexBuffer.h"
-#include "../../Graphics/Material.h"
-#include "../../Graphics/Octree.h"
-#include "../../Graphics/ParticleEffect.h"
-#include "../../Graphics/ParticleEmitter.h"
-#include "../../Graphics/RibbonTrail.h"
 #include "../../Graphics/Shader.h"
 #include "../../Graphics/ShaderPrecache.h"
 #include "../../Graphics/ShaderProgram.h"
-#include "../../Graphics/Skybox.h"
-#include "../../Graphics/StaticModelGroup.h"
-#include "../../Graphics/Technique.h"
-#include "../../Graphics/Terrain.h"
-#include "../../Graphics/TerrainPatch.h"
 #include "../../Graphics/Texture2D.h"
-#include "../../Graphics/Texture2DArray.h"
-#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"
 #include "../../Resource/ResourceCache.h"
@@ -257,10 +237,12 @@ static HWND GetWindowHandle(SDL_Window* window)
 static unsigned readableDepthFormat = 0;
 
 const Vector2 Graphics::pixelUVOffset(0.5f, 0.5f);
+bool Graphics::gl3Support = false;
 
 Graphics::Graphics(Context* context) :
     Object(context),
     impl_(new GraphicsImpl()),
+    window_(0),
     windowIcon_(0),
     externalWindow_(0),
     width_(0),
@@ -275,8 +257,10 @@ Graphics::Graphics(Context* context) :
     tripleBuffer_(false),
     flushGPU_(false),
     sRGB_(false),
-    deviceLost_(false),
-    queryIssued_(false),
+    anisotropySupport_(false),
+    dxtTextureSupport_(false),
+    etcTextureSupport_(false),
+    pvrtcTextureSupport_(false),
     lightPrepassSupport_(false),
     deferredSupport_(false),
     instancingSupport_(false),
@@ -286,7 +270,6 @@ Graphics::Graphics(Context* context) :
     numBatches_(0),
     maxScratchBufferRequest_(0),
     defaultTextureFilterMode_(FILTER_TRILINEAR),
-    shaderProgram_(0),
     shaderPath_("Shaders/HLSL/"),
     shaderExtension_(".hlsl"),
     orientations_("LandscapeLeft LandscapeRight"),
@@ -312,7 +295,7 @@ Graphics::~Graphics()
         gpuObjects_.Clear();
     }
 
-    vertexDeclarations_.Clear();
+    impl_->vertexDeclarations_.Clear();
 
     URHO3D_SAFE_RELEASE(impl_->defaultColorSurface_);
     URHO3D_SAFE_RELEASE(impl_->defaultDepthStencilSurface_);
@@ -320,11 +303,11 @@ Graphics::~Graphics()
     URHO3D_SAFE_RELEASE(impl_->device_);
     URHO3D_SAFE_RELEASE(impl_->interface_);
 
-    if (impl_->window_)
+    if (window_)
     {
         SDL_ShowCursor(SDL_TRUE);
-        SDL_DestroyWindow(impl_->window_);
-        impl_->window_ = 0;
+        SDL_DestroyWindow(window_);
+        window_ = 0;
     }
 
     delete impl_;
@@ -334,41 +317,6 @@ Graphics::~Graphics()
     SDL_Quit();
 }
 
-void Graphics::SetExternalWindow(void* window)
-{
-    if (!impl_->window_)
-        externalWindow_ = window;
-    else
-        URHO3D_LOGERROR("Window already opened, can not set external window");
-}
-
-void Graphics::SetWindowTitle(const String& windowTitle)
-{
-    windowTitle_ = windowTitle;
-    if (impl_->window_)
-        SDL_SetWindowTitle(impl_->window_, windowTitle_.CString());
-}
-
-void Graphics::SetWindowIcon(Image* windowIcon)
-{
-    windowIcon_ = windowIcon;
-    if (impl_->window_)
-        CreateWindowIcon();
-}
-
-void Graphics::SetWindowPosition(const IntVector2& position)
-{
-    if (impl_->window_)
-        SDL_SetWindowPosition(impl_->window_, position.x_, position.y_);
-    else
-        position_ = position; // Sets as initial position for OpenWindow()
-}
-
-void Graphics::SetWindowPosition(int x, int y)
-{
-    SetWindowPosition(IntVector2(x, y));
-}
-
 bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless, bool resizable, bool highDPI, bool vsync,
     bool tripleBuffer, int multiSample)
 {
@@ -416,7 +364,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
 
     SDL_SetHint(SDL_HINT_ORIENTATIONS, orientations_.CString());
 
-    if (!impl_->window_)
+    if (!window_)
     {
         if (!OpenWindow(width, height, resizable, borderless))
             return false;
@@ -470,7 +418,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
     if (maximize)
     {
         Maximize();
-        SDL_GetWindowSize(impl_->window_, &width, &height);
+        SDL_GetWindowSize(window_, &width, &height);
     }
 
     if (fullscreen)
@@ -490,7 +438,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
     impl_->presentParams_.MultiSampleType = multiSample > 1 ? (D3DMULTISAMPLE_TYPE)multiSample : D3DMULTISAMPLE_NONE;
     impl_->presentParams_.MultiSampleQuality = 0;
     impl_->presentParams_.SwapEffect = D3DSWAPEFFECT_DISCARD;
-    impl_->presentParams_.hDeviceWindow = GetWindowHandle(impl_->window_);
+    impl_->presentParams_.hDeviceWindow = GetWindowHandle(window_);
     impl_->presentParams_.EnableAutoDepthStencil = TRUE;
     impl_->presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8;
     impl_->presentParams_.Flags = D3DPRESENT_LINEAR_CONTENT;
@@ -582,24 +530,18 @@ void Graphics::SetFlushGPU(bool enable)
     flushGPU_ = enable;
 }
 
-void Graphics::SetOrientations(const String& orientations)
-{
-    orientations_ = orientations.Trimmed();
-    SDL_SetHint(SDL_HINT_ORIENTATIONS, orientations_.CString());
-}
-
-bool Graphics::ToggleFullscreen()
+void Graphics::SetForceGL2(bool enable)
 {
-    return SetMode(width_, height_, !fullscreen_, borderless_, resizable_, highDPI_, vsync_, tripleBuffer_, multiSample_);
+    // No effect on Direct3D9
 }
 
 void Graphics::Close()
 {
-    if (impl_->window_)
+    if (window_)
     {
         SDL_ShowCursor(SDL_TRUE);
-        SDL_DestroyWindow(impl_->window_);
-        impl_->window_ = 0;
+        SDL_DestroyWindow(window_);
+        window_ = 0;
     }
 }
 
@@ -669,7 +611,7 @@ bool Graphics::TakeScreenShot(Image& destImage)
     }
     else
     {
-        HWND hwnd = GetWindowHandle(impl_->window_);
+        HWND hwnd = GetWindowHandle(window_);
         GetClientRect(hwnd, &sourceRect);
         ClientToScreen(hwnd, (LPPOINT)&sourceRect);
     }
@@ -742,7 +684,7 @@ bool Graphics::BeginFrame()
     {
         int width, height;
 
-        SDL_GetWindowSize(impl_->window_, &width, &height);
+        SDL_GetWindowSize(window_, &width, &height);
         if (width != width_ || height != height_)
             SetMode(width, height);
     }
@@ -750,7 +692,7 @@ bool Graphics::BeginFrame()
     {
         // To prevent a loop of endless device loss and flicker, do not attempt to render when in fullscreen
         // and the window is minimized
-        if (fullscreen_ && (SDL_GetWindowFlags(impl_->window_) & SDL_WINDOW_MINIMIZED))
+        if (fullscreen_ && (SDL_GetWindowFlags(window_) & SDL_WINDOW_MINIMIZED))
             return false;
     }
 
@@ -760,7 +702,7 @@ bool Graphics::BeginFrame()
     {
         URHO3D_PROFILE(DeviceLost);
 
-        deviceLost_ = true;
+        impl_->deviceLost_ = true;
 
         // The device can not be reset yet, sleep and try again eventually
         if (hr == D3DERR_DEVICELOST)
@@ -811,7 +753,7 @@ void Graphics::EndFrame()
     // If a query was issued on the previous frame, first wait for it to finish
     if (impl_->frameQuery_)
     {
-        if (queryIssued_)
+        if (impl_->queryIssued_)
         {
             URHO3D_PROFILE(FlushGPU);
 
@@ -819,13 +761,13 @@ void Graphics::EndFrame()
             {
             }
 
-            queryIssued_ = false;
+            impl_->queryIssued_ = false;
         }
 
         if (flushGPU_)
         {
             impl_->frameQuery_->Issue(D3DISSUE_END);
-            queryIssued_ = true;
+            impl_->queryIssued_ = true;
         }
     }
 
@@ -1022,20 +964,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 +996,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 +1005,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 +1102,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 +1122,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 +1134,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 +1150,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 +1164,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 +1176,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 +1192,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 +1215,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 +1232,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 +1244,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 +1256,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 +1332,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)
@@ -1931,44 +1874,7 @@ void Graphics::PrecacheShaders(Deserializer& source)
 
 bool Graphics::IsInitialized() const
 {
-    return impl_->window_ != 0 && impl_->GetDevice() != 0;
-}
-
-IntVector2 Graphics::GetWindowPosition() const
-{
-    if (impl_->window_)
-        return position_;
-    return IntVector2::ZERO;
-}
-
-PODVector<IntVector2> Graphics::GetResolutions() const
-{
-    PODVector<IntVector2> ret;
-    unsigned numModes = (unsigned)SDL_GetNumDisplayModes(0);
-
-    for (unsigned i = 0; i < numModes; ++i)
-    {
-        SDL_DisplayMode mode;
-        SDL_GetDisplayMode(0, i, &mode);
-        int width = mode.w;
-        int height = mode.h;
-
-        // Store mode if unique
-        bool unique = true;
-        for (unsigned j = 0; j < ret.Size(); ++j)
-        {
-            if (ret[j].x_ == width && ret[j].y_ == height)
-            {
-                unique = false;
-                break;
-            }
-        }
-
-        if (unique)
-            ret.Push(IntVector2(width, height));
-    }
-
-    return ret;
+    return window_ != 0 && impl_->GetDevice() != 0;
 }
 
 PODVector<int> Graphics::GetMultiSampleLevels() const
@@ -1994,13 +1900,6 @@ PODVector<int> Graphics::GetMultiSampleLevels() const
     return ret;
 }
 
-IntVector2 Graphics::GetDesktopResolution() const
-{
-    SDL_DisplayMode mode;
-    SDL_GetDesktopDisplayMode(0, &mode);
-    return IntVector2(mode.w, mode.h);
-}
-
 unsigned Graphics::GetFormat(CompressedFormat format) const
 {
     switch (format)
@@ -2097,14 +1996,19 @@ IntVector2 Graphics::GetRenderTargetDimensions() const
     return IntVector2(width, height);
 }
 
-void Graphics::WindowResized()
+bool Graphics::IsDeviceLost() const
+{
+    return impl_->deviceLost_;
+}
+
+void Graphics::OnWindowResized()
 {
-    if (!impl_->device_ || !impl_->window_)
+    if (!impl_->device_ || !window_)
         return;
 
     int newWidth, newHeight;
 
-    SDL_GetWindowSize(impl_->window_, &newWidth, &newHeight);
+    SDL_GetWindowSize(window_, &newWidth, &newHeight);
     if (newWidth == width_ && newHeight == height_)
         return;
 
@@ -2131,14 +2035,14 @@ void Graphics::WindowResized()
     SendEvent(E_SCREENMODE, eventData);
 }
 
-void Graphics::WindowMoved()
+void Graphics::OnWindowMoved()
 {
-    if (!impl_->device_ || !impl_->window_ || fullscreen_)
+    if (!impl_->device_ || !window_ || fullscreen_)
         return;
 
     int newX, newY;
 
-    SDL_GetWindowPosition(impl_->window_, &newX, &newY);
+    SDL_GetWindowPosition(window_, &newX, &newY);
     if (newX == position_.x_ && newY == position_.y_)
         return;
 
@@ -2155,125 +2059,18 @@ void Graphics::WindowMoved()
     SendEvent(E_WINDOWPOS, eventData);
 }
 
-void Graphics::Maximize()
-{
-    if (!impl_->window_)
-        return;
-
-    SDL_MaximizeWindow(impl_->window_);
-}
-
-void Graphics::Minimize()
-{
-    if (!impl_->window_)
-        return;
-
-    SDL_MinimizeWindow(impl_->window_);
-}
-
-void Graphics::AddGPUObject(GPUObject* object)
-{
-    MutexLock lock(gpuObjectMutex_);
-
-    gpuObjects_.Push(object);
-}
-
-void Graphics::RemoveGPUObject(GPUObject* object)
-{
-    MutexLock lock(gpuObjectMutex_);
-
-    gpuObjects_.Remove(object);
-}
-
-void* Graphics::ReserveScratchBuffer(unsigned size)
-{
-    if (!size)
-        return 0;
-
-    if (size > maxScratchBufferRequest_)
-        maxScratchBufferRequest_ = size;
-
-    // First check for a free buffer that is large enough
-    for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
-    {
-        if (!i->reserved_ && i->size_ >= size)
-        {
-            i->reserved_ = true;
-            return i->data_.Get();
-        }
-    }
-
-    // Then check if a free buffer can be resized
-    for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
-    {
-        if (!i->reserved_)
-        {
-            i->data_ = new unsigned char[size];
-            i->size_ = size;
-            i->reserved_ = true;
-
-            URHO3D_LOGDEBUG("Resized scratch buffer to size " + String(size));
-
-            return i->data_.Get();
-        }
-    }
-
-    // Finally allocate a new buffer
-    ScratchBuffer newBuffer;
-    newBuffer.data_ = new unsigned char[size];
-    newBuffer.size_ = size;
-    newBuffer.reserved_ = true;
-    scratchBuffers_.Push(newBuffer);
-    return newBuffer.data_.Get();
-
-    URHO3D_LOGDEBUG("Allocated scratch buffer with size " + String(size));
-}
-
-void Graphics::FreeScratchBuffer(void* buffer)
-{
-    if (!buffer)
-        return;
-
-    for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
-    {
-        if (i->reserved_ && i->data_.Get() == buffer)
-        {
-            i->reserved_ = false;
-            return;
-        }
-    }
-
-    URHO3D_LOGWARNING("Reserved scratch buffer " + ToStringHex((unsigned)(size_t)buffer) + " not found");
-}
-
-void Graphics::CleanupScratchBuffers()
-{
-    for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
-    {
-        if (!i->reserved_ && i->size_ > maxScratchBufferRequest_ * 2 && i->size_ >= 1024 * 1024)
-        {
-            i->data_ = maxScratchBufferRequest_ > 0 ? new unsigned char[maxScratchBufferRequest_] : 0;
-            i->size_ = maxScratchBufferRequest_;
-
-            URHO3D_LOGDEBUG("Resized scratch buffer to size " + String(maxScratchBufferRequest_));
-        }
-    }
-
-    maxScratchBufferRequest_ = 0;
-}
-
 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()
@@ -2396,12 +2193,22 @@ unsigned Graphics::GetFormat(const String& formatName)
     return GetRGBFormat();
 }
 
+unsigned Graphics::GetMaxBones()
+{
+    return 64;
+}
+
+bool Graphics::GetGL3Support()
+{
+    return gl3Support;
+}
+
 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 +2216,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;
         }
     }
 }
@@ -2427,59 +2234,46 @@ bool Graphics::OpenWindow(int width, int height, bool resizable, bool borderless
         if (borderless)
             flags |= SDL_WINDOW_BORDERLESS;
 
-        impl_->window_ = SDL_CreateWindow(windowTitle_.CString(), position_.x_, position_.y_, width, height, flags);
+        window_ = SDL_CreateWindow(windowTitle_.CString(), position_.x_, position_.y_, width, height, flags);
     }
     else
-        impl_->window_ = SDL_CreateWindowFrom(externalWindow_, 0);
+        window_ = SDL_CreateWindowFrom(externalWindow_, 0);
 
-    if (!impl_->window_)
+    if (!window_)
     {
         URHO3D_LOGERRORF("Could not create window, root cause: '%s'", SDL_GetError());
         return false;
     }
 
-    SDL_GetWindowPosition(impl_->window_, &position_.x_, &position_.y_);
+    SDL_GetWindowPosition(window_, &position_.x_, &position_.y_);
 
     CreateWindowIcon();
 
     return true;
 }
 
-void Graphics::CreateWindowIcon()
-{
-    if (windowIcon_)
-    {
-        SDL_Surface* surface = windowIcon_->GetSDLSurface();
-        if (surface)
-        {
-            SDL_SetWindowIcon(impl_->window_, surface);
-            SDL_FreeSurface(surface);
-        }
-    }
-}
-
 void Graphics::AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen, bool& newBorderless)
 {
     if (!externalWindow_)
     {
         if (!newWidth || !newHeight)
         {
-            SDL_MaximizeWindow(impl_->window_);
-            SDL_GetWindowSize(impl_->window_, &newWidth, &newHeight);
+            SDL_MaximizeWindow(window_);
+            SDL_GetWindowSize(window_, &newWidth, &newHeight);
         }
         else
-            SDL_SetWindowSize(impl_->window_, newWidth, newHeight);
+            SDL_SetWindowSize(window_, newWidth, newHeight);
 
         // Hack fix: on SDL 2.0.4 a fullscreen->windowed transition results in a maximized window when the D3D device is reset, so hide before
-        SDL_HideWindow(impl_->window_);
-        SDL_SetWindowFullscreen(impl_->window_, newFullscreen ? SDL_WINDOW_FULLSCREEN : 0);
-        SDL_SetWindowBordered(impl_->window_, newBorderless ? SDL_FALSE : SDL_TRUE);
-        SDL_ShowWindow(impl_->window_);
+        SDL_HideWindow(window_);
+        SDL_SetWindowFullscreen(window_, newFullscreen ? SDL_WINDOW_FULLSCREEN : 0);
+        SDL_SetWindowBordered(window_, newBorderless ? SDL_FALSE : SDL_TRUE);
+        SDL_ShowWindow(window_);
     }
     else
     {
         // If external window, must ask its dimensions instead of trying to set them
-        SDL_GetWindowSize(impl_->window_, &newWidth, &newHeight);
+        SDL_GetWindowSize(window_, &newWidth, &newHeight);
         newFullscreen = false;
     }
 }
@@ -2535,7 +2329,7 @@ bool Graphics::CreateDevice(unsigned adapter, unsigned deviceType)
     HRESULT hr = impl_->interface_->CreateDevice(
         adapter,
         (D3DDEVTYPE)deviceType,
-        GetWindowHandle(impl_->window_),
+        GetWindowHandle(window_),
         behaviorFlags,
         &impl_->presentParams_,
         &impl_->device_);
@@ -2556,6 +2350,9 @@ bool Graphics::CreateDevice(unsigned adapter, unsigned deviceType)
 
 void Graphics::CheckFeatureSupport()
 {
+    anisotropySupport_ = true;
+    dxtTextureSupport_ = true;
+    
     // Reset features first
     lightPrepassSupport_ = false;
     deferredSupport_ = false;
@@ -2643,7 +2440,7 @@ void Graphics::ResetDevice()
 
     if (SUCCEEDED(impl_->device_->Reset(&impl_->presentParams_)))
     {
-        deviceLost_ = false;
+        impl_->deviceLost_ = false;
         OnDeviceReset();
     }
 }
@@ -2704,7 +2501,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 +2528,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,8 +2557,8 @@ void Graphics::ResetCachedState()
     impl_->srcBlend_ = D3DBLEND_ONE;
     impl_->destBlend_ = D3DBLEND_ZERO;
     impl_->blendOp_ = D3DBLENDOP_ADD;
-
-    queryIssued_ = false;
+    impl_->vertexDeclaration_ = 0;
+    impl_->queryIssued_ = false;
 }
 
 void Graphics::SetTextureUnitMappings()
@@ -2785,36 +2581,4 @@ void Graphics::SetTextureUnitMappings()
     textureUnits_["ZoneVolumeMap"] = TU_ZONE;
 }
 
-void RegisterGraphicsLibrary(Context* context)
-{
-    Animation::RegisterObject(context);
-    Material::RegisterObject(context);
-    Model::RegisterObject(context);
-    Shader::RegisterObject(context);
-    Technique::RegisterObject(context);
-    Texture2D::RegisterObject(context);
-    Texture2DArray::RegisterObject(context);
-    Texture3D::RegisterObject(context);
-    TextureCube::RegisterObject(context);
-    Camera::RegisterObject(context);
-    Drawable::RegisterObject(context);
-    Light::RegisterObject(context);
-    StaticModel::RegisterObject(context);
-    StaticModelGroup::RegisterObject(context);
-    Skybox::RegisterObject(context);
-    AnimatedModel::RegisterObject(context);
-    AnimationController::RegisterObject(context);
-    BillboardSet::RegisterObject(context);
-    ParticleEffect::RegisterObject(context);
-    ParticleEmitter::RegisterObject(context);
-    RibbonTrail::RegisterObject(context);
-    CustomGeometry::RegisterObject(context);
-    DecalSet::RegisterObject(context);
-    Terrain::RegisterObject(context);
-    TerrainPatch::RegisterObject(context);
-    DebugRenderer::RegisterObject(context);
-    Octree::RegisterObject(context);
-    Zone::RegisterObject(context);
-}
-
 }

+ 0 - 685
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.h

@@ -1,685 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/ArrayPtr.h"
-#include "../../Container/HashSet.h"
-#include "../../Core/Mutex.h"
-#include "../../Core/Object.h"
-#include "../../Graphics/GraphicsDefs.h"
-#include "../../Math/Color.h"
-#include "../../Math/Plane.h"
-#include "../../Math/Rect.h"
-#include "../../Resource/Image.h"
-
-namespace Urho3D
-{
-
-class File;
-class Image;
-class IndexBuffer;
-class GPUObject;
-class GraphicsImpl;
-class RenderSurface;
-class Shader;
-class ShaderPrecache;
-class ShaderProgram;
-class ShaderVariation;
-class Texture;
-class Texture2D;
-class TextureCube;
-class Vector3;
-class Vector4;
-class VertexBuffer;
-class VertexDeclaration;
-
-struct ShaderParameter;
-
-typedef HashMap<Pair<ShaderVariation*, ShaderVariation*>, SharedPtr<ShaderProgram> > ShaderProgramMap;
-
-/// CPU-side scratch buffer for vertex data updates.
-struct ScratchBuffer
-{
-    ScratchBuffer() :
-        size_(0),
-        reserved_(false)
-    {
-    }
-
-    /// Buffer data.
-    SharedArrayPtr<unsigned char> data_;
-    /// Data size.
-    unsigned size_;
-    /// Reserved flag.
-    bool reserved_;
-};
-
-/// %Graphics subsystem. Manages the application window, rendering state and GPU resources.
-class URHO3D_API Graphics : public Object
-{
-    URHO3D_OBJECT(Graphics, Object);
-
-public:
-    /// Construct.
-    Graphics(Context* context);
-    /// Destruct. Release the Direct3D9 device and close the window.
-    virtual ~Graphics();
-
-    /// Set external window handle. Only effective before setting the initial screen mode.
-    void SetExternalWindow(void* window);
-    /// Set window title.
-    void SetWindowTitle(const String& windowTitle);
-    /// Set window icon.
-    void SetWindowIcon(Image* windowIcon);
-    /// Set window position. Sets initial position if window is not created yet.
-    void SetWindowPosition(const IntVector2& position);
-    /// Set window position. Sets initial position if window is not created yet.
-    void SetWindowPosition(int x, int y);
-    /// Set screen mode. Return true if successful.
-    bool SetMode
-        (int width, int height, bool fullscreen, bool borderless, bool resizable, bool vsync, bool highDPI, bool tripleBuffer,
-            int multiSample);
-    /// Set screen resolution only. Return true if successful.
-    bool SetMode(int width, int height);
-    /// Set whether the main window uses sRGB conversion on write.
-    void SetSRGB(bool enable);
-    /// Set whether to flush the GPU command buffer to prevent multiple frames being queued and uneven frame timesteps. Default off, may decrease performance if enabled.
-    void SetFlushGPU(bool enable);
-    /// Set allowed screen orientations as a space-separated list of "LandscapeLeft", "LandscapeRight", "Portrait" and "PortraitUpsideDown". Affects currently only iOS platform.
-    void SetOrientations(const String& orientations);
-    /// Toggle between full screen and windowed mode. Return true if successful.
-    bool ToggleFullscreen();
-    /// Close the window.
-    void Close();
-    /// Take a screenshot. Return true if successful.
-    bool TakeScreenShot(Image& destImage);
-    /// Begin frame rendering. Return true if device available and can render.
-    bool BeginFrame();
-    /// End frame rendering and swap buffers.
-    void EndFrame();
-    /// Clear any or all of rendertarget, depth buffer and stencil buffer.
-    void Clear(unsigned flags, const Color& color = Color(0.0f, 0.0f, 0.0f, 0.0f), float depth = 1.0f, unsigned stencil = 0);
-    /// Resolve multisampled backbuffer to a texture rendertarget. The texture's size should match the viewport size.
-    bool ResolveToTexture(Texture2D* destination, const IntRect& viewport);
-    /// Draw non-indexed geometry.
-    void Draw(PrimitiveType type, unsigned vertexStart, unsigned vertexCount);
-    /// Draw indexed geometry with vertex index offset.
-    void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex, unsigned vertexCount);
-    /// Draw indexed geometry.
-    void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount);
-    /// Draw indexed, instanced geometry. An instancing vertex buffer must be set.
-    void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount,
-        unsigned instanceCount);
-    /// Draw indexed, instanced geometry with vertex index offset.
-    void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex,
-        unsigned vertexCount, unsigned instanceCount);
-    /// Set vertex buffer.
-    void SetVertexBuffer(VertexBuffer* buffer);
-    /// Set multiple vertex buffers.
-    bool SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, unsigned instanceOffset = 0);
-    /// Set multiple vertex buffers.
-    bool SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, unsigned instanceOffset = 0);
-    /// Set index buffer.
-    void SetIndexBuffer(IndexBuffer* buffer);
-    /// Set shaders.
-    void SetShaders(ShaderVariation* vs, ShaderVariation* ps);
-    /// Set shader float constants.
-    void SetShaderParameter(StringHash param, const float* data, unsigned count);
-    /// Set shader float constant.
-    void SetShaderParameter(StringHash param, float value);
-    /// Set shader boolean constant.
-    void SetShaderParameter(StringHash param, bool value);
-    /// Set shader color constant.
-    void SetShaderParameter(StringHash param, const Color& color);
-    /// Set shader 2D vector constant.
-    void SetShaderParameter(StringHash param, const Vector2& vector);
-    /// Set shader 3x3 matrix constant.
-    void SetShaderParameter(StringHash param, const Matrix3& matrix);
-    /// Set shader 3D vector constant.
-    void SetShaderParameter(StringHash param, const Vector3& vector);
-    /// Set shader 4x4 matrix constant.
-    void SetShaderParameter(StringHash param, const Matrix4& matrix);
-    /// Set shader 4D vector constant.
-    void SetShaderParameter(StringHash param, const Vector4& vector);
-    /// Set shader 3x4 matrix constant.
-    void SetShaderParameter(StringHash param, const Matrix3x4& matrix);
-    /// Set shader constant from a variant. Supported variant types: bool, float, vector2, vector3, vector4, color.
-    void SetShaderParameter(StringHash param, const Variant& value);
-    /// Check whether a shader parameter group needs update. Does not actually check whether parameters exist in the shaders.
-    bool NeedParameterUpdate(ShaderParameterGroup group, const void* source);
-    /// Check whether a shader parameter exists on the currently set shaders.
-    bool HasShaderParameter(StringHash param);
-    /// Check whether the current pixel shader uses a texture unit.
-    bool HasTextureUnit(TextureUnit unit);
-    /// Clear remembered shader parameter source group.
-    void ClearParameterSource(ShaderParameterGroup group);
-    /// Clear remembered shader parameter sources.
-    void ClearParameterSources();
-    /// Clear remembered transform shader parameter sources.
-    void ClearTransformSources();
-    /// Set texture.
-    void SetTexture(unsigned index, Texture* texture);
-    /// Set default texture filtering mode.
-    void SetDefaultTextureFilterMode(TextureFilterMode mode);
-    /// Set texture anisotropy.
-    void SetTextureAnisotropy(unsigned level);
-    /// Reset all rendertargets, depth-stencil surface and viewport.
-    void ResetRenderTargets();
-    /// Reset specific rendertarget.
-    void ResetRenderTarget(unsigned index);
-    /// Reset depth-stencil surface.
-    void ResetDepthStencil();
-    /// Set rendertarget.
-    void SetRenderTarget(unsigned index, RenderSurface* renderTarget);
-    /// Set rendertarget.
-    void SetRenderTarget(unsigned index, Texture2D* texture);
-    /// Set depth-stencil surface.
-    void SetDepthStencil(RenderSurface* depthStencil);
-    /// Set depth-stencil surface.
-    void SetDepthStencil(Texture2D* texture);
-    /// Set viewport.
-    void SetViewport(const IntRect& rect);
-    /// Set blending mode.
-    void SetBlendMode(BlendMode mode);
-    /// Set color write on/off.
-    void SetColorWrite(bool enable);
-    /// Set hardware culling mode.
-    void SetCullMode(CullMode mode);
-    /// Set depth bias.
-    void SetDepthBias(float constantBias, float slopeScaledBias);
-    /// Set depth compare.
-    void SetDepthTest(CompareMode mode);
-    /// Set depth write on/off.
-    void SetDepthWrite(bool enable);
-    /// Set polygon fill mode.
-    void SetFillMode(FillMode mode);
-    /// Set scissor test.
-    void SetScissorTest(bool enable, const Rect& rect = Rect::FULL, bool borderInclusive = true);
-    /// Set scissor test.
-    void SetScissorTest(bool enable, const IntRect& rect);
-    /// Set stencil test.
-    void SetStencilTest
-        (bool enable, CompareMode mode = CMP_ALWAYS, StencilOp pass = OP_KEEP, StencilOp fail = OP_KEEP, StencilOp zFail = OP_KEEP,
-            unsigned stencilRef = 0, unsigned compareMask = M_MAX_UNSIGNED, unsigned writeMask = M_MAX_UNSIGNED);
-    /// Set a custom clipping plane. The plane is specified in world space, but is dependent on the view and projection matrices.
-    void SetClipPlane(bool enable, const Plane& clipPlane = Plane::UP, const Matrix3x4& view = Matrix3x4::IDENTITY,
-        const Matrix4& projection = Matrix4::IDENTITY);
-    /// Begin dumping shader variation names to an XML file for precaching.
-    void BeginDumpShaders(const String& fileName);
-    /// End dumping shader variations names.
-    void EndDumpShaders();
-    /// Precache shader variations from an XML file generated with BeginDumpShaders().
-    void PrecacheShaders(Deserializer& source);
-
-    /// Return whether rendering initialized.
-    bool IsInitialized() const;
-
-    /// Return graphics implementation, which holds the actual API-specific resources.
-    GraphicsImpl* GetImpl() const { return impl_; }
-
-    /// Return OS-specific external window handle. Null if not in use.
-    void* GetExternalWindow() const { return externalWindow_; }
-
-    /// Return window title.
-    const String& GetWindowTitle() const { return windowTitle_; }
-
-    /// Return graphics API name.
-    const String& GetApiName() const { return apiName_; }
-
-    /// Return window position.
-    IntVector2 GetWindowPosition() const;
-
-    /// Return window width in pixels.
-    int GetWidth() const { return width_; }
-
-    /// Return window height in pixels.
-    int GetHeight() const { return height_; }
-
-    /// Return multisample mode (1 = no multisampling.)
-    int GetMultiSample() const { return multiSample_; }
-
-    /// Return whether window is fullscreen.
-    bool GetFullscreen() const { return fullscreen_; }
-
-    /// Return whether window is borderless.
-    bool GetBorderless() const { return borderless_; }
-
-    /// Return whether window is resizable.
-    bool GetResizable() const { return resizable_; }
-
-    /// Return whether window is high DPI.
-    bool GetHighDPI() const { return highDPI_; }
-
-    /// Return whether vertical sync is on.
-    bool GetVSync() const { return vsync_; }
-
-    /// Return whether triple buffering is enabled.
-    bool GetTripleBuffer() const { return tripleBuffer_; }
-
-    /// Return whether the main window is using sRGB conversion on write.
-    bool GetSRGB() const { return sRGB_; }
-
-    /// Return whether the GPU command buffer is flushed each frame.
-    bool GetFlushGPU() const { return flushGPU_; }
-
-    /// Return allowed screen orientations.
-    const String& GetOrientations() const { return orientations_; }
-
-    /// Return whether Direct3D device is lost, and can not yet render. This happens during fullscreen resolution switching.
-    bool IsDeviceLost() const { return deviceLost_; }
-
-    /// Return number of primitives drawn this frame.
-    unsigned GetNumPrimitives() const { return numPrimitives_; }
-
-    /// Return number of batches drawn this frame.
-    unsigned GetNumBatches() const { return numBatches_; }
-
-    /// Return dummy color texture format for shadow maps. Is "NULL" (consume no video memory) if supported.
-    unsigned GetDummyColorFormat() const { return dummyColorFormat_; }
-
-    /// Return shadow map depth texture format, or 0 if not supported.
-    unsigned GetShadowMapFormat() const { return shadowMapFormat_; }
-
-    /// Return 24-bit shadow map depth texture format, or 0 if not supported.
-    unsigned GetHiresShadowMapFormat() const { return hiresShadowMapFormat_; }
-
-    /// Return whether hardware instancing is supported..
-    bool GetInstancingSupport() const { return instancingSupport_; }
-
-    /// Return whether light pre-pass rendering is supported.
-    bool GetLightPrepassSupport() const { return lightPrepassSupport_; }
-
-    /// Return whether deferred rendering is supported.
-    bool GetDeferredSupport() const { return deferredSupport_; }
-
-    /// Return whether shadow map depth compare is done in hardware.
-    bool GetHardwareShadowSupport() const { return hardwareShadowSupport_; }
-
-    /// Return whether a readable hardware depth format is available.
-    bool GetReadableDepthSupport() const { return GetReadableDepthFormat() != 0; }
-
-    /// Return whether sRGB conversion on texture sampling is supported.
-    bool GetSRGBSupport() const { return sRGBSupport_; }
-
-    /// Return whether sRGB conversion on rendertarget writing is supported.
-    bool GetSRGBWriteSupport() const { return sRGBWriteSupport_; }
-
-    /// Return supported fullscreen resolutions. Will be empty if listing the resolutions is not supported on the platform (e.g. Web).
-    PODVector<IntVector2> GetResolutions() const;
-    /// Return supported multisampling levels.
-    PODVector<int> GetMultiSampleLevels() const;
-    /// Return the desktop resolution.
-    IntVector2 GetDesktopResolution() const;
-    /// Return hardware format for a compressed image format, or 0 if unsupported.
-    unsigned GetFormat(CompressedFormat format) const;
-    /// Return a shader variation by name and defines.
-    ShaderVariation* GetShader(ShaderType type, const String& name, const String& defines = String::EMPTY) const;
-    /// Return a shader variation by name and defines.
-    ShaderVariation* GetShader(ShaderType type, const char* name, const char* defines) const;
-    /// Return current vertex buffer by index.
-    VertexBuffer* GetVertexBuffer(unsigned index) const;
-
-    /// Return current index buffer.
-    IndexBuffer* GetIndexBuffer() const { return indexBuffer_; }
-
-    /// Return current vertex shader.
-    ShaderVariation* GetVertexShader() const { return vertexShader_; }
-
-    /// Return current pixel shader.
-    ShaderVariation* GetPixelShader() const { return pixelShader_; }
-
-    /// Return texture unit index by name.
-    TextureUnit GetTextureUnit(const String& name);
-    /// Return texture unit name by index.
-    const String& GetTextureUnitName(TextureUnit unit);
-    /// Return current texture by texture unit index.
-    Texture* GetTexture(unsigned index) const;
-
-    /// Return default texture filtering mode.
-    TextureFilterMode GetDefaultTextureFilterMode() const { return defaultTextureFilterMode_; }
-
-    /// Return current rendertarget by index.
-    RenderSurface* GetRenderTarget(unsigned index) const;
-
-    /// Return current depth-stencil surface.
-    RenderSurface* GetDepthStencil() const { return depthStencil_; }
-
-    /// Return the viewport coordinates.
-    IntRect GetViewport() const { return viewport_; }
-
-    /// Return texture anisotropy.
-    unsigned GetTextureAnisotropy() const { return textureAnisotropy_; }
-
-    /// Return blending mode.
-    BlendMode GetBlendMode() const { return blendMode_; }
-
-    /// Return whether color write is enabled.
-    bool GetColorWrite() const { return colorWrite_; }
-
-    /// Return hardware culling mode.
-    CullMode GetCullMode() const { return cullMode_; }
-
-    /// Return depth constant bias.
-    float GetDepthConstantBias() const { return constantDepthBias_; }
-
-    /// Return depth slope scaled bias.
-    float GetDepthSlopeScaledBias() const { return slopeScaledDepthBias_; }
-
-    /// Return depth compare mode.
-    CompareMode GetDepthTest() const { return depthTestMode_; }
-
-    /// Return whether depth write is enabled.
-    bool GetDepthWrite() const { return depthWrite_; }
-
-    /// Return polygon fill mode.
-    FillMode GetFillMode() const { return fillMode_; }
-
-    /// Return whether stencil test is enabled.
-    bool GetStencilTest() const { return stencilTest_; }
-
-    /// Return whether scissor test is enabled.
-    bool GetScissorTest() const { return scissorTest_; }
-
-    /// Return scissor rectangle coordinates.
-    const IntRect& GetScissorRect() const { return scissorRect_; }
-
-    /// Return stencil compare mode.
-    CompareMode GetStencilTestMode() const { return stencilTestMode_; }
-
-    /// Return stencil operation to do if stencil test passes.
-    StencilOp GetStencilPass() const { return stencilPass_; }
-
-    /// Return stencil operation to do if stencil test fails.
-    StencilOp GetStencilFail() const { return stencilFail_; }
-
-    /// Return stencil operation to do if depth compare fails.
-    StencilOp GetStencilZFail() const { return stencilZFail_; }
-
-    /// Return stencil reference value.
-    unsigned GetStencilRef() const { return stencilRef_; }
-
-    /// Return stencil compare bitmask.
-    unsigned GetStencilCompareMask() const { return stencilCompareMask_; }
-
-    /// Return stencil write bitmask.
-    unsigned GetStencilWriteMask() const { return stencilWriteMask_; }
-
-    /// Return whether a custom clipping plane is in use.
-    bool GetUseClipPlane() const { return useClipPlane_; }
-
-    /// Return rendertarget width and height.
-    IntVector2 GetRenderTargetDimensions() const;
-
-    /// Window was resized through user interaction. Called by Input subsystem.
-    void WindowResized();
-    /// Window was moved through user interaction. Called by Input subsystem.
-    void WindowMoved();
-    /// Maximize the Window.
-    void Maximize();
-    /// Minimize the Window.
-    void Minimize();
-    /// Add a GPU object to keep track of. Called by GPUObject.
-    void AddGPUObject(GPUObject* object);
-    /// Remove a GPU object. Called by GPUObject.
-    void RemoveGPUObject(GPUObject* object);
-    /// Reserve a CPU-side scratch buffer.
-    void* ReserveScratchBuffer(unsigned size);
-    /// Free a CPU-side scratch buffer.
-    void FreeScratchBuffer(void* buffer);
-    /// Clean up too large scratch buffers.
-    void CleanupScratchBuffers();
-    /// Clean up shader programs when a shader variation is released or destroyed.
-    void CleanupShaderPrograms(ShaderVariation* variation);
-
-    /// Return the API-specific alpha texture format.
-    static unsigned GetAlphaFormat();
-    /// Return the API-specific luminance texture format.
-    static unsigned GetLuminanceFormat();
-    /// Return the API-specific luminance alpha texture format.
-    static unsigned GetLuminanceAlphaFormat();
-    /// Return the API-specific RGB texture format.
-    static unsigned GetRGBFormat();
-    /// Return the API-specific RGBA texture format.
-    static unsigned GetRGBAFormat();
-    /// Return the API-specific RGBA 16-bit texture format.
-    static unsigned GetRGBA16Format();
-    /// Return the API-specific RGBA 16-bit float texture format.
-    static unsigned GetRGBAFloat16Format();
-    /// Return the API-specific RGBA 32-bit float texture format.
-    static unsigned GetRGBAFloat32Format();
-    /// Return the API-specific RG 16-bit texture format.
-    static unsigned GetRG16Format();
-    /// Return the API-specific RG 16-bit float texture format.
-    static unsigned GetRGFloat16Format();
-    /// Return the API-specific RG 32-bit float texture format.
-    static unsigned GetRGFloat32Format();
-    /// Return the API-specific single channel 16-bit float texture format.
-    static unsigned GetFloat16Format();
-    /// Return the API-specific single channel 32-bit float texture format.
-    static unsigned GetFloat32Format();
-    /// Return the API-specific linear depth texture format.
-    static unsigned GetLinearDepthFormat();
-    /// Return the API-specific hardware depth-stencil texture format.
-    static unsigned GetDepthStencilFormat();
-    /// Return the API-specific readable hardware depth format, or 0 if not supported.
-    static unsigned GetReadableDepthFormat();
-    /// Return the API-specific texture format from a textual description, for example "rgb".
-    static unsigned GetFormat(const String& formatName);
-
-    /// Return UV offset required for pixel perfect rendering.
-    static const Vector2& GetPixelUVOffset() { return pixelUVOffset; }
-
-    /// Return maximum number of supported bones for skinning.
-    static unsigned GetMaxBones() { return 64; }
-
-private:
-    /// Set vertex buffer stream frequency.
-    void SetStreamFrequency(unsigned index, unsigned frequency);
-    /// Reset stream frequencies.
-    void ResetStreamFrequencies();
-    /// Create the application window.
-    bool OpenWindow(int width, int height, bool resizable, bool borderless);
-    /// Create the application window icon.
-    void CreateWindowIcon();
-    /// Adjust the window for new resolution and fullscreen mode.
-    void AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen, bool& newBorderless);
-    /// Create the Direct3D interface.
-    bool CreateInterface();
-    /// Create the Direct3D device.
-    bool CreateDevice(unsigned adapter, unsigned deviceType);
-    /// Check supported rendering features.
-    void CheckFeatureSupport();
-    /// Reset the Direct3D device.
-    void ResetDevice();
-    /// Notify all GPU resources so they can release themselves as needed.
-    void OnDeviceLost();
-    /// Notify all GPU resources so they can recreate themselves as needed.
-    void OnDeviceReset();
-    /// Reset cached rendering state.
-    void ResetCachedState();
-    /// Initialize texture unit mappings.
-    void SetTextureUnitMappings();
-
-    /// Mutex for accessing the GPU objects vector from several threads.
-    Mutex gpuObjectMutex_;
-    /// Implementation.
-    GraphicsImpl* impl_;
-    /// Window title.
-    String windowTitle_;
-    /// Window Icon File Name
-    Image* windowIcon_;
-    /// External window, null if not in use (default.)
-    void* externalWindow_;
-    /// Window width in pixels.
-    int width_;
-    /// Window height in pixels.
-    int height_;
-    /// Window position.
-    IntVector2 position_;
-    /// Multisampling mode.
-    int multiSample_;
-    /// Fullscreen flag.
-    bool fullscreen_;
-    /// Borderless flag.
-    bool borderless_;
-    /// Resizable flag.
-    bool resizable_;
-    /// High DPI flag.
-    bool highDPI_;
-    /// Vertical sync flag.
-    bool vsync_;
-    /// Triple buffering flag.
-    bool tripleBuffer_;
-    /// Flush GPU command buffer flag.
-    bool flushGPU_;
-    /// sRGB conversion on write flag for the main window.
-    bool sRGB_;
-    /// Direct3D device lost flag.
-    bool deviceLost_;
-    /// Flush query issued flag.
-    bool queryIssued_;
-    /// Light pre-pass rendering support flag.
-    bool lightPrepassSupport_;
-    /// Deferred rendering support flag.
-    bool deferredSupport_;
-    /// Hardware shadow map depth compare support flag.
-    bool hardwareShadowSupport_;
-    /// Instancing support flag.
-    bool instancingSupport_;
-    /// sRGB conversion on read support flag.
-    bool sRGBSupport_;
-    /// sRGB conversion on write support flag.
-    bool sRGBWriteSupport_;
-    /// Number of primitives this frame.
-    unsigned numPrimitives_;
-    /// Number of batches this frame.
-    unsigned numBatches_;
-    /// Largest scratch buffer request this frame.
-    unsigned maxScratchBufferRequest_;
-    /// GPU objects.
-    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.
-    unsigned shadowMapFormat_;
-    /// Shadow map 24-bit depth texture format.
-    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.
-    ShaderVariation* pixelShader_;
-    /// Textures in use.
-    Texture* textures_[MAX_TEXTURE_UNITS];
-    /// Texture unit mappings.
-    HashMap<String, TextureUnit> textureUnits_;
-    /// Rendertargets in use.
-    RenderSurface* renderTargets_[MAX_RENDERTARGETS];
-    /// Depth-stencil surface in use.
-    RenderSurface* depthStencil_;
-    /// Viewport coordinates.
-    IntRect viewport_;
-    /// Texture anisotropy level.
-    unsigned textureAnisotropy_;
-    /// Blending mode.
-    BlendMode blendMode_;
-    /// Color write enable.
-    bool colorWrite_;
-    /// Hardware culling mode.
-    CullMode cullMode_;
-    /// Depth constant bias.
-    float constantDepthBias_;
-    /// Depth slope scaled bias.
-    float slopeScaledDepthBias_;
-    /// Depth compare mode.
-    CompareMode depthTestMode_;
-    /// Depth write enable flag.
-    bool depthWrite_;
-    /// Polygon fill mode.
-    FillMode fillMode_;
-    /// Scissor test rectangle.
-    IntRect scissorRect_;
-    /// Scissor test enable flag.
-    bool scissorTest_;
-    /// Stencil test compare mode.
-    CompareMode stencilTestMode_;
-    /// Stencil operation on pass.
-    StencilOp stencilPass_;
-    /// Stencil operation on fail.
-    StencilOp stencilFail_;
-    /// Stencil operation on depth fail.
-    StencilOp stencilZFail_;
-    /// Stencil test reference value.
-    unsigned stencilRef_;
-    /// Stencil compare bitmask.
-    unsigned stencilCompareMask_;
-    /// Stencil write bitmask.
-    unsigned stencilWriteMask_;
-    /// Stencil test enable flag.
-    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.
-    String shaderPath_;
-    /// File extension for shaders.
-    String shaderExtension_;
-    /// Last used shader in shader variation query.
-    mutable WeakPtr<Shader> lastShader_;
-    /// Last used shader name in shader variation query.
-    mutable String lastShaderName_;
-    /// Shader precache utility.
-    SharedPtr<ShaderPrecache> shaderPrecache_;
-    /// Allowed screen orientations.
-    String orientations_;
-    /// Graphics API name.
-    String apiName_;
-
-    /// Pixel perfect UV offset.
-    static const Vector2 pixelUVOffset;
-};
-
-/// Register Graphics library objects.
-void URHO3D_API RegisterGraphicsLibrary(Context* context);
-
-}

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

@@ -31,14 +31,16 @@ namespace Urho3D
 {
 
 GraphicsImpl::GraphicsImpl() :
-    window_(0),
     interface_(0),
     device_(0),
     defaultColorSurface_(0),
     defaultDepthStencilSurface_(0),
     frameQuery_(0),
     adapter_(D3DADAPTER_DEFAULT),
-    deviceType_(D3DDEVTYPE_HAL)
+    deviceType_(D3DDEVTYPE_HAL),
+    shaderProgram_(0),
+    deviceLost_(false),
+    queryIssued_(false)
 {
     memset(&presentParams_, 0, sizeof presentParams_);
 }

+ 22 - 7
Source/Urho3D/Graphics/Direct3D9/D3D9GraphicsImpl.h

@@ -22,12 +22,12 @@
 
 #pragma once
 
+#include "../../Graphics/ShaderProgram.h"
+#include "../../Graphics/VertexDeclaration.h"
 #include "../../Math/Color.h"
 
 #include <d3d9.h>
 
-struct SDL_Window;
-
 namespace Urho3D
 {
 
@@ -35,6 +35,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
 {
@@ -50,9 +53,6 @@ public:
     /// Return device capabilities.
     const D3DCAPS9& GetDeviceCaps() const { return deviceCaps_; }
 
-    /// Return window.
-    SDL_Window* GetWindow() const { return window_; }
-
     /// Return adapter identifier.
     const D3DADAPTER_IDENTIFIER9& GetAdapterIdentifier() const { return adapterIdentifier_; }
 
@@ -60,8 +60,6 @@ public:
     bool CheckFormatSupport(D3DFORMAT format, DWORD usage, D3DRESOURCETYPE type);
 
 private:
-    /// SDL window.
-    SDL_Window* window_;
     /// Direct3D interface.
     IDirect3D9* interface_;
     /// Direct3D device.
@@ -94,6 +92,10 @@ private:
     D3DTEXTUREADDRESS wAddressModes_[MAX_TEXTURE_UNITS];
     /// Texture border colors in use.
     Color borderColors_[MAX_TEXTURE_UNITS];
+    /// Device lost flag.
+    bool deviceLost_;
+    /// Frame query issued flag.
+    bool queryIssued_;
     /// sRGB mode in use.
     bool sRGBModes_[MAX_TEXTURE_UNITS];
     /// sRGB write flag.
@@ -110,6 +112,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_;
+
 };
 
 }

+ 20 - 132
Source/Urho3D/Graphics/Direct3D9/D3D9IndexBuffer.cpp

@@ -33,38 +33,17 @@
 namespace Urho3D
 {
 
-IndexBuffer::IndexBuffer(Context* context, bool forceHeadless) :
-    Object(context),
-    GPUObject(forceHeadless ? (Graphics*)0 : GetSubsystem<Graphics>()),
-    indexCount_(0),
-    indexSize_(0),
-    pool_(D3DPOOL_MANAGED),
-    usage_(0),
-    lockState_(LOCK_NONE),
-    lockStart_(0),
-    lockCount_(0),
-    lockScratchData_(0),
-    shadowed_(false)
-{
-    // Force shadowing mode if graphics subsystem does not exist
-    if (!graphics_)
-        shadowed_ = true;
-}
-
-IndexBuffer::~IndexBuffer()
-{
-    Release();
-}
-
 void IndexBuffer::OnDeviceLost()
 {
-    if (pool_ == D3DPOOL_DEFAULT)
+    // Dynamic buffers are in the default pool and need to be released on device loss
+    if (dynamic_)
         Release();
 }
 
 void IndexBuffer::OnDeviceReset()
 {
-    if (pool_ == D3DPOOL_DEFAULT || !object_)
+    // Dynamic buffers are in the default pool and need to be recreated after device reset
+    if (dynamic_ || !object_.ptr_)
     {
         Create();
         dataLost_ = !UpdateToGPU();
@@ -82,50 +61,7 @@ void IndexBuffer::Release()
     if (graphics_ && graphics_->GetIndexBuffer() == this)
         graphics_->SetIndexBuffer(0);
 
-    URHO3D_SAFE_RELEASE(object_);
-}
-
-void IndexBuffer::SetShadowed(bool enable)
-{
-    // If no graphics subsystem, can not disable shadowing
-    if (!graphics_)
-        enable = true;
-
-    if (enable != shadowed_)
-    {
-        if (enable && indexCount_ && indexSize_)
-            shadowData_ = new unsigned char[indexCount_ * indexSize_];
-        else
-            shadowData_.Reset();
-
-        shadowed_ = enable;
-    }
-}
-
-bool IndexBuffer::SetSize(unsigned indexCount, bool largeIndices, bool dynamic)
-{
-    Unlock();
-
-    if (dynamic)
-    {
-        pool_ = D3DPOOL_DEFAULT;
-        usage_ = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY;
-    }
-    else
-    {
-        pool_ = D3DPOOL_MANAGED;
-        usage_ = 0;
-    }
-
-    indexCount_ = indexCount;
-    indexSize_ = (unsigned)(largeIndices ? sizeof(unsigned) : sizeof(unsigned short));
-
-    if (shadowed_ && indexCount_ && indexSize_)
-        shadowData_ = new unsigned char[indexCount_ * indexSize_];
-    else
-        shadowData_.Reset();
-
-    return Create();
+    URHO3D_SAFE_RELEASE(object_.ptr_);
 }
 
 bool IndexBuffer::SetData(const void* data)
@@ -145,7 +81,7 @@ bool IndexBuffer::SetData(const void* data)
     if (shadowData_ && data != shadowData_.Get())
         memcpy(shadowData_.Get(), data, indexCount_ * indexSize_);
 
-    if (object_)
+    if (object_.ptr_)
     {
         if (graphics_->IsDeviceLost())
         {
@@ -197,7 +133,7 @@ bool IndexBuffer::SetDataRange(const void* data, unsigned start, unsigned count,
     if (shadowData_ && shadowData_.Get() + start * indexSize_ != data)
         memcpy(shadowData_.Get() + start * indexSize_, data, count * indexSize_);
 
-    if (object_)
+    if (object_.ptr_)
     {
         if (graphics_->IsDeviceLost())
         {
@@ -246,7 +182,7 @@ void* IndexBuffer::Lock(unsigned start, unsigned count, bool discard)
     lockCount_ = count;
 
     // Because shadow data must be kept in sync, can only lock hardware buffer if not shadowed
-    if (object_ && !shadowData_ && !graphics_->IsDeviceLost())
+    if (object_.ptr_ && !shadowData_ && !graphics_->IsDeviceLost())
         return MapBuffer(start, count, discard);
     else if (shadowData_)
     {
@@ -288,57 +224,6 @@ void IndexBuffer::Unlock()
     }
 }
 
-bool IndexBuffer::IsDynamic() const
-{
-    return pool_ == D3DPOOL_DEFAULT;
-}
-
-bool IndexBuffer::GetUsedVertexRange(unsigned start, unsigned count, unsigned& minVertex, unsigned& vertexCount)
-{
-    if (!shadowData_)
-    {
-        URHO3D_LOGERROR("Used vertex range can only be queried from an index buffer with shadow data");
-        return false;
-    }
-
-    if (start + count > indexCount_)
-    {
-        URHO3D_LOGERROR("Illegal index range for querying used vertices");
-        return false;
-    }
-
-    minVertex = M_MAX_UNSIGNED;
-    unsigned maxVertex = 0;
-
-    if (indexSize_ == sizeof(unsigned))
-    {
-        unsigned* indices = ((unsigned*)shadowData_.Get()) + start;
-
-        for (unsigned i = 0; i < count; ++i)
-        {
-            if (indices[i] < minVertex)
-                minVertex = indices[i];
-            if (indices[i] > maxVertex)
-                maxVertex = indices[i];
-        }
-    }
-    else
-    {
-        unsigned short* indices = ((unsigned short*)shadowData_.Get()) + start;
-
-        for (unsigned i = 0; i < count; ++i)
-        {
-            if (indices[i] < minVertex)
-                minVertex = indices[i];
-            if (indices[i] > maxVertex)
-                maxVertex = indices[i];
-        }
-    }
-
-    vertexCount = maxVertex - minVertex + 1;
-    return true;
-}
-
 bool IndexBuffer::Create()
 {
     Release();
@@ -354,17 +239,20 @@ bool IndexBuffer::Create()
             return true;
         }
 
+        unsigned pool = dynamic_ ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
+        unsigned d3dUsage = dynamic_ ? D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY : 0;
+
         IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
         HRESULT hr = device->CreateIndexBuffer(
             indexCount_ * indexSize_,
-            usage_,
+            d3dUsage,
             indexSize_ == sizeof(unsigned) ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
-            (D3DPOOL)pool_,
+            (D3DPOOL)pool,
             (IDirect3DIndexBuffer9**)&object_,
             0);
         if (FAILED(hr))
         {
-            URHO3D_SAFE_RELEASE(object_)
+            URHO3D_SAFE_RELEASE(object_.ptr_)
             URHO3D_LOGD3DERROR("Could not create index buffer", hr);
             return false;
         }
@@ -375,7 +263,7 @@ bool IndexBuffer::Create()
 
 bool IndexBuffer::UpdateToGPU()
 {
-    if (object_ && shadowData_)
+    if (object_.ptr_ && shadowData_)
         return SetData(shadowData_.Get());
     else
         return false;
@@ -385,14 +273,14 @@ void* IndexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
 {
     void* hwData = 0;
 
-    if (object_)
+    if (object_.ptr_)
     {
         DWORD flags = 0;
 
-        if (discard && usage_ & D3DUSAGE_DYNAMIC)
+        if (discard && dynamic_)
             flags = D3DLOCK_DISCARD;
 
-        HRESULT hr = ((IDirect3DIndexBuffer9*)object_)->Lock(start * indexSize_, count * indexSize_, &hwData, flags);
+        HRESULT hr = ((IDirect3DIndexBuffer9*)object_.ptr_)->Lock(start * indexSize_, count * indexSize_, &hwData, flags);
         if (FAILED(hr))
             URHO3D_LOGD3DERROR("Could not lock index buffer", hr);
         else
@@ -404,9 +292,9 @@ void* IndexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
 
 void IndexBuffer::UnmapBuffer()
 {
-    if (object_ && lockState_ == LOCK_HARDWARE)
+    if (object_.ptr_ && lockState_ == LOCK_HARDWARE)
     {
-        ((IDirect3DIndexBuffer9*)object_)->Unlock();
+        ((IDirect3DIndexBuffer9*)object_.ptr_)->Unlock();
         lockState_ = LOCK_NONE;
     }
 }

+ 0 - 120
Source/Urho3D/Graphics/Direct3D9/D3D9IndexBuffer.h

@@ -1,120 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Core/Object.h"
-#include "../../Container/ArrayPtr.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-
-namespace Urho3D
-{
-
-/// Hardware index buffer.
-class URHO3D_API IndexBuffer : public Object, public GPUObject
-{
-    URHO3D_OBJECT(IndexBuffer, Object);
-
-public:
-    /// Construct.
-    IndexBuffer(Context* context, bool forceHeadless = false);
-    /// Destruct.
-    virtual ~IndexBuffer();
-
-    /// Release default pool resources.
-    virtual void OnDeviceLost();
-    /// Recreate default pool resources.
-    virtual void OnDeviceReset();
-    /// Release buffer.
-    virtual void Release();
-
-    /// Enable shadowing in CPU memory. Shadowing is forced on if the graphics subsystem does not exist.
-    void SetShadowed(bool enable);
-    /// Set size and vertex elements and dynamic mode. Previous data will be lost.
-    bool SetSize(unsigned indexCount, bool largeIndices, bool dynamic = false);
-    /// Set all data in the buffer.
-    bool SetData(const void* data);
-    /// Set a data range in the buffer. Optionally discard data outside the range.
-    bool SetDataRange(const void* data, unsigned start, unsigned count, bool discard = false);
-    /// Lock the buffer for write-only editing. Return data pointer if successful. Optionally discard data outside the range.
-    void* Lock(unsigned start, unsigned count, bool discard = false);
-    /// Unlock the buffer and apply changes to the GPU buffer.
-    void Unlock();
-
-    /// Return whether CPU memory shadowing is enabled.
-    bool IsShadowed() const { return shadowed_; }
-
-    /// Return whether is dynamic.
-    bool IsDynamic() const;
-
-    /// Return whether is currently locked.
-    bool IsLocked() const { return lockState_ != LOCK_NONE; }
-
-    /// Return number of indices.
-    unsigned GetIndexCount() const { return indexCount_; }
-
-    /// Return index size in bytes.
-    unsigned GetIndexSize() const { return indexSize_; }
-
-    /// Return used vertex range from index range.
-    bool GetUsedVertexRange(unsigned start, unsigned count, unsigned& minVertex, unsigned& vertexCount);
-
-    /// Return CPU memory shadow data.
-    unsigned char* GetShadowData() const { return shadowData_.Get(); }
-
-    /// Return shared array pointer to the CPU memory shadow data.
-    SharedArrayPtr<unsigned char> GetShadowDataShared() const { return shadowData_; }
-
-private:
-    /// Create buffer.
-    bool Create();
-    /// Update the shadow data to the GPU buffer.
-    bool UpdateToGPU();
-    /// Map the GPU buffer into CPU memory.
-    void* MapBuffer(unsigned start, unsigned count, bool discard);
-    /// Unmap the GPU buffer.
-    void UnmapBuffer();
-
-    /// Shadow data.
-    SharedArrayPtr<unsigned char> shadowData_;
-    /// Number of indices.
-    unsigned indexCount_;
-    /// Index size.
-    unsigned indexSize_;
-    /// Memory pool.
-    unsigned pool_;
-    /// Usage type.
-    unsigned usage_;
-    /// Buffer locking state.
-    LockState lockState_;
-    /// Lock start vertex.
-    unsigned lockStart_;
-    /// Lock number of vertices.
-    unsigned lockCount_;
-    /// Scratch buffer for fallback locking.
-    void* lockScratchData_;
-    /// Shadowed flag.
-    bool shadowed_;
-};
-
-}

+ 5 - 59
Source/Urho3D/Graphics/Direct3D9/D3D9RenderSurface.cpp

@@ -42,51 +42,6 @@ RenderSurface::RenderSurface(Texture* parentTexture) :
 {
 }
 
-RenderSurface::~RenderSurface()
-{
-    Release();
-}
-
-void RenderSurface::SetNumViewports(unsigned num)
-{
-    viewports_.Resize(num);
-}
-
-void RenderSurface::SetViewport(unsigned index, Viewport* viewport)
-{
-    if (index >= viewports_.Size())
-        viewports_.Resize(index + 1);
-
-    viewports_[index] = viewport;
-}
-
-void RenderSurface::SetUpdateMode(RenderSurfaceUpdateMode mode)
-{
-    updateMode_ = mode;
-}
-
-void RenderSurface::SetLinkedRenderTarget(RenderSurface* renderTarget)
-{
-    if (renderTarget != this)
-        linkedRenderTarget_ = renderTarget;
-}
-
-void RenderSurface::SetLinkedDepthStencil(RenderSurface* depthStencil)
-{
-    if (depthStencil != this)
-        linkedDepthStencil_ = depthStencil;
-}
-
-void RenderSurface::QueueUpdate()
-{
-    updateQueued_ = true;
-}
-
-void RenderSurface::ResetUpdateQueued()
-{
-    updateQueued_ = false;
-}
-
 void RenderSurface::Release()
 {
     Graphics* graphics = parentTexture_->GetGraphics();
@@ -105,24 +60,15 @@ void RenderSurface::Release()
     URHO3D_SAFE_RELEASE(surface_);
 }
 
-int RenderSurface::GetWidth() const
-{
-    return parentTexture_->GetWidth();
-}
-
-int RenderSurface::GetHeight() const
-{
-    return parentTexture_->GetHeight();
-}
-
-TextureUsage RenderSurface::GetUsage() const
+bool RenderSurface::CreateRenderBuffer(unsigned width, unsigned height, unsigned format)
 {
-    return parentTexture_->GetUsage();
+    // Not used on Direct3D
+    return false;
 }
 
-Viewport* RenderSurface::GetViewport(unsigned index) const
+void RenderSurface::OnDeviceLost()
 {
-    return index < viewports_.Size() ? viewports_[index] : (Viewport*)0;
+    // No-op on Direct3D
 }
 
 }

+ 0 - 110
Source/Urho3D/Graphics/Direct3D9/D3D9RenderSurface.h

@@ -1,110 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Graphics/GraphicsDefs.h"
-#include "../../Graphics/Viewport.h"
-
-namespace Urho3D
-{
-
-class Texture;
-
-/// %Color or depth-stencil surface that can be rendered into.
-class URHO3D_API RenderSurface : public RefCounted
-{
-    friend class Texture2D;
-    friend class TextureCube;
-
-public:
-    /// Construct with parent texture.
-    RenderSurface(Texture* parentTexture);
-    /// Destruct.
-    ~RenderSurface();
-
-    /// Set number of viewports.
-    void SetNumViewports(unsigned num);
-    /// Set viewport.
-    void SetViewport(unsigned index, Viewport* viewport);
-    /// Set viewport update mode. Default is to update when visible.
-    void SetUpdateMode(RenderSurfaceUpdateMode mode);
-    /// Set linked color rendertarget.
-    void SetLinkedRenderTarget(RenderSurface* renderTarget);
-    /// Set linked depth-stencil surface.
-    void SetLinkedDepthStencil(RenderSurface* depthStencil);
-    /// Queue manual update of the viewport(s).
-    void QueueUpdate();
-    /// Release surface.
-    void Release();
-
-    /// Return parent texture.
-    Texture* GetParentTexture() const { return parentTexture_; }
-
-    /// Return Direct3D surface.
-    void* GetSurface() const { return surface_; }
-
-    /// Return width.
-    int GetWidth() const;
-    /// Return height.
-    int GetHeight() const;
-    /// Return usage.
-    TextureUsage GetUsage() const;
-
-    /// Return number of viewports.
-    unsigned GetNumViewports() const { return viewports_.Size(); }
-
-    /// Return viewport by index.
-    Viewport* GetViewport(unsigned index) const;
-
-    /// Return viewport update mode.
-    RenderSurfaceUpdateMode GetUpdateMode() const { return updateMode_; }
-
-    /// Return linked color rendertarget.
-    RenderSurface* GetLinkedRenderTarget() const { return linkedRenderTarget_; }
-
-    /// Return linked depth-stencil surface.
-    RenderSurface* GetLinkedDepthStencil() const { return linkedDepthStencil_; }
-
-    /// Return whether manual update queued. Called internally.
-    bool IsUpdateQueued() const { return updateQueued_; }
-    /// Reset update queued flag. Called internally.
-    void ResetUpdateQueued();
-
-private:
-    /// Parent texture.
-    Texture* parentTexture_;
-    /// Direct3D surface.
-    void* surface_;
-    /// Viewports.
-    Vector<SharedPtr<Viewport> > viewports_;
-    /// Linked color buffer.
-    WeakPtr<RenderSurface> linkedRenderTarget_;
-    /// Linked depth buffer.
-    WeakPtr<RenderSurface> linkedDepthStencil_;
-    /// Update mode for viewports.
-    RenderSurfaceUpdateMode updateMode_;
-    /// Update queued flag.
-    bool updateQueued_;
-};
-
-}

+ 65 - 69
Source/Urho3D/Graphics/Direct3D9/D3D9ShaderVariation.cpp

@@ -39,18 +39,39 @@
 namespace Urho3D
 {
 
-ShaderVariation::ShaderVariation(Shader* owner, ShaderType type) :
-    GPUObject(owner->GetSubsystem<Graphics>()),
-    owner_(owner),
-    type_(type)
+void CopyStrippedCode(PODVector<unsigned char>& byteCode, unsigned char* bufData, unsigned bufSize)
 {
-    for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
-        useTextureUnit_[i] = false;
+    unsigned const D3DSIO_COMMENT = 0xFFFE;
+    unsigned* srcWords = (unsigned*)bufData;
+    unsigned srcWordSize = bufSize >> 2;
+    byteCode.Clear();
+
+    for (unsigned i = 0; i < srcWordSize; ++i)
+    {
+        unsigned opcode = srcWords[i] & 0xffff;
+        // unsigned paramLength = (srcWords[i] & 0x0f000000) >> 24;
+        unsigned commentLength = srcWords[i] >> 16;
+
+        // For now, skip comment only at fixed position to prevent false positives
+        if (i == 1 && opcode == D3DSIO_COMMENT)
+        {
+            // Skip the comment
+            i += commentLength;
+        }
+        else
+        {
+            // Not a comment, copy the data
+            unsigned destPos = byteCode.Size();
+            byteCode.Resize(destPos + sizeof(unsigned));
+            unsigned* dest = (unsigned*)&byteCode[destPos];
+            *dest = srcWords[i];
+        }
+    }
 }
 
-ShaderVariation::~ShaderVariation()
+void ShaderVariation::OnDeviceLost()
 {
-    Release();
+    // No-op on Direct3D9, shaders are preserved through a device loss & reset
 }
 
 bool ShaderVariation::Create()
@@ -72,16 +93,15 @@ bool ShaderVariation::Create()
     extension = type_ == VS ? ".vs3" : ".ps3";
 
     String binaryShaderName = path + "Cache/" + name + "_" + StringHash(defines_).ToString() + extension;
-    PODVector<unsigned> byteCode;
 
-    if (!LoadByteCode(byteCode, binaryShaderName))
+    if (!LoadByteCode(binaryShaderName))
     {
         // Compile shader if don't have valid bytecode
-        if (!Compile(byteCode))
+        if (!Compile())
             return false;
         // Save the bytecode after successful compile, but not if the source is from a package
         if (owner_->GetTimeStamp())
-            SaveByteCode(byteCode, binaryShaderName);
+            SaveByteCode(binaryShaderName);
     }
 
     // Then create shader from the bytecode
@@ -89,32 +109,36 @@ bool ShaderVariation::Create()
     if (type_ == VS)
     {
         HRESULT hr = device->CreateVertexShader(
-            (const DWORD*)&byteCode[0],
-            (IDirect3DVertexShader9**)&object_);
+            (const DWORD*)&byteCode_[0],
+            (IDirect3DVertexShader9**)&object_.ptr_);
         if (FAILED(hr))
         {
-            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_SAFE_RELEASE(object_.ptr_);
             compilerOutput_ = "Could not create vertex shader (HRESULT " + ToStringHex((unsigned)hr) + ")";
         }
     }
     else
     {
         HRESULT hr = device->CreatePixelShader(
-            (const DWORD*)&byteCode[0],
-            (IDirect3DPixelShader9**)&object_);
+            (const DWORD*)&byteCode_[0],
+            (IDirect3DPixelShader9**)&object_.ptr_);
         if (FAILED(hr))
         {
-            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_SAFE_RELEASE(object_.ptr_);
             compilerOutput_ = "Could not create pixel shader (HRESULT " + ToStringHex((unsigned)hr) + ")";
         }
     }
 
-    return object_ != 0;
+    // The bytecode is not needed on Direct3D9 after creation, so delete it to save memory
+    byteCode_.Clear();
+    byteCode_.Reserve(0);
+
+    return object_.ptr_ != 0;
 }
 
 void ShaderVariation::Release()
 {
-    if (object_ && graphics_)
+    if (object_.ptr_ && graphics_)
     {
         graphics_->CleanupShaderPrograms(this);
 
@@ -130,7 +154,7 @@ void ShaderVariation::Release()
         }
     }
 
-    URHO3D_SAFE_RELEASE(object_);
+    URHO3D_SAFE_RELEASE(object_.ptr_);
 
     compilerOutput_.Clear();
 
@@ -139,22 +163,12 @@ void ShaderVariation::Release()
     parameters_.Clear();
 }
 
-void ShaderVariation::SetName(const String& name)
-{
-    name_ = name;
-}
-
 void ShaderVariation::SetDefines(const String& defines)
 {
     defines_ = defines;
 }
 
-Shader* ShaderVariation::GetOwner() const
-{
-    return owner_;
-}
-
-bool ShaderVariation::LoadByteCode(PODVector<unsigned>& byteCode, const String& binaryShaderName)
+bool ShaderVariation::LoadByteCode(const String& binaryShaderName)
 {
     ResourceCache* cache = owner_->GetSubsystem<ResourceCache>();
     if (!cache->Exists(binaryShaderName))
@@ -185,7 +199,11 @@ bool ShaderVariation::LoadByteCode(PODVector<unsigned>& byteCode, const String&
         unsigned reg = file->ReadUByte();
         unsigned regCount = file->ReadUByte();
 
-        ShaderParameter parameter(type_, name, reg, regCount);
+        ShaderParameter parameter;
+        parameter.type_ = type_;
+        parameter.name_ = name;
+        parameter.register_ = reg;
+        parameter.regCount_ = regCount;
         parameters_[StringHash(name)] = parameter;
     }
 
@@ -202,8 +220,8 @@ bool ShaderVariation::LoadByteCode(PODVector<unsigned>& byteCode, const String&
     unsigned byteCodeSize = file->ReadUInt();
     if (byteCodeSize)
     {
-        byteCode.Resize(byteCodeSize >> 2);
-        file->Read(&byteCode[0], byteCodeSize);
+        byteCode_.Resize(byteCodeSize);
+        file->Read(&byteCode_[0], byteCodeSize);
 
         if (type_ == VS)
             URHO3D_LOGDEBUG("Loaded cached vertex shader " + GetFullName());
@@ -219,7 +237,7 @@ bool ShaderVariation::LoadByteCode(PODVector<unsigned>& byteCode, const String&
     }
 }
 
-bool ShaderVariation::Compile(PODVector<unsigned>& byteCode)
+bool ShaderVariation::Compile()
 {
     const String& sourceCode = owner_->GetSourceCode(type_);
     Vector<String> defines = defines_.Split(' ');
@@ -301,13 +319,13 @@ bool ShaderVariation::Compile(PODVector<unsigned>& byteCode)
         unsigned char* bufData = (unsigned char*)shaderCode->GetBufferPointer();
         unsigned bufSize = (unsigned)shaderCode->GetBufferSize();
         ParseParameters(bufData, bufSize);
-        CopyStrippedCode(byteCode, bufData, bufSize);
+        CopyStrippedCode(byteCode_, bufData, bufSize);
     }
 
     URHO3D_SAFE_RELEASE(shaderCode);
     URHO3D_SAFE_RELEASE(errorMsgs);
 
-    return !byteCode.Empty();
+    return !byteCode_.Empty();
 }
 
 void ShaderVariation::ParseParameters(unsigned char* bufData, unsigned bufSize)
@@ -337,41 +355,19 @@ void ShaderVariation::ParseParameters(unsigned char* bufData, unsigned bufSize)
         }
         else
         {
-            ShaderParameter newParam(type_, name, reg, regCount);
-            parameters_[StringHash(name)] = newParam;
+            ShaderParameter parameter;
+            parameter.type_ = type_;
+            parameter.name_ = name;
+            parameter.register_ = reg;
+            parameter.regCount_ = regCount;
+            parameters_[StringHash(name)] = parameter;
         }
     }
 
     MOJOSHADER_freeParseData(parseData);
 }
 
-void ShaderVariation::CopyStrippedCode(PODVector<unsigned>& byteCode, unsigned char* bufData, unsigned bufSize)
-{
-    unsigned const D3DSIO_COMMENT = 0xFFFE;
-    unsigned* srcWords = (unsigned*)bufData;
-    unsigned srcWordSize = bufSize >> 2;
-
-    for (unsigned i = 0; i < srcWordSize; ++i)
-    {
-        unsigned opcode = srcWords[i] & 0xffff;
-        // unsigned paramLength = (srcWords[i] & 0x0f000000) >> 24;
-        unsigned commentLength = srcWords[i] >> 16;
-
-        // For now, skip comment only at fixed position to prevent false positives
-        if (i == 1 && opcode == D3DSIO_COMMENT)
-        {
-            // Skip the comment
-            i += commentLength;
-        }
-        else
-        {
-            // Not a comment, copy the data
-            byteCode.Push(srcWords[i]);
-        }
-    }
-}
-
-void ShaderVariation::SaveByteCode(const PODVector<unsigned>& byteCode, const String& binaryShaderName)
+void ShaderVariation::SaveByteCode(const String& binaryShaderName)
 {
     ResourceCache* cache = owner_->GetSubsystem<ResourceCache>();
     FileSystem* fileSystem = owner_->GetSubsystem<FileSystem>();
@@ -413,10 +409,10 @@ void ShaderVariation::SaveByteCode(const PODVector<unsigned>& byteCode, const St
         }
     }
 
-    unsigned dataSize = byteCode.Size() << 2;
+    unsigned dataSize = byteCode_.Size();
     file->WriteUInt(dataSize);
     if (dataSize)
-        file->Write(&byteCode[0], dataSize);
+        file->Write(&byteCode_[0], dataSize);
 }
 
 }

+ 0 - 140
Source/Urho3D/Graphics/Direct3D9/D3D9ShaderVariation.h

@@ -1,140 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/HashSet.h"
-#include "../../Container/RefCounted.h"
-#include "../../Container/ArrayPtr.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-
-namespace Urho3D
-{
-
-class Shader;
-
-/// %Shader parameter definition.
-struct ShaderParameter
-{
-    /// Construct with defaults.
-    ShaderParameter() :
-        type_(VS),
-        register_(M_MAX_UNSIGNED),
-        regCount_(0)
-    {
-    }
-
-    /// Construct with parameters.
-    ShaderParameter(ShaderType type, const String& name, unsigned reg, unsigned regCount) :
-        type_(type),
-        name_(name),
-        register_(reg),
-        regCount_(regCount)
-    {
-    }
-
-    /// %Shader type.
-    ShaderType type_;
-    /// Name of the parameter.
-    String name_;
-    /// Hardware register.
-    unsigned register_;
-    /// Number of registers.
-    unsigned regCount_;
-};
-
-/// Vertex or pixel shader on the GPU.
-class URHO3D_API ShaderVariation : public RefCounted, public GPUObject
-{
-public:
-    /// Construct.
-    ShaderVariation(Shader* owner, ShaderType type);
-    /// Destruct.
-    virtual ~ShaderVariation();
-
-    /// Release the shader.
-    virtual void Release();
-
-    /// Compile the shader. Return true if successful.
-    bool Create();
-    /// Set name.
-    void SetName(const String& name);
-    /// Set defines.
-    void SetDefines(const String& defines);
-
-    /// Return the owner resource.
-    Shader* GetOwner() const;
-
-    /// Return shader type.
-    ShaderType GetShaderType() const { return type_; }
-
-    /// Return shader name.
-    const String& GetName() const { return name_; }
-
-    /// Return defines.
-    const String& GetDefines() const { return defines_; }
-
-    /// Return full shader name.
-    String GetFullName() const { return name_ + "(" + defines_ + ")"; }
-
-    /// Return compile error/warning string.
-    const String& GetCompilerOutput() const { return compilerOutput_; }
-
-    /// Return whether uses a parameter.
-    bool HasParameter(StringHash param) const { return parameters_.Contains(param); }
-
-    /// Return whether uses a texture unit (only for pixel shaders.)
-    bool HasTextureUnit(TextureUnit unit) const { return useTextureUnit_[unit]; }
-
-    /// Return all parameter definitions.
-    const HashMap<StringHash, ShaderParameter>& GetParameters() const { return parameters_; }
-
-private:
-    /// Load bytecode from a file. Return true if successful.
-    bool LoadByteCode(PODVector<unsigned>& byteCode, const String& binaryShaderName);
-    /// Compile from source. Return true if successful.
-    bool Compile(PODVector<unsigned>& byteCode);
-    /// Inspect the constant parameters of the shader bytecode using MojoShader.
-    void ParseParameters(unsigned char* bufData, unsigned bufSize);
-    /// Strip comments from shader bytecode and store it.
-    void CopyStrippedCode(PODVector<unsigned>& byteCode, unsigned char* bufData, unsigned bufSize);
-    /// Save bytecode to a file.
-    void SaveByteCode(const PODVector<unsigned>& byteCode, const String& binaryShaderName);
-
-    /// Shader this variation belongs to.
-    WeakPtr<Shader> owner_;
-    /// Shader type.
-    ShaderType type_;
-    /// Shader name.
-    String name_;
-    /// Defines to use in compiling.
-    String defines_;
-    /// Shader compile error string.
-    String compilerOutput_;
-    /// Shader parameters.
-    HashMap<StringHash, ShaderParameter> parameters_;
-    /// Texture unit use flags.
-    bool useTextureUnit_[MAX_TEXTURE_UNITS];
-};
-
-}

+ 4 - 217
Source/Urho3D/Graphics/Direct3D9/D3D9Texture.cpp

@@ -35,76 +35,6 @@
 namespace Urho3D
 {
 
-static const char* addressModeNames[] =
-{
-    "wrap",
-    "mirror",
-    "clamp",
-    "border",
-    0
-};
-
-static const char* filterModeNames[] =
-{
-    "nearest",
-    "bilinear",
-    "trilinear",
-    "anisotropic",
-    "default",
-    0
-};
-
-Texture::Texture(Context* context) :
-    Resource(context),
-    GPUObject(GetSubsystem<Graphics>()),
-    format_(D3DFMT_UNKNOWN),
-    pool_(D3DPOOL_MANAGED),
-    usage_(0),
-    levels_(0),
-    requestedLevels_(0),
-    width_(0),
-    height_(0),
-    depth_(0),
-    filterMode_(FILTER_DEFAULT),
-    sRGB_(false)
-{
-    for (int i = 0; i < MAX_COORDS; ++i)
-        addressMode_[i] = ADDRESS_WRAP;
-    for (int i = 0; i < MAX_TEXTURE_QUALITY_LEVELS; ++i)
-        mipsToSkip_[i] = (unsigned)(MAX_TEXTURE_QUALITY_LEVELS - 1 - i);
-}
-
-Texture::~Texture()
-{
-}
-
-void Texture::SetNumLevels(unsigned levels)
-{
-    if (usage_ & D3DUSAGE_DEPTHSTENCIL)
-        requestedLevels_ = 1;
-    else
-        requestedLevels_ = levels;
-}
-
-void Texture::SetFilterMode(TextureFilterMode mode)
-{
-    filterMode_ = mode;
-}
-
-void Texture::SetAddressMode(TextureCoordinate coord, TextureAddressMode mode)
-{
-    addressMode_[coord] = mode;
-}
-
-void Texture::SetShadowCompare(bool /*enable*/)
-{
-}
-
-void Texture::SetBorderColor(const Color& color)
-{
-    borderColor_ = color;
-}
-
 void Texture::SetSRGB(bool enable)
 {
     if (graphics_)
@@ -113,24 +43,14 @@ void Texture::SetSRGB(bool enable)
     sRGB_ = enable;
 }
 
-void Texture::SetBackupTexture(Texture* texture)
+void Texture::UpdateParameters()
 {
-    backupTexture_ = texture;
+    // No-op on Direct3D9, handled by Graphics instead by modifying the sampler settings as necessary
 }
 
-void Texture::SetMipsToSkip(int quality, int toSkip)
+bool Texture::GetParametersDirty() const
 {
-    if (quality >= QUALITY_LOW && quality < MAX_TEXTURE_QUALITY_LEVELS)
-    {
-        mipsToSkip_[quality] = (unsigned)toSkip;
-
-        // Make sure a higher quality level does not actually skip more mips
-        for (int i = 1; i < MAX_TEXTURE_QUALITY_LEVELS; ++i)
-        {
-            if (mipsToSkip_[i] > mipsToSkip_[i - 1])
-                mipsToSkip_[i] = mipsToSkip_[i - 1];
-        }
-    }
+    return false;
 }
 
 bool Texture::IsCompressed() const
@@ -138,59 +58,6 @@ bool Texture::IsCompressed() const
     return format_ == D3DFMT_DXT1 || format_ == D3DFMT_DXT3 || format_ == D3DFMT_DXT5;
 }
 
-int Texture::GetMipsToSkip(int quality) const
-{
-    return (quality >= QUALITY_LOW && quality < MAX_TEXTURE_QUALITY_LEVELS) ? mipsToSkip_[quality] : 0;
-}
-
-int Texture::GetLevelWidth(unsigned level) const
-{
-    if (level > levels_)
-        return 0;
-    return Max(width_ >> level, 1);
-}
-
-int Texture::GetLevelHeight(unsigned level) const
-{
-    if (level > levels_)
-        return 0;
-    return Max(height_ >> level, 1);
-}
-
-int Texture::GetLevelDepth(unsigned level) const
-{
-    if (level > levels_)
-        return 0;
-    return Max(depth_ >> level, 1);
-}
-
-TextureUsage Texture::GetUsage() const
-{
-    if (usage_ & D3DUSAGE_DEPTHSTENCIL)
-        return TEXTURE_DEPTHSTENCIL;
-
-    if (usage_ & D3DUSAGE_RENDERTARGET)
-        return TEXTURE_RENDERTARGET;
-
-    if (pool_ == D3DPOOL_DEFAULT)
-        return TEXTURE_DYNAMIC;
-
-    return TEXTURE_STATIC;
-}
-
-unsigned Texture::GetDataSize(int width, int height) const
-{
-    if (IsCompressed())
-        return GetRowDataSize(width) * ((height + 3) >> 2);
-    else
-        return GetRowDataSize(width) * height;
-}
-
-unsigned Texture::GetDataSize(int width, int height, int depth) const
-{
-    return depth * GetDataSize(width, height);
-}
-
 unsigned Texture::GetRowDataSize(int width) const
 {
     switch (format_)
@@ -237,84 +104,4 @@ unsigned Texture::GetRowDataSize(int width) const
     }
 }
 
-unsigned Texture::GetComponents() const
-{
-    if (!width_ || IsCompressed())
-        return 0;
-    else
-        return GetRowDataSize(width_) / width_;
-}
-
-void Texture::SetParameters(XMLFile* file)
-{
-    if (!file)
-        return;
-
-    XMLElement rootElem = file->GetRoot();
-    SetParameters(rootElem);
-}
-
-void Texture::SetParameters(const XMLElement& element)
-{
-    XMLElement paramElem = element.GetChild();
-    while (paramElem)
-    {
-        String name = paramElem.GetName();
-
-        if (name == "address")
-        {
-            String coord = paramElem.GetAttributeLower("coord");
-            if (coord.Length() >= 1)
-            {
-                TextureCoordinate coordIndex = (TextureCoordinate)(coord[0] - 'u');
-                String mode = paramElem.GetAttributeLower("mode");
-                SetAddressMode(coordIndex, (TextureAddressMode)GetStringListIndex(mode.CString(), addressModeNames, ADDRESS_WRAP));
-            }
-        }
-
-        if (name == "border")
-            SetBorderColor(paramElem.GetColor("color"));
-
-        if (name == "filter")
-        {
-            String mode = paramElem.GetAttributeLower("mode");
-            SetFilterMode((TextureFilterMode)GetStringListIndex(mode.CString(), filterModeNames, FILTER_DEFAULT));
-        }
-
-        if (name == "mipmap")
-            SetNumLevels(paramElem.GetBool("enable") ? 0 : 1);
-
-        if (name == "quality")
-        {
-            if (paramElem.HasAttribute("low"))
-                SetMipsToSkip(QUALITY_LOW, paramElem.GetInt("low"));
-            if (paramElem.HasAttribute("med"))
-                SetMipsToSkip(QUALITY_MEDIUM, paramElem.GetInt("med"));
-            if (paramElem.HasAttribute("medium"))
-                SetMipsToSkip(QUALITY_MEDIUM, paramElem.GetInt("medium"));
-            if (paramElem.HasAttribute("high"))
-                SetMipsToSkip(QUALITY_HIGH, paramElem.GetInt("high"));
-        }
-
-        if (name == "srgb")
-            SetSRGB(paramElem.GetBool("enable"));
-
-        paramElem = paramElem.GetNext();
-    }
-}
-
-void Texture::CheckTextureBudget(StringHash type)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-    unsigned long long textureBudget = cache->GetMemoryBudget(type);
-    unsigned long long textureUse = cache->GetMemoryUse(type);
-    if (!textureBudget)
-        return;
-
-    // If textures are over the budget, they likely can not be freed directly as materials still refer to them.
-    // Therefore free unused materials first
-    if (textureUse > textureBudget)
-        cache->ReleaseResources(Material::GetTypeStatic());
-}
-
 }

+ 0 - 160
Source/Urho3D/Graphics/Direct3D9/D3D9Texture.h

@@ -1,160 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-#include "../../Math/Color.h"
-#include "../../Resource/Resource.h"
-
-namespace Urho3D
-{
-
-static const int MAX_TEXTURE_QUALITY_LEVELS = 3;
-
-class XMLElement;
-class XMLFile;
-
-/// Base class for texture resources.
-class URHO3D_API Texture : public Resource, public GPUObject
-{
-public:
-    /// Construct.
-    Texture(Context* context);
-    /// Destruct.
-    virtual ~Texture();
-
-    /// Set number of requested mip levels. Needs to be called before setting size.
-    void SetNumLevels(unsigned levels);
-    /// Set filtering mode.
-    void SetFilterMode(TextureFilterMode filter);
-    /// Set addressing mode by texture coordinate.
-    void SetAddressMode(TextureCoordinate coord, TextureAddressMode address);
-
-    /// Set shadow compare mode. No-op on D3D9.
-    void SetShadowCompare(bool enable);
-
-    /// Set border color for border addressing mode.
-    void SetBorderColor(const Color& color);
-    /// Set sRGB sampling and writing mode.
-    void SetSRGB(bool enable);
-    /// Set backup texture to use when rendering to this texture.
-    void SetBackupTexture(Texture* texture);
-    /// Set mip levels to skip on a quality setting when loading. Ensures higher quality levels do not skip more.
-    void SetMipsToSkip(int quality, int toSkip);
-
-    /// Return texture format.
-    unsigned GetFormat() const { return format_; }
-
-    /// Return whether the texture format is compressed.
-    bool IsCompressed() const;
-
-    /// Return number of mip levels.
-    unsigned GetLevels() const { return levels_; }
-
-    /// Return width.
-    int GetWidth() const { return width_; }
-
-    /// Return height.
-    int GetHeight() const { return height_; }
-
-    /// Return height.
-    int GetDepth() const { return depth_; }
-
-    /// Return filtering mode.
-    TextureFilterMode GetFilterMode() const { return filterMode_; }
-
-    /// Return addressing mode by texture coordinate.
-    TextureAddressMode GetAddressMode(TextureCoordinate coord) const { return addressMode_[coord]; }
-
-    /// Return whether shadow compare is enabled. Always false on D3D9.
-    bool GetShadowCompare() const { return false; }
-
-    /// Return border color.
-    const Color& GetBorderColor() const { return borderColor_; }
-
-    /// Return whether is using sRGB sampling and writing.
-    bool GetSRGB() const { return sRGB_; }
-
-    /// Return backup texture.
-    Texture* GetBackupTexture() const { return backupTexture_; }
-
-    /// Return mip levels to skip on a quality setting when loading.
-    int GetMipsToSkip(int quality) const;
-    /// Return mip level width, or 0 if level does not exist.
-    int GetLevelWidth(unsigned level) const;
-    /// Return mip level width, or 0 if level does not exist.
-    int GetLevelHeight(unsigned level) const;
-    /// Return mip level depth, or 0 if level does not exist.
-    int GetLevelDepth(unsigned level) const;
-    /// Return texture usage type.
-    TextureUsage GetUsage() const;
-    /// Return data size in bytes for a rectangular region.
-    unsigned GetDataSize(int width, int height) const;
-    /// Return data size in bytes for a volume region.
-    unsigned GetDataSize(int width, int height, int depth) const;
-    /// Return data size in bytes for a pixel or block row.
-    unsigned GetRowDataSize(int width) const;
-    /// Return number of image components required to receive pixel data from GetData(), or 0 for compressed images.
-    unsigned GetComponents() const;
-
-    /// Set additional parameters from an XML file.
-    void SetParameters(XMLFile* xml);
-    /// Set additional parameters from an XML element.
-    void SetParameters(const XMLElement& element);
-
-protected:
-    /// Check whether texture memory budget has been exceeded. Free unused materials in that case to release the texture references.
-    void CheckTextureBudget(StringHash type);
-
-    /// Texture format.
-    unsigned format_;
-    /// Memory pool.
-    unsigned pool_;
-    /// Texture usage type.
-    unsigned usage_;
-    /// Current mip levels.
-    unsigned levels_;
-    /// Requested mip levels.
-    unsigned requestedLevels_;
-    /// Texture width.
-    int width_;
-    /// Texture height.
-    int height_;
-    /// Texture depth.
-    int depth_;
-    /// Filtering mode.
-    TextureFilterMode filterMode_;
-    /// Addressing mode.
-    TextureAddressMode addressMode_[MAX_COORDS];
-    /// Mip levels to skip when loading per texture quality setting.
-    unsigned mipsToSkip_[MAX_TEXTURE_QUALITY_LEVELS];
-    /// Border color.
-    Color borderColor_;
-    /// sRGB sampling and writing mode flag.
-    bool sRGB_;
-    /// Backup texture.
-    SharedPtr<Texture> backupTexture_;
-};
-
-}

+ 36 - 142
Source/Urho3D/Graphics/Direct3D9/D3D9Texture2D.cpp

@@ -39,89 +39,22 @@
 namespace Urho3D
 {
 
-Texture2D::Texture2D(Context* context) :
-    Texture(context)
-{
-}
-
-Texture2D::~Texture2D()
-{
-    Release();
-}
-
-void Texture2D::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Texture2D>();
-}
-
-bool Texture2D::BeginLoad(Deserializer& source)
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If device is lost, retry later
-    if (graphics_->IsDeviceLost())
-    {
-        URHO3D_LOGWARNING("Texture load while device is lost");
-        dataPending_ = true;
-        return true;
-    }
-
-    // Load the image data for EndLoad()
-    loadImage_ = new Image(context_);
-    if (!loadImage_->Load(source))
-    {
-        loadImage_.Reset();
-        return false;
-    }
-
-    // Precalculate mip levels if async loading
-    if (GetAsyncLoadState() == ASYNC_LOADING)
-        loadImage_->PrecalculateLevels();
-
-    // Load the optional parameters file
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-    String xmlName = ReplaceExtension(GetName(), ".xml");
-    loadParameters_ = cache->GetTempResource<XMLFile>(xmlName, false);
-
-    return true;
-}
-
-bool Texture2D::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_ || graphics_->IsDeviceLost())
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-    bool success = SetData(loadImage_);
-
-    loadImage_.Reset();
-    loadParameters_.Reset();
-
-    return success;
-}
-
 void Texture2D::OnDeviceLost()
 {
-    if (pool_ == D3DPOOL_DEFAULT)
+    if (usage_ > TEXTURE_STATIC)
         Release();
 }
 
 void Texture2D::OnDeviceReset()
 {
-    if (pool_ == D3DPOOL_DEFAULT || !object_ || dataPending_)
+    if (usage_ > TEXTURE_STATIC || !object_.ptr_ || dataPending_)
     {
         // If has a resource file, reload through the resource cache. Otherwise just recreate.
         ResourceCache* cache = GetSubsystem<ResourceCache>();
         if (cache->Exists(GetName()))
             dataLost_ = !cache->ReloadResource(this);
 
-        if (!object_)
+        if (!object_.ptr_)
         {
             Create();
             dataLost_ = true;
@@ -145,60 +78,14 @@ void Texture2D::Release()
     if (renderSurface_)
         renderSurface_->Release();
 
-    URHO3D_SAFE_RELEASE(object_);
-}
-
-bool Texture2D::SetSize(int width, int height, unsigned format, TextureUsage usage)
-{
-    if (width <= 0 || height <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative texture dimensions");
-        return false;
-    }
-
-    // Delete the old rendersurface if any
-    renderSurface_.Reset();
-    pool_ = D3DPOOL_MANAGED;
-    usage_ = 0;
-
-    if (usage == TEXTURE_RENDERTARGET || usage == TEXTURE_DEPTHSTENCIL)
-    {
-        renderSurface_ = new RenderSurface(this);
-        if (usage == TEXTURE_RENDERTARGET)
-            usage_ |= D3DUSAGE_RENDERTARGET;
-        else
-            usage_ |= D3DUSAGE_DEPTHSTENCIL;
-        pool_ = D3DPOOL_DEFAULT;
-
-        // Clamp mode addressing by default, nearest filtering, and mipmaps disabled
-        addressMode_[COORD_U] = ADDRESS_CLAMP;
-        addressMode_[COORD_V] = ADDRESS_CLAMP;
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
-    }
-    else if (usage == TEXTURE_DYNAMIC)
-    {
-        usage_ |= D3DUSAGE_DYNAMIC;
-        pool_ = D3DPOOL_DEFAULT;
-    }
-
-    if (usage == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(Texture2D, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
-
-    width_ = width;
-    height_ = height;
-    format_ = format;
-
-    return Create();
+    URHO3D_SAFE_RELEASE(object_.ptr_);
 }
 
 bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, const void* data)
 {
     URHO3D_PROFILE(SetTextureData);
 
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not set data");
         return false;
@@ -245,10 +132,10 @@ bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, con
     d3dRect.bottom = y + height;
 
     DWORD flags = 0;
-    if (level == 0 && x == 0 && y == 0 && width == levelWidth && height == levelHeight && pool_ == D3DPOOL_DEFAULT)
+    if (level == 0 && x == 0 && y == 0 && width == levelWidth && height == levelHeight && usage_ > TEXTURE_STATIC)
         flags |= D3DLOCK_DISCARD;
 
-    HRESULT hr = ((IDirect3DTexture9*)object_)->LockRect(level, &d3dLockedRect, (flags & D3DLOCK_DISCARD) ? 0 : &d3dRect, flags);
+    HRESULT hr = ((IDirect3DTexture9*)object_.ptr_)->LockRect(level, &d3dLockedRect, (flags & D3DLOCK_DISCARD) ? 0 : &d3dRect, flags);
     if (FAILED(hr))
     {
         URHO3D_LOGD3DERROR("Could not lock texture", hr);
@@ -311,7 +198,7 @@ bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, con
         break;
     }
 
-    ((IDirect3DTexture9*)object_)->UnlockRect(level);
+    ((IDirect3DTexture9*)object_.ptr_)->UnlockRect(level);
     return true;
 }
 
@@ -440,7 +327,7 @@ bool Texture2D::SetData(Image* image, bool useAlpha)
 
 bool Texture2D::GetData(unsigned level, void* dest) const
 {
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not get data");
         return false;
@@ -510,7 +397,7 @@ bool Texture2D::GetData(unsigned level, void* dest) const
     }
     else
     {
-        HRESULT hr = ((IDirect3DTexture9*)object_)->LockRect(level, &d3dLockedRect, &d3dRect, D3DLOCK_READONLY);
+        HRESULT hr = ((IDirect3DTexture9*)object_.ptr_)->LockRect(level, &d3dLockedRect, &d3dRect, D3DLOCK_READONLY);
         if (FAILED(hr))
         {
             URHO3D_LOGD3DERROR("Could not lock texture", hr);
@@ -577,7 +464,7 @@ bool Texture2D::GetData(unsigned level, void* dest) const
         offscreenSurface->Release();
     }
     else
-        ((IDirect3DTexture9*)object_)->UnlockRect(level);
+        ((IDirect3DTexture9*)object_.ptr_)->UnlockRect(level);
 
     return true;
 }
@@ -595,9 +482,27 @@ bool Texture2D::Create()
         return true;
     }
 
+    unsigned pool = usage_ > TEXTURE_STATIC ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
+    unsigned d3dUsage = 0;
+
+    switch (usage_)
+    {
+    case TEXTURE_DYNAMIC:
+        d3dUsage |= D3DUSAGE_DYNAMIC;
+        break;
+    case TEXTURE_RENDERTARGET:
+        d3dUsage |= D3DUSAGE_RENDERTARGET;
+        break;
+    case TEXTURE_DEPTHSTENCIL:
+        d3dUsage |= D3DUSAGE_DEPTHSTENCIL;
+        break;
+    default:
+        break;
+    }
+
     IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
     // If creating a depth-stencil texture, and it is not supported, create a depth-stencil surface instead
-    if (usage_ & D3DUSAGE_DEPTHSTENCIL && !graphics_->GetImpl()->CheckFormatSupport((D3DFORMAT)format_, usage_, D3DRTYPE_TEXTURE))
+    if (usage_ == TEXTURE_DEPTHSTENCIL && !graphics_->GetImpl()->CheckFormatSupport((D3DFORMAT)format_, d3dUsage, D3DRTYPE_TEXTURE))
     {
         HRESULT hr = device->CreateDepthStencilSurface(
             (UINT)width_,
@@ -623,23 +528,23 @@ bool Texture2D::Create()
             (UINT)width_,
             (UINT)height_,
             requestedLevels_,
-            usage_,
+            d3dUsage,
             (D3DFORMAT)format_,
-            (D3DPOOL)pool_,
+            (D3DPOOL)pool,
             (IDirect3DTexture9**)&object_,
             0);
         if (FAILED(hr))
         {
-            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_SAFE_RELEASE(object_.ptr_);
             URHO3D_LOGD3DERROR("Could not create texture", hr);
             return false;
         }
 
-        levels_ = ((IDirect3DTexture9*)object_)->GetLevelCount();
+        levels_ = ((IDirect3DTexture9*)object_.ptr_)->GetLevelCount();
 
-        if (usage_ & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))
+        if (usage_ >= TEXTURE_RENDERTARGET)
         {
-            hr = ((IDirect3DTexture9*)object_)->GetSurfaceLevel(0, (IDirect3DSurface9**)&renderSurface_->surface_);
+            hr = ((IDirect3DTexture9*)object_.ptr_)->GetSurfaceLevel(0, (IDirect3DSurface9**)&renderSurface_->surface_);
             if (FAILED(hr))
                 URHO3D_LOGD3DERROR("Could not get rendertarget surface", hr);
         }
@@ -648,15 +553,4 @@ bool Texture2D::Create()
     return true;
 }
 
-void Texture2D::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    if (renderSurface_ && (renderSurface_->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurface_->IsUpdateQueued()))
-    {
-        Renderer* renderer = GetSubsystem<Renderer>();
-        if (renderer)
-            renderer->QueueRenderSurface(renderSurface_);
-        renderSurface_->ResetUpdateQueued();
-    }
-}
-
 }

+ 0 - 86
Source/Urho3D/Graphics/Direct3D9/D3D9Texture2D.h

@@ -1,86 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-
-namespace Urho3D
-{
-
-class Image;
-class XMLFile;
-
-/// 2D texture resource.
-class URHO3D_API Texture2D : public Texture
-{
-    URHO3D_OBJECT(Texture2D, Texture);
-
-public:
-    /// Construct.
-    Texture2D(Context* context);
-    /// Destruct.
-    virtual ~Texture2D();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Release default pool resources.
-    virtual void OnDeviceLost();
-    /// Recreate default pool resources.
-    virtual void OnDeviceReset();
-    /// Release texture.
-    virtual void Release();
-
-    /// Set size, format and usage. Zero size will follow application window size. Return true if successful.
-    bool SetSize(int width, int height, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a mip level. Return true if successful.
-    bool SetData(unsigned level, int x, int y, int width, int height, const void* data);
-    /// Set data from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(Image* image, bool useAlpha = false);
-
-    /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(unsigned level, void* dest) const;
-
-    /// Return render surface.
-    RenderSurface* GetRenderSurface() const { return renderSurface_; }
-
-private:
-    /// Create texture.
-    bool Create();
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
-
-    /// Render surface.
-    SharedPtr<RenderSurface> renderSurface_;
-    /// Image file acquired during BeginLoad.
-    SharedPtr<Image> loadImage_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 6 - 160
Source/Urho3D/Graphics/Direct3D9/D3D9Texture2DArray.cpp

@@ -43,111 +43,22 @@
 namespace Urho3D
 {
 
-Texture2DArray::Texture2DArray(Context* context) :
-    Texture(context),
-    layers_(0),
-    lockedLevel_(-1)
-{
-}
-
-Texture2DArray::~Texture2DArray()
-{
-    Release();
-}
-
-void Texture2DArray::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Texture2DArray>();
-}
-
-bool Texture2DArray::BeginLoad(Deserializer& source)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    cache->ResetDependencies(this);
-
-    String texPath, texName, texExt;
-    SplitPath(GetName(), texPath, texName, texExt);
-
-    loadParameters_ = (new XMLFile(context_));
-    if (!loadParameters_->Load(source))
-    {
-        loadParameters_.Reset();
-        return false;
-    }
-
-    loadImages_.Clear();
-
-    XMLElement textureElem = loadParameters_->GetRoot();
-    XMLElement layerElem = textureElem.GetChild("layer");
-    while (layerElem)
-    {
-        String name = layerElem.GetAttribute("name");
-
-        // If path is empty, add the XML file path
-        if (GetPath(name).Empty())
-            name = texPath + name;
-
-        loadImages_.Push(cache->GetTempResource<Image>(name));
-        cache->StoreResourceDependency(this, name);
-
-        layerElem = layerElem.GetNext("layer");
-    }
-
-    // Precalculate mip levels if async loading
-    if (GetAsyncLoadState() == ASYNC_LOADING)
-    {
-        for (unsigned i = 0; i < loadImages_.Size(); ++i)
-        {
-            if (loadImages_[i])
-                loadImages_[i]->PrecalculateLevels();
-        }
-    }
-
-    return true;
-}
-
-bool Texture2DArray::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-    SetLayers(loadImages_.Size());
-
-    for (unsigned i = 0; i < loadImages_.Size(); ++i)
-        SetData(i, loadImages_[i]);
-
-    loadImages_.Clear();
-    loadParameters_.Reset();
-
-    return true;
-}
-
 void Texture2DArray::OnDeviceLost()
 {
-    if (pool_ == D3DPOOL_DEFAULT)
+    if (usage_ > TEXTURE_STATIC)
         Release();
 }
 
 void Texture2DArray::OnDeviceReset()
 {
-    if (pool_ == D3DPOOL_DEFAULT || !object_ || dataPending_)
+    if (usage_ > TEXTURE_STATIC || !object_.ptr_ || dataPending_)
     {
         // If has a resource file, reload through the resource cache. Otherwise just recreate.
         ResourceCache* cache = GetSubsystem<ResourceCache>();
         if (cache->Exists(GetName()))
             dataLost_ = !cache->ReloadResource(this);
 
-        if (!object_)
+        if (!object_.ptr_)
         {
             Create();
             dataLost_ = true;
@@ -171,61 +82,7 @@ void Texture2DArray::Release()
     if (renderSurface_)
         renderSurface_->Release();
 
-    URHO3D_SAFE_RELEASE(object_);
-}
-
-void Texture2DArray::SetLayers(unsigned layers)
-{
-    Release();
-
-    layers_ = layers;
-}
-
-bool Texture2DArray::SetSize(unsigned layers, int width, int height, unsigned format, TextureUsage usage)
-{
-    if (width <= 0 || height <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative texture array size");
-        return false;
-    }
-    if (usage == TEXTURE_DEPTHSTENCIL)
-    {
-        URHO3D_LOGERROR("Depth-stencil usage not supported for texture arrays");
-        return false;
-    }
-
-    // Delete the old rendersurfaces if any
-    renderSurface_.Reset();
-
-    usage_ = usage;
-
-    if (usage_ == TEXTURE_RENDERTARGET)
-    {
-        renderSurface_ = new RenderSurface(this);
-
-        // Nearest filtering and mipmaps disabled by default
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
-    }
-    else if (usage_ == TEXTURE_DYNAMIC)
-        requestedLevels_ = 1;
-
-    if (usage_ == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(Texture2DArray, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
-
-    width_ = width;
-    height_ = height;
-    format_ = format;
-    if (layers)
-        layers_ = layers;
-
-    layerMemoryUse_.Resize(layers_);
-    for (unsigned i = 0; i < layers_; ++i)
-        layerMemoryUse_[i] = 0;
-
-    return Create();
+    URHO3D_SAFE_RELEASE(object_.ptr_);
 }
 
 bool Texture2DArray::SetData(unsigned layer, unsigned level, int x, int y, int width, int height, const void* data)
@@ -310,7 +167,7 @@ bool Texture2DArray::SetData(unsigned layer, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.ptr_)
             {
                 // Do not spam this error on D3D9
                 //URHO3D_LOGERROR("Texture array layer 0 must be loaded first");
@@ -367,7 +224,7 @@ bool Texture2DArray::SetData(unsigned layer, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.ptr_)
             {
                 //URHO3D_LOGERROR("Texture array layer 0 must be loaded first");
                 return false;
@@ -424,15 +281,4 @@ bool Texture2DArray::Create()
     return false;
 }
 
-void Texture2DArray::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    if (renderSurface_ && (renderSurface_->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurface_->IsUpdateQueued()))
-    {
-        Renderer* renderer = GetSubsystem<Renderer>();
-        if (renderer)
-            renderer->QueueRenderSurface(renderSurface_);
-        renderSurface_->ResetUpdateQueued();
-    }
-}
-
 }

+ 0 - 99
Source/Urho3D/Graphics/Direct3D9/D3D9Texture2DArray.h

@@ -1,99 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-
-namespace Urho3D
-{
-
-class Deserializer;
-class Image;
-
-/// 2D texture array resource.
-class URHO3D_API Texture2DArray : public Texture
-{
-    URHO3D_OBJECT(Texture2DArray, Texture)
-
-public:
-    /// Construct.
-    Texture2DArray(Context* context);
-    /// Destruct.
-    virtual ~Texture2DArray();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Release default pool resources.
-    virtual void OnDeviceLost();
-    /// Recreate default pool resources.
-    virtual void OnDeviceReset();
-    /// Release texture.
-    virtual void Release();
-
-    /// Set the number of layers in the texture. To be used before SetData.
-    void SetLayers(unsigned layers);
-    /// Set layers, size, format and usage. Set layers to zero to leave them unchanged. Return true if successful.
-    bool SetSize(unsigned layers, int width, int height, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a face's mip level. Return true if successful.
-    bool SetData(unsigned layer, unsigned level, int x, int y, int width, int height, const void* data);
-    /// Set data of one face from a stream. Return true if successful.
-    bool SetData(unsigned layer, Deserializer& source);
-    /// Set data of one face from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(unsigned layer, Image* image, bool useAlpha = false);
-
-    /// Return number of layers in the texture.
-    unsigned GetLayers() const { return layers_; }
-    /// Get data from a layer's mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(unsigned layer, unsigned level, void* dest) const;
-    /// Return render surface.
-    RenderSurface* GetRenderSurface() const { return renderSurface_; }
-
-private:
-    /// Create texture array.
-    bool Create();
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
-
-    /// Texture array layers number.
-    unsigned layers_;
-    /// Render surfaces.
-    SharedPtr<RenderSurface> renderSurface_;
-    /// Memory use per layer.
-    PODVector<unsigned> layerMemoryUse_;
-    /// Currently locked mip level.
-    int lockedLevel_;
-    /// Currently locked layer.
-    int lockedLayer_;
-    /// Layer image files acquired during BeginLoad.
-    Vector<SharedPtr<Image> > loadImages_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 18 - 156
Source/Urho3D/Graphics/Direct3D9/D3D9Texture3D.cpp

@@ -39,133 +39,22 @@
 namespace Urho3D
 {
 
-Texture3D::Texture3D(Context* context) :
-    Texture(context)
-{
-}
-
-Texture3D::~Texture3D()
-{
-    Release();
-}
-
-void Texture3D::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Texture3D>();
-}
-
-bool Texture3D::BeginLoad(Deserializer& source)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If device is lost, retry later
-    if (graphics_->IsDeviceLost())
-    {
-        URHO3D_LOGWARNING("Texture load while device is lost");
-        dataPending_ = true;
-        return true;
-    }
-
-    String texPath, texName, texExt;
-    SplitPath(GetName(), texPath, texName, texExt);
-
-    cache->ResetDependencies(this);
-
-    loadParameters_ = new XMLFile(context_);
-    if (!loadParameters_->Load(source))
-    {
-        loadParameters_.Reset();
-        return false;
-    }
-
-    XMLElement textureElem = loadParameters_->GetRoot();
-    XMLElement volumeElem = textureElem.GetChild("volume");
-    XMLElement colorlutElem = textureElem.GetChild("colorlut");
-
-    if (volumeElem)
-    {
-        String name = volumeElem.GetAttribute("name");
-
-        String volumeTexPath, volumeTexName, volumeTexExt;
-        SplitPath(name, volumeTexPath, volumeTexName, volumeTexExt);
-        // If path is empty, add the XML file path
-        if (volumeTexPath.Empty())
-            name = texPath + name;
-
-        loadImage_ = cache->GetTempResource<Image>(name);
-        // Precalculate mip levels if async loading
-        if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING)
-            loadImage_->PrecalculateLevels();
-        cache->StoreResourceDependency(this, name);
-        return true;
-    }
-    else if (colorlutElem)
-    {
-        String name = colorlutElem.GetAttribute("name");
-
-        String colorlutTexPath, colorlutTexName, colorlutTexExt;
-        SplitPath(name, colorlutTexPath, colorlutTexName, colorlutTexExt);
-        // If path is empty, add the XML file path
-        if (colorlutTexPath.Empty())
-            name = texPath + name;
-
-        SharedPtr<File> file = GetSubsystem<ResourceCache>()->GetFile(name);
-        loadImage_ = new Image(context_);
-        if (!loadImage_->LoadColorLUT(*(file.Get())))
-        {
-            loadParameters_.Reset();
-            loadImage_.Reset();
-            return false;
-        }
-        // Precalculate mip levels if async loading
-        if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING)
-            loadImage_->PrecalculateLevels();
-        cache->StoreResourceDependency(this, name);
-        return true;
-    }
-
-    URHO3D_LOGERROR("Texture3D XML data for " + GetName() + " did not contain either volume or colorlut element");
-    return false;
-}
-
-bool Texture3D::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_ || graphics_->IsDeviceLost())
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-    bool success = SetData(loadImage_);
-
-    loadImage_.Reset();
-    loadParameters_.Reset();
-
-    return success;
-}
-
 void Texture3D::OnDeviceLost()
 {
-    if (pool_ == D3DPOOL_DEFAULT)
+    if (usage_ > TEXTURE_STATIC)
         Release();
 }
 
 void Texture3D::OnDeviceReset()
 {
-    if (pool_ == D3DPOOL_DEFAULT || !object_ || dataPending_)
+    if (usage_ > TEXTURE_STATIC || !object_.ptr_ || dataPending_)
     {
         // If has a resource file, reload through the resource cache. Otherwise just recreate.
         ResourceCache* cache = GetSubsystem<ResourceCache>();
         if (cache->Exists(GetName()))
             dataLost_ = !cache->ReloadResource(this);
 
-        if (!object_)
+        if (!object_.ptr_)
         {
             Create();
             dataLost_ = true;
@@ -186,44 +75,14 @@ void Texture3D::Release()
         }
     }
 
-    URHO3D_SAFE_RELEASE(object_);
-}
-
-bool Texture3D::SetSize(int width, int height, int depth, unsigned format, TextureUsage usage)
-{
-    if (width <= 0 || height <= 0 || depth <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative 3D texture dimensions");
-        return false;
-    }
-    if (usage >= TEXTURE_RENDERTARGET)
-    {
-        URHO3D_LOGERROR("Rendertarget or depth-stencil usage not supported for 3D textures");
-        return false;
-    }
-
-    pool_ = D3DPOOL_MANAGED;
-    usage_ = 0;
-
-    if (usage == TEXTURE_DYNAMIC)
-    {
-        usage_ |= D3DUSAGE_DYNAMIC;
-        pool_ = D3DPOOL_DEFAULT;
-    }
-
-    width_ = width;
-    height_ = height;
-    depth_ = depth;
-    format_ = format;
-
-    return Create();
+    URHO3D_SAFE_RELEASE(object_.ptr_);
 }
 
 bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data)
 {
     URHO3D_PROFILE(SetTextureData);
 
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not set data");
         return false;
@@ -275,10 +134,10 @@ bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int heig
 
     DWORD flags = 0;
     if (level == 0 && x == 0 && y == 0 && z == 0 && width == levelWidth && height == levelHeight && depth == levelDepth &&
-        pool_ == D3DPOOL_DEFAULT)
+        usage_ > TEXTURE_STATIC)
         flags |= D3DLOCK_DISCARD;
 
-    HRESULT hr = ((IDirect3DVolumeTexture9*)object_)->LockBox(level, &d3dLockedBox, (flags & D3DLOCK_DISCARD) ? 0 : &d3dBox, flags);
+    HRESULT hr = ((IDirect3DVolumeTexture9*)object_.ptr_)->LockBox(level, &d3dLockedBox, (flags & D3DLOCK_DISCARD) ? 0 : &d3dBox, flags);
     if (FAILED(hr))
     {
         URHO3D_LOGD3DERROR("Could not lock texture", hr);
@@ -353,7 +212,7 @@ bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int heig
         break;
     }
 
-    ((IDirect3DVolumeTexture9*)object_)->UnlockBox(level);
+    ((IDirect3DVolumeTexture9*)object_.ptr_)->UnlockBox(level);
     return true;
 }
 
@@ -487,7 +346,7 @@ bool Texture3D::SetData(Image* image, bool useAlpha)
 
 bool Texture3D::GetData(unsigned level, void* dest) const
 {
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not get data");
         return false;
@@ -524,7 +383,7 @@ bool Texture3D::GetData(unsigned level, void* dest) const
     d3dBox.Bottom = (UINT)levelHeight;
     d3dBox.Back = (UINT)levelDepth;
 
-    HRESULT hr = ((IDirect3DVolumeTexture9*)object_)->LockBox(level, &d3dLockedBox, &d3dBox, D3DLOCK_READONLY);
+    HRESULT hr = ((IDirect3DVolumeTexture9*)object_.ptr_)->LockBox(level, &d3dLockedBox, &d3dBox, D3DLOCK_READONLY);
     if (FAILED(hr))
     {
         URHO3D_LOGD3DERROR("Could not lock texture", hr);
@@ -593,7 +452,7 @@ bool Texture3D::GetData(unsigned level, void* dest) const
         break;
     }
 
-    ((IDirect3DVolumeTexture9*)object_)->UnlockBox(level);
+    ((IDirect3DVolumeTexture9*)object_.ptr_)->UnlockBox(level);
     return true;
 }
 
@@ -610,25 +469,28 @@ bool Texture3D::Create()
         return true;
     }
 
+    unsigned pool = usage_ > TEXTURE_STATIC ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
+    unsigned d3dUsage = usage_ == TEXTURE_DYNAMIC ? D3DUSAGE_DYNAMIC : 0;
+
     IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
     HRESULT hr = device->CreateVolumeTexture(
         (UINT)width_,
         (UINT)height_,
         (UINT)depth_,
         requestedLevels_,
-        usage_,
+        d3dUsage,
         (D3DFORMAT)format_,
-        (D3DPOOL)pool_,
+        (D3DPOOL)pool,
         (IDirect3DVolumeTexture9**)&object_,
         0);
     if (FAILED(hr))
     {
-        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_SAFE_RELEASE(object_.ptr_);
         URHO3D_LOGD3DERROR("Could not create texture", hr);
         return false;
     }
 
-    levels_ = ((IDirect3DVolumeTexture9*)object_)->GetLevelCount();
+    levels_ = ((IDirect3DVolumeTexture9*)object_.ptr_)->GetLevelCount();
 
     return true;
 }

+ 0 - 78
Source/Urho3D/Graphics/Direct3D9/D3D9Texture3D.h

@@ -1,78 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-
-namespace Urho3D
-{
-
-class Image;
-
-/// 3D texture resource.
-class URHO3D_API Texture3D : public Texture
-{
-    URHO3D_OBJECT(Texture3D, Texture);
-
-public:
-    /// Construct.
-    Texture3D(Context* context);
-    /// Destruct.
-    virtual ~Texture3D();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Release default pool resources.
-    virtual void OnDeviceLost();
-    /// Recreate default pool resources.
-    virtual void OnDeviceReset();
-    /// Release texture.
-    virtual void Release();
-
-    /// Set size, format and usage. Zero size will follow application window size. Return true if successful.
-    bool SetSize(int width, int height, int depth, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a mip level. Return true if successful.
-    bool SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data);
-    /// Set data from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(Image* image, bool useAlpha = false);
-
-    /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(unsigned level, void* dest) const;
-
-private:
-    /// Create texture.
-    bool Create();
-
-    /// Image file acquired during BeginLoad.
-    SharedPtr<Image> loadImage_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 35 - 297
Source/Urho3D/Graphics/Direct3D9/D3D9TextureCube.cpp

@@ -43,231 +43,22 @@
 namespace Urho3D
 {
 
-static const char* cubeMapLayoutNames[] = {
-    "horizontal",
-    "horizontalnvidia",
-    "horizontalcross",
-    "verticalcross",
-    "blender",
-    0
-};
-
-static SharedPtr<Image> GetTileImage(Image* src, int tileX, int tileY, int tileWidth, int tileHeight)
-{
-    return SharedPtr<Image>(
-        src->GetSubimage(IntRect(tileX * tileWidth, tileY * tileHeight, (tileX + 1) * tileWidth, (tileY + 1) * tileHeight)));
-}
-
-TextureCube::TextureCube(Context* context) :
-    Texture(context),
-    lockedLevel_(-1)
-{
-    // Default to clamp mode addressing
-    addressMode_[COORD_U] = ADDRESS_CLAMP;
-    addressMode_[COORD_V] = ADDRESS_CLAMP;
-    addressMode_[COORD_W] = ADDRESS_CLAMP;
-
-    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-        faceMemoryUse_[i] = 0;
-}
-
-TextureCube::~TextureCube()
-{
-    Release();
-}
-
-void TextureCube::RegisterObject(Context* context)
-{
-    context->RegisterFactory<TextureCube>();
-}
-
-bool TextureCube::BeginLoad(Deserializer& source)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If device is lost, retry later
-    if (graphics_->IsDeviceLost())
-    {
-        URHO3D_LOGWARNING("Texture load while device is lost");
-        dataPending_ = true;
-        return true;
-    }
-
-    cache->ResetDependencies(this);
-
-    String texPath, texName, texExt;
-    SplitPath(GetName(), texPath, texName, texExt);
-
-    loadParameters_ = (new XMLFile(context_));
-    if (!loadParameters_->Load(source))
-    {
-        loadParameters_.Reset();
-        return false;
-    }
-
-    loadImages_.Clear();
-
-    XMLElement textureElem = loadParameters_->GetRoot();
-    XMLElement imageElem = textureElem.GetChild("image");
-    // Single image and multiple faces with layout
-    if (imageElem)
-    {
-        String name = imageElem.GetAttribute("name");
-        // If path is empty, add the XML file path
-        if (GetPath(name).Empty())
-            name = texPath + name;
-        
-        SharedPtr<Image> image = cache->GetTempResource<Image>(name);
-        if (!image)
-            return false;
-        
-        int faceWidth, faceHeight;
-        loadImages_.Resize(MAX_CUBEMAP_FACES);
-
-        if (image->IsCubemap())
-        {
-            loadImages_[FACE_POSITIVE_X] = image;
-            loadImages_[FACE_NEGATIVE_X] = loadImages_[FACE_POSITIVE_X]->GetNextSibling();
-            loadImages_[FACE_POSITIVE_Y] = loadImages_[FACE_NEGATIVE_X]->GetNextSibling();
-            loadImages_[FACE_NEGATIVE_Y] = loadImages_[FACE_POSITIVE_Y]->GetNextSibling();
-            loadImages_[FACE_POSITIVE_Z] = loadImages_[FACE_NEGATIVE_Y]->GetNextSibling();
-            loadImages_[FACE_NEGATIVE_Z] = loadImages_[FACE_POSITIVE_Z]->GetNextSibling();
-        } 
-        else
-        {
-            CubeMapLayout layout = (CubeMapLayout)GetStringListIndex(imageElem.GetAttribute("layout").CString(), cubeMapLayoutNames, CML_HORIZONTAL);
-            switch (layout)
-            {
-            case CML_HORIZONTAL:
-                faceWidth = image->GetWidth() / MAX_CUBEMAP_FACES;
-                faceHeight = image->GetHeight();
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 0, 0, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 2, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 3, 0, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 4, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 5, 0, faceWidth, faceHeight);
-                break;
-
-            case CML_HORIZONTALNVIDIA:
-                faceWidth = image->GetWidth() / MAX_CUBEMAP_FACES;
-                faceHeight = image->GetHeight();
-                for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-                    loadImages_[i] = GetTileImage(image, i, 0, faceWidth, faceHeight);
-                break;
-
-            case CML_HORIZONTALCROSS:
-                faceWidth = image->GetWidth() / 4;
-                faceHeight = image->GetHeight() / 3;
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 3, 1, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 1, 2, faceWidth, faceHeight);
-                break;
-
-            case CML_VERTICALCROSS:
-                faceWidth = image->GetWidth() / 3;
-                faceHeight = image->GetHeight() / 4;
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 1, 2, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 1, 3, faceWidth, faceHeight);
-                if (loadImages_[FACE_NEGATIVE_Z])
-                {
-                    loadImages_[FACE_NEGATIVE_Z]->FlipVertical();
-                    loadImages_[FACE_NEGATIVE_Z]->FlipHorizontal();
-                }
-                break;
-
-            case CML_BLENDER:
-                faceWidth = image->GetWidth() / 3;
-                faceHeight = image->GetHeight() / 2;
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
-                break;
-            }
-        }
-    }
-    // Face per image
-    else
-    {
-        XMLElement faceElem = textureElem.GetChild("face");
-        while (faceElem)
-        {
-            String name = faceElem.GetAttribute("name");
-
-            // If path is empty, add the XML file path
-            if (GetPath(name).Empty())
-                name = texPath + name;
-
-            loadImages_.Push(cache->GetTempResource<Image>(name));
-            cache->StoreResourceDependency(this, name);
-
-            faceElem = faceElem.GetNext("face");
-        }
-    }
-
-    // Precalculate mip levels if async loading
-    if (GetAsyncLoadState() == ASYNC_LOADING)
-    {
-        for (unsigned i = 0; i < loadImages_.Size(); ++i)
-        {
-            if (loadImages_[i])
-                loadImages_[i]->PrecalculateLevels();
-        }
-    }
-
-    return true;
-}
-
-bool TextureCube::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_ || graphics_->IsDeviceLost())
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-
-    for (unsigned i = 0; i < loadImages_.Size() && i < MAX_CUBEMAP_FACES; ++i)
-        SetData((CubeMapFace)i, loadImages_[i]);
-
-    loadImages_.Clear();
-    loadParameters_.Reset();
-
-    return true;
-}
-
 void TextureCube::OnDeviceLost()
 {
-    if (pool_ == D3DPOOL_DEFAULT)
+    if (usage_ > TEXTURE_STATIC)
         Release();
 }
 
 void TextureCube::OnDeviceReset()
 {
-    if (pool_ == D3DPOOL_DEFAULT || !object_ || dataPending_)
+    if (usage_ > TEXTURE_STATIC || !object_.ptr_ || dataPending_)
     {
         // If has a resource file, reload through the resource cache. Otherwise just recreate.
         ResourceCache* cache = GetSubsystem<ResourceCache>();
         if (cache->Exists(GetName()))
             dataLost_ = !cache->ReloadResource(this);
 
-        if (!object_)
+        if (!object_.ptr_)
         {
             Create();
             dataLost_ = true;
@@ -294,67 +85,14 @@ void TextureCube::Release()
             renderSurfaces_[i]->Release();
     }
 
-    URHO3D_SAFE_RELEASE(object_);
-}
-
-bool TextureCube::SetSize(int size, unsigned format, TextureUsage usage)
-{
-    if (size <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative cube texture size");
-        return false;
-    }
-    if (usage == TEXTURE_DEPTHSTENCIL)
-    {
-        URHO3D_LOGERROR("Depth-stencil usage not supported for cube maps");
-        return false;
-    }
-
-    // Delete the old rendersurfaces if any
-    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-    {
-        renderSurfaces_[i].Reset();
-        faceMemoryUse_[i] = 0;
-    }
-
-    pool_ = D3DPOOL_MANAGED;
-    usage_ = 0;
-
-    if (usage == TEXTURE_RENDERTARGET)
-    {
-        for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-            renderSurfaces_[i] = new RenderSurface(this);
-
-        usage_ |= D3DUSAGE_RENDERTARGET;
-        pool_ = D3DPOOL_DEFAULT;
-
-        // Nearest filtering and mipmaps disabled by default
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
-    }
-    else if (usage == TEXTURE_DYNAMIC)
-    {
-        usage_ |= D3DUSAGE_DYNAMIC;
-        pool_ = D3DPOOL_DEFAULT;
-    }
-
-    if (usage == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(TextureCube, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
-
-    width_ = size;
-    height_ = size;
-    format_ = format;
-
-    return Create();
+    URHO3D_SAFE_RELEASE(object_.ptr_);
 }
 
 bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int width, int height, const void* data)
 {
     URHO3D_PROFILE(SetTextureData);
 
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not set data");
         return false;
@@ -401,10 +139,10 @@ bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int wi
     d3dRect.bottom = y + height;
 
     DWORD flags = 0;
-    if (level == 0 && x == 0 && y == 0 && width == levelWidth && height == levelHeight && pool_ == D3DPOOL_DEFAULT)
+    if (level == 0 && x == 0 && y == 0 && width == levelWidth && height == levelHeight && usage_ > TEXTURE_STATIC)
         flags |= D3DLOCK_DISCARD;
 
-    HRESULT hr = ((IDirect3DCubeTexture9*)object_)->LockRect((D3DCUBEMAP_FACES)face, level, &d3dLockedRect,
+    HRESULT hr = ((IDirect3DCubeTexture9*)object_.ptr_)->LockRect((D3DCUBEMAP_FACES)face, level, &d3dLockedRect,
         (flags & D3DLOCK_DISCARD) ? 0 : &d3dRect, flags);
     if (FAILED(hr))
     {
@@ -468,7 +206,7 @@ bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int wi
         break;
     }
 
-    ((IDirect3DCubeTexture9*)object_)->UnlockRect((D3DCUBEMAP_FACES)face, level);
+    ((IDirect3DCubeTexture9*)object_.ptr_)->UnlockRect((D3DCUBEMAP_FACES)face, level);
     return true;
 }
 
@@ -553,7 +291,7 @@ bool TextureCube::SetData(CubeMapFace face, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.ptr_)
             {
                 URHO3D_LOGERROR("Cube texture face 0 must be loaded first");
                 return false;
@@ -615,7 +353,7 @@ bool TextureCube::SetData(CubeMapFace face, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.ptr_)
             {
                 URHO3D_LOGERROR("Cube texture face 0 must be loaded first");
                 return false;
@@ -657,7 +395,7 @@ bool TextureCube::SetData(CubeMapFace face, Image* image, bool useAlpha)
 
 bool TextureCube::GetData(CubeMapFace face, unsigned level, void* dest) const
 {
-    if (!object_)
+    if (!object_.ptr_)
     {
         URHO3D_LOGERROR("No texture created, can not get data");
         return false;
@@ -725,7 +463,7 @@ bool TextureCube::GetData(CubeMapFace face, unsigned level, void* dest) const
     }
     else
     {
-        HRESULT hr = ((IDirect3DCubeTexture9*)object_)->LockRect((D3DCUBEMAP_FACES)face, level, &d3dLockedRect, &d3dRect, D3DLOCK_READONLY);
+        HRESULT hr = ((IDirect3DCubeTexture9*)object_.ptr_)->LockRect((D3DCUBEMAP_FACES)face, level, &d3dLockedRect, &d3dRect, D3DLOCK_READONLY);
         if (FAILED(hr))
         {
             URHO3D_LOGD3DERROR("Could not lock texture", hr);
@@ -792,7 +530,7 @@ bool TextureCube::GetData(CubeMapFace face, unsigned level, void* dest) const
         offscreenSurface->Release();
     }
     else
-        ((IDirect3DCubeTexture9*)object_)->UnlockRect((D3DCUBEMAP_FACES)face, level);
+        ((IDirect3DCubeTexture9*)object_.ptr_)->UnlockRect((D3DCUBEMAP_FACES)face, level);
 
     return true;
 }
@@ -810,29 +548,44 @@ bool TextureCube::Create()
         return true;
     }
 
+    unsigned pool = usage_ > TEXTURE_STATIC ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
+    unsigned d3dUsage = 0;
+
+    switch (usage_)
+    {
+    case TEXTURE_DYNAMIC:
+        d3dUsage |= D3DUSAGE_DYNAMIC;
+        break;
+    case TEXTURE_RENDERTARGET:
+        d3dUsage |= D3DUSAGE_RENDERTARGET;
+        break;
+    default:
+        break;
+    }
+
     IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
     HRESULT hr = device->CreateCubeTexture(
         (UINT)width_,
         requestedLevels_,
-        usage_,
+        d3dUsage,
         (D3DFORMAT)format_,
-        (D3DPOOL)pool_,
-        (IDirect3DCubeTexture9**)&object_,
+        (D3DPOOL)pool,
+        (IDirect3DCubeTexture9**)&object_.ptr_,
         0);
     if (FAILED(hr))
     {
-        URHO3D_SAFE_RELEASE(object_);
+        URHO3D_SAFE_RELEASE(object_.ptr_);
         URHO3D_LOGD3DERROR("Could not create cube texture", hr);
         return false;
     }
 
-    levels_ = ((IDirect3DCubeTexture9*)object_)->GetLevelCount();
+    levels_ = ((IDirect3DCubeTexture9*)object_.ptr_)->GetLevelCount();
 
-    if (usage_ & D3DUSAGE_RENDERTARGET)
+    if (usage_ == TEXTURE_RENDERTARGET)
     {
         for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
         {
-            hr = ((IDirect3DCubeTexture9*)object_)->GetCubeMapSurface((D3DCUBEMAP_FACES)i, 0,
+            hr = ((IDirect3DCubeTexture9*)object_.ptr_)->GetCubeMapSurface((D3DCUBEMAP_FACES)i, 0,
                 (IDirect3DSurface9**)&renderSurfaces_[i]->surface_);
             if (FAILED(hr))
                 URHO3D_LOGD3DERROR("Could not get rendertarget surface", hr);
@@ -842,19 +595,4 @@ bool TextureCube::Create()
     return true;
 }
 
-void TextureCube::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    Renderer* renderer = GetSubsystem<Renderer>();
-
-    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-    {
-        if (renderSurfaces_[i] && (renderSurfaces_[i]->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurfaces_[i]->IsUpdateQueued()))
-        {
-            if (renderer)
-                renderer->QueueRenderSurface(renderSurfaces_[i]);
-            renderSurfaces_[i]->ResetUpdateQueued();
-        }
-    }
-}
-
 }

+ 0 - 94
Source/Urho3D/Graphics/Direct3D9/D3D9TextureCube.h

@@ -1,94 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-
-namespace Urho3D
-{
-
-class Deserializer;
-class Image;
-
-/// Cube texture resource.
-class URHO3D_API TextureCube : public Texture
-{
-    URHO3D_OBJECT(TextureCube, Texture);
-
-public:
-    /// Construct.
-    TextureCube(Context* context);
-    /// Destruct.
-    virtual ~TextureCube();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Release default pool resources.
-    virtual void OnDeviceLost();
-    /// ReCreate default pool resources.
-    virtual void OnDeviceReset();
-    /// Release texture.
-    virtual void Release();
-
-    /// Set size, format and usage. Return true if successful.
-    bool SetSize(int size, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a face's mip level. Return true if successful.
-    bool SetData(CubeMapFace face, unsigned level, int x, int y, int width, int height, const void* data);
-    /// Set data of one face from a stream. Return true if successful.
-    bool SetData(CubeMapFace face, Deserializer& source);
-    /// Set data of one face from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(CubeMapFace face, Image* image, bool useAlpha = false);
-
-    /// Get data from a face's mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(CubeMapFace face, unsigned level, void* dest) const;
-
-    /// Return render surface for one face.
-    RenderSurface* GetRenderSurface(CubeMapFace face) const { return renderSurfaces_[face]; }
-
-private:
-    /// Create texture.
-    bool Create();
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
-
-    /// Render surfaces.
-    SharedPtr<RenderSurface> renderSurfaces_[MAX_CUBEMAP_FACES];
-    /// Memory use per face.
-    unsigned faceMemoryUse_[MAX_CUBEMAP_FACES];
-    /// Currently locked mip level.
-    int lockedLevel_;
-    /// Currently locked face.
-    CubeMapFace lockedFace_;
-    /// Face image files acquired during BeginLoad.
-    Vector<SharedPtr<Image> > loadImages_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 21 - 199
Source/Urho3D/Graphics/Direct3D9/D3D9VertexBuffer.cpp

@@ -32,39 +32,17 @@
 namespace Urho3D
 {
 
-VertexBuffer::VertexBuffer(Context* context, bool forceHeadless) :
-    Object(context),
-    GPUObject(forceHeadless ? (Graphics*)0 : GetSubsystem<Graphics>()),
-    vertexCount_(0),
-    elementHash_(0),
-    elementMask_(0),
-    pool_(D3DPOOL_MANAGED),
-    usage_(0),
-    lockState_(LOCK_NONE),
-    lockStart_(0),
-    lockCount_(0),
-    lockScratchData_(0),
-    shadowed_(false)
-{
-    // Force shadowing mode if graphics subsystem does not exist
-    if (!graphics_)
-        shadowed_ = true;
-}
-
-VertexBuffer::~VertexBuffer()
-{
-    Release();
-}
-
 void VertexBuffer::OnDeviceLost()
 {
-    if (pool_ == D3DPOOL_DEFAULT)
+    // Dynamic buffers are in the default pool and need to be released on device loss
+    if (dynamic_)
         Release();
 }
 
 void VertexBuffer::OnDeviceReset()
 {
-    if (pool_ == D3DPOOL_DEFAULT || !object_)
+    // Dynamic buffers are in the default pool and need to be recreated after device reset
+    if (dynamic_ || !object_.ptr_)
     {
         Create();
         dataLost_ = !UpdateToGPU();
@@ -88,57 +66,7 @@ void VertexBuffer::Release()
         }
     }
 
-    URHO3D_SAFE_RELEASE(object_);
-}
-
-void VertexBuffer::SetShadowed(bool enable)
-{
-    // If no graphics subsystem, can not disable shadowing
-    if (!graphics_)
-        enable = true;
-
-    if (enable != shadowed_)
-    {
-        if (enable && vertexSize_ && vertexCount_)
-            shadowData_ = new unsigned char[vertexCount_ * vertexSize_];
-        else
-            shadowData_.Reset();
-
-        shadowed_ = enable;
-    }
-}
-
-bool VertexBuffer::SetSize(unsigned vertexCount, unsigned elementMask, bool dynamic)
-{
-    return SetSize(vertexCount, GetElements(elementMask), dynamic);
-}
-
-bool VertexBuffer::SetSize(unsigned vertexCount, const PODVector<VertexElement>& elements, bool dynamic)
-{
-    Unlock();
-
-    if (dynamic)
-    {
-        pool_ = D3DPOOL_DEFAULT;
-        usage_ = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY;
-    }
-    else
-    {
-        pool_ = D3DPOOL_MANAGED;
-        usage_ = 0;
-    }
-
-    vertexCount_ = vertexCount;
-    elements_ = elements;
-
-    UpdateOffsets();
-
-    if (shadowed_ && vertexCount_ && vertexSize_)
-        shadowData_ = new unsigned char[vertexCount_ * vertexSize_];
-    else
-        shadowData_.Reset();
-
-    return Create();
+    URHO3D_SAFE_RELEASE(object_.ptr_);
 }
 
 bool VertexBuffer::SetData(const void* data)
@@ -158,7 +86,7 @@ bool VertexBuffer::SetData(const void* data)
     if (shadowData_ && data != shadowData_.Get())
         memcpy(shadowData_.Get(), data, vertexCount_ * vertexSize_);
 
-    if (object_)
+    if (object_.ptr_)
     {
         if (graphics_->IsDeviceLost())
         {
@@ -210,7 +138,7 @@ bool VertexBuffer::SetDataRange(const void* data, unsigned start, unsigned count
     if (shadowData_ && shadowData_.Get() + start * vertexSize_ != data)
         memcpy(shadowData_.Get() + start * vertexSize_, data, count * vertexSize_);
 
-    if (object_)
+    if (object_.ptr_)
     {
         if (graphics_->IsDeviceLost())
         {
@@ -259,7 +187,7 @@ void* VertexBuffer::Lock(unsigned start, unsigned count, bool discard)
     lockCount_ = count;
 
     // Because shadow data must be kept in sync, can only lock hardware buffer if not shadowed
-    if (object_ && !shadowData_ && !graphics_->IsDeviceLost())
+    if (object_.ptr_ && !shadowData_ && !graphics_->IsDeviceLost())
         return MapBuffer(start, count, discard);
     else if (shadowData_)
     {
@@ -301,115 +229,6 @@ void VertexBuffer::Unlock()
     }
 }
 
-bool VertexBuffer::IsDynamic() const
-{
-    return pool_ == D3DPOOL_DEFAULT;
-}
-
-void VertexBuffer::UpdateOffsets()
-{
-    unsigned elementOffset = 0;
-    elementHash_ = 0;
-    elementMask_ = 0;
-
-    for (PODVector<VertexElement>::Iterator i = elements_.Begin(); i != elements_.End(); ++i)
-    {
-        i->offset_ = elementOffset;
-        elementOffset += ELEMENT_TYPESIZES[i->type_];
-        elementHash_ <<= 6;
-        elementHash_ += (((int)i->type_ + 1) * ((int)i->semantic_ + 1) + i->index_);
-
-        for (unsigned j = 0; j < MAX_LEGACY_VERTEX_ELEMENTS; ++j)
-        {
-            const VertexElement& legacy = LEGACY_VERTEXELEMENTS[j];
-            if (i->type_ == legacy.type_ && i->semantic_ == legacy.semantic_ && i->index_ == legacy.index_)
-                elementMask_ |= (1 << j);
-        }
-    }
-
-    vertexSize_ = elementOffset;
-}
-
-const VertexElement* VertexBuffer::GetElement(VertexElementSemantic semantic, unsigned char index) const
-{
-    for (PODVector<VertexElement>::ConstIterator i = elements_.Begin(); i != elements_.End(); ++i)
-    {
-        if (i->semantic_ == semantic && i->index_ == index)
-            return &(*i);
-    }
-
-    return 0;
-}
-
-const VertexElement* VertexBuffer::GetElement(VertexElementType type, VertexElementSemantic semantic, unsigned char index) const
-{
-    for (PODVector<VertexElement>::ConstIterator i = elements_.Begin(); i != elements_.End(); ++i)
-    {
-        if (i->type_ == type && i->semantic_ == semantic && i->index_ == index)
-            return &(*i);
-    }
-
-    return 0;
-}
-
-const VertexElement* VertexBuffer::GetElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
-{
-    for (PODVector<VertexElement>::ConstIterator i = elements.Begin(); i != elements.End(); ++i)
-    {
-        if (i->type_ == type && i->semantic_ == semantic && i->index_ == index)
-            return &(*i);
-    }
-
-    return 0;
-}
-
-bool VertexBuffer::HasElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
-{
-    return GetElement(elements, type, semantic, index) != 0;
-}
-
-unsigned VertexBuffer::GetElementOffset(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
-{
-    const VertexElement* element = GetElement(elements, type, semantic, index);
-    return element ? element->offset_ : M_MAX_UNSIGNED;
-}
-
-PODVector<VertexElement> VertexBuffer::GetElements(unsigned elementMask)
-{
-    PODVector<VertexElement> ret;
-
-    for (unsigned i = 0; i < MAX_LEGACY_VERTEX_ELEMENTS; ++i)
-    {
-        if (elementMask & (1 << i))
-            ret.Push(LEGACY_VERTEXELEMENTS[i]);
-    }
-
-    return ret;
-}
-
-unsigned VertexBuffer::GetVertexSize(const PODVector<VertexElement>& elements)
-{
-    unsigned size = 0;
-
-    for (unsigned i = 0; i < elements.Size(); ++i)
-        size += ELEMENT_TYPESIZES[elements[i].type_];
-
-    return size;
-}
-
-unsigned VertexBuffer::GetVertexSize(unsigned elementMask)
-{
-    unsigned size = 0;
-
-    for (unsigned i = 0; i < MAX_LEGACY_VERTEX_ELEMENTS; ++i)
-    {
-        if (elementMask & (1 << i))
-            size += ELEMENT_TYPESIZES[LEGACY_VERTEXELEMENTS[i].type_];
-    }
-
-    return size;
-}
-
 bool VertexBuffer::Create()
 {
     Release();
@@ -425,17 +244,20 @@ bool VertexBuffer::Create()
             return true;
         }
 
+        unsigned pool = dynamic_ ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
+        unsigned d3dUsage = dynamic_ ? D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY : 0;
+
         IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
         HRESULT hr = device->CreateVertexBuffer(
             vertexCount_ * vertexSize_,
-            usage_,
+            d3dUsage,
             0,
-            (D3DPOOL)pool_,
-            (IDirect3DVertexBuffer9**)&object_,
+            (D3DPOOL)pool,
+            (IDirect3DVertexBuffer9**)&object_.ptr_,
             0);
         if (FAILED(hr))
         {
-            URHO3D_SAFE_RELEASE(object_);
+            URHO3D_SAFE_RELEASE(object_.ptr_);
             URHO3D_LOGD3DERROR("Could not create vertex buffer", hr);
             return false;
         }
@@ -446,7 +268,7 @@ bool VertexBuffer::Create()
 
 bool VertexBuffer::UpdateToGPU()
 {
-    if (object_ && shadowData_)
+    if (object_.ptr_ && shadowData_)
         return SetData(shadowData_.Get());
     else
         return false;
@@ -456,14 +278,14 @@ void* VertexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
 {
     void* hwData = 0;
 
-    if (object_)
+    if (object_.ptr_)
     {
         DWORD flags = 0;
 
-        if (discard && usage_ & D3DUSAGE_DYNAMIC)
+        if (discard && dynamic_)
             flags = D3DLOCK_DISCARD;
 
-        HRESULT hr = ((IDirect3DVertexBuffer9*)object_)->Lock(start * vertexSize_, count * vertexSize_, &hwData, flags);
+        HRESULT hr = ((IDirect3DVertexBuffer9*)object_.ptr_)->Lock(start * vertexSize_, count * vertexSize_, &hwData, flags);
         if (FAILED(hr))
             URHO3D_LOGD3DERROR("Could not lock vertex buffer", hr);
         else
@@ -475,9 +297,9 @@ void* VertexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
 
 void VertexBuffer::UnmapBuffer()
 {
-    if (object_ && lockState_ == LOCK_HARDWARE)
+    if (object_.ptr_ && lockState_ == LOCK_HARDWARE)
     {
-        ((IDirect3DVertexBuffer9*)object_)->Unlock();
+        ((IDirect3DVertexBuffer9*)object_.ptr_)->Unlock();
         lockState_ = LOCK_NONE;
     }
 }

+ 0 - 171
Source/Urho3D/Graphics/Direct3D9/D3D9VertexBuffer.h

@@ -1,171 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/ArrayPtr.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-
-namespace Urho3D
-{
-
-/// Hardware vertex buffer.
-class URHO3D_API VertexBuffer : public Object, public GPUObject
-{
-    URHO3D_OBJECT(VertexBuffer, Object);
-
-public:
-    /// Construct.
-    VertexBuffer(Context* context, bool forceHeadless = false);
-    /// Destruct.
-    virtual ~VertexBuffer();
-
-    /// Release default pool resources.
-    virtual void OnDeviceLost();
-    /// ReCreate default pool resources.
-    virtual void OnDeviceReset();
-    /// Release buffer.
-    virtual void Release();
-
-    /// Enable shadowing in CPU memory. Shadowing is forced on if the graphics subsystem does not exist.
-    void SetShadowed(bool enable);
-    /// Set size, vertex elements and dynamic mode. Previous data will be lost.
-    bool SetSize(unsigned vertexCount, const PODVector<VertexElement>& elements, bool dynamic = false);
-    /// Set size and vertex elements and dynamic mode using legacy element bitmask. Previous data will be lost.
-    bool SetSize(unsigned vertexCount, unsigned elementMask, bool dynamic = false);
-    /// Set all data in the buffer.
-    bool SetData(const void* data);
-    /// Set a data range in the buffer. Optionally discard data outside the range.
-    bool SetDataRange(const void* data, unsigned start, unsigned count, bool discard = false);
-    /// Lock the buffer for write-only editing. Return data pointer if successful. Optionally discard data outside the range.
-    void* Lock(unsigned start, unsigned count, bool discard = false);
-    /// Unlock the buffer and apply changes to the GPU buffer.
-    void Unlock();
-
-    /// Return whether CPU memory shadowing is enabled.
-    bool IsShadowed() const { return shadowed_; }
-
-    /// Return whether is dynamic.
-    bool IsDynamic() const;
-
-    /// Return whether is currently locked.
-    bool IsLocked() const { return lockState_ != LOCK_NONE; }
-
-    /// Return number of vertices.
-    unsigned GetVertexCount() const { return vertexCount_; }
-
-    /// Return vertex size in bytes.
-    unsigned GetVertexSize() const { return vertexSize_; }
-
-    /// Return vertex elements.
-    const PODVector<VertexElement>& GetElements() const { return elements_; }
-
-    /// Return vertex element, or null if does not exist.
-    const VertexElement* GetElement(VertexElementSemantic semantic, unsigned char index = 0) const;
-
-    /// Return vertex element with specific type, or null if does not exist.
-    const VertexElement* GetElement(VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0) const;
-
-    /// Return whether has a specified element semantic.
-    bool HasElement(VertexElementSemantic semantic, unsigned char index = 0) const { return GetElement(semantic, index) != 0; }
-
-    /// Return whether has an element semantic with specific type.
-    bool HasElement(VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0) const { return GetElement(type, semantic, index) != 0; }
-
-    /// Return offset of a element within vertex, or M_MAX_UNSIGNED if does not exist.
-    unsigned GetElementOffset(VertexElementSemantic semantic, unsigned char index = 0) const { const VertexElement* element = GetElement(semantic, index); return element ? element->offset_ : M_MAX_UNSIGNED; }
-
-    /// Return offset of a element with specific type within vertex, or M_MAX_UNSIGNED if element does not exist.
-    unsigned GetElementOffset(VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0) const { const VertexElement* element = GetElement(type, semantic, index); return element ? element->offset_ : M_MAX_UNSIGNED; }
-
-    /// Return legacy vertex element mask. Note that both semantic and type must match the legacy element for a mask bit to be set.
-    unsigned GetElementMask() const { return elementMask_; }
-
-    /// Return CPU memory shadow data.
-    unsigned char* GetShadowData() const { return shadowData_.Get(); }
-
-    /// Return shared array pointer to the CPU memory shadow data.
-    SharedArrayPtr<unsigned char> GetShadowDataShared() const { return shadowData_; }
-
-    /// Return buffer hash for building vertex declarations. Used internally.
-    unsigned long long GetBufferHash(unsigned streamIndex) { return elementHash_ << (streamIndex * 16); }
-
-    /// Return element with specified type and semantic from a vertex element list, or null if does not exist.
-    static const VertexElement* GetElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0);
-
-    /// Return whether element list has a specified element type and semantic.
-    static bool HasElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0);
-
-    /// Return element offset for specified type and semantic from a vertex element list, or M_MAX_UNSIGNED if does not exist.
-    static unsigned GetElementOffset(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0);
-
-    /// Return a vertex element list from a legacy element bitmask.
-    static PODVector<VertexElement> GetElements(unsigned elementMask);
-
-    /// Return vertex size from an element list.
-    static unsigned GetVertexSize(const PODVector<VertexElement>& elements);
-
-    /// Return vertex size for a legacy vertex element bitmask.
-    static unsigned GetVertexSize(unsigned elementMask);
-
-private:
-    /// Update vertex size, offsets of vertex elements and the element hash.
-    void UpdateOffsets();
-    /// Create buffer.
-    bool Create();
-    /// Update the shadow data to the GPU buffer.
-    bool UpdateToGPU();
-    /// Map the GPU buffer into CPU memory.
-    void* MapBuffer(unsigned start, unsigned count, bool discard);
-    /// Unmap the GPU buffer.
-    void UnmapBuffer();
-
-    /// Shadow data.
-    SharedArrayPtr<unsigned char> shadowData_;
-    /// Number of vertices.
-    unsigned vertexCount_;
-    /// Vertex size.
-    unsigned vertexSize_;
-    /// Vertex elements.
-    PODVector<VertexElement> elements_;
-    /// Vertex element hash.
-    unsigned long long elementHash_;
-    /// Vertex element legacy bitmask.
-    unsigned elementMask_;
-    /// Memory pool.
-    unsigned pool_;
-    /// Usage type.
-    unsigned usage_;
-    /// Buffer locking state.
-    LockState lockState_;
-    /// Lock start vertex.
-    unsigned lockStart_;
-    /// Lock number of vertices.
-    unsigned lockCount_;
-    /// Scratch buffer for fallback locking.
-    void* lockScratchData_;
-    /// Shadowed flag.
-    bool shadowed_;
-};
-
-}

+ 80 - 64
Source/Urho3D/Graphics/OpenGL/OGLGPUObject.cpp → Source/Urho3D/Graphics/GPUObject.cpp

@@ -1,64 +1,80 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#include "../../Precompiled.h"
-
-#include "../../Graphics/Graphics.h"
-#include "../../Graphics/GPUObject.h"
-
-#include "../../DebugNew.h"
-
-namespace Urho3D
-{
-
-GPUObject::GPUObject(Graphics* graphics) :
-    graphics_(graphics),
-    object_(0),
-    dataLost_(false),
-    dataPending_(false)
-{
-    if (graphics_)
-        graphics->AddGPUObject(this);
-}
-
-GPUObject::~GPUObject()
-{
-    if (graphics_)
-        graphics_->RemoveGPUObject(this);
-}
-
-void GPUObject::OnDeviceLost()
-{
-    object_ = 0;
-}
-
-void GPUObject::ClearDataLost()
-{
-    dataLost_ = false;
-}
-
-Graphics* GPUObject::GetGraphics() const
-{
-    return graphics_;
-}
-
-}
+//
+// Copyright (c) 2008-2016 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "../Precompiled.h"
+
+#include "../Graphics/Graphics.h"
+#include "../Graphics/GPUObject.h"
+
+#include "../DebugNew.h"
+
+namespace Urho3D
+{
+
+GPUObject::GPUObject(Graphics* graphics) :
+    graphics_(graphics),
+    dataLost_(false),
+    dataPending_(false)
+{
+#ifdef URHO3D_OPENGL
+    object_.name_ = 0;
+#else
+    object_.ptr_ = 0;
+#endif
+
+    if (graphics_)
+        graphics->AddGPUObject(this);
+}
+
+GPUObject::~GPUObject()
+{
+    if (graphics_)
+        graphics_->RemoveGPUObject(this);
+}
+
+void GPUObject::OnDeviceLost()
+{
+#ifdef URHO3D_OPENGL
+    // On OpenGL the object has already been lost at this point; reset object name
+    object_.name_ = 0;
+#endif
+}
+
+void GPUObject::OnDeviceReset()
+{
+}
+
+void GPUObject::Release()
+{
+}
+
+void GPUObject::ClearDataLost()
+{
+    dataLost_ = false;
+}
+
+Graphics* GPUObject::GetGraphics() const
+{
+    return graphics_;
+}
+
+}

+ 59 - 7
Source/Urho3D/Graphics/GPUObject.h

@@ -22,10 +22,62 @@
 
 #pragma once
 
-#if defined(URHO3D_OPENGL)
-#include "OpenGL/OGLGPUObject.h"
-#elif defined(URHO3D_D3D11)
-#include "Direct3D11/D3D11GPUObject.h"
-#else
-#include "Direct3D9/D3D9GPUObject.h"
-#endif
+#include "../Container/Ptr.h"
+
+namespace Urho3D
+{
+
+class Graphics;
+
+/// API-specific GPU object representation.
+union GPUObjectHandle
+{
+    /// Object pointer (Direct3D.)
+    void* ptr_;
+    /// Object name (OpenGL.)
+    unsigned name_;
+};
+
+/// Base class for GPU resources.
+class URHO3D_API GPUObject
+{
+public:
+    /// Construct with graphics subsystem pointer.
+    GPUObject(Graphics* graphics);
+    /// Destruct. Remove from the Graphics.
+    virtual ~GPUObject();
+
+    /// Mark the GPU resource destroyed on graphics context destruction.
+    virtual void OnDeviceLost();
+    /// Recreate the GPU resource and restore data if applicable.
+    virtual void OnDeviceReset();
+    /// Unconditionally release the GPU resource.
+    virtual void Release();
+
+    /// Clear the data lost flag.
+    void ClearDataLost();
+
+    /// Return the graphics subsystem associated with this GPU object.
+    Graphics* GetGraphics() const;
+    /// Return the object pointer. Applicable only on Direct3D.
+    void* GetGPUObject() const { return object_.ptr_; }
+    /// Return the object name. Applicable only on OpenGL.
+    unsigned GetGPUObjectName() const { return object_.name_; }
+    /// Return whether data is lost due to context loss.
+    bool IsDataLost() const { return dataLost_; }
+    /// Return whether has pending data assigned while graphics context was lost.
+    bool HasPendingData() const { return dataPending_; }
+
+protected:
+    /// Graphics subsystem.
+    WeakPtr<Graphics> graphics_;
+    /// Object pointer or name.
+    GPUObjectHandle object_;
+    /// Data lost flag.
+    bool dataLost_;
+    /// Data pending flag.
+    bool dataPending_;
+};
+
+}
+

+ 310 - 0
Source/Urho3D/Graphics/Graphics.cpp

@@ -0,0 +1,310 @@
+//
+// Copyright (c) 2008-2016 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "../Precompiled.h"
+
+#include "../Graphics/AnimatedModel.h"
+#include "../Graphics/Animation.h"
+#include "../Graphics/AnimationController.h"
+#include "../Graphics/Camera.h"
+#include "../Graphics/CustomGeometry.h"
+#include "../Graphics/DebugRenderer.h"
+#include "../Graphics/DecalSet.h"
+#include "../Graphics/Graphics.h"
+#include "../Graphics/GraphicsImpl.h"
+#include "../Graphics/Material.h"
+#include "../Graphics/Octree.h"
+#include "../Graphics/ParticleEffect.h"
+#include "../Graphics/ParticleEmitter.h"
+#include "../Graphics/RibbonTrail.h"
+#include "../Graphics/Shader.h"
+#include "../Graphics/Skybox.h"
+#include "../Graphics/StaticModelGroup.h"
+#include "../Graphics/Technique.h"
+#include "../Graphics/Terrain.h"
+#include "../Graphics/TerrainPatch.h"
+#include "../Graphics/Texture2D.h"
+#include "../Graphics/Texture2DArray.h"
+#include "../Graphics/Texture3D.h"
+#include "../Graphics/TextureCube.h"
+#include "../Graphics/Zone.h"
+#include "../IO/Log.h"
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_syswm.h>
+
+#include "../DebugNew.h"
+
+namespace Urho3D
+{
+
+void Graphics::SetExternalWindow(void* window)
+{
+    if (!window_)
+        externalWindow_ = window;
+    else
+        URHO3D_LOGERROR("Window already opened, can not set external window");
+}
+
+void Graphics::SetWindowTitle(const String& windowTitle)
+{
+    windowTitle_ = windowTitle;
+    if (window_)
+        SDL_SetWindowTitle(window_, windowTitle_.CString());
+}
+
+void Graphics::SetWindowIcon(Image* windowIcon)
+{
+    windowIcon_ = windowIcon;
+    if (window_)
+        CreateWindowIcon();
+}
+
+void Graphics::SetWindowPosition(const IntVector2& position)
+{
+    if (window_)
+        SDL_SetWindowPosition(window_, position.x_, position.y_);
+    else
+        position_ = position; // Sets as initial position for OpenWindow()
+}
+
+void Graphics::SetWindowPosition(int x, int y)
+{
+    SetWindowPosition(IntVector2(x, y));
+}
+
+void Graphics::SetOrientations(const String& orientations)
+{
+    orientations_ = orientations.Trimmed();
+    SDL_SetHint(SDL_HINT_ORIENTATIONS, orientations_.CString());
+}
+
+bool Graphics::ToggleFullscreen()
+{
+    return SetMode(width_, height_, !fullscreen_, borderless_, resizable_, highDPI_, vsync_, tripleBuffer_, multiSample_);
+}
+
+IntVector2 Graphics::GetWindowPosition() const
+{
+    if (window_)
+        return position_;
+    return IntVector2::ZERO;
+}
+
+PODVector<IntVector2> Graphics::GetResolutions() const
+{
+    PODVector<IntVector2> ret;
+    // Emscripten is not able to return a valid list
+#ifndef __EMSCRIPTEN__
+    unsigned numModes = (unsigned)SDL_GetNumDisplayModes(0);
+
+    for (unsigned i = 0; i < numModes; ++i)
+    {
+        SDL_DisplayMode mode;
+        SDL_GetDisplayMode(0, i, &mode);
+        int width = mode.w;
+        int height = mode.h;
+
+        // Store mode if unique
+        bool unique = true;
+        for (unsigned j = 0; j < ret.Size(); ++j)
+        {
+            if (ret[j].x_ == width && ret[j].y_ == height)
+            {
+                unique = false;
+                break;
+            }
+        }
+
+        if (unique)
+            ret.Push(IntVector2(width, height));
+    }
+#endif
+
+    return ret;
+}
+
+IntVector2 Graphics::GetDesktopResolution() const
+{
+#if !defined(__ANDROID__) && !defined(IOS)
+    SDL_DisplayMode mode;
+    SDL_GetDesktopDisplayMode(0, &mode);
+    return IntVector2(mode.w, mode.h);
+#else
+    // SDL_GetDesktopDisplayMode() may not work correctly on mobile platforms. Rather return the window size
+    return IntVector2(width_, height_);
+#endif
+}
+
+void Graphics::Maximize()
+{
+    if (!window_)
+        return;
+
+    SDL_MaximizeWindow(window_);
+}
+
+void Graphics::Minimize()
+{
+    if (!window_)
+        return;
+
+    SDL_MinimizeWindow(window_);
+}
+
+void Graphics::AddGPUObject(GPUObject* object)
+{
+    MutexLock lock(gpuObjectMutex_);
+
+    gpuObjects_.Push(object);
+}
+
+void Graphics::RemoveGPUObject(GPUObject* object)
+{
+    MutexLock lock(gpuObjectMutex_);
+
+    gpuObjects_.Remove(object);
+}
+
+void* Graphics::ReserveScratchBuffer(unsigned size)
+{
+    if (!size)
+        return 0;
+
+    if (size > maxScratchBufferRequest_)
+        maxScratchBufferRequest_ = size;
+
+    // First check for a free buffer that is large enough
+    for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
+    {
+        if (!i->reserved_ && i->size_ >= size)
+        {
+            i->reserved_ = true;
+            return i->data_.Get();
+        }
+    }
+
+    // Then check if a free buffer can be resized
+    for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
+    {
+        if (!i->reserved_)
+        {
+            i->data_ = new unsigned char[size];
+            i->size_ = size;
+            i->reserved_ = true;
+
+            URHO3D_LOGDEBUG("Resized scratch buffer to size " + String(size));
+
+            return i->data_.Get();
+        }
+    }
+
+    // Finally allocate a new buffer
+    ScratchBuffer newBuffer;
+    newBuffer.data_ = new unsigned char[size];
+    newBuffer.size_ = size;
+    newBuffer.reserved_ = true;
+    scratchBuffers_.Push(newBuffer);
+    return newBuffer.data_.Get();
+
+    URHO3D_LOGDEBUG("Allocated scratch buffer with size " + String(size));
+}
+
+void Graphics::FreeScratchBuffer(void* buffer)
+{
+    if (!buffer)
+        return;
+
+    for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
+    {
+        if (i->reserved_ && i->data_.Get() == buffer)
+        {
+            i->reserved_ = false;
+            return;
+        }
+    }
+
+    URHO3D_LOGWARNING("Reserved scratch buffer " + ToStringHex((unsigned)(size_t)buffer) + " not found");
+}
+
+void Graphics::CleanupScratchBuffers()
+{
+    for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
+    {
+        if (!i->reserved_ && i->size_ > maxScratchBufferRequest_ * 2 && i->size_ >= 1024 * 1024)
+        {
+            i->data_ = maxScratchBufferRequest_ > 0 ? new unsigned char[maxScratchBufferRequest_] : 0;
+            i->size_ = maxScratchBufferRequest_;
+
+            URHO3D_LOGDEBUG("Resized scratch buffer to size " + String(maxScratchBufferRequest_));
+        }
+    }
+
+    maxScratchBufferRequest_ = 0;
+}
+
+void Graphics::CreateWindowIcon()
+{
+    if (windowIcon_)
+    {
+        SDL_Surface* surface = windowIcon_->GetSDLSurface();
+        if (surface)
+        {
+            SDL_SetWindowIcon(window_, surface);
+            SDL_FreeSurface(surface);
+        }
+    }
+}
+
+void RegisterGraphicsLibrary(Context* context)
+{
+    Animation::RegisterObject(context);
+    Material::RegisterObject(context);
+    Model::RegisterObject(context);
+    Shader::RegisterObject(context);
+    Technique::RegisterObject(context);
+    Texture2D::RegisterObject(context);
+    Texture2DArray::RegisterObject(context);
+    Texture3D::RegisterObject(context);
+    TextureCube::RegisterObject(context);
+    Camera::RegisterObject(context);
+    Drawable::RegisterObject(context);
+    Light::RegisterObject(context);
+    StaticModel::RegisterObject(context);
+    StaticModelGroup::RegisterObject(context);
+    Skybox::RegisterObject(context);
+    AnimatedModel::RegisterObject(context);
+    AnimationController::RegisterObject(context);
+    BillboardSet::RegisterObject(context);
+    ParticleEffect::RegisterObject(context);
+    ParticleEmitter::RegisterObject(context);
+    RibbonTrail::RegisterObject(context);
+    CustomGeometry::RegisterObject(context);
+    DecalSet::RegisterObject(context);
+    Terrain::RegisterObject(context);
+    TerrainPatch::RegisterObject(context);
+    DebugRenderer::RegisterObject(context);
+    Octree::RegisterObject(context);
+    Zone::RegisterObject(context);
+}
+
+}

+ 728 - 7
Source/Urho3D/Graphics/Graphics.h

@@ -22,10 +22,731 @@
 
 #pragma once
 
-#if defined(URHO3D_OPENGL)
-#include "OpenGL/OGLGraphics.h"
-#elif defined(URHO3D_D3D11)
-#include "Direct3D11/D3D11Graphics.h"
-#else
-#include "Direct3D9/D3D9Graphics.h"
-#endif
+#include "../Container/ArrayPtr.h"
+#include "../Container/HashSet.h"
+#include "../Core/Mutex.h"
+#include "../Core/Object.h"
+#include "../Graphics/GraphicsDefs.h"
+#include "../Graphics/ShaderVariation.h"
+#include "../Math/Color.h"
+#include "../Math/Plane.h"
+#include "../Math/Rect.h"
+#include "../Resource/Image.h"
+
+struct SDL_Window;
+
+namespace Urho3D
+{
+
+class ConstantBuffer;
+class File;
+class Image;
+class IndexBuffer;
+class GPUObject;
+class GraphicsImpl;
+class RenderSurface;
+class Shader;
+class ShaderPrecache;
+class ShaderProgram;
+class ShaderVariation;
+class Texture;
+class Texture2D;
+class Texture2DArray;
+class TextureCube;
+class Vector3;
+class Vector4;
+class VertexBuffer;
+class VertexDeclaration;
+
+struct ShaderParameter;
+
+/// CPU-side scratch buffer for vertex data updates.
+struct ScratchBuffer
+{
+    ScratchBuffer() :
+        size_(0),
+        reserved_(false)
+    {
+    }
+
+    /// Buffer data.
+    SharedArrayPtr<unsigned char> data_;
+    /// Data size.
+    unsigned size_;
+    /// Reserved flag.
+    bool reserved_;
+};
+
+/// %Graphics subsystem. Manages the application window, rendering state and GPU resources.
+class URHO3D_API Graphics : public Object
+{
+    URHO3D_OBJECT(Graphics, Object);
+
+public:
+    /// Construct.
+    Graphics(Context* context);
+    /// Destruct. Release the Direct3D11 device and close the window.
+    virtual ~Graphics();
+
+    /// Set external window handle. Only effective before setting the initial screen mode.
+    void SetExternalWindow(void* window);
+    /// Set window title.
+    void SetWindowTitle(const String& windowTitle);
+    /// Set window icon.
+    void SetWindowIcon(Image* windowIcon);
+    /// Set window position. Sets initial position if window is not created yet.
+    void SetWindowPosition(const IntVector2& position);
+    /// Set window position. Sets initial position if window is not created yet.
+    void SetWindowPosition(int x, int y);
+    /// Set screen mode. Return true if successful.
+    bool SetMode
+        (int width, int height, bool fullscreen, bool borderless, bool resizable, bool highDPI, bool vsync, bool tripleBuffer,
+            int multiSample);
+    /// Set screen resolution only. Return true if successful.
+    bool SetMode(int width, int height);
+    /// Set whether the main window uses sRGB conversion on write.
+    void SetSRGB(bool enable);
+    /// Set whether to flush the GPU command buffer to prevent multiple frames being queued and uneven frame timesteps. Default off, may decrease performance if enabled. Not currently implemented on OpenGL.
+    void SetFlushGPU(bool enable);
+    /// Set forced use of OpenGL 2 even if OpenGL 3 is available. Must be called before setting the screen mode for the first time. Default false. No effect on Direct3D9 & 11.
+    void SetForceGL2(bool enable);
+    /// Set allowed screen orientations as a space-separated list of "LandscapeLeft", "LandscapeRight", "Portrait" and "PortraitUpsideDown". Affects currently only iOS platform.
+    void SetOrientations(const String& orientations);
+    /// Toggle between full screen and windowed mode. Return true if successful.
+    bool ToggleFullscreen();
+    /// Close the window.
+    void Close();
+    /// Take a screenshot. Return true if successful.
+    bool TakeScreenShot(Image& destImage);
+    /// Begin frame rendering. Return true if device available and can render.
+    bool BeginFrame();
+    /// End frame rendering and swap buffers.
+    void EndFrame();
+    /// Clear any or all of rendertarget, depth buffer and stencil buffer.
+    void Clear(unsigned flags, const Color& color = Color(0.0f, 0.0f, 0.0f, 0.0f), float depth = 1.0f, unsigned stencil = 0);
+    /// Resolve multisampled backbuffer to a texture rendertarget. The texture's size should match the viewport size.
+    bool ResolveToTexture(Texture2D* destination, const IntRect& viewport);
+    /// Draw non-indexed geometry.
+    void Draw(PrimitiveType type, unsigned vertexStart, unsigned vertexCount);
+    /// Draw indexed geometry.
+    void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount);
+    /// Draw indexed geometry with vertex index offset.
+    void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex, unsigned vertexCount);
+    /// Draw indexed, instanced geometry. An instancing vertex buffer must be set.
+    void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount,
+        unsigned instanceCount);
+    /// Draw indexed, instanced geometry with vertex index offset.
+    void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex,
+        unsigned vertexCount, unsigned instanceCount);
+    /// Set vertex buffer.
+    void SetVertexBuffer(VertexBuffer* buffer);
+    /// Set multiple vertex buffers.
+    bool SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, unsigned instanceOffset = 0);
+    /// Set multiple vertex buffers.
+    bool SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, unsigned instanceOffset = 0);
+    /// Set index buffer.
+    void SetIndexBuffer(IndexBuffer* buffer);
+    /// Set shaders.
+    void SetShaders(ShaderVariation* vs, ShaderVariation* ps);
+    /// Set shader float constants.
+    void SetShaderParameter(StringHash param, const float* data, unsigned count);
+    /// Set shader float constant.
+    void SetShaderParameter(StringHash param, float value);
+    /// Set shader boolean constant.
+    void SetShaderParameter(StringHash param, bool value);
+    /// Set shader color constant.
+    void SetShaderParameter(StringHash param, const Color& color);
+    /// Set shader 2D vector constant.
+    void SetShaderParameter(StringHash param, const Vector2& vector);
+    /// Set shader 3x3 matrix constant.
+    void SetShaderParameter(StringHash param, const Matrix3& matrix);
+    /// Set shader 3D vector constant.
+    void SetShaderParameter(StringHash param, const Vector3& vector);
+    /// Set shader 4x4 matrix constant.
+    void SetShaderParameter(StringHash param, const Matrix4& matrix);
+    /// Set shader 4D vector constant.
+    void SetShaderParameter(StringHash param, const Vector4& vector);
+    /// Set shader 3x4 matrix constant.
+    void SetShaderParameter(StringHash param, const Matrix3x4& matrix);
+    /// Set shader constant from a variant. Supported variant types: bool, float, vector2, vector3, vector4, color.
+    void SetShaderParameter(StringHash param, const Variant& value);
+    /// Check whether a shader parameter group needs update. Does not actually check whether parameters exist in the shaders.
+    bool NeedParameterUpdate(ShaderParameterGroup group, const void* source);
+    /// Check whether a shader parameter exists on the currently set shaders.
+    bool HasShaderParameter(StringHash param);
+    /// Check whether the current vertex or pixel shader uses a texture unit.
+    bool HasTextureUnit(TextureUnit unit);
+    /// Clear remembered shader parameter source group.
+    void ClearParameterSource(ShaderParameterGroup group);
+    /// Clear remembered shader parameter sources.
+    void ClearParameterSources();
+    /// Clear remembered transform shader parameter sources.
+    void ClearTransformSources();
+    /// Set texture.
+    void SetTexture(unsigned index, Texture* texture);
+    /// Bind texture unit 0 for update. Called by Texture. Used only on OpenGL.
+    void SetTextureForUpdate(Texture* texture);
+    /// Set default texture filtering mode.
+    void SetDefaultTextureFilterMode(TextureFilterMode mode);
+    /// Set texture anisotropy.
+    void SetTextureAnisotropy(unsigned level);
+    /// Dirty texture parameters of all textures (when global settings change.)
+    void SetTextureParametersDirty();
+    /// Reset all rendertargets, depth-stencil surface and viewport.
+    void ResetRenderTargets();
+    /// Reset specific rendertarget.
+    void ResetRenderTarget(unsigned index);
+    /// Reset depth-stencil surface.
+    void ResetDepthStencil();
+    /// Set rendertarget.
+    void SetRenderTarget(unsigned index, RenderSurface* renderTarget);
+    /// Set rendertarget.
+    void SetRenderTarget(unsigned index, Texture2D* texture);
+    /// Set depth-stencil surface.
+    void SetDepthStencil(RenderSurface* depthStencil);
+    /// Set depth-stencil surface.
+    void SetDepthStencil(Texture2D* texture);
+    /// Set viewport.
+    void SetViewport(const IntRect& rect);
+    /// Set blending mode.
+    void SetBlendMode(BlendMode mode);
+    /// Set color write on/off.
+    void SetColorWrite(bool enable);
+    /// Set hardware culling mode.
+    void SetCullMode(CullMode mode);
+    /// Set depth bias.
+    void SetDepthBias(float constantBias, float slopeScaledBias);
+    /// Set depth compare.
+    void SetDepthTest(CompareMode mode);
+    /// Set depth write on/off.
+    void SetDepthWrite(bool enable);
+    /// Set polygon fill mode.
+    void SetFillMode(FillMode mode);
+    /// Set scissor test.
+    void SetScissorTest(bool enable, const Rect& rect = Rect::FULL, bool borderInclusive = true);
+    /// Set scissor test.
+    void SetScissorTest(bool enable, const IntRect& rect);
+    /// Set stencil test.
+    void SetStencilTest
+        (bool enable, CompareMode mode = CMP_ALWAYS, StencilOp pass = OP_KEEP, StencilOp fail = OP_KEEP, StencilOp zFail = OP_KEEP,
+            unsigned stencilRef = 0, unsigned compareMask = M_MAX_UNSIGNED, unsigned writeMask = M_MAX_UNSIGNED);
+    /// Set a custom clipping plane. The plane is specified in world space, but is dependent on the view and projection matrices.
+    void SetClipPlane(bool enable, const Plane& clipPlane = Plane::UP, const Matrix3x4& view = Matrix3x4::IDENTITY,
+        const Matrix4& projection = Matrix4::IDENTITY);
+    /// Begin dumping shader variation names to an XML file for precaching.
+    void BeginDumpShaders(const String& fileName);
+    /// End dumping shader variations names.
+    void EndDumpShaders();
+    /// Precache shader variations from an XML file generated with BeginDumpShaders().
+    void PrecacheShaders(Deserializer& source);
+
+    /// Return whether rendering initialized.
+    bool IsInitialized() const;
+
+    /// Return graphics implementation, which holds the actual API-specific resources.
+    GraphicsImpl* GetImpl() const { return impl_; }
+
+    /// Return OS-specific external window handle. Null if not in use.
+    void* GetExternalWindow() const { return externalWindow_; }
+
+    /// Return SDL window.
+    SDL_Window* GetWindow() const { return window_; }
+
+    /// Return window title.
+    const String& GetWindowTitle() const { return windowTitle_; }
+
+    /// Return graphics API name.
+    const String& GetApiName() const { return apiName_; }
+
+    /// Return window position.
+    IntVector2 GetWindowPosition() const;
+
+    /// Return window width in pixels.
+    int GetWidth() const { return width_; }
+
+    /// Return window height in pixels.
+    int GetHeight() const { return height_; }
+
+    /// Return multisample mode (1 = no multisampling.)
+    int GetMultiSample() const { return multiSample_; }
+
+    /// Return whether window is fullscreen.
+    bool GetFullscreen() const { return fullscreen_; }
+
+    /// Return whether window is borderless.
+    bool GetBorderless() const { return borderless_; }
+
+    /// Return whether window is resizable.
+    bool GetResizable() const { return resizable_; }
+
+    /// Return whether window is high DPI.
+    bool GetHighDPI() const { return highDPI_; }
+
+    /// Return whether vertical sync is on.
+    bool GetVSync() const { return vsync_; }
+
+    /// Return whether triple buffering is enabled.
+    bool GetTripleBuffer() const { return tripleBuffer_; }
+
+    /// Return whether the main window is using sRGB conversion on write.
+    bool GetSRGB() const { return sRGB_; }
+
+    /// Return whether the GPU command buffer is flushed each frame.
+    bool GetFlushGPU() const { return flushGPU_; }
+
+    /// Return whether OpenGL 2 use is forced. Effective only on OpenGL.
+    bool GetForceGL2() const { return forceGL2_; }
+
+    /// Return allowed screen orientations.
+    const String& GetOrientations() const { return orientations_; }
+
+    /// Return whether graphics context is lost and can not render or load GPU resources.
+    bool IsDeviceLost() const;
+
+    /// Return number of primitives drawn this frame.
+    unsigned GetNumPrimitives() const { return numPrimitives_; }
+
+    /// Return number of batches drawn this frame.
+    unsigned GetNumBatches() const { return numBatches_; }
+
+    /// Return dummy color texture format for shadow maps. Is "NULL" (consume no video memory) if supported.
+    unsigned GetDummyColorFormat() const { return dummyColorFormat_; }
+
+    /// Return shadow map depth texture format, or 0 if not supported.
+    unsigned GetShadowMapFormat() const { return shadowMapFormat_; }
+
+    /// Return 24-bit shadow map depth texture format, or 0 if not supported.
+    unsigned GetHiresShadowMapFormat() const { return hiresShadowMapFormat_; }
+
+    /// Return whether hardware instancing is supported.
+    bool GetInstancingSupport() const { return instancingSupport_; }
+
+    /// Return whether light pre-pass rendering is supported.
+    bool GetLightPrepassSupport() const { return lightPrepassSupport_; }
+
+    /// Return whether deferred rendering is supported.
+    bool GetDeferredSupport() const { return deferredSupport_; }
+
+    /// Return whether anisotropic texture filtering is supported.
+    bool GetAnisotropySupport() const { return anisotropySupport_; }
+
+    /// Return whether shadow map depth compare is done in hardware.
+    bool GetHardwareShadowSupport() const { return hardwareShadowSupport_; }
+
+    /// Return whether a readable hardware depth format is available.
+    bool GetReadableDepthSupport() const { return GetReadableDepthFormat() != 0; }
+
+    /// Return whether sRGB conversion on texture sampling is supported.
+    bool GetSRGBSupport() const { return sRGBSupport_; }
+
+    /// Return whether sRGB conversion on rendertarget writing is supported.
+    bool GetSRGBWriteSupport() const { return sRGBWriteSupport_; }
+
+    /// Return supported fullscreen resolutions. Will be empty if listing the resolutions is not supported on the platform (e.g. Web).
+    PODVector<IntVector2> GetResolutions() const;
+    /// Return supported multisampling levels.
+    PODVector<int> GetMultiSampleLevels() const;
+    /// Return the desktop resolution.
+    IntVector2 GetDesktopResolution() const;
+    /// Return hardware format for a compressed image format, or 0 if unsupported.
+    unsigned GetFormat(CompressedFormat format) const;
+    /// Return a shader variation by name and defines.
+    ShaderVariation* GetShader(ShaderType type, const String& name, const String& defines = String::EMPTY) const;
+    /// Return a shader variation by name and defines.
+    ShaderVariation* GetShader(ShaderType type, const char* name, const char* defines) const;
+    /// Return current vertex buffer by index.
+    VertexBuffer* GetVertexBuffer(unsigned index) const;
+
+    /// Return current index buffer.
+    IndexBuffer* GetIndexBuffer() const { return indexBuffer_; }
+
+    /// Return current vertex shader.
+    ShaderVariation* GetVertexShader() const { return vertexShader_; }
+
+    /// Return current pixel shader.
+    ShaderVariation* GetPixelShader() const { return pixelShader_; }
+
+    /// 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);
+    /// Return texture unit name by index.
+    const String& GetTextureUnitName(TextureUnit unit);
+    /// Return current texture by texture unit index.
+    Texture* GetTexture(unsigned index) const;
+
+    /// Return default texture filtering mode.
+    TextureFilterMode GetDefaultTextureFilterMode() const { return defaultTextureFilterMode_; }
+
+    /// Return current rendertarget by index.
+    RenderSurface* GetRenderTarget(unsigned index) const;
+
+    /// Return current depth-stencil surface.
+    RenderSurface* GetDepthStencil() const { return depthStencil_; }
+
+    /// Return the viewport coordinates.
+    IntRect GetViewport() const { return viewport_; }
+
+    /// Return texture anisotropy.
+    unsigned GetTextureAnisotropy() const { return textureAnisotropy_; }
+
+    /// Return blending mode.
+    BlendMode GetBlendMode() const { return blendMode_; }
+
+    /// Return whether color write is enabled.
+    bool GetColorWrite() const { return colorWrite_; }
+
+    /// Return hardware culling mode.
+    CullMode GetCullMode() const { return cullMode_; }
+
+    /// Return depth constant bias.
+    float GetDepthConstantBias() const { return constantDepthBias_; }
+
+    /// Return depth slope scaled bias.
+    float GetDepthSlopeScaledBias() const { return slopeScaledDepthBias_; }
+
+    /// Return depth compare mode.
+    CompareMode GetDepthTest() const { return depthTestMode_; }
+
+    /// Return whether depth write is enabled.
+    bool GetDepthWrite() const { return depthWrite_; }
+
+    /// Return polygon fill mode.
+    FillMode GetFillMode() const { return fillMode_; }
+
+    /// Return whether stencil test is enabled.
+    bool GetStencilTest() const { return stencilTest_; }
+
+    /// Return whether scissor test is enabled.
+    bool GetScissorTest() const { return scissorTest_; }
+
+    /// Return scissor rectangle coordinates.
+    const IntRect& GetScissorRect() const { return scissorRect_; }
+
+    /// Return stencil compare mode.
+    CompareMode GetStencilTestMode() const { return stencilTestMode_; }
+
+    /// Return stencil operation to do if stencil test passes.
+    StencilOp GetStencilPass() const { return stencilPass_; }
+
+    /// Return stencil operation to do if stencil test fails.
+    StencilOp GetStencilFail() const { return stencilFail_; }
+
+    /// Return stencil operation to do if depth compare fails.
+    StencilOp GetStencilZFail() const { return stencilZFail_; }
+
+    /// Return stencil reference value.
+    unsigned GetStencilRef() const { return stencilRef_; }
+
+    /// Return stencil compare bitmask.
+    unsigned GetStencilCompareMask() const { return stencilCompareMask_; }
+
+    /// Return stencil write bitmask.
+    unsigned GetStencilWriteMask() const { return stencilWriteMask_; }
+
+    /// Return whether a custom clipping plane is in use.
+    bool GetUseClipPlane() const { return useClipPlane_; }
+
+    /// Return current rendertarget width and height.
+    IntVector2 GetRenderTargetDimensions() const;
+
+    /// Window was resized through user interaction. Called by Input subsystem.
+    void OnWindowResized();
+    /// Window was moved through user interaction. Called by Input subsystem.
+    void OnWindowMoved();
+    /// Restore GPU objects and reinitialize state. Requires an open window. Used only on OpenGL.
+    void Restore();
+    /// Maximize the window.
+    void Maximize();
+    /// Minimize the window.
+    void Minimize();
+    /// Add a GPU object to keep track of. Called by GPUObject.
+    void AddGPUObject(GPUObject* object);
+    /// Remove a GPU object. Called by GPUObject.
+    void RemoveGPUObject(GPUObject* object);
+    /// Reserve a CPU-side scratch buffer.
+    void* ReserveScratchBuffer(unsigned size);
+    /// Free a CPU-side scratch buffer.
+    void FreeScratchBuffer(void* buffer);
+    /// Clean up too large scratch buffers.
+    void CleanupScratchBuffers();
+    /// Clean up shader parameters when a shader variation is released or destroyed.
+    void CleanupShaderPrograms(ShaderVariation* variation);
+    /// Clean up a render surface from all FBOs. Used only on OpenGL.
+    void CleanupRenderSurface(RenderSurface* surface);
+    /// Get or create a constant buffer. Will be shared between shaders if possible.
+    ConstantBuffer* GetOrCreateConstantBuffer(ShaderType type, unsigned index, unsigned size);
+    /// Mark the FBO needing an update. Used only on OpenGL.
+    void MarkFBODirty();
+    /// Bind a VBO, avoiding redundant operation. Used only on OpenGL.
+    void SetVBO(unsigned object);
+    /// Bind a UBO, avoiding redundant operation. Used only on OpenGL.
+    void SetUBO(unsigned object);
+
+    /// Return the API-specific alpha texture format.
+    static unsigned GetAlphaFormat();
+    /// Return the API-specific luminance texture format.
+    static unsigned GetLuminanceFormat();
+    /// Return the API-specific luminance alpha texture format.
+    static unsigned GetLuminanceAlphaFormat();
+    /// Return the API-specific RGB texture format.
+    static unsigned GetRGBFormat();
+    /// Return the API-specific RGBA texture format.
+    static unsigned GetRGBAFormat();
+    /// Return the API-specific RGBA 16-bit texture format.
+    static unsigned GetRGBA16Format();
+    /// Return the API-specific RGBA 16-bit float texture format.
+    static unsigned GetRGBAFloat16Format();
+    /// Return the API-specific RGBA 32-bit float texture format.
+    static unsigned GetRGBAFloat32Format();
+    /// Return the API-specific RG 16-bit texture format.
+    static unsigned GetRG16Format();
+    /// Return the API-specific RG 16-bit float texture format.
+    static unsigned GetRGFloat16Format();
+    /// Return the API-specific RG 32-bit float texture format.
+    static unsigned GetRGFloat32Format();
+    /// Return the API-specific single channel 16-bit float texture format.
+    static unsigned GetFloat16Format();
+    /// Return the API-specific single channel 32-bit float texture format.
+    static unsigned GetFloat32Format();
+    /// Return the API-specific linear depth texture format.
+    static unsigned GetLinearDepthFormat();
+    /// Return the API-specific hardware depth-stencil texture format.
+    static unsigned GetDepthStencilFormat();
+    /// Return the API-specific readable hardware depth format, or 0 if not supported.
+    static unsigned GetReadableDepthFormat();
+    /// Return the API-specific texture format from a textual description, for example "rgb".
+    static unsigned GetFormat(const String& formatName);
+
+    /// Return UV offset required for pixel perfect rendering.
+    static const Vector2& GetPixelUVOffset() { return pixelUVOffset; }
+
+    /// Return maximum number of supported bones for skinning.
+    static unsigned GetMaxBones();
+    /// Return whether is using an OpenGL 3 context. Return always false on Direct3D9 & Direct3D11.
+    static bool GetGL3Support();
+
+private:
+    /// Create the application window.
+    bool OpenWindow(int width, int height, bool resizable, bool borderless);
+    /// Create the application window icon.
+    void CreateWindowIcon();
+    /// Adjust the window for new resolution and fullscreen mode.
+    void AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen, bool& newBorderless);
+    /// Create the Direct3D11 device and swap chain. Requires an open window. Can also be called again to recreate swap chain. Return true on success.
+    bool CreateDevice(int width, int height, int multiSample);
+    /// Update Direct3D11 swap chain state for a new mode and create views for the backbuffer & default depth buffer. Return true on success.
+    bool UpdateSwapChain(int width, int height);
+    /// Create the Direct3D9 interface.
+    bool CreateInterface();
+    /// Create the Direct3D9 device.
+    bool CreateDevice(unsigned adapter, unsigned deviceType);
+    /// Reset the Direct3D9 device.
+    void ResetDevice();
+    /// Notify all GPU resources so they can release themselves as needed. Used only on Direct3D9.
+    void OnDeviceLost();
+    /// Notify all GPU resources so they can recreate themselves as needed. Used only on Direct3D9.
+    void OnDeviceReset();
+    /// Set vertex buffer stream frequency. Used only on Direct3D9.
+    void SetStreamFrequency(unsigned index, unsigned frequency);
+    /// Reset stream frequencies. Used only on Direct3D9.
+    void ResetStreamFrequencies();
+    /// Check supported rendering features.
+    void CheckFeatureSupport();
+    /// Reset cached rendering state.
+    void ResetCachedState();
+    /// Initialize texture unit mappings.
+    void SetTextureUnitMappings();
+    /// Process dirtied state before draw.
+    void PrepareDraw();
+    /// Create intermediate texture for multisampled backbuffer resolve. No-op if already exists.
+    void CreateResolveTexture();
+    /// Clean up all framebuffers. Called when destroying the context. Used only on OpenGL.
+    void CleanupFramebuffers();
+    /// Create a framebuffer using either extension or core functionality. Used only on OpenGL.
+    unsigned CreateFramebuffer();
+    /// Delete a framebuffer using either extension or core functionality. Used only on OpenGL.
+    void DeleteFramebuffer(unsigned fbo);
+    /// Bind a framebuffer using either extension or core functionality. Used only on OpenGL.
+    void BindFramebuffer(unsigned fbo);
+    /// Bind a framebuffer color attachment using either extension or core functionality. Used only on OpenGL.
+    void BindColorAttachment(unsigned index, unsigned target, unsigned object);
+    /// Bind a framebuffer depth attachment using either extension or core functionality. Used only on OpenGL.
+    void BindDepthAttachment(unsigned object, bool isRenderBuffer);
+    /// Bind a framebuffer stencil attachment using either extension or core functionality. Used only on OpenGL.
+    void BindStencilAttachment(unsigned object, bool isRenderBuffer);
+    /// Check FBO completeness using either extension or core functionality. Used only on OpenGL.
+    bool CheckFramebuffer();
+    /// Set vertex attrib divisor. No-op if unsupported. Used only on OpenGL.
+    void SetVertexAttribDivisor(unsigned location, unsigned divisor);
+    /// Release/clear GPU objects and optionally close the window. Used only on OpenGL.
+    void Release(bool clearGPUObjects, bool closeWindow);
+
+    /// Mutex for accessing the GPU objects vector from several threads.
+    Mutex gpuObjectMutex_;
+    /// Implementation.
+    GraphicsImpl* impl_;
+    /// SDL window.
+    SDL_Window* window_;
+    /// Window title.
+    String windowTitle_;
+    /// Window icon image.
+    WeakPtr<Image> windowIcon_;
+    /// External window, null if not in use (default.)
+    void* externalWindow_;
+    /// Window width in pixels.
+    int width_;
+    /// Window height in pixels.
+    int height_;
+    /// Window position.
+    IntVector2 position_;
+    /// Multisampling mode.
+    int multiSample_;
+    /// Fullscreen flag.
+    bool fullscreen_;
+    /// Borderless flag.
+    bool borderless_;
+    /// Resizable flag.
+    bool resizable_;
+    /// High DPI flag.
+    bool highDPI_;
+    /// Vertical sync flag.
+    bool vsync_;
+    /// Triple buffering flag.
+    bool tripleBuffer_;
+    /// Flush GPU command buffer flag.
+    bool flushGPU_;
+    /// Force OpenGL 2 flag. Only used on OpenGL.
+    bool forceGL2_;
+    /// sRGB conversion on write flag for the main window.
+    bool sRGB_;
+    /// Light pre-pass rendering support flag.
+    bool lightPrepassSupport_;
+    /// Deferred rendering support flag.
+    bool deferredSupport_;
+    /// Anisotropic filtering support flag.
+    bool anisotropySupport_;
+    /// DXT format support flag.
+    bool dxtTextureSupport_;
+    /// ETC1 format support flag.
+    bool etcTextureSupport_;
+    /// PVRTC formats support flag.
+    bool pvrtcTextureSupport_;
+    /// Hardware shadow map depth compare support flag.
+    bool hardwareShadowSupport_;
+    /// Instancing support flag.
+    bool instancingSupport_;
+    /// sRGB conversion on read support flag.
+    bool sRGBSupport_;
+    /// sRGB conversion on write support flag.
+    bool sRGBWriteSupport_;
+    /// Number of primitives this frame.
+    unsigned numPrimitives_;
+    /// Number of batches this frame.
+    unsigned numBatches_;
+    /// Largest scratch buffer request this frame.
+    unsigned maxScratchBufferRequest_;
+    /// GPU objects.
+    PODVector<GPUObject*> gpuObjects_;
+    /// Scratch buffers.
+    Vector<ScratchBuffer> scratchBuffers_;
+    /// Shadow map dummy color texture format.
+    unsigned dummyColorFormat_;
+    /// Shadow map depth texture format.
+    unsigned shadowMapFormat_;
+    /// Shadow map 24-bit depth texture format.
+    unsigned hiresShadowMapFormat_;
+    /// Vertex buffers in use.
+    VertexBuffer* vertexBuffers_[MAX_VERTEX_STREAMS];
+    /// Index buffer in use.
+    IndexBuffer* indexBuffer_;
+    /// Current vertex declaration hash.
+    unsigned long long vertexDeclarationHash_;
+    /// Current primitive type.
+    unsigned primitiveType_;
+    /// Vertex shader in use.
+    ShaderVariation* vertexShader_;
+    /// Pixel shader in use.
+    ShaderVariation* pixelShader_;
+    /// Textures in use.
+    Texture* textures_[MAX_TEXTURE_UNITS];
+    /// Texture unit mappings.
+    HashMap<String, TextureUnit> textureUnits_;
+    /// 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.
+    BlendMode blendMode_;
+    /// Color write enable.
+    bool colorWrite_;
+    /// Hardware culling mode.
+    CullMode cullMode_;
+    /// Depth constant bias.
+    float constantDepthBias_;
+    /// Depth slope scaled bias.
+    float slopeScaledDepthBias_;
+    /// Depth compare mode.
+    CompareMode depthTestMode_;
+    /// Depth write enable flag.
+    bool depthWrite_;
+    /// Polygon fill mode.
+    FillMode fillMode_;
+    /// Scissor test rectangle.
+    IntRect scissorRect_;
+    /// Scissor test enable flag.
+    bool scissorTest_;
+    /// Stencil test compare mode.
+    CompareMode stencilTestMode_;
+    /// Stencil operation on pass.
+    StencilOp stencilPass_;
+    /// Stencil operation on fail.
+    StencilOp stencilFail_;
+    /// Stencil operation on depth fail.
+    StencilOp stencilZFail_;
+    /// Stencil test reference value.
+    unsigned stencilRef_;
+    /// Stencil compare bitmask.
+    unsigned stencilCompareMask_;
+    /// Stencil write bitmask.
+    unsigned stencilWriteMask_;
+    /// Current custom clip plane in post-projection space.
+    Vector4 clipPlane_;
+    /// Stencil test enable flag.
+    bool stencilTest_;
+    /// Custom clip plane enable flag.
+    bool useClipPlane_;
+    /// Remembered shader parameter sources.
+    const void* shaderParameterSources_[MAX_SHADER_PARAMETER_GROUPS];
+    /// Base directory for shaders.
+    String shaderPath_;
+    /// File extension for shaders.
+    String shaderExtension_;
+    /// Last used shader in shader variation query.
+    mutable WeakPtr<Shader> lastShader_;
+    /// Last used shader name in shader variation query.
+    mutable String lastShaderName_;
+    /// Shader precache utility.
+    SharedPtr<ShaderPrecache> shaderPrecache_;
+    /// Allowed screen orientations.
+    String orientations_;
+    /// Graphics API name.
+    String apiName_;
+
+    /// Pixel perfect UV offset.
+    static const Vector2 pixelUVOffset;
+    /// OpenGL3 support flag.
+    static bool gl3Support;
+};
+
+/// Register Graphics library objects.
+void URHO3D_API RegisterGraphicsLibrary(Context* context);
+
+}

+ 3 - 0
Source/Urho3D/Graphics/GraphicsImpl.h

@@ -22,6 +22,9 @@
 
 #pragma once
 
+// Note: GraphicsImpl class is purposefully API-specific. It should not be used by Urho3D client applications,
+// unless required for e.g. integration of 3rd party libraries that interface directly with the graphics device.
+
 #if defined(URHO3D_OPENGL)
 #include "OpenGL/OGLGraphicsImpl.h"
 #elif defined(URHO3D_D3D11)

+ 137 - 0
Source/Urho3D/Graphics/IndexBuffer.cpp

@@ -0,0 +1,137 @@
+//
+// Copyright (c) 2008-2016 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+// This file contains IndexBuffer code common to all graphics APIs.
+
+#include "../Precompiled.h"
+
+#include "../Graphics/Graphics.h"
+#include "../Graphics/IndexBuffer.h"
+#include "../IO/Log.h"
+
+#include "../DebugNew.h"
+
+namespace Urho3D
+{
+
+IndexBuffer::IndexBuffer(Context* context, bool forceHeadless) :
+    Object(context),
+    GPUObject(forceHeadless ? (Graphics*)0 : GetSubsystem<Graphics>()),
+    indexCount_(0),
+    indexSize_(0),
+    lockState_(LOCK_NONE),
+    lockStart_(0),
+    lockCount_(0),
+    lockScratchData_(0),
+    shadowed_(false),
+    dynamic_(false)
+{
+    // Force shadowing mode if graphics subsystem does not exist
+    if (!graphics_)
+        shadowed_ = true;
+}
+
+IndexBuffer::~IndexBuffer()
+{
+    Release();
+}
+
+void IndexBuffer::SetShadowed(bool enable)
+{
+    // If no graphics subsystem, can not disable shadowing
+    if (!graphics_)
+        enable = true;
+
+    if (enable != shadowed_)
+    {
+        if (enable && indexCount_ && indexSize_)
+            shadowData_ = new unsigned char[indexCount_ * indexSize_];
+        else
+            shadowData_.Reset();
+
+        shadowed_ = enable;
+    }
+}
+
+bool IndexBuffer::SetSize(unsigned indexCount, bool largeIndices, bool dynamic)
+{
+    Unlock();
+
+    indexCount_ = indexCount;
+    indexSize_ = (unsigned)(largeIndices ? sizeof(unsigned) : sizeof(unsigned short));
+    dynamic_ = dynamic;
+
+    if (shadowed_ && indexCount_ && indexSize_)
+        shadowData_ = new unsigned char[indexCount_ * indexSize_];
+    else
+        shadowData_.Reset();
+
+    return Create();
+}
+
+bool IndexBuffer::GetUsedVertexRange(unsigned start, unsigned count, unsigned& minVertex, unsigned& vertexCount)
+{
+    if (!shadowData_)
+    {
+        URHO3D_LOGERROR("Used vertex range can only be queried from an index buffer with shadow data");
+        return false;
+    }
+
+    if (start + count > indexCount_)
+    {
+        URHO3D_LOGERROR("Illegal index range for querying used vertices");
+        return false;
+    }
+
+    minVertex = M_MAX_UNSIGNED;
+    unsigned maxVertex = 0;
+
+    if (indexSize_ == sizeof(unsigned))
+    {
+        unsigned* indices = ((unsigned*)shadowData_.Get()) + start;
+
+        for (unsigned i = 0; i < count; ++i)
+        {
+            if (indices[i] < minVertex)
+                minVertex = indices[i];
+            if (indices[i] > maxVertex)
+                maxVertex = indices[i];
+        }
+    }
+    else
+    {
+        unsigned short* indices = ((unsigned short*)shadowData_.Get()) + start;
+
+        for (unsigned i = 0; i < count; ++i)
+        {
+            if (indices[i] < minVertex)
+                minVertex = indices[i];
+            if (indices[i] > maxVertex)
+                maxVertex = indices[i];
+        }
+    }
+
+    vertexCount = maxVertex - minVertex + 1;
+    return true;
+}
+
+}

+ 94 - 7
Source/Urho3D/Graphics/IndexBuffer.h

@@ -22,10 +22,97 @@
 
 #pragma once
 
-#if defined(URHO3D_OPENGL)
-#include "OpenGL/OGLIndexBuffer.h"
-#elif defined(URHO3D_D3D11)
-#include "Direct3D11/D3D11IndexBuffer.h"
-#else
-#include "Direct3D9/D3D9IndexBuffer.h"
-#endif
+#include "../Core/Object.h"
+#include "../Container/ArrayPtr.h"
+#include "../Graphics/GPUObject.h"
+#include "../Graphics/GraphicsDefs.h"
+
+namespace Urho3D
+{
+
+/// Hardware index buffer.
+class URHO3D_API IndexBuffer : public Object, public GPUObject
+{
+    URHO3D_OBJECT(IndexBuffer, Object);
+
+public:
+    /// Construct. Optionally force headless (no GPU-side buffer) operation.
+    IndexBuffer(Context* context, bool forceHeadless = false);
+    /// Destruct.
+    virtual ~IndexBuffer();
+
+    /// Mark the buffer destroyed on graphics context destruction. May be a no-op depending on the API.
+    virtual void OnDeviceLost();
+    /// Recreate the buffer and restore data if applicable. May be a no-op depending on the API.
+    virtual void OnDeviceReset();
+    /// Release buffer.
+    virtual void Release();
+
+    /// Enable shadowing in CPU memory. Shadowing is forced on if the graphics subsystem does not exist.
+    void SetShadowed(bool enable);
+    /// Set size and vertex elements and dynamic mode. Previous data will be lost.
+    bool SetSize(unsigned indexCount, bool largeIndices, bool dynamic = false);
+    /// Set all data in the buffer.
+    bool SetData(const void* data);
+    /// Set a data range in the buffer. Optionally discard data outside the range.
+    bool SetDataRange(const void* data, unsigned start, unsigned count, bool discard = false);
+    /// Lock the buffer for write-only editing. Return data pointer if successful. Optionally discard data outside the range.
+    void* Lock(unsigned start, unsigned count, bool discard = false);
+    /// Unlock the buffer and apply changes to the GPU buffer.
+    void Unlock();
+
+    /// Return whether CPU memory shadowing is enabled.
+    bool IsShadowed() const { return shadowed_; }
+
+    /// Return whether is dynamic.
+    bool IsDynamic() const { return dynamic_; }
+
+    /// Return whether is currently locked.
+    bool IsLocked() const { return lockState_ != LOCK_NONE; }
+
+    /// Return number of indices.
+    unsigned GetIndexCount() const { return indexCount_; }
+
+    /// Return index size in bytes.
+    unsigned GetIndexSize() const { return indexSize_; }
+
+    /// Return used vertex range from index range.
+    bool GetUsedVertexRange(unsigned start, unsigned count, unsigned& minVertex, unsigned& vertexCount);
+
+    /// Return CPU memory shadow data.
+    unsigned char* GetShadowData() const { return shadowData_.Get(); }
+
+    /// Return shared array pointer to the CPU memory shadow data.
+    SharedArrayPtr<unsigned char> GetShadowDataShared() const { return shadowData_; }
+
+private:
+    /// Create buffer.
+    bool Create();
+    /// Update the shadow data to the GPU buffer.
+    bool UpdateToGPU();
+    /// Map the GPU buffer into CPU memory. Not used on OpenGL.
+    void* MapBuffer(unsigned start, unsigned count, bool discard);
+    /// Unmap the GPU buffer. Not used on OpenGL.
+    void UnmapBuffer();
+
+    /// Shadow data.
+    SharedArrayPtr<unsigned char> shadowData_;
+    /// Number of indices.
+    unsigned indexCount_;
+    /// Index size.
+    unsigned indexSize_;
+    /// Buffer locking state.
+    LockState lockState_;
+    /// Lock start vertex.
+    unsigned lockStart_;
+    /// Lock number of vertices.
+    unsigned lockCount_;
+    /// Scratch buffer for fallback locking.
+    void* lockScratchData_;
+    /// Dynamic flag.
+    bool dynamic_;
+    /// Shadowed flag.
+    bool shadowed_;
+};
+
+}

+ 8 - 48
Source/Urho3D/Graphics/OpenGL/OGLConstantBuffer.cpp

@@ -32,30 +32,18 @@
 namespace Urho3D
 {
 
-
-ConstantBuffer::ConstantBuffer(Context* context) :
-    Object(context),
-    GPUObject(GetSubsystem<Graphics>())
-{
-}
-
-ConstantBuffer::~ConstantBuffer()
-{
-    Release();
-}
-
 void ConstantBuffer::Release()
 {
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_)
             return;
 
 #ifndef GL_ES_VERSION_2_0
         graphics_->SetUBO(0);
-        glDeleteBuffers(1, &object_);
+        glDeleteBuffers(1, &object_.name_);
 #endif
-        object_ = 0;
+        object_.name_ = 0;
     }
 
     shadowData_.Reset();
@@ -88,9 +76,9 @@ bool ConstantBuffer::SetSize(unsigned size)
     if (graphics_)
     {
 #ifndef GL_ES_VERSION_2_0
-        if (!object_)
-            glGenBuffers(1, &object_);
-        graphics_->SetUBO(object_);
+        if (!object_.name_)
+            glGenBuffers(1, &object_.name_);
+        graphics_->SetUBO(object_.name_);
         glBufferData(GL_UNIFORM_BUFFER, size_, shadowData_.Get(), GL_DYNAMIC_DRAW);
 #endif
     }
@@ -98,40 +86,12 @@ bool ConstantBuffer::SetSize(unsigned size)
     return true;
 }
 
-void ConstantBuffer::SetParameter(unsigned offset, unsigned size, const void* data)
-{
-    if (offset + size > size_)
-        return; // Would overflow the buffer
-
-    memcpy(&shadowData_[offset], data, size);
-    dirty_ = true;
-}
-
-void ConstantBuffer::SetVector3ArrayParameter(unsigned offset, unsigned rows, const void* data)
-{
-    if (offset + rows * 4 * sizeof(float) > size_)
-        return; // Would overflow the buffer
-
-    float* dest = (float*)&shadowData_[offset];
-    const float* src = (const float*)data;
-
-    while (rows--)
-    {
-        *dest++ = *src++;
-        *dest++ = *src++;
-        *dest++ = *src++;
-        ++dest; // Skip over the w coordinate
-    }
-
-    dirty_ = true;
-}
-
 void ConstantBuffer::Apply()
 {
-    if (dirty_ && object_)
+    if (dirty_ && object_.name_)
     {
 #ifndef GL_ES_VERSION_2_0
-        graphics_->SetUBO(object_);
+        graphics_->SetUBO(object_.name_);
         glBufferData(GL_UNIFORM_BUFFER, size_, shadowData_.Get(), GL_DYNAMIC_DRAW);
 #endif
         dirty_ = false;

+ 0 - 73
Source/Urho3D/Graphics/OpenGL/OGLConstantBuffer.h

@@ -1,73 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/ArrayPtr.h"
-#include "../../Core/Object.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-
-namespace Urho3D
-{
-
-/// Hardware constant buffer.
-class URHO3D_API ConstantBuffer : public Object, public GPUObject
-{
-    URHO3D_OBJECT(ConstantBuffer, Object);
-
-public:
-    /// Construct.
-    ConstantBuffer(Context* context);
-    /// Destruct.
-    virtual ~ConstantBuffer();
-
-    /// Recreate the GPU resource and restore data if applicable.
-    virtual void OnDeviceReset();
-    /// Release the buffer.
-    virtual void Release();
-
-    /// Set size and create GPU-side buffer. Return true on success.
-    bool SetSize(unsigned size);
-    /// Set a generic parameter and mark buffer dirty.
-    void SetParameter(unsigned offset, unsigned size, const void* data);
-    /// Set a Vector3 array parameter and mark buffer dirty.
-    void SetVector3ArrayParameter(unsigned offset, unsigned rows, const void* data);
-    /// Apply to GPU.
-    void Apply();
-
-    /// Return size.
-    unsigned GetSize() const { return size_; }
-
-    /// Return whether has unapplied data.
-    bool IsDirty() const { return dirty_; }
-
-private:
-    /// Shadow data.
-    SharedArrayPtr<unsigned char> shadowData_;
-    /// Buffer byte size.
-    unsigned size_;
-    /// Dirty flag.
-    bool dirty_;
-};
-
-}

+ 0 - 76
Source/Urho3D/Graphics/OpenGL/OGLGPUObject.h

@@ -1,76 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-
-namespace Urho3D
-{
-
-class Graphics;
-
-/// Base class for GPU resources.
-class URHO3D_API GPUObject
-{
-public:
-    /// Construct with graphics subsystem pointer.
-    GPUObject(Graphics* graphics);
-    /// Destruct. Remove from the Graphics.
-    virtual ~GPUObject();
-
-    /// Mark the GPU resource destroyed on context destruction.
-    virtual void OnDeviceLost();
-
-    /// Recreate the GPU resource and restore data if applicable.
-    virtual void OnDeviceReset() { }
-
-    /// Unconditionally release the GPU resource.
-    virtual void Release() { }
-
-    /// Clear the data lost flag.
-    void ClearDataLost();
-
-    /// Return the graphics subsystem.
-    Graphics* GetGraphics() const;
-
-    /// Return the object's OpenGL handle.
-    unsigned GetGPUObject() const { return object_; }
-
-    /// Return whether data is lost due to context loss.
-    bool IsDataLost() const { return dataLost_; }
-
-    /// Return whether has pending data assigned while context was lost.
-    bool HasPendingData() const { return dataPending_; }
-
-protected:
-    /// Graphics subsystem.
-    WeakPtr<Graphics> graphics_;
-    /// Object handle.
-    unsigned object_;
-    /// Data lost flag.
-    bool dataLost_;
-    /// Data pending flag.
-    bool dataPending_;
-};
-
-}

File diff suppressed because it is too large
+ 153 - 325
Source/Urho3D/Graphics/OpenGL/OGLGraphics.cpp


+ 0 - 732
Source/Urho3D/Graphics/OpenGL/OGLGraphics.h

@@ -1,732 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/ArrayPtr.h"
-#include "../../Core/Mutex.h"
-#include "../../Core/Object.h"
-#include "../../Graphics/GraphicsDefs.h"
-#include "../../Math/Color.h"
-#include "../../Math/Plane.h"
-#include "../../Math/Rect.h"
-#include "../../Resource/Image.h"
-
-namespace Urho3D
-{
-
-class ConstantBuffer;
-class File;
-class Image;
-class IndexBuffer;
-class GPUObject;
-class GraphicsImpl;
-class RenderSurface;
-class Shader;
-class ShaderPrecache;
-class ShaderProgram;
-class ShaderVariation;
-class Texture;
-class Texture2D;
-class Texture2DArray;
-class TextureCube;
-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.
-struct ScratchBuffer
-{
-    ScratchBuffer() :
-        size_(0),
-        reserved_(false)
-    {
-    }
-
-    /// Buffer data.
-    SharedArrayPtr<unsigned char> data_;
-    /// Data size.
-    unsigned size_;
-    /// Reserved flag.
-    bool reserved_;
-};
-
-/// %Graphics subsystem. Manages the application window, rendering state and GPU resources.
-class URHO3D_API Graphics : public Object
-{
-    URHO3D_OBJECT(Graphics, Object);
-
-public:
-    /// Construct.
-    Graphics(Context* context_);
-    /// Destruct. Release the OpenGL context and close the window.
-    virtual ~Graphics();
-
-    /// Set external window handle. Only effective before setting the initial screen mode. On Windows it is necessary to set up OpenGL pixel format manually for the window.
-    void SetExternalWindow(void* window);
-    /// Set window icon.
-    void SetWindowIcon(Image* windowIcon);
-    /// Set window title.
-    void SetWindowTitle(const String& windowTitle);
-    /// Set window position.
-    void SetWindowPosition(const IntVector2& position);
-    /// Set window position.
-    void SetWindowPosition(int x, int y);
-    /// Set screen mode. Return true if successful.
-    bool SetMode
-        (int width, int height, bool fullscreen, bool borderless, bool resizable, bool highDPI, bool vsync, bool tripleBuffer,
-            int multiSample);
-    /// Set screen resolution only. Return true if successful.
-    bool SetMode(int width, int height);
-    /// Set whether the main window uses sRGB conversion on write.
-    void SetSRGB(bool enable);
-    /// Set whether to flush the GPU command buffer to prevent multiple frames being queued and uneven frame timesteps. Not yet implemented on OpenGL.
-    void SetFlushGPU(bool enable);
-    /// Set forced use of OpenGL 2 even if OpenGL 3 is available. Must be called before setting the screen mode for the first time. Default false.
-    void SetForceGL2(bool enable);
-    /// Set allowed screen orientations as a space-separated list of "LandscapeLeft", "LandscapeRight", "Portrait" and "PortraitUpsideDown". Affects currently only iOS platform.
-    void SetOrientations(const String& orientations);
-    /// Toggle between full screen and windowed mode. Return true if successful.
-    bool ToggleFullscreen();
-    /// Close the window.
-    void Close();
-    /// Take a screenshot. Return true if successful.
-    bool TakeScreenShot(Image& destImage);
-    /// Begin frame rendering. Return true if device available and can render.
-    bool BeginFrame();
-    /// End frame rendering and swap buffers.
-    void EndFrame();
-    /// Clear any or all of rendertarget, depth buffer and stencil buffer.
-    void Clear(unsigned flags, const Color& color = Color(0.0f, 0.0f, 0.0f, 0.0f), float depth = 1.0f, unsigned stencil = 0);
-    /// Resolve multisampled backbuffer to a texture rendertarget. The texture's size should match the viewport size.
-    bool ResolveToTexture(Texture2D* destination, const IntRect& viewport);
-    /// Draw non-indexed geometry.
-    void Draw(PrimitiveType type, unsigned vertexStart, unsigned vertexCount);
-    /// Draw indexed geometry.
-    void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount);
-    /// Draw indexed geometry with vertex index offset. Only supported on desktop OpenGL 3.2 or greater.
-    void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex, unsigned vertexCount);
-    /// Draw indexed, instanced geometry.
-    void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount,
-        unsigned instanceCount);
-    /// Draw indexed, instanced geometry with vertex index offset. Only supported on desktop OpenGL 3.2 or greater.
-    void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex,
-        unsigned vertexCount, unsigned instanceCount);
-    /// Set vertex buffer.
-    void SetVertexBuffer(VertexBuffer* buffer);
-    /// Set multiple vertex buffers.
-    bool SetVertexBuffers
-        (const PODVector<VertexBuffer*>& buffers, unsigned instanceOffset = 0);
-    /// Set multiple vertex buffers.
-    bool SetVertexBuffers
-        (const Vector<SharedPtr<VertexBuffer> >& buffers, unsigned instanceOffset = 0);
-    /// Set index buffer.
-    void SetIndexBuffer(IndexBuffer* buffer);
-    /// Set shaders.
-    void SetShaders(ShaderVariation* vs, ShaderVariation* ps);
-    /// Set shader float constants.
-    void SetShaderParameter(StringHash param, const float* data, unsigned count);
-    /// Set shader float constant.
-    void SetShaderParameter(StringHash param, float value);
-    /// Set shader color constant.
-    void SetShaderParameter(StringHash param, const Color& color);
-    /// Set shader 2D vector constant.
-    void SetShaderParameter(StringHash param, const Vector2& vector);
-    /// Set shader 3x3 matrix constant.
-    void SetShaderParameter(StringHash param, const Matrix3& matrix);
-    /// Set shader 3D vector constant.
-    void SetShaderParameter(StringHash param, const Vector3& vector);
-    /// Set shader 4x4 matrix constant.
-    void SetShaderParameter(StringHash param, const Matrix4& matrix);
-    /// Set shader 4D vector constant.
-    void SetShaderParameter(StringHash param, const Vector4& vector);
-    /// Set shader 4x3 matrix constant.
-    void SetShaderParameter(StringHash param, const Matrix3x4& matrix);
-    /// Set shader constant from a variant. Supported variant types: bool, float, vector2, vector3, vector4, color.
-    void SetShaderParameter(StringHash param, const Variant& value);
-    /// Check whether a shader parameter group needs update. Does not actually check whether parameters exist in the shaders.
-    bool NeedParameterUpdate(ShaderParameterGroup group, const void* source);
-    /// Check whether a shader parameter exists on the currently set shaders.
-    bool HasShaderParameter(StringHash param);
-    /// Check whether the current shader program uses a texture unit.
-    bool HasTextureUnit(TextureUnit unit);
-    /// Clear remembered shader parameter source group.
-    void ClearParameterSource(ShaderParameterGroup group);
-    /// Clear remembered shader parameter sources.
-    void ClearParameterSources();
-    /// Clear remembered transform shader parameter sources.
-    void ClearTransformSources();
-    /// Set texture.
-    void SetTexture(unsigned index, Texture* texture);
-    /// Bind texture unit 0 for update. Called by Texture.
-    void SetTextureForUpdate(Texture* texture);
-    /// Set default texture filtering mode.
-    void SetDefaultTextureFilterMode(TextureFilterMode mode);
-    /// Set texture anisotropy.
-    void SetTextureAnisotropy(unsigned level);
-    /// Dirty texture parameters of all textures (when global settings change.)
-    void SetTextureParametersDirty();
-    /// Reset all rendertargets, depth-stencil surface and viewport.
-    void ResetRenderTargets();
-    /// Reset specific rendertarget.
-    void ResetRenderTarget(unsigned index);
-    /// Reset depth-stencil surface.
-    void ResetDepthStencil();
-    /// Set rendertarget.
-    void SetRenderTarget(unsigned index, RenderSurface* renderTarget);
-    /// Set rendertarget.
-    void SetRenderTarget(unsigned index, Texture2D* texture);
-    /// Set depth-stencil surface.
-    void SetDepthStencil(RenderSurface* depthStencil);
-    /// Set depth-stencil surface.
-    void SetDepthStencil(Texture2D* texture);
-    /// Set viewport.
-    void SetViewport(const IntRect& rect);
-    /// Set blending mode.
-    void SetBlendMode(BlendMode mode);
-    /// Set color write on/off.
-    void SetColorWrite(bool enable);
-    /// Set hardware culling mode.
-    void SetCullMode(CullMode mode);
-    /// Set depth bias.
-    void SetDepthBias(float constantBias, float slopeScaledBias);
-    /// Set depth compare.
-    void SetDepthTest(CompareMode mode);
-    /// Set depth write on/off.
-    void SetDepthWrite(bool enable);
-    /// Set polygon fill mode.
-    void SetFillMode(FillMode mode);
-    /// Set scissor test.
-    void SetScissorTest(bool enable, const Rect& rect = Rect::FULL, bool borderInclusive = true);
-    /// Set scissor test.
-    void SetScissorTest(bool enable, const IntRect& rect);
-    /// Set stencil test.
-    void SetStencilTest
-        (bool enable, CompareMode mode = CMP_ALWAYS, StencilOp pass = OP_KEEP, StencilOp fail = OP_KEEP, StencilOp zFail = OP_KEEP,
-            unsigned stencilRef = 0, unsigned compareMask = M_MAX_UNSIGNED, unsigned writeMask = M_MAX_UNSIGNED);
-    /// Set a custom clipping plane. The plane is specified in world space, but is dependent on the view and projection matrices.
-    void SetClipPlane(bool enable, const Plane& clipPlane = Plane::UP, const Matrix3x4& view = Matrix3x4::IDENTITY,
-        const Matrix4& projection = Matrix4::IDENTITY);
-    /// Begin dumping shader variation names to an XML file for precaching.
-    void BeginDumpShaders(const String& fileName);
-    /// End dumping shader variations names.
-    void EndDumpShaders();
-    /// Precache shader variations from an XML file generated with BeginDumpShaders().
-    void PrecacheShaders(Deserializer& source);
-
-    /// Return whether rendering initialized.
-    bool IsInitialized() const;
-
-    /// Return graphics implementation, which holds the actual API-specific resources.
-    GraphicsImpl* GetImpl() const { return impl_; }
-
-    /// Return OS-specific external window handle. Null if not in use.
-    void* GetExternalWindow() const { return externalWindow_; }
-
-    /// Return window title.
-    const String& GetWindowTitle() const { return windowTitle_; }
-
-    /// Return graphics API name.
-    const String& GetApiName() const { return apiName_; }
-
-    /// Return window position.
-    IntVector2 GetWindowPosition() const;
-
-    /// Return window width in pixels.
-    int GetWidth() const { return width_; }
-
-    /// Return window height in pixels.
-    int GetHeight() const { return height_; }
-
-    /// Return multisample mode (1 = no multisampling.)
-    int GetMultiSample() const { return multiSample_; }
-
-    /// Return whether window is fullscreen.
-    bool GetFullscreen() const { return fullscreen_; }
-
-    /// Return whether window is borderless.
-    bool GetBorderless() const { return borderless_; }
-
-    /// Return whether window is resizable.
-    bool GetResizable() const { return resizable_; }
-
-    /// Return whether window is high DPI.
-    bool GetHighDPI() const { return highDPI_; }
-
-    /// Return whether vertical sync is on.
-    bool GetVSync() const { return vsync_; }
-
-    /// Return whether triple buffering is enabled.
-    bool GetTripleBuffer() const { return tripleBuffer_; }
-
-    /// Return whether the main window is using sRGB conversion on write.
-    bool GetSRGB() const { return sRGB_; }
-
-    /// Return whether the GPU command buffer is flushed each frame. Not yet implemented on OpenGL.
-    bool GetFlushGPU() const { return false; }
-
-    /// Return whether OpenGL 2 use is forced.
-    bool GetForceGL2() const { return forceGL2_; }
-
-    /// Return allowed screen orientations.
-    const String& GetOrientations() const { return orientations_; }
-
-    /// Return whether device is lost, and can not yet render.
-    bool IsDeviceLost() const;
-
-    /// Return number of primitives drawn this frame.
-    unsigned GetNumPrimitives() const { return numPrimitives_; }
-
-    /// Return number of batches drawn this frame.
-    unsigned GetNumBatches() const { return numBatches_; }
-
-    /// Return dummy color texture format for shadow maps. 0 if not needed, may be nonzero on OS X to work around an Intel driver issue.
-    unsigned GetDummyColorFormat() const { return dummyColorFormat_; }
-
-    /// Return shadow map depth texture format, or 0 if not supported.
-    unsigned GetShadowMapFormat() const { return shadowMapFormat_; }
-
-    /// Return 24-bit shadow map depth texture format, or 0 if not supported.
-    unsigned GetHiresShadowMapFormat() const { return hiresShadowMapFormat_; }
-
-    /// Return whether hardware instancing is supported.
-    bool GetInstancingSupport() const { return instancingSupport_; }
-
-    /// Return whether light pre-pass rendering is supported.
-    bool GetLightPrepassSupport() const { return lightPrepassSupport_; }
-
-    /// Return whether deferred rendering is supported.
-    bool GetDeferredSupport() const { return deferredSupport_; }
-
-    /// Return whether anisotropic texture filtering is supported.
-    bool GetAnisotropySupport() const { return anisotropySupport_; }
-
-    /// Return whether shadow map depth compare is done in hardware. Always true on OpenGL.
-    bool GetHardwareShadowSupport() const { return true; }
-
-    /// Return whether a readable hardware depth format is available.
-    bool GetReadableDepthSupport() const { return GetReadableDepthFormat() != 0; }
-
-    /// Return whether sRGB conversion on texture sampling is supported.
-    bool GetSRGBSupport() const { return sRGBSupport_; }
-
-    /// Return whether sRGB conversion on rendertarget writing is supported.
-    bool GetSRGBWriteSupport() const { return sRGBWriteSupport_; }
-
-    /// Return supported fullscreen resolutions. Will be empty if listing the resolutions is not supported on the platform (e.g. Web).
-    PODVector<IntVector2> GetResolutions() const;
-    /// Return supported multisampling levels.
-    PODVector<int> GetMultiSampleLevels() const;
-    /// Return the desktop resolution.
-    IntVector2 GetDesktopResolution() const;
-    /// Return hardware format for a compressed image format, or 0 if unsupported.
-    unsigned GetFormat(CompressedFormat format) const;
-    /// Return a shader variation by name and defines.
-    ShaderVariation* GetShader(ShaderType type, const String& name, const String& defines = String::EMPTY) const;
-    /// Return a shader variation by name and defines.
-    ShaderVariation* GetShader(ShaderType type, const char* name, const char* defines) const;
-    /// Return current vertex buffer by index.
-    VertexBuffer* GetVertexBuffer(unsigned index) const;
-
-    /// Return index buffer.
-    IndexBuffer* GetIndexBuffer() const { return indexBuffer_; }
-
-    /// Return vertex shader.
-    ShaderVariation* GetVertexShader() const { return vertexShader_; }
-
-    /// Return pixel shader.
-    ShaderVariation* GetPixelShader() const { return pixelShader_; }
-
-    /// Return shader program.
-    ShaderProgram* GetShaderProgram() const { return shaderProgram_; }
-
-    /// Return texture unit index by name.
-    TextureUnit GetTextureUnit(const String& name);
-    /// Return texture unit name by index.
-    const String& GetTextureUnitName(TextureUnit unit);
-    /// Return texture by texture unit index.
-    Texture* GetTexture(unsigned index) const;
-
-    /// Return default texture filtering mode.
-    TextureFilterMode GetDefaultTextureFilterMode() const { return defaultTextureFilterMode_; }
-
-    /// Return rendertarget by index.
-    RenderSurface* GetRenderTarget(unsigned index) const;
-
-    /// Return depth-stencil surface.
-    RenderSurface* GetDepthStencil() const { return depthStencil_; }
-
-    /// Return readable depth-stencil texture. Not created automatically on OpenGL.
-    Texture2D* GetDepthTexture() const { return 0; }
-
-    /// Return the viewport coordinates.
-    IntRect GetViewport() const { return viewport_; }
-
-    /// Return texture anisotropy.
-    unsigned GetTextureAnisotropy() const { return textureAnisotropy_; }
-
-    /// Return blending mode.
-    BlendMode GetBlendMode() const { return blendMode_; }
-
-    /// Return whether color write is enabled.
-    bool GetColorWrite() const { return colorWrite_; }
-
-    /// Return hardware culling mode.
-    CullMode GetCullMode() const { return cullMode_; }
-
-    /// Return depth constant bias.
-    float GetDepthConstantBias() const { return constantDepthBias_; }
-
-    /// Return depth slope scaled bias.
-    float GetDepthSlopeScaledBias() const { return slopeScaledDepthBias_; }
-
-    /// Return depth compare mode.
-    CompareMode GetDepthTest() const { return depthTestMode_; }
-
-    /// Return whether depth write is enabled.
-    bool GetDepthWrite() const { return depthWrite_; }
-
-    /// Return polygon fill mode.
-    FillMode GetFillMode() const { return fillMode_; }
-
-    /// Return whether stencil test is enabled.
-    bool GetStencilTest() const { return stencilTest_; }
-
-    /// Return whether scissor test is enabled.
-    bool GetScissorTest() const { return scissorTest_; }
-
-    /// Return scissor rectangle coordinates.
-    const IntRect& GetScissorRect() const { return scissorRect_; }
-
-    /// Return stencil compare mode.
-    CompareMode GetStencilTestMode() const { return stencilTestMode_; }
-
-    /// Return stencil operation to do if stencil test passes.
-    StencilOp GetStencilPass() const { return stencilPass_; }
-
-    /// Return stencil operation to do if stencil test fails.
-    StencilOp GetStencilFail() const { return stencilFail_; }
-
-    /// Return stencil operation to do if depth compare fails.
-    StencilOp GetStencilZFail() const { return stencilZFail_; }
-
-    /// Return stencil reference value.
-    unsigned GetStencilRef() const { return stencilRef_; }
-
-    /// Return stencil compare bitmask.
-    unsigned GetStencilCompareMask() const { return stencilCompareMask_; }
-
-    /// Return stencil write bitmask.
-    unsigned GetStencilWriteMask() const { return stencilWriteMask_; }
-
-    /// Return whether a custom clipping plane is in use.
-    bool GetUseClipPlane() const { return useClipPlane_; }
-
-    /// Return rendertarget width and height.
-    IntVector2 GetRenderTargetDimensions() const;
-
-    /// Window was resized through user interaction. Called by Input subsystem.
-    void WindowResized();
-    /// Window was moved through user interaction. Called by Input subsystem.
-    void WindowMoved();
-    /// Add a GPU object to keep track of. Called by GPUObject.
-    void AddGPUObject(GPUObject* object);
-    /// Remove a GPU object. Called by GPUObject.
-    void RemoveGPUObject(GPUObject* object);
-    /// Reserve a CPU-side scratch buffer.
-    void* ReserveScratchBuffer(unsigned size);
-    /// Free a CPU-side scratch buffer.
-    void FreeScratchBuffer(void* buffer);
-    /// Clean up too large scratch buffers.
-    void CleanupScratchBuffers();
-    /// Clean up a render surface from all FBOs.
-    void CleanupRenderSurface(RenderSurface* surface);
-    /// Clean up shader programs when a shader variation is released or destroyed.
-    void CleanupShaderPrograms(ShaderVariation* variation);
-    /// Reserve a constant buffer.
-    ConstantBuffer* GetOrCreateConstantBuffer(unsigned bindingIndex, unsigned size);
-    /// Release/clear GPU objects and optionally close the window.
-    void Release(bool clearGPUObjects, bool closeWindow);
-    /// Restore GPU objects and reinitialize state. Requires an open window.
-    void Restore();
-    /// Maximize the Window.
-    void Maximize();
-    /// Minimize the Window.
-    void Minimize();
-    /// Mark the FBO needing an update.
-    void MarkFBODirty();
-    /// Bind a VBO, avoiding redundant operation.
-    void SetVBO(unsigned object);
-    /// Bind a UBO, avoiding redundant operation.
-    void SetUBO(unsigned object);
-
-    /// Return the API-specific alpha texture format.
-    static unsigned GetAlphaFormat();
-    /// Return the API-specific luminance texture format.
-    static unsigned GetLuminanceFormat();
-    /// Return the API-specific luminance alpha texture format.
-    static unsigned GetLuminanceAlphaFormat();
-    /// Return the API-specific RGB texture format.
-    static unsigned GetRGBFormat();
-    /// Return the API-specific RGBA texture format.
-    static unsigned GetRGBAFormat();
-    /// Return the API-specific RGBA 16-bit texture format.
-    static unsigned GetRGBA16Format();
-    /// Return the API-specific RGBA 16-bit float texture format.
-    static unsigned GetRGBAFloat16Format();
-    /// Return the API-specific RGBA 32-bit float texture format.
-    static unsigned GetRGBAFloat32Format();
-    /// Return the API-specific RG 16-bit texture format.
-    static unsigned GetRG16Format();
-    /// Return the API-specific RG 16-bit float texture format.
-    static unsigned GetRGFloat16Format();
-    /// Return the API-specific RG 32-bit float texture format.
-    static unsigned GetRGFloat32Format();
-    /// Return the API-specific single channel 16-bit float texture format.
-    static unsigned GetFloat16Format();
-    /// Return the API-specific single channel 32-bit float texture format.
-    static unsigned GetFloat32Format();
-    /// Return the API-specific linear depth texture format.
-    static unsigned GetLinearDepthFormat();
-    /// Return the API-specific hardware depth-stencil texture format.
-    static unsigned GetDepthStencilFormat();
-    /// Return the API-specific readable hardware depth format, or 0 if not supported.
-    static unsigned GetReadableDepthFormat();
-    /// Return the API-specific texture format from a textual description, for example "rgb".
-    static unsigned GetFormat(const String& formatName);
-
-    /// Return UV offset required for pixel perfect rendering.
-    static const Vector2& GetPixelUVOffset() { return pixelUVOffset; }
-
-    /// Return maximum number of supported bones for skinning.
-    static unsigned GetMaxBones();
-
-    /// Return whether is using an OpenGL 3 context.
-    static bool GetGL3Support() { return gl3Support; }
-
-private:
-    /// Create the application window icon.
-    void CreateWindowIcon();
-    /// Check supported rendering features.
-    void CheckFeatureSupport();
-    /// Prepare for draw call. Update constant buffers and setup the FBO.
-    void PrepareDraw();
-    /// Clean up all framebuffers. Called when destroying the context.
-    void CleanupFramebuffers();
-    /// Reset cached rendering state.
-    void ResetCachedState();
-    /// Initialize texture unit mappings.
-    void SetTextureUnitMappings();
-    /// Create a framebuffer using either extension or core functionality.
-    unsigned CreateFramebuffer();
-    /// Delete a framebuffer using either extension or core functionality.
-    void DeleteFramebuffer(unsigned fbo);
-    /// Bind a framebuffer using either extension or core functionality.
-    void BindFramebuffer(unsigned fbo);
-    /// Bind a framebuffer color attachment using either extension or core functionality.
-    void BindColorAttachment(unsigned index, unsigned target, unsigned object);
-    /// Bind a framebuffer depth attachment using either extension or core functionality.
-    void BindDepthAttachment(unsigned object, bool isRenderBuffer);
-    /// Bind a framebuffer stencil attachment using either extension or core functionality.
-    void BindStencilAttachment(unsigned object, bool isRenderBuffer);
-    /// Check FBO completeness using either extension or core functionality.
-    bool CheckFramebuffer();
-    /// Set vertex attrib divisor. No-op if unsupported.
-    void SetVertexAttribDivisor(unsigned location, unsigned divisor);
-
-    /// Mutex for accessing the GPU objects vector from several threads.
-    Mutex gpuObjectMutex_;
-    /// Implementation.
-    GraphicsImpl* impl_;
-    /// Window title.
-    String windowTitle_;
-    /// Window Icon File Name
-    Image* windowIcon_;
-    /// External window, null if not in use (default.)
-    void* externalWindow_;
-    /// Window width in pixels.
-    int width_;
-    /// Window height in pixels.
-    int height_;
-    /// Window position.
-    IntVector2 position_;
-    /// Multisampling mode.
-    int multiSample_;
-    /// Fullscreen flag.
-    bool fullscreen_;
-    /// Borderless flag.
-    bool borderless_;
-    /// Resizable flag.
-    bool resizable_;
-    /// High DPI flag.
-    bool highDPI_;
-    /// Vertical sync flag.
-    bool vsync_;
-    /// Triple buffering flag.
-    bool tripleBuffer_;
-    /// sRGB conversion on write flag for the main window.
-    bool sRGB_;
-    /// Force OpenGL 2 use flag.
-    bool forceGL2_;
-    /// Instancing support flag.
-    bool instancingSupport_;
-    /// Light prepass support flag.
-    bool lightPrepassSupport_;
-    /// Deferred rendering support flag.
-    bool deferredSupport_;
-    /// Anisotropic filtering support flag.
-    bool anisotropySupport_;
-    /// DXT format support flag.
-    bool dxtTextureSupport_;
-    /// ETC1 format support flag.
-    bool etcTextureSupport_;
-    /// PVRTC formats support flag.
-    bool pvrtcTextureSupport_;
-    /// sRGB conversion on read support flag.
-    bool sRGBSupport_;
-    /// sRGB conversion on write support flag.
-    bool sRGBWriteSupport_;
-    /// Number of primitives this frame.
-    unsigned numPrimitives_;
-    /// Number of batches this frame.
-    unsigned numBatches_;
-    /// Largest scratch buffer request this frame.
-    unsigned maxScratchBufferRequest_;
-    /// GPU objects.
-    PODVector<GPUObject*> gpuObjects_;
-    /// Scratch buffers.
-    Vector<ScratchBuffer> scratchBuffers_;
-    /// Shadow map dummy color texture format.
-    unsigned dummyColorFormat_;
-    /// Shadow map depth texture format.
-    unsigned shadowMapFormat_;
-    /// Shadow map 24-bit depth texture format.
-    unsigned hiresShadowMapFormat_;
-    /// Vertex buffers in use.
-    VertexBuffer* vertexBuffers_[MAX_VERTEX_STREAMS];
-    /// Element mask in use.
-    unsigned elementMasks_[MAX_VERTEX_STREAMS];
-    /// Index buffer in use.
-    IndexBuffer* indexBuffer_;
-    /// Vertex shader in use.
-    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_;
-    /// Texture anisotropy level.
-    unsigned textureAnisotropy_;
-    /// Blending mode.
-    BlendMode blendMode_;
-    /// Color write enable.
-    bool colorWrite_;
-    /// Hardware culling mode.
-    CullMode cullMode_;
-    /// Depth constant bias.
-    float constantDepthBias_;
-    /// Depth slope scaled bias.
-    float slopeScaledDepthBias_;
-    /// Depth compare mode.
-    CompareMode depthTestMode_;
-    /// Depth write enable flag.
-    bool depthWrite_;
-    /// Polygon fill mode.
-    FillMode fillMode_;
-    /// Scissor test rectangle.
-    IntRect scissorRect_;
-    /// Scissor test enable flag.
-    bool scissorTest_;
-    /// Current custom clip plane in post-projection space.
-    Vector4 clipPlane_;
-    /// Stencil test compare mode.
-    CompareMode stencilTestMode_;
-    /// Stencil operation on pass.
-    StencilOp stencilPass_;
-    /// Stencil operation on fail.
-    StencilOp stencilFail_;
-    /// Stencil operation on depth fail.
-    StencilOp stencilZFail_;
-    /// Stencil test reference value.
-    unsigned stencilRef_;
-    /// Stencil compare bitmask.
-    unsigned stencilCompareMask_;
-    /// Stencil write bitmask.
-    unsigned stencilWriteMask_;
-    /// Stencil test enable flag.
-    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.
-    String shaderExtension_;
-    /// Last used shader in shader variation query.
-    mutable WeakPtr<Shader> lastShader_;
-    /// Last used shader name in shader variation query.
-    mutable String lastShaderName_;
-    /// Shader precache utility.
-    SharedPtr<ShaderPrecache> shaderPrecache_;
-    /// Allowed screen orientations.
-    String orientations_;
-    /// Graphics API name.
-    String apiName_;
-
-    /// Pixel perfect UV offset.
-    static const Vector2 pixelUVOffset;
-    /// Flag for OpenGL 3 support.
-    static bool gl3Support;
-};
-
-/// Register Graphics library objects.
-void URHO3D_API RegisterGraphicsLibrary(Context* context_);
-
-}

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

@@ -31,7 +31,6 @@ namespace Urho3D
 {
 
 GraphicsImpl::GraphicsImpl() :
-    window_(0),
     context_(0),
     systemFBO_(0),
     activeTexture_(0),
@@ -44,7 +43,8 @@ GraphicsImpl::GraphicsImpl() :
     boundUBO_(0),
     pixelFormat_(0),
     fboDirty_(false),
-    vertexBuffersDirty_(false)
+    vertexBuffersDirty_(false),
+    shaderProgram_(0)
 {
 }
 

+ 22 - 5
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)
@@ -61,7 +64,6 @@
 #define COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8c03
 #endif
 
-struct SDL_Window;
 typedef void *SDL_GLContext;
 
 namespace Urho3D
@@ -69,6 +71,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
 {
@@ -103,14 +108,10 @@ public:
     /// Construct.
     GraphicsImpl();
 
-    /// Return the SDL window.
-    SDL_Window* GetWindow() const { return window_; }
     /// Return the GL Context.
     const SDL_GLContext& GetGLContext() { return context_; }
 
 private:
-    /// SDL window.
-    SDL_Window* window_;
     /// SDL OpenGL context.
     SDL_GLContext context_;
     /// IOS system framebuffer handle.
@@ -135,6 +136,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.

+ 23 - 108
Source/Urho3D/Graphics/OpenGL/OGLIndexBuffer.cpp

@@ -33,31 +33,14 @@
 namespace Urho3D
 {
 
-IndexBuffer::IndexBuffer(Context* context, bool forceHeadless) :
-    Object(context),
-    GPUObject(forceHeadless ? (Graphics*)0 : GetSubsystem<Graphics>()),
-    indexCount_(0),
-    indexSize_(0),
-    lockState_(LOCK_NONE),
-    lockStart_(0),
-    lockCount_(0),
-    lockScratchData_(0),
-    shadowed_(false),
-    dynamic_(false)
+void IndexBuffer::OnDeviceLost()
 {
-    // Force shadowing mode if graphics subsystem does not exist
-    if (!graphics_)
-        shadowed_ = true;
-}
-
-IndexBuffer::~IndexBuffer()
-{
-    Release();
+    GPUObject::OnDeviceLost();
 }
 
 void IndexBuffer::OnDeviceReset()
 {
-    if (!object_)
+    if (!object_.name_)
     {
         Create();
         dataLost_ = !UpdateToGPU();
@@ -72,7 +55,7 @@ void IndexBuffer::Release()
 {
     Unlock();
 
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_)
             return;
@@ -82,46 +65,13 @@ void IndexBuffer::Release()
             if (graphics_->GetIndexBuffer() == this)
                 graphics_->SetIndexBuffer(0);
 
-            glDeleteBuffers(1, &object_);
+            glDeleteBuffers(1, &object_.name_);
         }
 
-        object_ = 0;
+        object_.name_ = 0;
     }
 }
 
-void IndexBuffer::SetShadowed(bool enable)
-{
-    // If no graphics subsystem, can not disable shadowing
-    if (!graphics_)
-        enable = true;
-
-    if (enable != shadowed_)
-    {
-        if (enable && indexCount_ && indexSize_)
-            shadowData_ = new unsigned char[indexCount_ * indexSize_];
-        else
-            shadowData_.Reset();
-
-        shadowed_ = enable;
-    }
-}
-
-bool IndexBuffer::SetSize(unsigned indexCount, bool largeIndices, bool dynamic)
-{
-    Unlock();
-
-    dynamic_ = dynamic;
-    indexCount_ = indexCount;
-    indexSize_ = (unsigned)(largeIndices ? sizeof(unsigned) : sizeof(unsigned short));
-
-    if (shadowed_ && indexCount_ && indexSize_)
-        shadowData_ = new unsigned char[indexCount_ * indexSize_];
-    else
-        shadowData_.Reset();
-
-    return Create();
-}
-
 bool IndexBuffer::SetData(const void* data)
 {
     if (!data)
@@ -139,7 +89,7 @@ bool IndexBuffer::SetData(const void* data)
     if (shadowData_ && data != shadowData_.Get())
         memcpy(shadowData_.Get(), data, indexCount_ * indexSize_);
 
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_->IsDeviceLost())
         {
@@ -186,7 +136,7 @@ bool IndexBuffer::SetDataRange(const void* data, unsigned start, unsigned count,
     if (shadowData_ && shadowData_.Get() + start * indexSize_ != data)
         memcpy(shadowData_.Get() + start * indexSize_, data, count * indexSize_);
 
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_->IsDeviceLost())
         {
@@ -269,52 +219,6 @@ void IndexBuffer::Unlock()
     }
 }
 
-bool IndexBuffer::GetUsedVertexRange(unsigned start, unsigned count, unsigned& minVertex, unsigned& vertexCount)
-{
-    if (!shadowData_)
-    {
-        URHO3D_LOGERROR("Used vertex range can only be queried from an index buffer with shadow data");
-        return false;
-    }
-
-    if (start + count > indexCount_)
-    {
-        URHO3D_LOGERROR("Illegal index range for querying used vertices");
-        return false;
-    }
-
-    minVertex = M_MAX_UNSIGNED;
-    unsigned maxVertex = 0;
-
-    if (indexSize_ == sizeof(unsigned))
-    {
-        unsigned* indices = ((unsigned*)shadowData_.Get()) + start;
-
-        for (unsigned i = 0; i < count; ++i)
-        {
-            if (indices[i] < minVertex)
-                minVertex = indices[i];
-            if (indices[i] > maxVertex)
-                maxVertex = indices[i];
-        }
-    }
-    else
-    {
-        unsigned short* indices = ((unsigned short*)shadowData_.Get()) + start;
-
-        for (unsigned i = 0; i < count; ++i)
-        {
-            if (indices[i] < minVertex)
-                minVertex = indices[i];
-            if (indices[i] > maxVertex)
-                maxVertex = indices[i];
-        }
-    }
-
-    vertexCount = maxVertex - minVertex + 1;
-    return true;
-}
-
 bool IndexBuffer::Create()
 {
     if (!indexCount_)
@@ -331,9 +235,9 @@ bool IndexBuffer::Create()
             return true;
         }
 
-        if (!object_)
-            glGenBuffers(1, &object_);
-        if (!object_)
+        if (!object_.name_)
+            glGenBuffers(1, &object_.name_);
+        if (!object_.name_)
         {
             URHO3D_LOGERROR("Failed to create index buffer");
             return false;
@@ -348,10 +252,21 @@ bool IndexBuffer::Create()
 
 bool IndexBuffer::UpdateToGPU()
 {
-    if (object_ && shadowData_)
+    if (object_.name_ && shadowData_)
         return SetData(shadowData_.Get());
     else
         return false;
 }
 
+void* IndexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
+{
+    // Never called on OpenGL
+    return 0;
+}
+
+void IndexBuffer::UnmapBuffer()
+{
+    // Never called on OpenGL
+}
+
 }

+ 0 - 112
Source/Urho3D/Graphics/OpenGL/OGLIndexBuffer.h

@@ -1,112 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/ArrayPtr.h"
-#include "../../Core/Object.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-
-namespace Urho3D
-{
-
-/// Hardware index buffer.
-class URHO3D_API IndexBuffer : public Object, public GPUObject
-{
-    URHO3D_OBJECT(IndexBuffer, Object);
-
-public:
-    /// Construct.
-    IndexBuffer(Context* context, bool forceHeadless = false);
-    /// Destruct.
-    virtual ~IndexBuffer();
-
-    /// Recreate the GPU resource and restore data if applicable.
-    virtual void OnDeviceReset();
-    /// Release the buffer.
-    virtual void Release();
-
-    /// Enable shadowing in CPU memory. Shadowing is forced on if the graphics subsystem does not exist.
-    void SetShadowed(bool enable);
-    /// Set buffer size and dynamic mode. Previous data will be lost.
-    bool SetSize(unsigned indexCount, bool largeIndices, bool dynamic = false);
-    /// Set all data in the buffer.
-    bool SetData(const void* data);
-    /// Set a data range in the buffer. Optionally discard data outside the range.
-    bool SetDataRange(const void* data, unsigned start, unsigned count, bool discard = false);
-    /// Lock the buffer for write-only editing. Return data pointer if successful. Optionally discard data outside the range.
-    void* Lock(unsigned start, unsigned count, bool discard = false);
-    /// Unlock the buffer and apply changes to the GPU buffer.
-    void Unlock();
-
-    /// Return whether CPU memory shadowing is enabled.
-    bool IsShadowed() const { return shadowed_; }
-
-    /// Return whether is dynamic.
-    bool IsDynamic() const { return dynamic_; }
-
-    /// Return whether is currently locked.
-    bool IsLocked() const { return lockState_ != LOCK_NONE; }
-
-    /// Return number of indices.
-    unsigned GetIndexCount() const { return indexCount_; }
-
-    /// Return index size in bytes.
-    unsigned GetIndexSize() const { return indexSize_; }
-
-    /// Return used vertex range from index range. Only supported for shadowed buffers.
-    bool GetUsedVertexRange(unsigned start, unsigned count, unsigned& minVertex, unsigned& vertexCount);
-
-    /// Return CPU memory shadow data.
-    unsigned char* GetShadowData() const { return shadowData_.Get(); }
-
-    /// Return shared array pointer to the CPU memory shadow data.
-    SharedArrayPtr<unsigned char> GetShadowDataShared() const { return shadowData_; }
-
-private:
-    /// Create buffer.
-    bool Create();
-    /// Update the shadow data to the GPU buffer.
-    bool UpdateToGPU();
-
-    /// Shadow data.
-    SharedArrayPtr<unsigned char> shadowData_;
-    /// Number of indices.
-    unsigned indexCount_;
-    /// Index size.
-    unsigned indexSize_;
-    /// Buffer locking state.
-    LockState lockState_;
-    /// Lock start vertex.
-    unsigned lockStart_;
-    /// Lock number of vertices.
-    unsigned lockCount_;
-    /// Scratch buffer for fallback locking.
-    void* lockScratchData_;
-    /// Shadowed flag.
-    bool shadowed_;
-    /// Dynamic flag.
-    bool dynamic_;
-};
-
-}

+ 0 - 70
Source/Urho3D/Graphics/OpenGL/OGLRenderSurface.cpp

@@ -51,51 +51,6 @@ RenderSurface::RenderSurface(Texture* parentTexture) :
 {
 }
 
-RenderSurface::~RenderSurface()
-{
-    Release();
-}
-
-void RenderSurface::SetNumViewports(unsigned num)
-{
-    viewports_.Resize(num);
-}
-
-void RenderSurface::SetViewport(unsigned index, Viewport* viewport)
-{
-    if (index >= viewports_.Size())
-        viewports_.Resize(index + 1);
-
-    viewports_[index] = viewport;
-}
-
-void RenderSurface::SetUpdateMode(RenderSurfaceUpdateMode mode)
-{
-    updateMode_ = mode;
-}
-
-void RenderSurface::SetLinkedRenderTarget(RenderSurface* renderTarget)
-{
-    if (renderTarget != this)
-        linkedRenderTarget_ = renderTarget;
-}
-
-void RenderSurface::SetLinkedDepthStencil(RenderSurface* depthStencil)
-{
-    if (depthStencil != this)
-        linkedDepthStencil_ = depthStencil;
-}
-
-void RenderSurface::QueueUpdate()
-{
-    updateQueued_ = true;
-}
-
-void RenderSurface::ResetUpdateQueued()
-{
-    updateQueued_ = false;
-}
-
 bool RenderSurface::CreateRenderBuffer(unsigned width, unsigned height, unsigned format)
 {
     Graphics* graphics = parentTexture_->GetGraphics();
@@ -159,29 +114,4 @@ void RenderSurface::Release()
     renderBuffer_ = 0;
 }
 
-int RenderSurface::GetWidth() const
-{
-    return parentTexture_->GetWidth();
-}
-
-int RenderSurface::GetHeight() const
-{
-    return parentTexture_->GetHeight();
-}
-
-TextureUsage RenderSurface::GetUsage() const
-{
-    return parentTexture_->GetUsage();
-}
-
-Viewport* RenderSurface::GetViewport(unsigned index) const
-{
-    return index < viewports_.Size() ? viewports_[index] : (Viewport*)0;
-}
-
-void RenderSurface::SetTarget(unsigned target)
-{
-    target_ = target;
-}
-
 }

+ 0 - 124
Source/Urho3D/Graphics/OpenGL/OGLRenderSurface.h

@@ -1,124 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Graphics/GraphicsDefs.h"
-#include "../../Graphics/Viewport.h"
-
-namespace Urho3D
-{
-
-class Camera;
-class Scene;
-class Texture;
-
-/// %Color or depth-stencil surface that can be rendered into.
-class URHO3D_API RenderSurface : public RefCounted
-{
-    friend class Texture2D;
-    friend class TextureCube;
-
-public:
-    /// Construct with parent texture.
-    RenderSurface(Texture* parentTexture);
-    /// Destruct.
-    ~RenderSurface();
-
-    /// Set number of viewports.
-    void SetNumViewports(unsigned num);
-    /// Set viewport.
-    void SetViewport(unsigned index, Viewport* viewport);
-    /// Set viewport update mode. Default is to update when visible.
-    void SetUpdateMode(RenderSurfaceUpdateMode mode);
-    /// Set linked color rendertarget.
-    void SetLinkedRenderTarget(RenderSurface* renderTarget);
-    /// Set linked depth-stencil surface.
-    void SetLinkedDepthStencil(RenderSurface* depthStencil);
-    /// Queue manual update of the viewport(s).
-    void QueueUpdate();
-    /// Create a renderbuffer. Return true if successful.
-    bool CreateRenderBuffer(unsigned width, unsigned height, unsigned format);
-    /// Handle device loss.
-    void OnDeviceLost();
-    /// Release renderbuffer if any.
-    void Release();
-
-    /// Return parent texture.
-    Texture* GetParentTexture() const { return parentTexture_; }
-
-    /// Return renderbuffer if created.
-    unsigned GetRenderBuffer() const { return renderBuffer_; }
-
-    /// Return width.
-    int GetWidth() const;
-    /// Return height.
-    int GetHeight() const;
-    /// Return usage.
-    TextureUsage GetUsage() const;
-
-    /// Return number of viewports.
-    unsigned GetNumViewports() const { return viewports_.Size(); }
-
-    /// Return viewport by index.
-    Viewport* GetViewport(unsigned index) const;
-
-    /// Return viewport update mode.
-    RenderSurfaceUpdateMode GetUpdateMode() const { return updateMode_; }
-
-    /// Return linked color buffer.
-    RenderSurface* GetLinkedRenderTarget() const { return linkedRenderTarget_; }
-
-    /// Return linked depth buffer.
-    RenderSurface* GetLinkedDepthStencil() const { return linkedDepthStencil_; }
-
-    /// Set surface's OpenGL target.
-    void SetTarget(unsigned target);
-
-    /// Return surface's OpenGL target.
-    unsigned GetTarget() const { return target_; }
-
-    /// Return whether manual update queued. Called internally.
-    bool IsUpdateQueued() const { return updateQueued_; }
-    /// Reset update queued flag. Called internally.
-    void ResetUpdateQueued();
-
-private:
-    /// Parent texture.
-    Texture* parentTexture_;
-    /// OpenGL target.
-    unsigned target_;
-    /// OpenGL renderbuffer.
-    unsigned renderBuffer_;
-    /// Viewports.
-    Vector<SharedPtr<Viewport> > viewports_;
-    /// Linked color buffer.
-    WeakPtr<RenderSurface> linkedRenderTarget_;
-    /// Linked depth buffer.
-    WeakPtr<RenderSurface> linkedDepthStencil_;
-    /// Update mode for viewports.
-    RenderSurfaceUpdateMode updateMode_;
-    /// Update queued flag.
-    bool updateQueued_;
-};
-
-}

+ 46 - 52
Source/Urho3D/Graphics/OpenGL/OGLShaderProgram.cpp

@@ -44,19 +44,6 @@ static const char* shaderParameterGroups[] = {
     "custom"
 };
 
-static const char* elementSemanticNames[] =
-{
-    "POS",
-    "NORMAL",
-    "BINORMAL",
-    "TANGENT",
-    "TEXCOORD",
-    "COLOR",
-    "BLENDWEIGHT",
-    "BLENDINDICES",
-    "OBJECTINDEX"
-};
-
 static unsigned NumberPostfix(const String& str)
 {
     for (unsigned i = 0; i < str.Length(); ++i)
@@ -101,7 +88,7 @@ void ShaderProgram::OnDeviceLost()
 
 void ShaderProgram::Release()
 {
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_)
             return;
@@ -111,10 +98,10 @@ void ShaderProgram::Release()
             if (graphics_->GetShaderProgram() == this)
                 graphics_->SetShaders(0, 0);
 
-            glDeleteProgram(object_);
+            glDeleteProgram(object_.name_);
         }
 
-        object_ = 0;
+        object_.name_ = 0;
         linkerOutput_.Clear();
         shaderParameters_.Clear();
         vertexAttributes_.Clear();
@@ -131,35 +118,35 @@ bool ShaderProgram::Link()
 {
     Release();
 
-    if (!vertexShader_ || !pixelShader_ || !vertexShader_->GetGPUObject() || !pixelShader_->GetGPUObject())
+    if (!vertexShader_ || !pixelShader_ || !vertexShader_->GetGPUObjectName() || !pixelShader_->GetGPUObjectName())
         return false;
 
-    object_ = glCreateProgram();
-    if (!object_)
+    object_.name_ = glCreateProgram();
+    if (!object_.name_)
     {
         linkerOutput_ = "Could not create shader program";
         return false;
     }
 
-    glAttachShader(object_, vertexShader_->GetGPUObject());
-    glAttachShader(object_, pixelShader_->GetGPUObject());
-    glLinkProgram(object_);
+    glAttachShader(object_.name_, vertexShader_->GetGPUObjectName());
+    glAttachShader(object_.name_, pixelShader_->GetGPUObjectName());
+    glLinkProgram(object_.name_);
 
     int linked, length;
-    glGetProgramiv(object_, GL_LINK_STATUS, &linked);
+    glGetProgramiv(object_.name_, GL_LINK_STATUS, &linked);
     if (!linked)
     {
-        glGetProgramiv(object_, GL_INFO_LOG_LENGTH, &length);
+        glGetProgramiv(object_.name_, GL_INFO_LOG_LENGTH, &length);
         linkerOutput_.Resize((unsigned)length);
         int outLength;
-        glGetProgramInfoLog(object_, length, &outLength, &linkerOutput_[0]);
-        glDeleteProgram(object_);
-        object_ = 0;
+        glGetProgramInfoLog(object_.name_, length, &outLength, &linkerOutput_[0]);
+        glDeleteProgram(object_.name_);
+        object_.name_ = 0;
     }
     else
         linkerOutput_.Clear();
 
-    if (!object_)
+    if (!object_.name_)
         return false;
 
     const int MAX_NAME_LENGTH = 256;
@@ -167,13 +154,13 @@ bool ShaderProgram::Link()
     int attributeCount, uniformCount, elementCount, nameLength;
     GLenum type;
 
-    glUseProgram(object_);
+    glUseProgram(object_.name_);
 
     // Check for vertex attributes
-    glGetProgramiv(object_, GL_ACTIVE_ATTRIBUTES, &attributeCount);
+    glGetProgramiv(object_.name_, GL_ACTIVE_ATTRIBUTES, &attributeCount);
     for (int i = 0; i < attributeCount; ++i)
     {
-        glGetActiveAttrib(object_, i, (GLsizei)MAX_NAME_LENGTH, &nameLength, &elementCount, &type, nameBuffer);
+        glGetActiveAttrib(object_.name_, i, (GLsizei)MAX_NAME_LENGTH, &nameLength, &elementCount, &type, nameBuffer);
 
         String name = String(nameBuffer, nameLength);
         VertexElementSemantic semantic = MAX_VERTEX_ELEMENT_SEMANTICS;
@@ -182,7 +169,7 @@ bool ShaderProgram::Link()
         // Go in reverse order so that "binormal" is detected before "normal"
         for (unsigned j = MAX_VERTEX_ELEMENT_SEMANTICS - 1; j < MAX_VERTEX_ELEMENT_SEMANTICS; --j)
         {
-            if (name.Contains(elementSemanticNames[j], false))
+            if (name.Contains(ShaderVariation::elementSemanticNames[j], false))
             {
                 semantic = (VertexElementSemantic)j;
                 unsigned index = NumberPostfix(name);
@@ -199,7 +186,7 @@ bool ShaderProgram::Link()
             continue;
         }
 
-        int location = glGetAttribLocation(object_, name.CString());
+        int location = glGetAttribLocation(object_.name_, name.CString());
         vertexAttributes_[MakePair((unsigned char)semantic, semanticIndex)] = location;
         usedVertexAttributes_ |= (1 << location);
     }
@@ -212,14 +199,14 @@ bool ShaderProgram::Link()
     {
         int numUniformBlocks = 0;
 
-        glGetProgramiv(object_, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks);
+        glGetProgramiv(object_.name_, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks);
         for (int i = 0; i < numUniformBlocks; ++i)
         {
-            glGetActiveUniformBlockName(object_, (GLuint)i, MAX_NAME_LENGTH, &nameLength, nameBuffer);
+            glGetActiveUniformBlockName(object_.name_, (GLuint)i, MAX_NAME_LENGTH, &nameLength, nameBuffer);
 
             String name(nameBuffer, (unsigned)nameLength);
 
-            unsigned blockIndex = glGetUniformBlockIndex(object_, name.CString());
+            unsigned blockIndex = glGetUniformBlockIndex(object_.name_, name.CString());
             unsigned group = M_MAX_UNSIGNED;
 
             // Try to recognize the use of the buffer from its name
@@ -245,30 +232,34 @@ bool ShaderProgram::Link()
 
             // Find total constant buffer data size
             int dataSize;
-            glGetActiveUniformBlockiv(object_, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &dataSize);
+            glGetActiveUniformBlockiv(object_.name_, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &dataSize);
             if (!dataSize)
                 continue;
 
             unsigned bindingIndex = group;
             // Vertex shader constant buffer bindings occupy slots starting from zero to maximum supported, pixel shader bindings
             // from that point onward
+            ShaderType shaderType = VS;
             if (name.Contains("PS", false))
+            {
                 bindingIndex += MAX_SHADER_PARAMETER_GROUPS;
+                shaderType = PS;
+            }
 
-            glUniformBlockBinding(object_, blockIndex, bindingIndex);
+            glUniformBlockBinding(object_.name_, blockIndex, bindingIndex);
             blockToBinding[blockIndex] = bindingIndex;
 
-            constantBuffers_[bindingIndex] = graphics_->GetOrCreateConstantBuffer(bindingIndex, (unsigned)dataSize);
+            constantBuffers_[bindingIndex] = graphics_->GetOrCreateConstantBuffer(shaderType, bindingIndex, (unsigned)dataSize);
         }
     }
 #endif
 
     // Check for shader parameters and texture units
-    glGetProgramiv(object_, GL_ACTIVE_UNIFORMS, &uniformCount);
+    glGetProgramiv(object_.name_, GL_ACTIVE_UNIFORMS, &uniformCount);
     for (int i = 0; i < uniformCount; ++i)
     {
-        glGetActiveUniform(object_, (GLuint)i, MAX_NAME_LENGTH, 0, &elementCount, &type, nameBuffer);
-        int location = glGetUniformLocation(object_, nameBuffer);
+        glGetActiveUniform(object_.name_, (GLuint)i, MAX_NAME_LENGTH, 0, &elementCount, &type, nameBuffer);
+        int location = glGetUniformLocation(object_.name_, nameBuffer);
 
         // Check for array index included in the name and strip it
         String name(nameBuffer);
@@ -286,27 +277,30 @@ bool ShaderProgram::Link()
         {
             // Store constant uniform
             String paramName = name.Substring(1);
-            ShaderParameter newParam;
-            newParam.type_ = type;
-            newParam.location_ = location;
+            ShaderParameter parameter;
+            parameter.name_ = paramName;
+            parameter.glType_ = type;
+            parameter.location_ = location;
+            bool store = location >= 0;
 
 #ifndef GL_ES_VERSION_2_0
             // If running OpenGL 3, the uniform may be inside a constant buffer
-            if (newParam.location_ < 0 && Graphics::GetGL3Support())
+            if (parameter.location_ < 0 && Graphics::GetGL3Support())
             {
                 int blockIndex, blockOffset;
-                glGetActiveUniformsiv(object_, 1, (const GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &blockIndex);
-                glGetActiveUniformsiv(object_, 1, (const GLuint*)&i, GL_UNIFORM_OFFSET, &blockOffset);
+                glGetActiveUniformsiv(object_.name_, 1, (const GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &blockIndex);
+                glGetActiveUniformsiv(object_.name_, 1, (const GLuint*)&i, GL_UNIFORM_OFFSET, &blockOffset);
                 if (blockIndex >= 0)
                 {
-                    newParam.location_ = blockOffset;
-                    newParam.bufferPtr_ = constantBuffers_[blockToBinding[blockIndex]];
+                    parameter.offset_ = blockOffset;
+                    parameter.bufferPtr_ = constantBuffers_[blockToBinding[blockIndex]];
+                    store = true;
                 }
             }
 #endif
 
-            if (newParam.location_ >= 0)
-                shaderParameters_[StringHash(paramName)] = newParam;
+            if (store)
+                shaderParameters_[StringHash(paramName)] = parameter;
         }
         else if (location >= 0 && name[0] == 's')
         {

+ 1 - 18
Source/Urho3D/Graphics/OpenGL/OGLShaderProgram.h

@@ -26,30 +26,13 @@
 #include "../../Container/RefCounted.h"
 #include "../../Graphics/GPUObject.h"
 #include "../../Graphics/GraphicsDefs.h"
+#include "../../Graphics/ShaderVariation.h"
 
 namespace Urho3D
 {
 
 class ConstantBuffer;
 class Graphics;
-class ShaderVariation;
-
-/// %Shader parameter definition.
-struct ShaderParameter
-{
-    /// Construct with defaults.
-    ShaderParameter() :
-        bufferPtr_(0)
-    {
-    }
-
-    /// Uniform location or byte offset in constant buffer.
-    int location_;
-    /// Element type.
-    unsigned type_;
-    /// Constant buffer pointer.
-    ConstantBuffer* bufferPtr_;
-};
 
 /// Linked shader program on the GPU.
 class URHO3D_API ShaderProgram : public RefCounted, public GPUObject

+ 24 - 33
Source/Urho3D/Graphics/OpenGL/OGLShaderVariation.cpp

@@ -34,17 +34,18 @@
 namespace Urho3D
 {
 
-ShaderVariation::ShaderVariation(Shader* owner, ShaderType type) :
-    GPUObject(owner->GetSubsystem<Graphics>()),
-    owner_(owner),
-    type_(type)
+const char* ShaderVariation::elementSemanticNames[] =
 {
-}
-
-ShaderVariation::~ShaderVariation()
-{
-    Release();
-}
+    "POS",
+    "NORMAL",
+    "BINORMAL",
+    "TANGENT",
+    "TEXCOORD",
+    "COLOR",
+    "BLENDWEIGHT",
+    "BLENDINDICES",
+    "OBJECTINDEX"
+};
 
 void ShaderVariation::OnDeviceLost()
 {
@@ -55,7 +56,7 @@ void ShaderVariation::OnDeviceLost()
 
 void ShaderVariation::Release()
 {
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_)
             return;
@@ -73,10 +74,10 @@ void ShaderVariation::Release()
                     graphics_->SetShaders(0, 0);
             }
 
-            glDeleteShader(object_);
+            glDeleteShader(object_.name_);
         }
 
-        object_ = 0;
+        object_.name_ = 0;
         graphics_->CleanupShaderPrograms(this);
     }
 
@@ -93,8 +94,8 @@ bool ShaderVariation::Create()
         return false;
     }
 
-    object_ = glCreateShader(type_ == VS ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);
-    if (!object_)
+    object_.name_ = glCreateShader(type_ == VS ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);
+    if (!object_.name_)
     {
         compilerOutput_ = "Could not create shader object";
         return false;
@@ -166,29 +167,24 @@ bool ShaderVariation::Create()
         shaderCode += originalShaderCode;
 
     const char* shaderCStr = shaderCode.CString();
-    glShaderSource(object_, 1, &shaderCStr, 0);
-    glCompileShader(object_);
+    glShaderSource(object_.name_, 1, &shaderCStr, 0);
+    glCompileShader(object_.name_);
 
     int compiled, length;
-    glGetShaderiv(object_, GL_COMPILE_STATUS, &compiled);
+    glGetShaderiv(object_.name_, GL_COMPILE_STATUS, &compiled);
     if (!compiled)
     {
-        glGetShaderiv(object_, GL_INFO_LOG_LENGTH, &length);
+        glGetShaderiv(object_.name_, GL_INFO_LOG_LENGTH, &length);
         compilerOutput_.Resize((unsigned)length);
         int outLength;
-        glGetShaderInfoLog(object_, length, &outLength, &compilerOutput_[0]);
-        glDeleteShader(object_);
-        object_ = 0;
+        glGetShaderInfoLog(object_.name_, length, &outLength, &compilerOutput_[0]);
+        glDeleteShader(object_.name_);
+        object_.name_ = 0;
     }
     else
         compilerOutput_.Clear();
 
-    return object_ != 0;
-}
-
-void ShaderVariation::SetName(const String& name)
-{
-    name_ = name;
+    return object_.name_ != 0;
 }
 
 void ShaderVariation::SetDefines(const String& defines)
@@ -196,9 +192,4 @@ void ShaderVariation::SetDefines(const String& defines)
     defines_ = defines;
 }
 
-Shader* ShaderVariation::GetOwner() const
-{
-    return owner_;
-}
-
 }

+ 0 - 88
Source/Urho3D/Graphics/OpenGL/OGLShaderVariation.h

@@ -1,88 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/RefCounted.h"
-#include "../../Container/ArrayPtr.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-
-namespace Urho3D
-{
-
-class Shader;
-class ShaderProgram;
-
-/// Vertex or pixel shader on the GPU.
-class URHO3D_API ShaderVariation : public RefCounted, public GPUObject
-{
-public:
-    /// Construct.
-    ShaderVariation(Shader* owner, ShaderType type);
-    /// Destruct.
-    virtual ~ShaderVariation();
-
-    /// Mark the GPU resource destroyed on context destruction.
-    virtual void OnDeviceLost();
-    /// Release the shader.
-    virtual void Release();
-
-    /// Compile the shader. Return true if successful.
-    bool Create();
-    /// Set name.
-    void SetName(const String& name);
-    /// Set defines.
-    void SetDefines(const String& defines);
-
-    /// Return the owner resource.
-    Shader* GetOwner() const;
-
-    /// Return shader type.
-    ShaderType GetShaderType() const { return type_; }
-
-    /// Return name.
-    const String& GetName() const { return name_; }
-
-    /// Return defines.
-    const String& GetDefines() const { return defines_; }
-
-    /// Return full shader name.
-    String GetFullName() const { return name_ + "(" + defines_ + ")"; }
-
-    /// Return compile error/warning string.
-    const String& GetCompilerOutput() const { return compilerOutput_; }
-
-private:
-    /// Shader this variation belongs to.
-    WeakPtr<Shader> owner_;
-    /// Shader type.
-    ShaderType type_;
-    /// Shader name.
-    String name_;
-    /// Defines to use in compiling.
-    String defines_;
-    /// Shader compile error string.
-    String compilerOutput_;
-};
-
-}

+ 4 - 223
Source/Urho3D/Graphics/OpenGL/OGLTexture.cpp

@@ -57,25 +57,6 @@ static GLenum gl3WrapModes[] =
 };
 #endif
 
-static const char* addressModeNames[] =
-{
-    "wrap",
-    "mirror",
-    "clamp",
-    "border",
-    0
-};
-
-static const char* filterModeNames[] =
-{
-    "nearest",
-    "bilinear",
-    "trilinear",
-    "anisotropic",
-    "default",
-    0
-};
-
 static GLenum GetWrapMode(TextureAddressMode mode)
 {
 #ifndef GL_ES_VERSION_2_0
@@ -85,60 +66,6 @@ static GLenum GetWrapMode(TextureAddressMode mode)
 #endif
 }
 
-Texture::Texture(Context* context) :
-    Resource(context),
-    GPUObject(GetSubsystem<Graphics>()),
-    usage_(TEXTURE_STATIC),
-    format_(0),
-    levels_(0),
-    requestedLevels_(0),
-    width_(0),
-    height_(0),
-    depth_(0),
-    shadowCompare_(false),
-    parametersDirty_(true),
-    filterMode_(FILTER_DEFAULT),
-    sRGB_(false)
-{
-    for (int i = 0; i < MAX_COORDS; ++i)
-        addressMode_[i] = ADDRESS_WRAP;
-    for (int i = 0; i < MAX_TEXTURE_QUALITY_LEVELS; ++i)
-        mipsToSkip_[i] = (unsigned)(MAX_TEXTURE_QUALITY_LEVELS - 1 - i);
-}
-
-Texture::~Texture()
-{
-}
-
-void Texture::SetNumLevels(unsigned levels)
-{
-    requestedLevels_ = levels;
-}
-
-void Texture::SetFilterMode(TextureFilterMode mode)
-{
-    filterMode_ = mode;
-    parametersDirty_ = true;
-}
-
-void Texture::SetAddressMode(TextureCoordinate coord, TextureAddressMode mode)
-{
-    addressMode_[coord] = mode;
-    parametersDirty_ = true;
-}
-
-void Texture::SetShadowCompare(bool enable)
-{
-    shadowCompare_ = enable;
-    parametersDirty_ = true;
-}
-
-void Texture::SetBorderColor(const Color& color)
-{
-    borderColor_ = color;
-    parametersDirty_ = true;
-}
-
 void Texture::SetSRGB(bool enable)
 {
     if (graphics_)
@@ -148,7 +75,7 @@ void Texture::SetSRGB(bool enable)
     {
         sRGB_ = enable;
         // If texture had already been created, must recreate it to set the sRGB texture format
-        if (object_)
+        if (object_.name_)
             Create();
 
         // If texture in use in the framebuffer, mark it dirty
@@ -157,34 +84,9 @@ void Texture::SetSRGB(bool enable)
     }
 }
 
-void Texture::SetBackupTexture(Texture* texture)
-{
-    backupTexture_ = texture;
-}
-
-void Texture::SetMipsToSkip(int quality, int toSkip)
-{
-    if (quality >= QUALITY_LOW && quality < MAX_TEXTURE_QUALITY_LEVELS)
-    {
-        mipsToSkip_[quality] = (unsigned)toSkip;
-
-        // Make sure a higher quality level does not actually skip more mips
-        for (int i = 1; i < MAX_TEXTURE_QUALITY_LEVELS; ++i)
-        {
-            if (mipsToSkip_[i] > mipsToSkip_[i - 1])
-                mipsToSkip_[i] = mipsToSkip_[i - 1];
-        }
-    }
-}
-
-void Texture::SetParametersDirty()
-{
-    parametersDirty_ = true;
-}
-
 void Texture::UpdateParameters()
 {
-    if (!object_ || !graphics_)
+    if (!object_.name_ || !graphics_)
         return;
 
     // Wrapping
@@ -250,9 +152,9 @@ void Texture::UpdateParameters()
     parametersDirty_ = false;
 }
 
-int Texture::GetMipsToSkip(int quality) const
+bool Texture::GetParametersDirty() const
 {
-    return (quality >= QUALITY_LOW && quality < MAX_TEXTURE_QUALITY_LEVELS) ? mipsToSkip_[quality] : 0;
+    return parametersDirty_;
 }
 
 bool Texture::IsCompressed() const
@@ -263,47 +165,6 @@ bool Texture::IsCompressed() const
            format_ == COMPRESSED_RGB_PVRTC_2BPPV1_IMG || format_ == COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
 }
 
-int Texture::GetLevelWidth(unsigned level) const
-{
-    if (level > levels_)
-        return 0;
-    return Max(width_ >> level, 1);
-}
-
-int Texture::GetLevelHeight(unsigned level) const
-{
-    if (level > levels_)
-        return 0;
-    return Max(height_ >> level, 1);
-}
-
-int Texture::GetLevelDepth(unsigned level) const
-{
-    if (level > levels_)
-        return 0;
-    return Max(depth_ >> level, 1);
-}
-
-unsigned Texture::GetDataSize(int width, int height) const
-{
-    if (IsCompressed())
-    {
-        if (format_ == COMPRESSED_RGB_PVRTC_4BPPV1_IMG || format_ == COMPRESSED_RGBA_PVRTC_4BPPV1_IMG)
-            return (unsigned)((Max(width, 8) * Max(height, 8) * 4 + 7) >> 3);
-        else if (format_ == COMPRESSED_RGB_PVRTC_2BPPV1_IMG || format_ == COMPRESSED_RGBA_PVRTC_2BPPV1_IMG)
-            return (unsigned)((Max(width, 16) * Max(height, 8) * 2 + 7) >> 3);
-        else
-            return GetRowDataSize(width) * ((height + 3) >> 2);
-    }
-    else
-        return GetRowDataSize(width) * height;
-}
-
-unsigned Texture::GetDataSize(int width, int height, int depth) const
-{
-    return depth * GetDataSize(width, height);
-}
-
 unsigned Texture::GetRowDataSize(int width) const
 {
     switch (format_)
@@ -366,14 +227,6 @@ unsigned Texture::GetRowDataSize(int width) const
     }
 }
 
-unsigned Texture::GetComponents() const
-{
-    if (!width_ || IsCompressed())
-        return 0;
-    else
-        return GetRowDataSize(width_) / width_;
-}
-
 unsigned Texture::GetExternalFormat(unsigned format)
 {
 #ifndef GL_ES_VERSION_2_0
@@ -423,64 +276,6 @@ unsigned Texture::GetDataType(unsigned format)
 #endif
 }
 
-void Texture::SetParameters(XMLFile* file)
-{
-    if (!file)
-        return;
-
-    XMLElement rootElem = file->GetRoot();
-    SetParameters(rootElem);
-}
-
-void Texture::SetParameters(const XMLElement& elem)
-{
-    XMLElement paramElem = elem.GetChild();
-    while (paramElem)
-    {
-        String name = paramElem.GetName();
-
-        if (name == "address")
-        {
-            String coord = paramElem.GetAttributeLower("coord");
-            if (coord.Length() >= 1)
-            {
-                TextureCoordinate coordIndex = (TextureCoordinate)(coord[0] - 'u');
-                String mode = paramElem.GetAttributeLower("mode");
-                SetAddressMode(coordIndex, (TextureAddressMode)GetStringListIndex(mode.CString(), addressModeNames, ADDRESS_WRAP));
-            }
-        }
-
-        if (name == "border")
-            SetBorderColor(paramElem.GetColor("color"));
-
-        if (name == "filter")
-        {
-            String mode = paramElem.GetAttributeLower("mode");
-            SetFilterMode((TextureFilterMode)GetStringListIndex(mode.CString(), filterModeNames, FILTER_DEFAULT));
-        }
-
-        if (name == "mipmap")
-            SetNumLevels(paramElem.GetBool("enable") ? 0 : 1);
-
-        if (name == "quality")
-        {
-            if (paramElem.HasAttribute("low"))
-                SetMipsToSkip(QUALITY_LOW, paramElem.GetInt("low"));
-            if (paramElem.HasAttribute("med"))
-                SetMipsToSkip(QUALITY_MEDIUM, paramElem.GetInt("med"));
-            if (paramElem.HasAttribute("medium"))
-                SetMipsToSkip(QUALITY_MEDIUM, paramElem.GetInt("medium"));
-            if (paramElem.HasAttribute("high"))
-                SetMipsToSkip(QUALITY_HIGH, paramElem.GetInt("high"));
-        }
-
-        if (name == "srgb")
-            SetSRGB(paramElem.GetBool("enable"));
-
-        paramElem = paramElem.GetNext();
-    }
-}
-
 unsigned Texture::GetSRGBFormat(unsigned format)
 {
 #ifndef GL_ES_VERSION_2_0
@@ -511,18 +306,4 @@ unsigned Texture::GetSRGBFormat(unsigned format)
 #endif
 }
 
-void Texture::CheckTextureBudget(StringHash type)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-    unsigned long long textureBudget = cache->GetMemoryBudget(type);
-    unsigned long long textureUse = cache->GetMemoryUse(type);
-    if (!textureBudget)
-        return;
-
-    // If textures are over the budget, they likely can not be freed directly as materials still refer to them.
-    // Therefore free unused materials first
-    if (textureUse > textureBudget)
-        cache->ReleaseResources(Material::GetTypeStatic());
-}
-
 }

+ 0 - 183
Source/Urho3D/Graphics/OpenGL/OGLTexture.h

@@ -1,183 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-#include "../../Math/Color.h"
-#include "../../Resource/Resource.h"
-
-namespace Urho3D
-{
-
-static const int MAX_TEXTURE_QUALITY_LEVELS = 3;
-
-class XMLElement;
-class XMLFile;
-
-/// Base class for texture resources.
-class URHO3D_API Texture : public Resource, public GPUObject
-{
-public:
-    /// Construct.
-    Texture(Context* context);
-    /// Destruct.
-    virtual ~Texture();
-
-    /// Set number of requested mip levels. Needs to be called before setting size.
-    void SetNumLevels(unsigned levels);
-    /// Set filtering mode.
-    void SetFilterMode(TextureFilterMode filter);
-    /// Set addressing mode by texture coordinate.
-    void SetAddressMode(TextureCoordinate coord, TextureAddressMode address);
-    /// Set shadow compare mode.
-    void SetShadowCompare(bool enable);
-    /// Set border color for border addressing mode.
-    void SetBorderColor(const Color& color);
-    /// Set sRGB sampling and writing mode.
-    void SetSRGB(bool enable);
-    /// Set backup texture to use when rendering to this texture.
-    void SetBackupTexture(Texture* texture);
-    /// Set mip levels to skip on a quality setting when loading. Ensures higher quality levels do not skip more.
-    void SetMipsToSkip(int quality, int toSkip);
-    /// Dirty the parameters.
-    void SetParametersDirty();
-    /// Update changed parameters to OpenGL. Called by Graphics when binding the texture.
-    void UpdateParameters();
-
-    /// Return texture's OpenGL target.
-    unsigned GetTarget() const { return target_; }
-
-    /// Return texture format.
-    unsigned GetFormat() const { return format_; }
-
-    /// Return whether the texture format is compressed.
-    bool IsCompressed() const;
-
-    /// Return number of mip levels.
-    unsigned GetLevels() const { return levels_; }
-
-    /// Return width.
-    int GetWidth() const { return width_; }
-
-    /// Return height.
-    int GetHeight() const { return height_; }
-
-    /// Return height.
-    int GetDepth() const { return depth_; }
-
-    /// Return whether parameters are dirty.
-    bool GetParametersDirty() const { return parametersDirty_; }
-
-    /// Return filtering mode.
-    TextureFilterMode GetFilterMode() const { return filterMode_; }
-
-    /// Return addressing mode by texture coordinate.
-    TextureAddressMode GetAddressMode(TextureCoordinate coord) const { return addressMode_[coord]; }
-
-    /// Return whether shadow compare is enabled.
-    bool GetShadowCompare() const { return shadowCompare_; }
-
-    /// Return border color.
-    const Color& GetBorderColor() const { return borderColor_; }
-
-    /// Return whether is using sRGB sampling and writing.
-    bool GetSRGB() const { return sRGB_; }
-
-    /// Return backup texture.
-    Texture* GetBackupTexture() const { return backupTexture_; }
-
-    /// Return mip levels to skip on a quality setting when loading.
-    int GetMipsToSkip(int quality) const;
-    /// Return mip level width, or 0 if level does not exist.
-    int GetLevelWidth(unsigned level) const;
-    /// Return mip level width, or 0 if level does not exist.
-    int GetLevelHeight(unsigned level) const;
-    /// Return mip level depth, or 0 if level does not exist.
-    int GetLevelDepth(unsigned level) const;
-
-    /// Return texture usage type.
-    TextureUsage GetUsage() const { return usage_; }
-
-    /// Return data size in bytes for a rectangular region.
-    unsigned GetDataSize(int width, int height) const;
-    /// Return data size in bytes for a volume region.
-    unsigned GetDataSize(int width, int height, int depth) const;
-    /// Return data size in bytes for a pixel or block row.
-    unsigned GetRowDataSize(int width) const;
-    /// Return number of image components required to receive pixel data from GetData(), or 0 for compressed images.
-    unsigned GetComponents() const;
-    /// Return the non-internal texture format corresponding to an OpenGL internal format.
-    static unsigned GetExternalFormat(unsigned format);
-    /// Return the data type corresponding to an OpenGL internal format.
-    static unsigned GetDataType(unsigned format);
-
-    /// Set additional parameters from an XML file.
-    void SetParameters(XMLFile* xml);
-    /// Set additional parameters from an XML element.
-    void SetParameters(const XMLElement& element);
-    /// Return the corresponding SRGB texture format if supported. If not supported, return format unchanged.
-    unsigned GetSRGBFormat(unsigned format);
-
-protected:
-    /// Check whether texture memory budget has been exceeded. Free unused materials in that case to release the texture references.
-    void CheckTextureBudget(StringHash type);
-
-    /// Create texture.
-    virtual bool Create() { return true; }
-
-    /// Texture usage type.
-    TextureUsage usage_;
-    /// OpenGL target.
-    unsigned target_;
-    /// Texture format.
-    unsigned format_;
-    /// Current mip levels.
-    unsigned levels_;
-    /// Requested mip levels.
-    unsigned requestedLevels_;
-    /// Texture width.
-    int width_;
-    /// Texture height.
-    int height_;
-    /// Texture depth.
-    int depth_;
-    /// Shadow compare mode.
-    bool shadowCompare_;
-    /// Parameters dirty flag.
-    bool parametersDirty_;
-    /// Filtering mode.
-    TextureFilterMode filterMode_;
-    /// Addressing mode.
-    TextureAddressMode addressMode_[MAX_COORDS];
-    /// Mip levels to skip when loading per texture quality setting.
-    unsigned mipsToSkip_[MAX_TEXTURE_QUALITY_LEVELS];
-    /// Border color.
-    Color borderColor_;
-    /// sRGB sampling and writing mode flag.
-    bool sRGB_;
-    /// Backup texture.
-    SharedPtr<Texture> backupTexture_;
-};
-
-}

+ 10 - 135
Source/Urho3D/Graphics/OpenGL/OGLTexture2D.cpp

@@ -39,74 +39,6 @@
 namespace Urho3D
 {
 
-Texture2D::Texture2D(Context* context) :
-    Texture(context)
-{
-    target_ = GL_TEXTURE_2D;
-}
-
-Texture2D::~Texture2D()
-{
-    Release();
-}
-
-void Texture2D::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Texture2D>();
-}
-
-bool Texture2D::BeginLoad(Deserializer& source)
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If device is lost, retry later
-    if (graphics_->IsDeviceLost())
-    {
-        URHO3D_LOGWARNING("Texture load while device is lost");
-        dataPending_ = true;
-        return true;
-    }
-
-    // Load the image data for EndLoad()
-    loadImage_ = new Image(context_);
-    if (!loadImage_->Load(source))
-    {
-        loadImage_.Reset();
-        return false;
-    }
-
-    // Precalculate mip levels if async loading
-    if (GetAsyncLoadState() == ASYNC_LOADING)
-        loadImage_->PrecalculateLevels();
-
-    // Load the optional parameters file
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-    String xmlName = ReplaceExtension(GetName(), ".xml");
-    loadParameters_ = cache->GetTempResource<XMLFile>(xmlName, false);
-
-    return true;
-}
-
-bool Texture2D::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_ || graphics_->IsDeviceLost())
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-    bool success = SetData(loadImage_);
-
-    loadImage_.Reset();
-    loadParameters_.Reset();
-
-    return success;
-}
-
 void Texture2D::OnDeviceLost()
 {
     GPUObject::OnDeviceLost();
@@ -117,14 +49,14 @@ void Texture2D::OnDeviceLost()
 
 void Texture2D::OnDeviceReset()
 {
-    if (!object_ || dataPending_)
+    if (!object_.name_ || dataPending_)
     {
         // If has a resource file, reload through the resource cache. Otherwise just recreate.
         ResourceCache* cache = GetSubsystem<ResourceCache>();
         if (cache->Exists(GetName()))
             dataLost_ = !cache->ReloadResource(this);
 
-        if (!object_)
+        if (!object_.name_)
         {
             Create();
             dataLost_ = true;
@@ -136,7 +68,7 @@ void Texture2D::OnDeviceReset()
 
 void Texture2D::Release()
 {
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_)
             return;
@@ -149,13 +81,13 @@ void Texture2D::Release()
                     graphics_->SetTexture(i, 0);
             }
 
-            glDeleteTextures(1, &object_);
+            glDeleteTextures(1, &object_.name_);
         }
 
         if (renderSurface_)
             renderSurface_->Release();
 
-        object_ = 0;
+        object_.name_ = 0;
     }
     else
     {
@@ -164,47 +96,11 @@ void Texture2D::Release()
     }
 }
 
-bool Texture2D::SetSize(int width, int height, unsigned format, TextureUsage usage)
-{
-    if (width <= 0 || height <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative texture dimensions");
-        return false;
-    }
-
-    // Delete the old rendersurface if any
-    renderSurface_.Reset();
-
-    usage_ = usage;
-
-    if (usage >= TEXTURE_RENDERTARGET)
-    {
-        renderSurface_ = new RenderSurface(this);
-
-        // Clamp mode addressing by default, nearest filtering, and mipmaps disabled
-        addressMode_[COORD_U] = ADDRESS_CLAMP;
-        addressMode_[COORD_V] = ADDRESS_CLAMP;
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
-    }
-
-    if (usage == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(Texture2D, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
-
-    width_ = width;
-    height_ = height;
-    format_ = format;
-
-    return Create();
-}
-
 bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, const void* data)
 {
     URHO3D_PROFILE(SetTextureData);
 
-    if (!object_ || !graphics_)
+    if (!object_.name_ || !graphics_)
     {
         URHO3D_LOGERROR("No texture created, can not set data");
         return false;
@@ -336,7 +232,7 @@ bool Texture2D::SetData(Image* image, bool useAlpha)
         if (IsCompressed() && requestedLevels_ > 1)
             requestedLevels_ = 0;
         SetSize(levelWidth, levelHeight, format);
-        if (!object_)
+        if (!object_.name_)
             return false;
 
         for (unsigned i = 0; i < levels_; ++i)
@@ -403,7 +299,7 @@ bool Texture2D::SetData(Image* image, bool useAlpha)
 
 bool Texture2D::GetData(unsigned level, void* dest) const
 {
-    if (!object_ || !graphics_)
+    if (!object_.name_ || !graphics_)
     {
         URHO3D_LOGERROR("No texture created, can not get data");
         return false;
@@ -488,7 +384,7 @@ bool Texture2D::Create()
             return false;
     }
 
-    glGenTextures(1, &object_);
+    glGenTextures(1, &object_.name_);
 
     // Ensure that our texture is bound to OpenGL texture unit 0
     graphics_->SetTextureForUpdate(this);
@@ -508,17 +404,7 @@ bool Texture2D::Create()
     }
 
     // Set mipmapping
-    levels_ = requestedLevels_;
-    if (!levels_)
-    {
-        unsigned maxSize = Max((int)width_, (int)height_);
-        while (maxSize)
-        {
-            maxSize >>= 1;
-            ++levels_;
-        }
-    }
-
+    levels_ = CheckMaxLevels(width_, height_, requestedLevels_);
 #ifndef GL_ES_VERSION_2_0
     glTexParameteri(target_, GL_TEXTURE_BASE_LEVEL, 0);
     glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, levels_ - 1);
@@ -531,15 +417,4 @@ bool Texture2D::Create()
     return success;
 }
 
-void Texture2D::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    if (renderSurface_ && (renderSurface_->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurface_->IsUpdateQueued()))
-    {
-        Renderer* renderer = GetSubsystem<Renderer>();
-        if (renderer)
-            renderer->QueueRenderSurface(renderSurface_);
-        renderSurface_->ResetUpdateQueued();
-    }
-}
-
 }

+ 0 - 88
Source/Urho3D/Graphics/OpenGL/OGLTexture2D.h

@@ -1,88 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-
-namespace Urho3D
-{
-
-class Image;
-class XMLFile;
-
-/// 2D texture resource.
-class URHO3D_API Texture2D : public Texture
-{
-    URHO3D_OBJECT(Texture2D, Texture);
-
-public:
-    /// Construct.
-    Texture2D(Context* context);
-    /// Destruct.
-    virtual ~Texture2D();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Mark the GPU resource destroyed on context destruction.
-    virtual void OnDeviceLost();
-    /// Recreate the GPU resource and restore data if applicable.
-    virtual void OnDeviceReset();
-    /// Release the texture.
-    virtual void Release();
-
-    /// Set size, format and usage. Zero size will follow application window size. Return true if successful.
-    bool SetSize(int width, int height, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a mip level. Return true if successful.
-    bool SetData(unsigned level, int x, int y, int width, int height, const void* data);
-    /// Set data from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(Image* image, bool useAlpha = false);
-
-    /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(unsigned level, void* dest) const;
-
-    /// Return render surface.
-    RenderSurface* GetRenderSurface() const { return renderSurface_; }
-
-protected:
-    /// Create texture.
-    virtual bool Create();
-
-private:
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
-
-    /// Render surface.
-    SharedPtr<RenderSurface> renderSurface_;
-    /// Image file acquired during BeginLoad.
-    SharedPtr<Image> loadImage_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 11 - 185
Source/Urho3D/Graphics/OpenGL/OGLTexture2DArray.cpp

@@ -43,107 +43,6 @@
 namespace Urho3D
 {
 
-Texture2DArray::Texture2DArray(Context* context) :
-    Texture(context),
-    layers_(0)
-{
-#ifndef GL_ES_VERSION_2_0
-    target_ = GL_TEXTURE_2D_ARRAY;
-#else
-    target_ = 0;
-#endif
-}
-
-Texture2DArray::~Texture2DArray()
-{
-    Release();
-}
-
-void Texture2DArray::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Texture2DArray>();
-}
-
-bool Texture2DArray::BeginLoad(Deserializer& source)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If device is lost, retry later
-    if (graphics_->IsDeviceLost())
-    {
-        URHO3D_LOGWARNING("Texture load while device is lost");
-        dataPending_ = true;
-        return true;
-    }
-
-    cache->ResetDependencies(this);
-
-    String texPath, texName, texExt;
-    SplitPath(GetName(), texPath, texName, texExt);
-
-    loadParameters_ = (new XMLFile(context_));
-    if (!loadParameters_->Load(source))
-    {
-        loadParameters_.Reset();
-        return false;
-    }
-
-    loadImages_.Clear();
-
-    XMLElement textureElem = loadParameters_->GetRoot();
-    XMLElement layerElem = textureElem.GetChild("layer");
-    while (layerElem)
-    {
-        String name = layerElem.GetAttribute("name");
-
-        // If path is empty, add the XML file path
-        if (GetPath(name).Empty())
-            name = texPath + name;
-
-        loadImages_.Push(cache->GetTempResource<Image>(name));
-        cache->StoreResourceDependency(this, name);
-
-        layerElem = layerElem.GetNext("layer");
-    }
-
-    // Precalculate mip levels if async loading
-    if (GetAsyncLoadState() == ASYNC_LOADING)
-    {
-        for (unsigned i = 0; i < loadImages_.Size(); ++i)
-        {
-            if (loadImages_[i])
-                loadImages_[i]->PrecalculateLevels();
-        }
-    }
-
-    return true;
-}
-
-bool Texture2DArray::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_ || graphics_->IsDeviceLost())
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-    SetLayers(loadImages_.Size());
-
-    for (unsigned i = 0; i < loadImages_.Size(); ++i)
-        SetData(i, loadImages_[i]);
-
-    loadImages_.Clear();
-    loadParameters_.Reset();
-
-    return true;
-}
-
 void Texture2DArray::OnDeviceLost()
 {
     GPUObject::OnDeviceLost();
@@ -154,14 +53,14 @@ void Texture2DArray::OnDeviceLost()
 
 void Texture2DArray::OnDeviceReset()
 {
-    if (!object_ || dataPending_)
+    if (!object_.name_ || dataPending_)
     {
         // If has a resource file, reload through the resource cache. Otherwise just recreate.
         ResourceCache* cache = GetSubsystem<ResourceCache>();
         if (cache->Exists(GetName()))
             dataLost_ = !cache->ReloadResource(this);
 
-        if (!object_)
+        if (!object_.name_)
         {
             Create();
             dataLost_ = true;
@@ -173,7 +72,7 @@ void Texture2DArray::OnDeviceReset()
 
 void Texture2DArray::Release()
 {
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_)
             return;
@@ -186,73 +85,21 @@ void Texture2DArray::Release()
                     graphics_->SetTexture(i, 0);
             }
 
-            glDeleteTextures(1, &object_);
+            glDeleteTextures(1, &object_.name_);
         }
 
         if (renderSurface_)
             renderSurface_->Release();
 
-        object_ = 0;
+        object_.name_ = 0;
     }
 }
 
-void Texture2DArray::SetLayers(unsigned layers)
-{
-    Release();
-
-    layers_ = layers;
-}
-
-bool Texture2DArray::SetSize(unsigned layers, int width, int height, unsigned format, TextureUsage usage)
-{
-    if (width <= 0 || height <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative texture array size");
-        return false;
-    }
-    if (usage == TEXTURE_DEPTHSTENCIL)
-    {
-        URHO3D_LOGERROR("Depth-stencil usage not supported for texture arrays");
-        return false;
-    }
-
-    // Delete the old rendersurface if any
-    renderSurface_.Reset();
-
-    usage_ = usage;
-
-    if (usage == TEXTURE_RENDERTARGET)
-    {
-        renderSurface_ = new RenderSurface(this);
-
-        // Nearest filtering and mipmaps disabled by default
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
-    }
-
-    if (usage == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(Texture2DArray, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
-
-    width_ = width;
-    height_ = height;
-    format_ = format;
-    if (layers)
-        layers_ = layers;
-
-    layerMemoryUse_.Resize(layers_);
-    for (unsigned i = 0; i < layers_; ++i)
-        layerMemoryUse_[i] = 0;
-
-    return Create();
-}
-
 bool Texture2DArray::SetData(unsigned layer, unsigned level, int x, int y, int width, int height, const void* data)
 {
     URHO3D_PROFILE(SetTextureData);
 
-    if (!object_ || !graphics_)
+    if (!object_.name_ || !graphics_)
     {
         URHO3D_LOGERROR("Texture array not created, can not set data");
         return false;
@@ -420,7 +267,7 @@ bool Texture2DArray::SetData(unsigned layer, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.name_)
             {
                 URHO3D_LOGERROR("Texture array layer 0 must be loaded first");
                 return false;
@@ -476,7 +323,7 @@ bool Texture2DArray::SetData(unsigned layer, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.name_)
             {
                 URHO3D_LOGERROR("Texture array layer 0 must be loaded first");
                 return false;
@@ -519,7 +366,7 @@ bool Texture2DArray::SetData(unsigned layer, Image* image, bool useAlpha)
 bool Texture2DArray::GetData(unsigned layer, unsigned level, void* dest) const
 {
 #ifndef GL_ES_VERSION_2_0
-    if (!object_ || !graphics_)
+    if (!object_.name_ || !graphics_)
     {
         URHO3D_LOGERROR("Texture array not created, can not get data");
         return false;
@@ -582,7 +429,7 @@ bool Texture2DArray::Create()
         return true;
     }
 
-    glGenTextures(1, &object_);
+    glGenTextures(1, &object_.name_);
 
     // Ensure that our texture is bound to OpenGL texture unit 0
     graphics_->SetTextureForUpdate(this);
@@ -604,17 +451,7 @@ bool Texture2DArray::Create()
         URHO3D_LOGERROR("Failed to create texture array");
 
     // Set mipmapping
-    levels_ = requestedLevels_;
-    if (!levels_)
-    {
-        unsigned maxSize = (unsigned)Max(width_, height_);
-        while (maxSize)
-        {
-            maxSize >>= 1;
-            ++levels_;
-        }
-    }
-
+    levels_ = CheckMaxLevels(width_, height_, requestedLevels_);
     glTexParameteri(target_, GL_TEXTURE_BASE_LEVEL, 0);
     glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, levels_ - 1);
 
@@ -626,15 +463,4 @@ bool Texture2DArray::Create()
 #endif
 }
 
-void Texture2DArray::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    if (renderSurface_ && (renderSurface_->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurface_->IsUpdateQueued()))
-    {
-        Renderer* renderer = GetSubsystem<Renderer>();
-        if (renderer)
-            renderer->QueueRenderSurface(renderSurface_);
-        renderSurface_->ResetUpdateQueued();
-    }
-}
-
 }

+ 0 - 97
Source/Urho3D/Graphics/OpenGL/OGLTexture2DArray.h

@@ -1,97 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-
-namespace Urho3D
-{
-
-class Deserializer;
-class Image;
-
-/// 2D texture array resource.
-class URHO3D_API Texture2DArray : public Texture
-{
-    URHO3D_OBJECT(Texture2DArray, Texture)
-
-public:
-    /// Construct.
-    Texture2DArray(Context* context);
-    /// Destruct.
-    virtual ~Texture2DArray();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Mark the GPU resource destroyed on context destruction.
-    virtual void OnDeviceLost();
-    /// Recreate the GPU resource and restore data if applicable.
-    virtual void OnDeviceReset();
-    /// Release the texture.
-    virtual void Release();
-
-    /// Set the number of layers in the texture. To be used before SetData.
-    void SetLayers(unsigned layers);
-    /// Set layers, size, format and usage. Set layers to zero to leave them unchanged. Return true if successful.
-    bool SetSize(unsigned layers, int width, int height, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a layer's mip level. Return true if successful.
-    bool SetData(unsigned layer, unsigned level, int x, int y, int width, int height, const void* data);
-    /// Set data of one layer from a stream. Return true if successful.
-    bool SetData(unsigned layer, Deserializer& source);
-    /// Set data of one layer from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(unsigned layer, Image* image, bool useAlpha = false);
-
-    // Return number of layers in the texture.
-    unsigned GetLayers() const { return layers_; }
-    /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(unsigned layer, unsigned level, void* dest) const;
-    /// Return render surface.
-    RenderSurface* GetRenderSurface() const { return renderSurface_; }
-
-protected:
-    /// Create texture array.
-    virtual bool Create();
-
-private:
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
-
-    /// Texture array layers number.
-    unsigned layers_;
-    /// Render surface.
-    SharedPtr<RenderSurface> renderSurface_;
-    /// Memory use per layer.
-    PODVector<unsigned> layerMemoryUse_;
-    /// Layer image files acquired during BeginLoad.
-    Vector<SharedPtr<Image> > loadImages_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 10 - 160
Source/Urho3D/Graphics/OpenGL/OGLTexture3D.cpp

@@ -39,123 +39,6 @@
 namespace Urho3D
 {
 
-Texture3D::Texture3D(Context* context) :
-    Texture(context)
-{
-#ifndef GL_ES_VERSION_2_0
-    target_ = GL_TEXTURE_3D;
-#else
-    target_ = 0;
-#endif
-}
-
-Texture3D::~Texture3D()
-{
-    Release();
-}
-
-void Texture3D::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Texture3D>();
-}
-
-bool Texture3D::BeginLoad(Deserializer& source)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If device is lost, retry later
-    if (graphics_->IsDeviceLost())
-    {
-        URHO3D_LOGWARNING("Texture load while device is lost");
-        dataPending_ = true;
-        return true;
-    }
-
-    String texPath, texName, texExt;
-    SplitPath(GetName(), texPath, texName, texExt);
-
-    cache->ResetDependencies(this);
-
-    loadParameters_ = new XMLFile(context_);
-    if (!loadParameters_->Load(source))
-    {
-        loadParameters_.Reset();
-        return false;
-    }
-
-    XMLElement textureElem = loadParameters_->GetRoot();
-    XMLElement volumeElem = textureElem.GetChild("volume");
-    XMLElement colorlutElem = textureElem.GetChild("colorlut");
-
-    if (volumeElem)
-    {
-        String name = volumeElem.GetAttribute("name");
-
-        String volumeTexPath, volumeTexName, volumeTexExt;
-        SplitPath(name, volumeTexPath, volumeTexName, volumeTexExt);
-        // If path is empty, add the XML file path
-        if (volumeTexPath.Empty())
-            name = texPath + name;
-
-        loadImage_ = cache->GetTempResource<Image>(name);
-        // Precalculate mip levels if async loading
-        if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING)
-            loadImage_->PrecalculateLevels();
-        cache->StoreResourceDependency(this, name);
-        return true;
-    }
-    else if (colorlutElem)
-    {
-        String name = colorlutElem.GetAttribute("name");
-
-        String colorlutTexPath, colorlutTexName, colorlutTexExt;
-        SplitPath(name, colorlutTexPath, colorlutTexName, colorlutTexExt);
-        // If path is empty, add the XML file path
-        if (colorlutTexPath.Empty())
-            name = texPath + name;
-
-        SharedPtr<File> file = GetSubsystem<ResourceCache>()->GetFile(name);
-        loadImage_ = new Image(context_);
-        if (!loadImage_->LoadColorLUT(*(file.Get())))
-        {
-            loadParameters_.Reset();
-            loadImage_.Reset();
-            return false;
-        }
-        // Precalculate mip levels if async loading
-        if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING)
-            loadImage_->PrecalculateLevels();
-        cache->StoreResourceDependency(this, name);
-        return true;
-    }
-
-    URHO3D_LOGERROR("Texture3D XML data for " + GetName() + " did not contain either volume or colorlut element");
-    return false;
-}
-
-
-bool Texture3D::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_ || graphics_->IsDeviceLost())
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-    bool success = SetData(loadImage_);
-
-    loadImage_.Reset();
-    loadParameters_.Reset();
-
-    return success;
-}
-
 void Texture3D::OnDeviceLost()
 {
     GPUObject::OnDeviceLost();
@@ -163,14 +46,14 @@ void Texture3D::OnDeviceLost()
 
 void Texture3D::OnDeviceReset()
 {
-    if (!object_ || dataPending_)
+    if (!object_.name_ || dataPending_)
     {
         // If has a resource file, reload through the resource cache. Otherwise just recreate.
         ResourceCache* cache = GetSubsystem<ResourceCache>();
         if (cache->Exists(GetName()))
             dataLost_ = !cache->ReloadResource(this);
 
-        if (!object_)
+        if (!object_.name_)
         {
             Create();
             dataLost_ = true;
@@ -182,7 +65,7 @@ void Texture3D::OnDeviceReset()
 
 void Texture3D::Release()
 {
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_ || graphics_->IsDeviceLost())
             return;
@@ -193,39 +76,16 @@ void Texture3D::Release()
                 graphics_->SetTexture(i, 0);
         }
 
-        glDeleteTextures(1, &object_);
-        object_ = 0;
-    }
-}
-
-bool Texture3D::SetSize(int width, int height, int depth, unsigned format, TextureUsage usage)
-{
-    if (width <= 0 || height <= 0 || depth <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative 3D texture dimensions");
-        return false;
-    }
-    if (usage >= TEXTURE_RENDERTARGET)
-    {
-        URHO3D_LOGERROR("Rendertarget or depth-stencil usage not supported for 3D textures");
-        return false;
+        glDeleteTextures(1, &object_.name_);
+        object_.name_ = 0;
     }
-
-    usage_ = usage;
-
-    width_ = width;
-    height_ = height;
-    depth_ = depth;
-    format_ = format;
-
-    return Create();
 }
 
 bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data)
 {
     URHO3D_PROFILE(SetTextureData);
 
-    if (!object_ || !graphics_)
+    if (!object_.name_ || !graphics_)
     {
         URHO3D_LOGERROR("No texture created, can not set data");
         return false;
@@ -364,7 +224,7 @@ bool Texture3D::SetData(Image* image, bool useAlpha)
         if (IsCompressed() && requestedLevels_ > 1)
             requestedLevels_ = 0;
         SetSize(levelWidth, levelHeight, levelDepth, format);
-        if (!object_)
+        if (!object_.name_)
             return false;
 
         for (unsigned i = 0; i < levels_; ++i)
@@ -435,7 +295,7 @@ bool Texture3D::SetData(Image* image, bool useAlpha)
 bool Texture3D::GetData(unsigned level, void* dest) const
 {
 #ifndef GL_ES_VERSION_2_0
-    if (!object_ || !graphics_)
+    if (!object_.name_ || !graphics_)
     {
         URHO3D_LOGERROR("No texture created, can not get data");
         return false;
@@ -495,7 +355,7 @@ bool Texture3D::Create()
     unsigned externalFormat = GetExternalFormat(format_);
     unsigned dataType = GetDataType(format_);
 
-    glGenTextures(1, &object_);
+    glGenTextures(1, &object_.name_);
 
     // Ensure that our texture is bound to OpenGL texture unit 0
     graphics_->SetTextureForUpdate(this);
@@ -515,17 +375,7 @@ bool Texture3D::Create()
     }
 
     // Set mipmapping
-    levels_ = requestedLevels_;
-    if (!levels_)
-    {
-        unsigned maxSize = (unsigned)Max(Max((int)width_, (int)height_), (int)depth_);
-        while (maxSize)
-        {
-            maxSize >>= 1;
-            ++levels_;
-        }
-    }
-
+    levels_ = CheckMaxLevels(width_, height_, depth_, requestedLevels_);
     glTexParameteri(target_, GL_TEXTURE_BASE_LEVEL, 0);
     glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, levels_ - 1);
 

+ 0 - 78
Source/Urho3D/Graphics/OpenGL/OGLTexture3D.h

@@ -1,78 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-#include "../../Resource/Image.h"
-
-namespace Urho3D
-{
-
-/// 3D texture resource.
-class URHO3D_API Texture3D : public Texture
-{
-    URHO3D_OBJECT(Texture3D, Texture);
-
-public:
-    /// Construct.
-    Texture3D(Context* context);
-    /// Destruct.
-    virtual ~Texture3D();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Mark the GPU resource destroyed on context destruction.
-    virtual void OnDeviceLost();
-    /// Recreate the GPU resource and restore data if applicable.
-    virtual void OnDeviceReset();
-    /// Release the texture.
-    virtual void Release();
-
-    /// Set size, format and usage. Zero size will follow application window size. Return true if successful.
-    bool SetSize(int width, int height, int depth, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a mip level. Return true if successful.
-    bool SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data);
-    /// Set data from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(Image* image, bool useAlpha = false);
-
-    /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(unsigned level, void* dest) const;
-
-protected:
-    /// Create texture.
-    virtual bool Create();
-
-private:
-    /// Image file acquired during BeginLoad.
-    SharedPtr<Image> loadImage_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 11 - 296
Source/Urho3D/Graphics/OpenGL/OGLTextureCube.cpp

@@ -43,219 +43,6 @@
 namespace Urho3D
 {
 
-static const char* cubeMapLayoutNames[] = {
-    "horizontal",
-    "horizontalnvidia",
-    "horizontalcross",
-    "verticalcross",
-    "blender",
-    0
-};
-
-static SharedPtr<Image> GetTileImage(Image* src, int tileX, int tileY, int tileWidth, int tileHeight)
-{
-    return SharedPtr<Image>(
-        src->GetSubimage(IntRect(tileX * tileWidth, tileY * tileHeight, (tileX + 1) * tileWidth, (tileY + 1) * tileHeight)));
-}
-
-TextureCube::TextureCube(Context* context) :
-    Texture(context)
-{
-    target_ = GL_TEXTURE_CUBE_MAP;
-
-    // Default to clamp mode addressing
-    addressMode_[COORD_U] = ADDRESS_CLAMP;
-    addressMode_[COORD_V] = ADDRESS_CLAMP;
-    addressMode_[COORD_W] = ADDRESS_CLAMP;
-
-    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-        faceMemoryUse_[i] = 0;
-}
-
-TextureCube::~TextureCube()
-{
-    Release();
-}
-
-void TextureCube::RegisterObject(Context* context)
-{
-    context->RegisterFactory<TextureCube>();
-}
-
-bool TextureCube::BeginLoad(Deserializer& source)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_)
-        return true;
-
-    // If device is lost, retry later
-    if (graphics_->IsDeviceLost())
-    {
-        URHO3D_LOGWARNING("Texture load while device is lost");
-        dataPending_ = true;
-        return true;
-    }
-
-    cache->ResetDependencies(this);
-
-    String texPath, texName, texExt;
-    SplitPath(GetName(), texPath, texName, texExt);
-
-    loadParameters_ = (new XMLFile(context_));
-    if (!loadParameters_->Load(source))
-    {
-        loadParameters_.Reset();
-        return false;
-    }
-
-    loadImages_.Clear();
-
-    XMLElement textureElem = loadParameters_->GetRoot();
-    XMLElement imageElem = textureElem.GetChild("image");
-    // Single image and multiple faces with layout
-    if (imageElem)
-    {
-        String name = imageElem.GetAttribute("name");
-        // If path is empty, add the XML file path
-        if (GetPath(name).Empty())
-            name = texPath + name;
-
-        SharedPtr<Image> image = cache->GetTempResource<Image>(name);
-        if (!image)
-            return false;
-
-        int faceWidth, faceHeight;
-        loadImages_.Resize(MAX_CUBEMAP_FACES);
-
-        if (image->IsCubemap())
-        {
-            loadImages_[FACE_POSITIVE_X] = image;
-            loadImages_[FACE_NEGATIVE_X] = loadImages_[FACE_POSITIVE_X]->GetNextSibling();
-            loadImages_[FACE_POSITIVE_Y] = loadImages_[FACE_NEGATIVE_X]->GetNextSibling();
-            loadImages_[FACE_NEGATIVE_Y] = loadImages_[FACE_POSITIVE_Y]->GetNextSibling();
-            loadImages_[FACE_POSITIVE_Z] = loadImages_[FACE_NEGATIVE_Y]->GetNextSibling();
-            loadImages_[FACE_NEGATIVE_Z] = loadImages_[FACE_POSITIVE_Z]->GetNextSibling();
-        }
-        else
-        {
-        
-            CubeMapLayout layout =
-                (CubeMapLayout)GetStringListIndex(imageElem.GetAttribute("layout").CString(), cubeMapLayoutNames, CML_HORIZONTAL);
-            
-            switch (layout)
-            {
-            case CML_HORIZONTAL:
-                faceWidth = image->GetWidth() / MAX_CUBEMAP_FACES;
-                faceHeight = image->GetHeight();
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 0, 0, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 2, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 3, 0, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 4, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 5, 0, faceWidth, faceHeight);
-                break;
-
-            case CML_HORIZONTALNVIDIA:
-                faceWidth = image->GetWidth() / MAX_CUBEMAP_FACES;
-                faceHeight = image->GetHeight();
-                for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-                    loadImages_[i] = GetTileImage(image, i, 0, faceWidth, faceHeight);
-                break;
-
-            case CML_HORIZONTALCROSS:
-                faceWidth = image->GetWidth() / 4;
-                faceHeight = image->GetHeight() / 3;
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 3, 1, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 1, 2, faceWidth, faceHeight);
-                break;
-
-            case CML_VERTICALCROSS:
-                faceWidth = image->GetWidth() / 3;
-                faceHeight = image->GetHeight() / 4;
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 1, 2, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 1, 3, faceWidth, faceHeight);
-                if (loadImages_[FACE_NEGATIVE_Z])
-                {
-                    loadImages_[FACE_NEGATIVE_Z]->FlipVertical();
-                    loadImages_[FACE_NEGATIVE_Z]->FlipHorizontal();
-                }
-                break;
-
-            case CML_BLENDER:
-                faceWidth = image->GetWidth() / 3;
-                faceHeight = image->GetHeight() / 2;
-                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 0, faceWidth, faceHeight);
-                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
-                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
-                break;
-            }
-        }
-    }
-    // Face per image
-    else
-    {
-        XMLElement faceElem = textureElem.GetChild("face");
-        while (faceElem)
-        {
-            String name = faceElem.GetAttribute("name");
-
-            // If path is empty, add the XML file path
-            if (GetPath(name).Empty())
-                name = texPath + name;
-
-            loadImages_.Push(cache->GetTempResource<Image>(name));
-            cache->StoreResourceDependency(this, name);
-
-            faceElem = faceElem.GetNext("face");
-        }
-    }
-
-    // Precalculate mip levels if async loading
-    if (GetAsyncLoadState() == ASYNC_LOADING)
-    {
-        for (unsigned i = 0; i < loadImages_.Size(); ++i)
-        {
-            if (loadImages_[i])
-                loadImages_[i]->PrecalculateLevels();
-        }
-    }
-
-    return true;
-}
-
-bool TextureCube::EndLoad()
-{
-    // In headless mode, do not actually load the texture, just return success
-    if (!graphics_ || graphics_->IsDeviceLost())
-        return true;
-
-    // If over the texture budget, see if materials can be freed to allow textures to be freed
-    CheckTextureBudget(GetTypeStatic());
-
-    SetParameters(loadParameters_);
-
-    for (unsigned i = 0; i < loadImages_.Size() && i < MAX_CUBEMAP_FACES; ++i)
-        SetData((CubeMapFace)i, loadImages_[i]);
-
-    loadImages_.Clear();
-    loadParameters_.Reset();
-
-    return true;
-}
-
 void TextureCube::OnDeviceLost()
 {
     GPUObject::OnDeviceLost();
@@ -269,14 +56,14 @@ void TextureCube::OnDeviceLost()
 
 void TextureCube::OnDeviceReset()
 {
-    if (!object_ || dataPending_)
+    if (!object_.name_ || dataPending_)
     {
         // If has a resource file, reload through the resource cache. Otherwise just recreate.
         ResourceCache* cache = GetSubsystem<ResourceCache>();
         if (cache->Exists(GetName()))
             dataLost_ = !cache->ReloadResource(this);
 
-        if (!object_)
+        if (!object_.name_)
         {
             Create();
             dataLost_ = true;
@@ -288,7 +75,7 @@ void TextureCube::OnDeviceReset()
 
 void TextureCube::Release()
 {
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_)
             return;
@@ -301,7 +88,7 @@ void TextureCube::Release()
                     graphics_->SetTexture(i, 0);
             }
 
-            glDeleteTextures(1, &object_);
+            glDeleteTextures(1, &object_.name_);
         }
 
         for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
@@ -310,62 +97,15 @@ void TextureCube::Release()
                 renderSurfaces_[i]->Release();
         }
 
-        object_ = 0;
-    }
-}
-
-bool TextureCube::SetSize(int size, unsigned format, TextureUsage usage)
-{
-    if (size <= 0)
-    {
-        URHO3D_LOGERROR("Zero or negative cube texture size");
-        return false;
-    }
-    if (usage == TEXTURE_DEPTHSTENCIL)
-    {
-        URHO3D_LOGERROR("Depth-stencil usage not supported for cube maps");
-        return false;
-    }
-
-    // Delete the old rendersurfaces if any
-    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-    {
-        renderSurfaces_[i].Reset();
-        faceMemoryUse_[i] = 0;
-    }
-
-    usage_ = usage;
-
-    if (usage == TEXTURE_RENDERTARGET)
-    {
-        for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-        {
-            renderSurfaces_[i] = new RenderSurface(this);
-            renderSurfaces_[i]->SetTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i);
-        }
-
-        // Nearest filtering and mipmaps disabled by default
-        filterMode_ = FILTER_NEAREST;
-        requestedLevels_ = 1;
+        object_.name_ = 0;
     }
-
-    if (usage == TEXTURE_RENDERTARGET)
-        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(TextureCube, HandleRenderSurfaceUpdate));
-    else
-        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
-
-    width_ = size;
-    height_ = size;
-    format_ = format;
-
-    return Create();
 }
 
 bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int width, int height, const void* data)
 {
     URHO3D_PROFILE(SetTextureData);
 
-    if (!object_ || !graphics_)
+    if (!object_.name_ || !graphics_)
     {
         URHO3D_LOGERROR("No texture created, can not set data");
         return false;
@@ -522,7 +262,7 @@ bool TextureCube::SetData(CubeMapFace face, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.name_)
             {
                 URHO3D_LOGERROR("Cube texture face 0 must be loaded first");
                 return false;
@@ -584,7 +324,7 @@ bool TextureCube::SetData(CubeMapFace face, Image* image, bool useAlpha)
         }
         else
         {
-            if (!object_)
+            if (!object_.name_)
             {
                 URHO3D_LOGERROR("Cube texture face 0 must be loaded first");
                 return false;
@@ -625,7 +365,7 @@ bool TextureCube::SetData(CubeMapFace face, Image* image, bool useAlpha)
 
 bool TextureCube::GetData(CubeMapFace face, unsigned level, void* dest) const
 {
-    if (!object_ || !graphics_)
+    if (!object_.name_ || !graphics_)
     {
         URHO3D_LOGERROR("No texture created, can not get data");
         return false;
@@ -688,7 +428,7 @@ bool TextureCube::Create()
         return true;
     }
 
-    glGenTextures(1, &object_);
+    glGenTextures(1, &object_.name_);
 
     // Ensure that our texture is bound to OpenGL texture unit 0
     graphics_->SetTextureForUpdate(this);
@@ -713,17 +453,7 @@ bool TextureCube::Create()
         URHO3D_LOGERROR("Failed to create texture");
 
     // Set mipmapping
-    levels_ = requestedLevels_;
-    if (!levels_)
-    {
-        unsigned maxSize = (unsigned)Max(width_, height_);
-        while (maxSize)
-        {
-            maxSize >>= 1;
-            ++levels_;
-        }
-    }
-
+    levels_ = CheckMaxLevels(width_, height_, requestedLevels_);
 #ifndef GL_ES_VERSION_2_0
     glTexParameteri(target_, GL_TEXTURE_BASE_LEVEL, 0);
     glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, levels_ - 1);
@@ -736,19 +466,4 @@ bool TextureCube::Create()
     return success;
 }
 
-void TextureCube::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
-{
-    Renderer* renderer = GetSubsystem<Renderer>();
-
-    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
-    {
-        if (renderSurfaces_[i] && (renderSurfaces_[i]->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurfaces_[i]->IsUpdateQueued()))
-        {
-            if (renderer)
-                renderer->QueueRenderSurface(renderSurfaces_[i]);
-            renderSurfaces_[i]->ResetUpdateQueued();
-        }
-    }
-}
-
 }

+ 0 - 92
Source/Urho3D/Graphics/OpenGL/OGLTextureCube.h

@@ -1,92 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/Ptr.h"
-#include "../../Graphics/RenderSurface.h"
-#include "../../Graphics/Texture.h"
-
-namespace Urho3D
-{
-
-class Deserializer;
-class Image;
-
-/// Cube texture resource.
-class URHO3D_API TextureCube : public Texture
-{
-    URHO3D_OBJECT(TextureCube, Texture);
-
-public:
-    /// Construct.
-    TextureCube(Context* context);
-    /// Destruct.
-    virtual ~TextureCube();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource from stream. May be called from a worker thread. Return true if successful.
-    virtual bool BeginLoad(Deserializer& source);
-    /// Finish resource loading. Always called from the main thread. Return true if successful.
-    virtual bool EndLoad();
-    /// Mark the GPU resource destroyed on context destruction.
-    virtual void OnDeviceLost();
-    /// Recreate the GPU resource and restore data if applicable.
-    virtual void OnDeviceReset();
-    /// Release the texture.
-    virtual void Release();
-
-    /// Set size, format and usage. Return true if successful.
-    bool SetSize(int size, unsigned format, TextureUsage usage = TEXTURE_STATIC);
-    /// Set data either partially or fully on a face's mip level. Return true if successful.
-    bool SetData(CubeMapFace face, unsigned level, int x, int y, int width, int height, const void* data);
-    /// Set data of one face from a stream. Return true if successful.
-    bool SetData(CubeMapFace face, Deserializer& source);
-    /// Set data of one face from an image. Return true if successful. Optionally make a single channel image alpha-only.
-    bool SetData(CubeMapFace face, Image* image, bool useAlpha = false);
-
-    /// Get data from a face's mip level. The destination buffer must be big enough. Return true if successful.
-    bool GetData(CubeMapFace face, unsigned level, void* dest) const;
-
-    /// Return render surface for one face.
-    RenderSurface* GetRenderSurface(CubeMapFace face) const { return renderSurfaces_[face]; }
-
-protected:
-    /// Create texture.
-    virtual bool Create();
-
-private:
-    /// Handle render surface update event.
-    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
-
-    /// Render surfaces.
-    SharedPtr<RenderSurface> renderSurfaces_[MAX_CUBEMAP_FACES];
-    /// Memory use per face.
-    unsigned faceMemoryUse_[MAX_CUBEMAP_FACES];
-    /// Face image files acquired during BeginLoad.
-    Vector<SharedPtr<Image> > loadImages_;
-    /// Parameter file acquired during BeginLoad.
-    SharedPtr<XMLFile> loadParameters_;
-};
-
-}

+ 26 - 178
Source/Urho3D/Graphics/OpenGL/OGLVertexBuffer.cpp

@@ -32,33 +32,14 @@
 namespace Urho3D
 {
 
-VertexBuffer::VertexBuffer(Context* context, bool forceHeadless) :
-    Object(context),
-    GPUObject(forceHeadless ? (Graphics*)0 : GetSubsystem<Graphics>()),
-    vertexCount_(0),
-    elementMask_(0),
-    lockState_(LOCK_NONE),
-    lockStart_(0),
-    lockCount_(0),
-    lockScratchData_(0),
-    shadowed_(false),
-    dynamic_(false)
+void VertexBuffer::OnDeviceLost()
 {
-    UpdateOffsets();
-
-    // Force shadowing mode if graphics subsystem does not exist
-    if (!graphics_)
-        shadowed_ = true;
-}
-
-VertexBuffer::~VertexBuffer()
-{
-    Release();
+    GPUObject::OnDeviceLost();
 }
 
 void VertexBuffer::OnDeviceReset()
 {
-    if (!object_)
+    if (!object_.name_)
     {
         Create();
         dataLost_ = !UpdateToGPU();
@@ -73,7 +54,7 @@ void VertexBuffer::Release()
 {
     Unlock();
 
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_)
             return;
@@ -87,53 +68,13 @@ void VertexBuffer::Release()
             }
 
             graphics_->SetVBO(0);
-            glDeleteBuffers(1, &object_);
+            glDeleteBuffers(1, &object_.name_);
         }
 
-        object_ = 0;
-    }
-}
-
-void VertexBuffer::SetShadowed(bool enable)
-{
-    // If no graphics subsystem, can not disable shadowing
-    if (!graphics_)
-        enable = true;
-
-    if (enable != shadowed_)
-    {
-        if (enable && vertexSize_ && vertexCount_)
-            shadowData_ = new unsigned char[vertexCount_ * vertexSize_];
-        else
-            shadowData_.Reset();
-
-        shadowed_ = enable;
+        object_.name_ = 0;
     }
 }
 
-bool VertexBuffer::SetSize(unsigned vertexCount, unsigned elementMask, bool dynamic)
-{
-    return SetSize(vertexCount, GetElements(elementMask), dynamic);
-}
-
-bool VertexBuffer::SetSize(unsigned vertexCount, const PODVector<VertexElement>& elements, bool dynamic)
-{
-    Unlock();
-
-    vertexCount_ = vertexCount;
-    elements_ = elements;
-    dynamic_ = dynamic;
-
-    UpdateOffsets();
-
-    if (shadowed_ && vertexCount_ && vertexSize_)
-        shadowData_ = new unsigned char[vertexCount_ * vertexSize_];
-    else
-        shadowData_.Reset();
-
-    return Create();
-}
-
 bool VertexBuffer::SetData(const void* data)
 {
     if (!data)
@@ -151,11 +92,11 @@ bool VertexBuffer::SetData(const void* data)
     if (shadowData_ && data != shadowData_.Get())
         memcpy(shadowData_.Get(), data, vertexCount_ * vertexSize_);
 
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_->IsDeviceLost())
         {
-            graphics_->SetVBO(object_);
+            graphics_->SetVBO(object_.name_);
             glBufferData(GL_ARRAY_BUFFER, vertexCount_ * vertexSize_, data, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
         }
         else
@@ -198,11 +139,11 @@ bool VertexBuffer::SetDataRange(const void* data, unsigned start, unsigned count
     if (shadowData_ && shadowData_.Get() + start * vertexSize_ != data)
         memcpy(shadowData_.Get() + start * vertexSize_, data, count * vertexSize_);
 
-    if (object_)
+    if (object_.name_)
     {
         if (!graphics_->IsDeviceLost())
         {
-            graphics_->SetVBO(object_);
+            graphics_->SetVBO(object_.name_);
             if (!discard || start != 0)
                 glBufferSubData(GL_ARRAY_BUFFER, start * vertexSize_, count * vertexSize_, data);
             else
@@ -281,110 +222,6 @@ void VertexBuffer::Unlock()
     }
 }
 
-void VertexBuffer::UpdateOffsets()
-{
-    unsigned elementOffset = 0;
-    elementHash_ = 0;
-    elementMask_ = 0;
-
-    for (PODVector<VertexElement>::Iterator i = elements_.Begin(); i != elements_.End(); ++i)
-    {
-        i->offset_ = elementOffset;
-        elementOffset += ELEMENT_TYPESIZES[i->type_];
-        elementHash_ <<= 6;
-        elementHash_ += (((int)i->type_ + 1) * ((int)i->semantic_ + 1) + i->index_);
-
-        for (unsigned j = 0; j < MAX_LEGACY_VERTEX_ELEMENTS; ++j)
-        {
-            const VertexElement& legacy = LEGACY_VERTEXELEMENTS[j];
-            if (i->type_ == legacy.type_ && i->semantic_ == legacy.semantic_ && i->index_ == legacy.index_)
-                elementMask_ |= (1 << j);
-        }
-    }
-
-    vertexSize_ = elementOffset;
-}
-
-const VertexElement* VertexBuffer::GetElement(VertexElementSemantic semantic, unsigned char index) const
-{
-    for (PODVector<VertexElement>::ConstIterator i = elements_.Begin(); i != elements_.End(); ++i)
-    {
-        if (i->semantic_ == semantic && i->index_ == index)
-            return &(*i);
-    }
-
-    return 0;
-}
-
-const VertexElement* VertexBuffer::GetElement(VertexElementType type, VertexElementSemantic semantic, unsigned char index) const
-{
-    for (PODVector<VertexElement>::ConstIterator i = elements_.Begin(); i != elements_.End(); ++i)
-    {
-        if (i->type_ == type && i->semantic_ == semantic && i->index_ == index)
-            return &(*i);
-    }
-
-    return 0;
-}
-
-const VertexElement* VertexBuffer::GetElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
-{
-    for (PODVector<VertexElement>::ConstIterator i = elements.Begin(); i != elements.End(); ++i)
-    {
-        if (i->type_ == type && i->semantic_ == semantic && i->index_ == index)
-            return &(*i);
-    }
-
-    return 0;
-}
-
-bool VertexBuffer::HasElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
-{
-    return GetElement(elements, type, semantic, index) != 0;
-}
-
-unsigned VertexBuffer::GetElementOffset(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
-{
-    const VertexElement* element = GetElement(elements, type, semantic, index);
-    return element ? element->offset_ : M_MAX_UNSIGNED;
-}
-
-PODVector<VertexElement> VertexBuffer::GetElements(unsigned elementMask)
-{
-    PODVector<VertexElement> ret;
-
-    for (unsigned i = 0; i < MAX_LEGACY_VERTEX_ELEMENTS; ++i)
-    {
-        if (elementMask & (1 << i))
-            ret.Push(LEGACY_VERTEXELEMENTS[i]);
-    }
-
-    return ret;
-}
-
-unsigned VertexBuffer::GetVertexSize(const PODVector<VertexElement>& elements)
-{
-    unsigned size = 0;
-
-    for (unsigned i = 0; i < elements.Size(); ++i)
-        size += ELEMENT_TYPESIZES[elements[i].type_];
-
-    return size;
-}
-
-unsigned VertexBuffer::GetVertexSize(unsigned elementMask)
-{
-    unsigned size = 0;
-
-    for (unsigned i = 0; i < MAX_LEGACY_VERTEX_ELEMENTS; ++i)
-    {
-        if (elementMask & (1 << i))
-            size += ELEMENT_TYPESIZES[LEGACY_VERTEXELEMENTS[i].type_];
-    }
-
-    return size;
-}
-
 bool VertexBuffer::Create()
 {
     if (!vertexCount_ || !elementMask_)
@@ -401,15 +238,15 @@ bool VertexBuffer::Create()
             return true;
         }
 
-        if (!object_)
-            glGenBuffers(1, &object_);
-        if (!object_)
+        if (!object_.name_)
+            glGenBuffers(1, &object_.name_);
+        if (!object_.name_)
         {
             URHO3D_LOGERROR("Failed to create vertex buffer");
             return false;
         }
 
-        graphics_->SetVBO(object_);
+        graphics_->SetVBO(object_.name_);
         glBufferData(GL_ARRAY_BUFFER, vertexCount_ * vertexSize_, 0, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
     }
 
@@ -418,10 +255,21 @@ bool VertexBuffer::Create()
 
 bool VertexBuffer::UpdateToGPU()
 {
-    if (object_ && shadowData_)
+    if (object_.name_ && shadowData_)
         return SetData(shadowData_.Get());
     else
         return false;
 }
 
+void* VertexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
+{
+    // Never called on OpenGL
+    return 0;
+}
+
+void VertexBuffer::UnmapBuffer()
+{
+    // Never called on OpenGL
+}
+
 }

+ 0 - 163
Source/Urho3D/Graphics/OpenGL/OGLVertexBuffer.h

@@ -1,163 +0,0 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../../Container/ArrayPtr.h"
-#include "../../Graphics/GPUObject.h"
-#include "../../Graphics/GraphicsDefs.h"
-
-namespace Urho3D
-{
-
-/// Hardware vertex buffer.
-class URHO3D_API VertexBuffer : public Object, public GPUObject
-{
-    URHO3D_OBJECT(VertexBuffer, Object);
-
-public:
-    /// Construct.
-    VertexBuffer(Context* context, bool forceHeadless = false);
-    /// Destruct.
-    virtual ~VertexBuffer();
-
-    /// Recreate the GPU resource and restore data if applicable.
-    virtual void OnDeviceReset();
-    /// Release the buffer.
-    virtual void Release();
-
-    /// Enable shadowing in CPU memory. Shadowing is forced on if the graphics subsystem does not exist.
-    void SetShadowed(bool enable);
-    /// Set size, vertex elements and dynamic mode. Previous data will be lost.
-    bool SetSize(unsigned vertexCount, const PODVector<VertexElement>& elements, bool dynamic = false);
-    /// Set size and vertex elements and dynamic mode using legacy element bitmask. Previous data will be lost.
-    bool SetSize(unsigned vertexCount, unsigned elementMask, bool dynamic = false);
-    /// Set all data in the buffer.
-    bool SetData(const void* data);
-    /// Set a data range in the buffer. Optionally discard data outside the range.
-    bool SetDataRange(const void* data, unsigned start, unsigned count, bool discard = false);
-    /// Lock the buffer for write-only editing. Return data pointer if successful. Optionally discard data outside the range.
-    void* Lock(unsigned start, unsigned count, bool discard = false);
-    /// Unlock the buffer and apply changes to the GPU buffer.
-    void Unlock();
-
-    /// Return whether CPU memory shadowing is enabled.
-    bool IsShadowed() const { return shadowed_; }
-
-    /// Return whether is dynamic.
-    bool IsDynamic() const { return dynamic_; }
-
-    /// Return whether is currently locked.
-    bool IsLocked() const { return lockState_ != LOCK_NONE; }
-
-    /// Return number of vertices.
-    unsigned GetVertexCount() const { return vertexCount_; }
-
-    /// Return vertex size in bytes.
-    unsigned GetVertexSize() const { return vertexSize_; }
-
-    /// Return vertex elements.
-    const PODVector<VertexElement>& GetElements() const { return elements_; }
-
-    /// Return vertex element, or null if does not exist.
-    const VertexElement* GetElement(VertexElementSemantic semantic, unsigned char index = 0) const;
-
-    /// Return vertex element with specific type, or null if does not exist.
-    const VertexElement* GetElement(VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0) const;
-
-    /// Return whether has a specified element semantic.
-    bool HasElement(VertexElementSemantic semantic, unsigned char index = 0) const { return GetElement(semantic, index) != 0; }
-
-    /// Return whether has an element semantic with specific type.
-    bool HasElement(VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0) const { return GetElement(type, semantic, index) != 0; }
-
-    /// Return offset of a element within vertex, or M_MAX_UNSIGNED if does not exist.
-    unsigned GetElementOffset(VertexElementSemantic semantic, unsigned char index = 0) const { const VertexElement* element = GetElement(semantic, index); return element ? element->offset_ : M_MAX_UNSIGNED; }
-
-    /// Return offset of a element with specific type within vertex, or M_MAX_UNSIGNED if element does not exist.
-    unsigned GetElementOffset(VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0) const { const VertexElement* element = GetElement(type, semantic, index); return element ? element->offset_ : M_MAX_UNSIGNED; }
-
-    /// Return legacy vertex element mask. Note that both semantic and type must match the legacy element for a mask bit to be set.
-    unsigned GetElementMask() const { return elementMask_; }
-
-    /// Return CPU memory shadow data.
-    unsigned char* GetShadowData() const { return shadowData_.Get(); }
-
-    /// Return shared array pointer to the CPU memory shadow data.
-    SharedArrayPtr<unsigned char> GetShadowDataShared() const { return shadowData_; }
-
-    /// Return buffer hash for building vertex declarations. Used internally.
-    unsigned long long GetBufferHash(unsigned streamIndex) { return elementHash_ << (streamIndex * 16); }
-
-    /// Return element with specified type and semantic from a vertex element list, or null if does not exist.
-    static const VertexElement* GetElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0);
-
-    /// Return whether element list has a specified element type and semantic.
-    static bool HasElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0);
-
-    /// Return element offset for specified type and semantic from a vertex element list, or M_MAX_UNSIGNED if does not exist.
-    static unsigned GetElementOffset(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0);
-
-    /// Return a vertex element list from a legacy element bitmask.
-    static PODVector<VertexElement> GetElements(unsigned elementMask);
-
-    /// Return vertex size from an element list.
-    static unsigned GetVertexSize(const PODVector<VertexElement>& elements);
-
-    /// Return vertex size for a legacy vertex element bitmask.
-    static unsigned GetVertexSize(unsigned elementMask);
-
-private:
-    /// Update offsets of vertex elements.
-    void UpdateOffsets();
-    /// Create buffer.
-    bool Create();
-    /// Update the shadow data to the GPU buffer.
-    bool UpdateToGPU();
-
-    /// Shadow data.
-    SharedArrayPtr<unsigned char> shadowData_;
-    /// Number of vertices.
-    unsigned vertexCount_;
-    /// Vertex size.
-    unsigned vertexSize_;
-    /// Vertex elements.
-    PODVector<VertexElement> elements_;
-    /// Vertex element hash.
-    unsigned long long elementHash_;
-    /// Vertex element legacy bitmask.
-    unsigned elementMask_;
-    /// Buffer locking state.
-    LockState lockState_;
-    /// Lock start vertex.
-    unsigned lockStart_;
-    /// Lock number of vertices.
-    unsigned lockCount_;
-    /// Scratch buffer for fallback locking.
-    void* lockScratchData_;
-    /// Shadowed flag.
-    bool shadowed_;
-    /// Dynamic flag.
-    bool dynamic_;
-};
-
-}

+ 102 - 0
Source/Urho3D/Graphics/RenderSurface.cpp

@@ -0,0 +1,102 @@
+//
+// Copyright (c) 2008-2016 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "../Precompiled.h"
+
+#include "../Graphics/Camera.h"
+#include "../Graphics/Graphics.h"
+#include "../Graphics/GraphicsImpl.h"
+#include "../Graphics/Renderer.h"
+#include "../Graphics/RenderSurface.h"
+#include "../Graphics/Texture.h"
+
+#include "../DebugNew.h"
+
+namespace Urho3D
+{
+
+RenderSurface::~RenderSurface()
+{
+    Release();
+}
+
+void RenderSurface::SetNumViewports(unsigned num)
+{
+    viewports_.Resize(num);
+}
+
+void RenderSurface::SetViewport(unsigned index, Viewport* viewport)
+{
+    if (index >= viewports_.Size())
+        viewports_.Resize(index + 1);
+
+    viewports_[index] = viewport;
+}
+
+void RenderSurface::SetUpdateMode(RenderSurfaceUpdateMode mode)
+{
+    updateMode_ = mode;
+}
+
+void RenderSurface::SetLinkedRenderTarget(RenderSurface* renderTarget)
+{
+    if (renderTarget != this)
+        linkedRenderTarget_ = renderTarget;
+}
+
+void RenderSurface::SetLinkedDepthStencil(RenderSurface* depthStencil)
+{
+    if (depthStencil != this)
+        linkedDepthStencil_ = depthStencil;
+}
+
+void RenderSurface::QueueUpdate()
+{
+    updateQueued_ = true;
+}
+
+void RenderSurface::ResetUpdateQueued()
+{
+    updateQueued_ = false;
+}
+
+int RenderSurface::GetWidth() const
+{
+    return parentTexture_->GetWidth();
+}
+
+int RenderSurface::GetHeight() const
+{
+    return parentTexture_->GetHeight();
+}
+
+TextureUsage RenderSurface::GetUsage() const
+{
+    return parentTexture_->GetUsage();
+}
+
+Viewport* RenderSurface::GetViewport(unsigned index) const
+{
+    return index < viewports_.Size() ? viewports_[index] : (Viewport*)0;
+}
+
+}

+ 123 - 7
Source/Urho3D/Graphics/RenderSurface.h

@@ -22,10 +22,126 @@
 
 #pragma once
 
-#if defined(URHO3D_OPENGL)
-#include "OpenGL/OGLRenderSurface.h"
-#elif defined(URHO3D_D3D11)
-#include "Direct3D11/D3D11RenderSurface.h"
-#else
-#include "Direct3D9/D3D9RenderSurface.h"
-#endif
+#include "../Graphics/GraphicsDefs.h"
+#include "../Graphics/Viewport.h"
+
+namespace Urho3D
+{
+
+class Texture;
+
+/// %Color or depth-stencil surface that can be rendered into.
+class URHO3D_API RenderSurface : public RefCounted
+{
+    friend class Texture2D;
+    friend class Texture2DArray;
+    friend class TextureCube;
+
+public:
+    /// Construct with parent texture.
+    RenderSurface(Texture* parentTexture);
+    /// Destruct.
+    ~RenderSurface();
+
+    /// Set number of viewports.
+    void SetNumViewports(unsigned num);
+    /// Set viewport.
+    void SetViewport(unsigned index, Viewport* viewport);
+    /// Set viewport update mode. Default is to update when visible.
+    void SetUpdateMode(RenderSurfaceUpdateMode mode);
+    /// Set linked color rendertarget.
+    void SetLinkedRenderTarget(RenderSurface* renderTarget);
+    /// Set linked depth-stencil surface.
+    void SetLinkedDepthStencil(RenderSurface* depthStencil);
+    /// Queue manual update of the viewport(s).
+    void QueueUpdate();
+    /// Release surface.
+    void Release();
+    /// Mark the GPU resource destroyed on graphics context destruction. Only used on OpenGL.
+    void OnDeviceLost();
+    /// Create renderbuffer that cannot be sampled as a texture. Only used on OpenGL.
+    bool CreateRenderBuffer(unsigned width, unsigned height, unsigned format);
+
+    /// Return width.
+    int GetWidth() const;
+    
+    /// Return height.
+    int GetHeight() const;
+    
+    /// Return usage.
+    TextureUsage GetUsage() const;
+
+    /// Return number of viewports.
+    unsigned GetNumViewports() const { return viewports_.Size(); }
+
+    /// Return viewport by index.
+    Viewport* GetViewport(unsigned index) const;
+
+    /// Return viewport update mode.
+    RenderSurfaceUpdateMode GetUpdateMode() const { return updateMode_; }
+
+    /// Return linked color rendertarget.
+    RenderSurface* GetLinkedRenderTarget() const { return linkedRenderTarget_; }
+
+    /// Return linked depth-stencil surface.
+    RenderSurface* GetLinkedDepthStencil() const { return linkedDepthStencil_; }
+
+    /// Return whether manual update queued. Called internally.
+    bool IsUpdateQueued() const { return updateQueued_; }
+    
+    /// Reset update queued flag. Called internally.
+    void ResetUpdateQueued();
+
+    /// Return parent texture.
+    Texture* GetParentTexture() const { return parentTexture_; }
+
+    /// Return Direct3D9 surface.
+    void* GetSurface() const { return surface_; }
+
+    /// Return Direct3D11 rendertarget or depth-stencil view. Not valid on OpenGL.
+    void* GetRenderTargetView() const { return renderTargetView_; }
+
+    /// Return Direct3D11 read-only depth-stencil view. May be null if not applicable. Not valid on OpenGL.
+    void* GetReadOnlyView() const { return readOnlyView_; }
+
+    /// Return surface's OpenGL target.
+    unsigned GetTarget() const { return target_; }
+
+    /// Return OpenGL renderbuffer if created.
+    unsigned GetRenderBuffer() const { return renderBuffer_; }
+
+private:
+    /// Parent texture.
+    Texture* parentTexture_;
+
+    union
+    {
+        /// Direct3D9 surface.
+        void* surface_;
+        /// Direct3D11 rendertarget or depth-stencil view.
+        void* renderTargetView_;
+        /// OpenGL renderbuffer name.
+        unsigned renderBuffer_;
+    };
+
+    union
+    {
+        /// Direct3D11 read-only depth-stencil view. Present only on depth-stencil surfaces.
+        void* readOnlyView_;
+        /// OpenGL target.
+        unsigned target_;
+    };
+
+    /// Viewports.
+    Vector<SharedPtr<Viewport> > viewports_;
+    /// Linked color buffer.
+    WeakPtr<RenderSurface> linkedRenderTarget_;
+    /// Linked depth buffer.
+    WeakPtr<RenderSurface> linkedDepthStencil_;
+    /// Update mode for viewports.
+    RenderSurfaceUpdateMode updateMode_;
+    /// Update queued flag.
+    bool updateQueued_;
+};
+
+}

+ 2 - 0
Source/Urho3D/Graphics/ShaderProgram.h

@@ -22,6 +22,8 @@
 
 #pragma once
 
+// Note: ShaderProgram class is purposefully API-specific. It should not be used by Urho3D client applications.
+
 #if defined(URHO3D_OPENGL)
 #include "OpenGL/OGLShaderProgram.h"
 #elif defined(URHO3D_D3D11)

+ 61 - 59
Source/Urho3D/Graphics/Direct3D9/D3D9GPUObject.cpp → Source/Urho3D/Graphics/ShaderVariation.cpp

@@ -1,59 +1,61 @@
-//
-// Copyright (c) 2008-2016 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#include "../../Precompiled.h"
-
-#include "../../Graphics/Graphics.h"
-#include "../../Graphics/GPUObject.h"
-
-#include "../../DebugNew.h"
-
-namespace Urho3D
-{
-
-GPUObject::GPUObject(Graphics* graphics) :
-    graphics_(graphics),
-    object_(0),
-    dataLost_(false),
-    dataPending_(false)
-{
-    if (graphics_)
-        graphics->AddGPUObject(this);
-}
-
-GPUObject::~GPUObject()
-{
-    if (graphics_)
-        graphics_->RemoveGPUObject(this);
-}
-
-void GPUObject::ClearDataLost()
-{
-    dataLost_ = false;
-}
-
-Graphics* GPUObject::GetGraphics() const
-{
-    return graphics_;
-}
-
-}
+//
+// Copyright (c) 2008-2016 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "../Precompiled.h"
+
+#include "../Graphics/Graphics.h"
+#include "../Graphics/Shader.h"
+#include "../Graphics/ShaderVariation.h"
+
+#include "../DebugNew.h"
+
+namespace Urho3D
+{
+
+ShaderVariation::ShaderVariation(Shader* owner, ShaderType type) :
+    GPUObject(owner->GetSubsystem<Graphics>()),
+    owner_(owner),
+    type_(type),
+    elementHash_(0)
+{
+    for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
+        useTextureUnit_[i] = false;
+    for (unsigned i = 0; i < MAX_SHADER_PARAMETER_GROUPS; ++i)
+        constantBufferSizes_[i] = 0;
+}
+
+ShaderVariation::~ShaderVariation()
+{
+    Release();
+}
+
+void ShaderVariation::SetName(const String& name)
+{
+    name_ = name;
+}
+
+Shader* ShaderVariation::GetOwner() const
+{
+    return owner_;
+}
+
+}

+ 152 - 7
Source/Urho3D/Graphics/ShaderVariation.h

@@ -22,10 +22,155 @@
 
 #pragma once
 
-#if defined(URHO3D_OPENGL)
-#include "OpenGL/OGLShaderVariation.h"
-#elif defined(URHO3D_D3D11)
-#include "Direct3D11/D3D11ShaderVariation.h"
-#else
-#include "Direct3D9/D3D9ShaderVariation.h"
-#endif
+#include "../Container/HashMap.h"
+#include "../Container/RefCounted.h"
+#include "../Container/ArrayPtr.h"
+#include "../Graphics/GPUObject.h"
+#include "../Graphics/GraphicsDefs.h"
+
+namespace Urho3D
+{
+
+class ConstantBuffer;
+class Shader;
+
+/// %Shader parameter definition.
+struct ShaderParameter
+{
+    /// Construct with defaults.
+    ShaderParameter() :
+        bufferPtr_(0)
+    {
+    }
+
+    /// %Shader type.
+    ShaderType type_;
+    /// Name of the parameter.
+    String name_;
+
+    union
+    {
+        /// Offset in constant buffer.
+        unsigned offset_;
+        /// OpenGL uniform location.
+        int location_;
+        /// Direct3D9 register index.
+        unsigned register_;
+    };
+
+    union
+    {
+        /// Parameter size. Used only on Direct3D11 to calculate constant buffer size.
+        unsigned size_;
+        /// Parameter OpenGL type.
+        unsigned glType_;
+        /// Number of registers on Direct3D9.
+        unsigned regCount_;
+    };
+
+    /// Constant buffer index. Only used on Direct3D11.
+    unsigned buffer_;
+    /// Constant buffer pointer. Defined only in shader programs.
+    ConstantBuffer* bufferPtr_;
+};
+
+/// Vertex or pixel shader on the GPU.
+class URHO3D_API ShaderVariation : public RefCounted, public GPUObject
+{
+public:
+    /// Construct.
+    ShaderVariation(Shader* owner, ShaderType type);
+    /// Destruct.
+    virtual ~ShaderVariation();
+
+    /// Mark the GPU resource destroyed on graphics context destruction.
+    virtual void OnDeviceLost();
+    /// Release the shader.
+    virtual void Release();
+
+    /// Compile the shader. Return true if successful.
+    bool Create();
+    /// Set name.
+    void SetName(const String& name);
+    /// Set defines.
+    void SetDefines(const String& defines);
+
+    /// Return the owner resource.
+    Shader* GetOwner() const;
+
+    /// Return shader type.
+    ShaderType GetShaderType() const { return type_; }
+
+    /// Return shader name.
+    const String& GetName() const { return name_; }
+
+    /// Return full shader name.
+    String GetFullName() const { return name_ + "(" + defines_ + ")"; }
+
+    /// Return whether uses a parameter. Not applicable on OpenGL, where this information is contained in ShaderProgram instead.
+    bool HasParameter(StringHash param) const { return parameters_.Contains(param); }
+
+    /// Return whether uses a texture unit (only for pixel shaders.) Not applicable on OpenGL, where this information is contained in ShaderProgram instead.
+    bool HasTextureUnit(TextureUnit unit) const { return useTextureUnit_[unit]; }
+
+    /// Return all parameter definitions. Not applicable on OpenGL, where this information is contained in ShaderProgram instead.
+    const HashMap<StringHash, ShaderParameter>& GetParameters() const { return parameters_; }
+
+    /// Return vertex element hash.
+    unsigned long long GetElementHash() const { return elementHash_; }
+
+    /// Return shader bytecode. Stored persistently on Direct3D11 only.
+    const PODVector<unsigned char>& GetByteCode() const { return byteCode_; }
+
+    /// Return defines.
+    const String& GetDefines() const { return defines_; }
+
+    /// Return compile error/warning string.
+    const String& GetCompilerOutput() const { return compilerOutput_; }
+
+    /// Return constant buffer data sizes.
+    const unsigned* GetConstantBufferSizes() const { return &constantBufferSizes_[0]; }
+
+    /// Return defines with the CLIPPLANE define appended. Used internally on Direct3D11 only, will be empty on other APIs.
+    const String& GetDefinesClipPlane() { return definesClipPlane_; }
+
+    /// D3D11 vertex semantic names. Used internally.
+    static const char* elementSemanticNames[];
+
+private:
+    /// Load bytecode from a file. Return true if successful.
+    bool LoadByteCode(const String& binaryShaderName);
+    /// Compile from source. Return true if successful.
+    bool Compile();
+    /// Inspect the constant parameters and input layout (if applicable) from the shader bytecode.
+    void ParseParameters(unsigned char* bufData, unsigned bufSize);
+    /// Save bytecode to a file.
+    void SaveByteCode(const String& binaryShaderName);
+    /// Calculate constant buffer sizes from parameters.
+    void CalculateConstantBufferSizes();
+
+    /// Shader this variation belongs to.
+    WeakPtr<Shader> owner_;
+    /// Shader type.
+    ShaderType type_;
+    /// Vertex element hash for vertex shaders. Zero for pixel shaders. Note that hashing is different than vertex buffers.
+    unsigned long long elementHash_;
+    /// Shader parameters.
+    HashMap<StringHash, ShaderParameter> parameters_;
+    /// Texture unit use flags.
+    bool useTextureUnit_[MAX_TEXTURE_UNITS];
+    /// Constant buffer sizes. 0 if a constant buffer slot is not in use.
+    unsigned constantBufferSizes_[MAX_SHADER_PARAMETER_GROUPS];
+    /// Shader bytecode. Needed for inspecting the input signature and parameters. Not used on OpenGL.
+    PODVector<unsigned char> byteCode_;
+    /// Shader name.
+    String name_;
+    /// Defines to use in compiling.
+    String defines_;
+    /// Defines to use in compiling + CLIPPLANE define appended. Used only on Direct3D11.
+    String definesClipPlane_;
+    /// Shader compile error string.
+    String compilerOutput_;
+};
+
+}

+ 293 - 0
Source/Urho3D/Graphics/Texture.cpp

@@ -0,0 +1,293 @@
+//
+// Copyright (c) 2008-2016 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "../Precompiled.h"
+
+#include "../Graphics/Graphics.h"
+#include "../Graphics/GraphicsImpl.h"
+#include "../Graphics/Material.h"
+#include "../IO/FileSystem.h"
+#include "../IO/Log.h"
+#include "../Resource/ResourceCache.h"
+#include "../Resource/XMLFile.h"
+
+#include "../DebugNew.h"
+
+namespace Urho3D
+{
+
+static const char* addressModeNames[] =
+{
+    "wrap",
+    "mirror",
+    "clamp",
+    "border",
+    0
+};
+
+static const char* filterModeNames[] =
+{
+    "nearest",
+    "bilinear",
+    "trilinear",
+    "anisotropic",
+    "default",
+    0
+};
+
+Texture::Texture(Context* context) :
+    Resource(context),
+    GPUObject(GetSubsystem<Graphics>()),
+    shaderResourceView_(0),
+    sampler_(0),
+    format_(0),
+    usage_(TEXTURE_STATIC),
+    levels_(0),
+    requestedLevels_(0),
+    width_(0),
+    height_(0),
+    depth_(0),
+    shadowCompare_(false),
+    filterMode_(FILTER_DEFAULT),
+    sRGB_(false),
+    parametersDirty_(true)
+{
+    for (int i = 0; i < MAX_COORDS; ++i)
+        addressMode_[i] = ADDRESS_WRAP;
+    for (int i = 0; i < MAX_TEXTURE_QUALITY_LEVELS; ++i)
+        mipsToSkip_[i] = (unsigned)(MAX_TEXTURE_QUALITY_LEVELS - 1 - i);
+}
+
+Texture::~Texture()
+{
+}
+
+void Texture::SetNumLevels(unsigned levels)
+{
+    if (usage_ > TEXTURE_RENDERTARGET)
+        requestedLevels_ = 1;
+    else
+        requestedLevels_ = levels;
+}
+
+void Texture::SetFilterMode(TextureFilterMode mode)
+{
+    filterMode_ = mode;
+    parametersDirty_ = true;
+}
+
+void Texture::SetAddressMode(TextureCoordinate coord, TextureAddressMode mode)
+{
+    addressMode_[coord] = mode;
+    parametersDirty_ = true;
+}
+
+void Texture::SetShadowCompare(bool enable)
+{
+    shadowCompare_ = enable;
+    parametersDirty_ = true;
+}
+
+void Texture::SetBorderColor(const Color& color)
+{
+    borderColor_ = color;
+    parametersDirty_ = true;
+}
+
+void Texture::SetBackupTexture(Texture* texture)
+{
+    backupTexture_ = texture;
+}
+
+void Texture::SetMipsToSkip(int quality, int toSkip)
+{
+    if (quality >= QUALITY_LOW && quality < MAX_TEXTURE_QUALITY_LEVELS)
+    {
+        mipsToSkip_[quality] = (unsigned)toSkip;
+
+        // Make sure a higher quality level does not actually skip more mips
+        for (int i = 1; i < MAX_TEXTURE_QUALITY_LEVELS; ++i)
+        {
+            if (mipsToSkip_[i] > mipsToSkip_[i - 1])
+                mipsToSkip_[i] = mipsToSkip_[i - 1];
+        }
+    }
+}
+
+int Texture::GetMipsToSkip(int quality) const
+{
+    return (quality >= QUALITY_LOW && quality < MAX_TEXTURE_QUALITY_LEVELS) ? mipsToSkip_[quality] : 0;
+}
+
+int Texture::GetLevelWidth(unsigned level) const
+{
+    if (level > levels_)
+        return 0;
+    return Max(width_ >> level, 1);
+}
+
+int Texture::GetLevelHeight(unsigned level) const
+{
+    if (level > levels_)
+        return 0;
+    return Max(height_ >> level, 1);
+}
+
+int Texture::GetLevelDepth(unsigned level) const
+{
+    if (level > levels_)
+        return 0;
+    return Max(depth_ >> level, 1);
+}
+
+unsigned Texture::GetDataSize(int width, int height) const
+{
+    if (IsCompressed())
+        return GetRowDataSize(width) * ((height + 3) >> 2);
+    else
+        return GetRowDataSize(width) * height;
+}
+
+unsigned Texture::GetDataSize(int width, int height, int depth) const
+{
+    return depth * GetDataSize(width, height);
+}
+
+unsigned Texture::GetComponents() const
+{
+    if (!width_ || IsCompressed())
+        return 0;
+    else
+        return GetRowDataSize(width_) / width_;
+}
+
+void Texture::SetParameters(XMLFile* file)
+{
+    if (!file)
+        return;
+
+    XMLElement rootElem = file->GetRoot();
+    SetParameters(rootElem);
+}
+
+void Texture::SetParameters(const XMLElement& element)
+{
+    XMLElement paramElem = element.GetChild();
+    while (paramElem)
+    {
+        String name = paramElem.GetName();
+
+        if (name == "address")
+        {
+            String coord = paramElem.GetAttributeLower("coord");
+            if (coord.Length() >= 1)
+            {
+                TextureCoordinate coordIndex = (TextureCoordinate)(coord[0] - 'u');
+                String mode = paramElem.GetAttributeLower("mode");
+                SetAddressMode(coordIndex, (TextureAddressMode)GetStringListIndex(mode.CString(), addressModeNames, ADDRESS_WRAP));
+            }
+        }
+
+        if (name == "border")
+            SetBorderColor(paramElem.GetColor("color"));
+
+        if (name == "filter")
+        {
+            String mode = paramElem.GetAttributeLower("mode");
+            SetFilterMode((TextureFilterMode)GetStringListIndex(mode.CString(), filterModeNames, FILTER_DEFAULT));
+        }
+
+        if (name == "mipmap")
+            SetNumLevels(paramElem.GetBool("enable") ? 0 : 1);
+
+        if (name == "quality")
+        {
+            if (paramElem.HasAttribute("low"))
+                SetMipsToSkip(QUALITY_LOW, paramElem.GetInt("low"));
+            if (paramElem.HasAttribute("med"))
+                SetMipsToSkip(QUALITY_MEDIUM, paramElem.GetInt("med"));
+            if (paramElem.HasAttribute("medium"))
+                SetMipsToSkip(QUALITY_MEDIUM, paramElem.GetInt("medium"));
+            if (paramElem.HasAttribute("high"))
+                SetMipsToSkip(QUALITY_HIGH, paramElem.GetInt("high"));
+        }
+
+        if (name == "srgb")
+            SetSRGB(paramElem.GetBool("enable"));
+
+        paramElem = paramElem.GetNext();
+    }
+}
+
+void Texture::SetParametersDirty()
+{
+    parametersDirty_ = true;
+}
+
+unsigned Texture::CheckMaxLevels(int width, int height, unsigned requestedLevels)
+{
+    unsigned maxLevels = 1;
+    while (width > 1 || height > 1)
+    {
+        ++maxLevels;
+        width = width > 1 ? (width >> 1) : 1;
+        height = height > 1 ? (height >> 1) : 1;
+    }
+
+    if (!requestedLevels || maxLevels < requestedLevels)
+        return maxLevels;
+    else
+        return requestedLevels;
+}
+
+unsigned Texture::CheckMaxLevels(int width, int height, int depth, unsigned requestedLevels)
+{
+    unsigned maxLevels = 1;
+    while (width > 1 || height > 1 || depth > 1)
+    {
+        ++maxLevels;
+        width = width > 1 ? (width >> 1) : 1;
+        height = height > 1 ? (height >> 1) : 1;
+        depth = depth > 1 ? (depth >> 1) : 1;
+    }
+
+    if (!requestedLevels || maxLevels < requestedLevels)
+        return maxLevels;
+    else
+        return requestedLevels;
+}
+
+void Texture::CheckTextureBudget(StringHash type)
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    unsigned long long textureBudget = cache->GetMemoryBudget(type);
+    unsigned long long textureUse = cache->GetMemoryUse(type);
+    if (!textureBudget)
+        return;
+
+    // If textures are over the budget, they likely can not be freed directly as materials still refer to them.
+    // Therefore free unused materials first
+    if (textureUse > textureBudget)
+        cache->ReleaseResources(Material::GetTypeStatic());
+}
+
+}

+ 183 - 7
Source/Urho3D/Graphics/Texture.h

@@ -22,10 +22,186 @@
 
 #pragma once
 
-#if defined(URHO3D_OPENGL)
-#include "OpenGL/OGLTexture.h"
-#elif defined(URHO3D_D3D11)
-#include "Direct3D11/D3D11Texture.h"
-#else
-#include "Direct3D9/D3D9Texture.h"
-#endif
+#include "../Graphics/GPUObject.h"
+#include "../Graphics/GraphicsDefs.h"
+#include "../Math/Color.h"
+#include "../Resource/Resource.h"
+
+namespace Urho3D
+{
+
+static const int MAX_TEXTURE_QUALITY_LEVELS = 3;
+
+class XMLElement;
+class XMLFile;
+
+/// Base class for texture resources.
+class URHO3D_API Texture : public Resource, public GPUObject
+{
+public:
+    /// Construct.
+    Texture(Context* context);
+    /// Destruct.
+    virtual ~Texture();
+
+    /// Set number of requested mip levels. Needs to be called before setting size.
+    void SetNumLevels(unsigned levels);
+    /// Set filtering mode.
+    void SetFilterMode(TextureFilterMode filter);
+    /// Set addressing mode by texture coordinate.
+    void SetAddressMode(TextureCoordinate coord, TextureAddressMode address);
+    /// Set shadow compare mode. Not used on Direct3D9.
+    void SetShadowCompare(bool enable);
+    /// Set border color for border addressing mode.
+    void SetBorderColor(const Color& color);
+    /// Set sRGB sampling and writing mode.
+    void SetSRGB(bool enable);
+    /// Set backup texture to use when rendering to this texture.
+    void SetBackupTexture(Texture* texture);
+    /// Set mip levels to skip on a quality setting when loading. Ensures higher quality levels do not skip more.
+    void SetMipsToSkip(int quality, int toSkip);
+
+    /// Return API-specific texture format.
+    unsigned GetFormat() const { return format_; }
+
+    /// Return whether the texture format is compressed.
+    bool IsCompressed() const;
+
+    /// Return number of mip levels.
+    unsigned GetLevels() const { return levels_; }
+
+    /// Return width.
+    int GetWidth() const { return width_; }
+
+    /// Return height.
+    int GetHeight() const { return height_; }
+
+    /// Return height.
+    int GetDepth() const { return depth_; }
+
+    /// Return filtering mode.
+    TextureFilterMode GetFilterMode() const { return filterMode_; }
+
+    /// Return addressing mode by texture coordinate.
+    TextureAddressMode GetAddressMode(TextureCoordinate coord) const { return addressMode_[coord]; }
+
+    /// Return whether shadow compare is enabled. Not used on Direct3D9.
+    bool GetShadowCompare() const { return shadowCompare_; }
+
+    /// Return border color.
+    const Color& GetBorderColor() const { return borderColor_; }
+
+    /// Return whether is using sRGB sampling and writing.
+    bool GetSRGB() const { return sRGB_; }
+
+    /// Return backup texture.
+    Texture* GetBackupTexture() const { return backupTexture_; }
+
+    /// Return mip levels to skip on a quality setting when loading.
+    int GetMipsToSkip(int quality) const;
+    /// Return mip level width, or 0 if level does not exist.
+    int GetLevelWidth(unsigned level) const;
+    /// Return mip level width, or 0 if level does not exist.
+    int GetLevelHeight(unsigned level) const;
+    /// Return mip level depth, or 0 if level does not exist.
+    int GetLevelDepth(unsigned level) const;
+
+    /// Return texture usage type.
+    TextureUsage GetUsage() const { return usage_; }
+
+    /// Return data size in bytes for a rectangular region.
+    unsigned GetDataSize(int width, int height) const;
+    /// Return data size in bytes for a volume region.
+    unsigned GetDataSize(int width, int height, int depth) const;
+    /// Return data size in bytes for a pixel or block row.
+    unsigned GetRowDataSize(int width) const;
+    /// Return number of image components required to receive pixel data from GetData(), or 0 for compressed images.
+    unsigned GetComponents() const;
+
+    /// Return whether the parameters are dirty.
+    bool GetParametersDirty() const;
+
+    /// Set additional parameters from an XML file.
+    void SetParameters(XMLFile* xml);
+    /// Set additional parameters from an XML element.
+    void SetParameters(const XMLElement& element);
+    /// Mark parameters dirty. Called by Graphics.
+    void SetParametersDirty();
+    /// Update dirty parameters to the texture object. Called by Graphics when assigning the texture.
+    void UpdateParameters();
+
+    /// Return shader resource view. Only used on Direct3D11.
+    void* GetShaderResourceView() const { return shaderResourceView_; }
+
+    /// Return sampler state object. Only used on Direct3D11.
+    void* GetSampler() const { return sampler_; }
+
+    /// Return texture's target. Only used on OpenGL.
+    unsigned GetTarget() const { return target_; }
+
+    /// Convert format to sRGB. Not used on Direct3D9.
+    unsigned GetSRGBFormat(unsigned format);
+
+    /// Check maximum allowed mip levels for a specific texture size.
+    static unsigned CheckMaxLevels(int width, int height, unsigned requestedLevels);
+    /// Check maximum allowed mip levels for a specific 3D texture size.
+    static unsigned CheckMaxLevels(int width, int height, int depth, unsigned requestedLevels);
+    /// Return the shader resource view format corresponding to a texture format. Handles conversion of typeless depth texture formats. Only used on Direct3D11.
+    static unsigned GetSRVFormat(unsigned format);
+    /// Return the depth-stencil view format corresponding to a texture format. Handles conversion of typeless depth texture formats. Only used on Direct3D11.
+    static unsigned GetDSVFormat(unsigned format);
+    /// Return the non-internal texture format corresponding to an OpenGL internal format.
+    static unsigned GetExternalFormat(unsigned format);
+    /// Return the data type corresponding to an OpenGL internal format.
+    static unsigned GetDataType(unsigned format);
+
+protected:
+    /// Check whether texture memory budget has been exceeded. Free unused materials in that case to release the texture references.
+    void CheckTextureBudget(StringHash type);
+    /// Create the GPU texture. Implemented in subclasses.
+    virtual bool Create() { return true; }
+
+    union
+    {
+        /// Direct3D11 shader resource view.
+        void* shaderResourceView_;
+        /// OpenGL target.
+        unsigned target_;
+    };
+
+    /// Direct3D11 sampler state object.
+    void* sampler_;
+
+    /// Texture format.
+    unsigned format_;
+    /// Texture usage type.
+    TextureUsage usage_;
+    /// Current mip levels.
+    unsigned levels_;
+    /// Requested mip levels.
+    unsigned requestedLevels_;
+    /// Texture width.
+    int width_;
+    /// Texture height.
+    int height_;
+    /// Texture depth.
+    int depth_;
+    /// Shadow compare mode.
+    bool shadowCompare_;
+    /// Filtering mode.
+    TextureFilterMode filterMode_;
+    /// Addressing mode.
+    TextureAddressMode addressMode_[MAX_COORDS];
+    /// Mip levels to skip when loading per texture quality setting.
+    unsigned mipsToSkip_[MAX_TEXTURE_QUALITY_LEVELS];
+    /// Border color.
+    Color borderColor_;
+    /// sRGB sampling and writing mode flag.
+    bool sRGB_;
+    /// Parameters dirty flag.
+    bool parametersDirty_;
+    /// Backup texture.
+    SharedPtr<Texture> backupTexture_;
+};
+
+}

+ 159 - 0
Source/Urho3D/Graphics/Texture2D.cpp

@@ -0,0 +1,159 @@
+//
+// Copyright (c) 2008-2016 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rightsR
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "../Precompiled.h"
+
+#include "../Core/Context.h"
+#include "../Core/Profiler.h"
+#include "../Graphics/Graphics.h"
+#include "../Graphics/GraphicsEvents.h"
+#include "../Graphics/GraphicsImpl.h"
+#include "../Graphics/Renderer.h"
+#include "../Graphics/Texture2D.h"
+#include "../IO/FileSystem.h"
+#include "../IO/Log.h"
+#include "../Resource/ResourceCache.h"
+#include "../Resource/XMLFile.h"
+
+#include "../DebugNew.h"
+
+namespace Urho3D
+{
+
+Texture2D::Texture2D(Context* context) :
+    Texture(context)
+{
+#ifdef URHO3D_OPENGL
+    target_ = GL_TEXTURE_2D;
+#endif
+}
+
+Texture2D::~Texture2D()
+{
+    Release();
+}
+
+void Texture2D::RegisterObject(Context* context)
+{
+    context->RegisterFactory<Texture2D>();
+}
+
+bool Texture2D::BeginLoad(Deserializer& source)
+{
+    // In headless mode, do not actually load the texture, just return success
+    if (!graphics_)
+        return true;
+
+    // If device is lost, retry later
+    if (graphics_->IsDeviceLost())
+    {
+        URHO3D_LOGWARNING("Texture load while device is lost");
+        dataPending_ = true;
+        return true;
+    }
+
+    // Load the image data for EndLoad()
+    loadImage_ = new Image(context_);
+    if (!loadImage_->Load(source))
+    {
+        loadImage_.Reset();
+        return false;
+    }
+
+    // Precalculate mip levels if async loading
+    if (GetAsyncLoadState() == ASYNC_LOADING)
+        loadImage_->PrecalculateLevels();
+
+    // Load the optional parameters file
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    String xmlName = ReplaceExtension(GetName(), ".xml");
+    loadParameters_ = cache->GetTempResource<XMLFile>(xmlName, false);
+
+    return true;
+}
+
+bool Texture2D::EndLoad()
+{
+    // In headless mode, do not actually load the texture, just return success
+    if (!graphics_ || graphics_->IsDeviceLost())
+        return true;
+
+    // If over the texture budget, see if materials can be freed to allow textures to be freed
+    CheckTextureBudget(GetTypeStatic());
+
+    SetParameters(loadParameters_);
+    bool success = SetData(loadImage_);
+
+    loadImage_.Reset();
+    loadParameters_.Reset();
+
+    return success;
+}
+
+bool Texture2D::SetSize(int width, int height, unsigned format, TextureUsage usage)
+{
+    if (width <= 0 || height <= 0)
+    {
+        URHO3D_LOGERROR("Zero or negative texture dimensions");
+        return false;
+    }
+
+    // Delete the old rendersurface if any
+    renderSurface_.Reset();
+
+    usage_ = usage;
+    
+    if (usage >= TEXTURE_RENDERTARGET)
+    {
+        renderSurface_ = new RenderSurface(this);
+
+        // Clamp mode addressing by default, nearest filtering, and mipmaps disabled
+        addressMode_[COORD_U] = ADDRESS_CLAMP;
+        addressMode_[COORD_V] = ADDRESS_CLAMP;
+        filterMode_ = FILTER_NEAREST;
+        requestedLevels_ = 1;
+    }
+
+    if (usage == TEXTURE_RENDERTARGET)
+        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(Texture2D, HandleRenderSurfaceUpdate));
+    else
+        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
+
+    width_ = width;
+    height_ = height;
+    format_ = format;
+
+    return Create();
+}
+
+void Texture2D::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
+{
+    if (renderSurface_ && (renderSurface_->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurface_->IsUpdateQueued()))
+    {
+        Renderer* renderer = GetSubsystem<Renderer>();
+        if (renderer)
+            renderer->QueueRenderSurface(renderSurface_);
+        renderSurface_->ResetUpdateQueued();
+    }
+}
+
+}

+ 64 - 7
Source/Urho3D/Graphics/Texture2D.h

@@ -22,10 +22,67 @@
 
 #pragma once
 
-#if defined(URHO3D_OPENGL)
-#include "OpenGL/OGLTexture2D.h"
-#elif defined(URHO3D_D3D11)
-#include "Direct3D11/D3D11Texture2D.h"
-#else
-#include "Direct3D9/D3D9Texture2D.h"
-#endif
+#include "../Container/Ptr.h"
+#include "../Graphics/RenderSurface.h"
+#include "../Graphics/Texture.h"
+
+namespace Urho3D
+{
+
+class Image;
+class XMLFile;
+
+/// 2D texture resource.
+class URHO3D_API Texture2D : public Texture
+{
+    URHO3D_OBJECT(Texture2D, Texture);
+
+public:
+    /// Construct.
+    Texture2D(Context* context);
+    /// Destruct.
+    virtual ~Texture2D();
+    /// Register object factory.
+    static void RegisterObject(Context* context);
+
+    /// Load resource from stream. May be called from a worker thread. Return true if successful.
+    virtual bool BeginLoad(Deserializer& source);
+    /// Finish resource loading. Always called from the main thread. Return true if successful.
+    virtual bool EndLoad();
+    /// Mark the GPU resource destroyed on context destruction.
+    virtual void OnDeviceLost();
+    /// Recreate the GPU resource and restore data if applicable.
+    virtual void OnDeviceReset();
+    /// Release the texture.
+    virtual void Release();
+
+    /// Set size, format and usage. Zero size will follow application window size. Return true if successful.
+    bool SetSize(int width, int height, unsigned format, TextureUsage usage = TEXTURE_STATIC);
+    /// Set data either partially or fully on a mip level. Return true if successful.
+    bool SetData(unsigned level, int x, int y, int width, int height, const void* data);
+    /// Set data from an image. Return true if successful. Optionally make a single channel image alpha-only.
+    bool SetData(Image* image, bool useAlpha = false);
+
+    /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
+    bool GetData(unsigned level, void* dest) const;
+
+    /// Return render surface.
+    RenderSurface* GetRenderSurface() const { return renderSurface_; }
+
+protected:
+    /// Create the GPU texture.
+    virtual bool Create();
+
+private:
+    /// Handle render surface update event.
+    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
+
+    /// Render surface.
+    SharedPtr<RenderSurface> renderSurface_;
+    /// Image file acquired during BeginLoad.
+    SharedPtr<Image> loadImage_;
+    /// Parameter file acquired during BeginLoad.
+    SharedPtr<XMLFile> loadParameters_;
+};
+
+}

+ 212 - 0
Source/Urho3D/Graphics/Texture2DArray.cpp

@@ -0,0 +1,212 @@
+//
+// Copyright (c) 2008-2016 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "../Precompiled.h"
+
+#include "../Core/Context.h"
+#include "../Core/Profiler.h"
+#include "../Graphics/Graphics.h"
+#include "../Graphics/GraphicsEvents.h"
+#include "../Graphics/GraphicsImpl.h"
+#include "../Graphics/Renderer.h"
+#include "../Graphics/Texture2DArray.h"
+#include "../IO/FileSystem.h"
+#include "../IO/Log.h"
+#include "../Resource/ResourceCache.h"
+#include "../Resource/XMLFile.h"
+
+#include "../DebugNew.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable:4355)
+#endif
+
+namespace Urho3D
+{
+
+Texture2DArray::Texture2DArray(Context* context) :
+    Texture(context),
+    layers_(0)
+{
+#ifdef URHO3D_OPENGL
+#ifndef GL_ES_VERSION_2_0
+    target_ = GL_TEXTURE_2D_ARRAY;
+#else
+    target_ = 0;
+#endif
+#endif
+}
+
+Texture2DArray::~Texture2DArray()
+{
+    Release();
+}
+
+void Texture2DArray::RegisterObject(Context* context)
+{
+    context->RegisterFactory<Texture2DArray>();
+}
+
+bool Texture2DArray::BeginLoad(Deserializer& source)
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+
+    // In headless mode, do not actually load the texture, just return success
+    if (!graphics_)
+        return true;
+
+    // If device is lost, retry later
+    if (graphics_->IsDeviceLost())
+    {
+        URHO3D_LOGWARNING("Texture load while device is lost");
+        dataPending_ = true;
+        return true;
+    }
+
+    cache->ResetDependencies(this);
+
+    String texPath, texName, texExt;
+    SplitPath(GetName(), texPath, texName, texExt);
+
+    loadParameters_ = (new XMLFile(context_));
+    if (!loadParameters_->Load(source))
+    {
+        loadParameters_.Reset();
+        return false;
+    }
+
+    loadImages_.Clear();
+
+    XMLElement textureElem = loadParameters_->GetRoot();
+    XMLElement layerElem = textureElem.GetChild("layer");
+    while (layerElem)
+    {
+        String name = layerElem.GetAttribute("name");
+
+        // If path is empty, add the XML file path
+        if (GetPath(name).Empty())
+            name = texPath + name;
+
+        loadImages_.Push(cache->GetTempResource<Image>(name));
+        cache->StoreResourceDependency(this, name);
+
+        layerElem = layerElem.GetNext("layer");
+    }
+
+    // Precalculate mip levels if async loading
+    if (GetAsyncLoadState() == ASYNC_LOADING)
+    {
+        for (unsigned i = 0; i < loadImages_.Size(); ++i)
+        {
+            if (loadImages_[i])
+                loadImages_[i]->PrecalculateLevels();
+        }
+    }
+
+    return true;
+}
+
+bool Texture2DArray::EndLoad()
+{
+    // In headless mode, do not actually load the texture, just return success
+    if (!graphics_ || graphics_->IsDeviceLost())
+        return true;
+
+    // If over the texture budget, see if materials can be freed to allow textures to be freed
+    CheckTextureBudget(GetTypeStatic());
+
+    SetParameters(loadParameters_);
+    SetLayers(loadImages_.Size());
+
+    for (unsigned i = 0; i < loadImages_.Size(); ++i)
+        SetData(i, loadImages_[i]);
+
+    loadImages_.Clear();
+    loadParameters_.Reset();
+
+    return true;
+}
+
+void Texture2DArray::SetLayers(unsigned layers)
+{
+    Release();
+
+    layers_ = layers;
+}
+
+bool Texture2DArray::SetSize(unsigned layers, int width, int height, unsigned format, TextureUsage usage)
+{
+    if (width <= 0 || height <= 0)
+    {
+        URHO3D_LOGERROR("Zero or negative texture array size");
+        return false;
+    }
+    if (usage == TEXTURE_DEPTHSTENCIL)
+    {
+        URHO3D_LOGERROR("Depth-stencil usage not supported for texture arrays");
+        return false;
+    }
+
+    // Delete the old rendersurface if any
+    renderSurface_.Reset();
+
+    usage_ = usage;
+
+    if (usage == TEXTURE_RENDERTARGET)
+    {
+        renderSurface_ = new RenderSurface(this);
+
+        // Nearest filtering and mipmaps disabled by default
+        filterMode_ = FILTER_NEAREST;
+        requestedLevels_ = 1;
+    }
+
+    if (usage == TEXTURE_RENDERTARGET)
+        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(Texture2DArray, HandleRenderSurfaceUpdate));
+    else
+        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
+
+    width_ = width;
+    height_ = height;
+    format_ = format;
+    if (layers)
+        layers_ = layers;
+
+    layerMemoryUse_.Resize(layers_);
+    for (unsigned i = 0; i < layers_; ++i)
+        layerMemoryUse_[i] = 0;
+
+    return Create();
+}
+
+void Texture2DArray::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
+{
+    if (renderSurface_ && (renderSurface_->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurface_->IsUpdateQueued()))
+    {
+        Renderer* renderer = GetSubsystem<Renderer>();
+        if (renderer)
+            renderer->QueueRenderSurface(renderSurface_);
+        renderSurface_->ResetUpdateQueued();
+    }
+}
+
+}

+ 73 - 7
Source/Urho3D/Graphics/Texture2DArray.h

@@ -22,10 +22,76 @@
 
 #pragma once
 
-#if defined(URHO3D_OPENGL)
-#include "OpenGL/OGLTexture2DArray.h"
-#elif defined(URHO3D_D3D11)
-#include "Direct3D11/D3D11Texture2DArray.h"
-#else
-#include "Direct3D9/D3D9Texture2DArray.h"
-#endif
+#include "../Container/Ptr.h"
+#include "../Graphics/RenderSurface.h"
+#include "../Graphics/Texture.h"
+
+namespace Urho3D
+{
+
+class Deserializer;
+class Image;
+
+/// 2D texture array resource.
+class URHO3D_API Texture2DArray : public Texture
+{
+    URHO3D_OBJECT(Texture2DArray, Texture)
+
+public:
+    /// Construct.
+    Texture2DArray(Context* context);
+    /// Destruct.
+    virtual ~Texture2DArray();
+    /// Register object factory.
+    static void RegisterObject(Context* context);
+
+    /// Load resource from stream. May be called from a worker thread. Return true if successful.
+    virtual bool BeginLoad(Deserializer& source);
+    /// Finish resource loading. Always called from the main thread. Return true if successful.
+    virtual bool EndLoad();
+    /// Mark the GPU resource destroyed on context destruction.
+    virtual void OnDeviceLost();
+    /// Recreate the GPU resource and restore data if applicable.
+    virtual void OnDeviceReset();
+    /// Release the texture.
+    virtual void Release();
+
+    /// Set the number of layers in the texture. To be used before SetData.
+    void SetLayers(unsigned layers);
+    /// Set layers, size, format and usage. Set layers to zero to leave them unchanged. Return true if successful.
+    bool SetSize(unsigned layers, int width, int height, unsigned format, TextureUsage usage = TEXTURE_STATIC);
+    /// Set data either partially or fully on a layer's mip level. Return true if successful.
+    bool SetData(unsigned layer, unsigned level, int x, int y, int width, int height, const void* data);
+    /// Set data of one layer from a stream. Return true if successful.
+    bool SetData(unsigned layer, Deserializer& source);
+    /// Set data of one layer from an image. Return true if successful. Optionally make a single channel image alpha-only.
+    bool SetData(unsigned layer, Image* image, bool useAlpha = false);
+
+    // Return number of layers in the texture.
+    unsigned GetLayers() const { return layers_; }
+    /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
+    bool GetData(unsigned layer, unsigned level, void* dest) const;
+    /// Return render surface.
+    RenderSurface* GetRenderSurface() const { return renderSurface_; }
+
+protected:
+    /// Create the GPU texture.
+    virtual bool Create();
+
+private:
+    /// Handle render surface update event.
+    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
+
+    /// Texture array layers number.
+    unsigned layers_;
+    /// Render surface.
+    SharedPtr<RenderSurface> renderSurface_;
+    /// Memory use per layer.
+    PODVector<unsigned> layerMemoryUse_;
+    /// Layer image files acquired during BeginLoad.
+    Vector<SharedPtr<Image> > loadImages_;
+    /// Parameter file acquired during BeginLoad.
+    SharedPtr<XMLFile> loadParameters_;
+};
+
+}

+ 184 - 0
Source/Urho3D/Graphics/Texture3D.cpp

@@ -0,0 +1,184 @@
+//
+// Copyright (c) 2008-2016 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "../Precompiled.h"
+
+#include "../Core/Context.h"
+#include "../Core/Profiler.h"
+#include "../Graphics/Graphics.h"
+#include "../Graphics/GraphicsEvents.h"
+#include "../Graphics/GraphicsImpl.h"
+#include "../Graphics/Renderer.h"
+#include "../Graphics/Texture3D.h"
+#include "../IO/FileSystem.h"
+#include "../IO/Log.h"
+#include "../Resource/ResourceCache.h"
+#include "../Resource/XMLFile.h"
+
+#include "../DebugNew.h"
+
+namespace Urho3D
+{
+
+Texture3D::Texture3D(Context* context) :
+    Texture(context)
+{
+#ifdef URHO3D_OPENGL
+#ifndef GL_ES_VERSION_2_0
+    target_ = GL_TEXTURE_3D;
+#else
+    target_ = 0;
+#endif
+#endif
+}
+
+Texture3D::~Texture3D()
+{
+    Release();
+}
+
+void Texture3D::RegisterObject(Context* context)
+{
+    context->RegisterFactory<Texture3D>();
+}
+
+bool Texture3D::BeginLoad(Deserializer& source)
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+
+    // In headless mode, do not actually load the texture, just return success
+    if (!graphics_)
+        return true;
+
+    // If device is lost, retry later
+    if (graphics_->IsDeviceLost())
+    {
+        URHO3D_LOGWARNING("Texture load while device is lost");
+        dataPending_ = true;
+        return true;
+    }
+
+    String texPath, texName, texExt;
+    SplitPath(GetName(), texPath, texName, texExt);
+
+    cache->ResetDependencies(this);
+
+    loadParameters_ = new XMLFile(context_);
+    if (!loadParameters_->Load(source))
+    {
+        loadParameters_.Reset();
+        return false;
+    }
+
+    XMLElement textureElem = loadParameters_->GetRoot();
+    XMLElement volumeElem = textureElem.GetChild("volume");
+    XMLElement colorlutElem = textureElem.GetChild("colorlut");
+
+    if (volumeElem)
+    {
+        String name = volumeElem.GetAttribute("name");
+
+        String volumeTexPath, volumeTexName, volumeTexExt;
+        SplitPath(name, volumeTexPath, volumeTexName, volumeTexExt);
+        // If path is empty, add the XML file path
+        if (volumeTexPath.Empty())
+            name = texPath + name;
+
+        loadImage_ = cache->GetTempResource<Image>(name);
+        // Precalculate mip levels if async loading
+        if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING)
+            loadImage_->PrecalculateLevels();
+        cache->StoreResourceDependency(this, name);
+        return true;
+    }
+    else if (colorlutElem)
+    {
+        String name = colorlutElem.GetAttribute("name");
+
+        String colorlutTexPath, colorlutTexName, colorlutTexExt;
+        SplitPath(name, colorlutTexPath, colorlutTexName, colorlutTexExt);
+        // If path is empty, add the XML file path
+        if (colorlutTexPath.Empty())
+            name = texPath + name;
+
+        SharedPtr<File> file = GetSubsystem<ResourceCache>()->GetFile(name);
+        loadImage_ = new Image(context_);
+        if (!loadImage_->LoadColorLUT(*(file.Get())))
+        {
+            loadParameters_.Reset();
+            loadImage_.Reset();
+            return false;
+        }
+        // Precalculate mip levels if async loading
+        if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING)
+            loadImage_->PrecalculateLevels();
+        cache->StoreResourceDependency(this, name);
+        return true;
+    }
+
+    URHO3D_LOGERROR("Texture3D XML data for " + GetName() + " did not contain either volume or colorlut element");
+    return false;
+}
+
+
+bool Texture3D::EndLoad()
+{
+    // In headless mode, do not actually load the texture, just return success
+    if (!graphics_ || graphics_->IsDeviceLost())
+        return true;
+
+    // If over the texture budget, see if materials can be freed to allow textures to be freed
+    CheckTextureBudget(GetTypeStatic());
+
+    SetParameters(loadParameters_);
+    bool success = SetData(loadImage_);
+
+    loadImage_.Reset();
+    loadParameters_.Reset();
+
+    return success;
+}
+
+bool Texture3D::SetSize(int width, int height, int depth, unsigned format, TextureUsage usage)
+{
+    if (width <= 0 || height <= 0 || depth <= 0)
+    {
+        URHO3D_LOGERROR("Zero or negative 3D texture dimensions");
+        return false;
+    }
+    if (usage >= TEXTURE_RENDERTARGET)
+    {
+        URHO3D_LOGERROR("Rendertarget or depth-stencil usage not supported for 3D textures");
+        return false;
+    }
+
+    usage_ = usage;
+
+    width_ = width;
+    height_ = height;
+    depth_ = depth;
+    format_ = format;
+
+    return Create();
+}
+
+}

+ 54 - 7
Source/Urho3D/Graphics/Texture3D.h

@@ -22,10 +22,57 @@
 
 #pragma once
 
-#if defined(URHO3D_OPENGL)
-#include "OpenGL/OGLTexture3D.h"
-#elif defined(URHO3D_D3D11)
-#include "Direct3D11/D3D11Texture3D.h"
-#else
-#include "Direct3D9/D3D9Texture3D.h"
-#endif
+#include "../Container/Ptr.h"
+#include "../Graphics/RenderSurface.h"
+#include "../Graphics/Texture.h"
+#include "../Resource/Image.h"
+
+namespace Urho3D
+{
+
+/// 3D texture resource.
+class URHO3D_API Texture3D : public Texture
+{
+    URHO3D_OBJECT(Texture3D, Texture);
+
+public:
+    /// Construct.
+    Texture3D(Context* context);
+    /// Destruct.
+    virtual ~Texture3D();
+    /// Register object factory.
+    static void RegisterObject(Context* context);
+
+    /// Load resource from stream. May be called from a worker thread. Return true if successful.
+    virtual bool BeginLoad(Deserializer& source);
+    /// Finish resource loading. Always called from the main thread. Return true if successful.
+    virtual bool EndLoad();
+    /// Mark the GPU resource destroyed on context destruction.
+    virtual void OnDeviceLost();
+    /// Recreate the GPU resource and restore data if applicable.
+    virtual void OnDeviceReset();
+    /// Release the texture.
+    virtual void Release();
+
+    /// Set size, format and usage. Zero size will follow application window size. Return true if successful.
+    bool SetSize(int width, int height, int depth, unsigned format, TextureUsage usage = TEXTURE_STATIC);
+    /// Set data either partially or fully on a mip level. Return true if successful.
+    bool SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data);
+    /// Set data from an image. Return true if successful. Optionally make a single channel image alpha-only.
+    bool SetData(Image* image, bool useAlpha = false);
+
+    /// Get data from a mip level. The destination buffer must be big enough. Return true if successful.
+    bool GetData(unsigned level, void* dest) const;
+
+protected:
+    /// Create the GPU texture.
+    virtual bool Create();
+
+private:
+    /// Image file acquired during BeginLoad.
+    SharedPtr<Image> loadImage_;
+    /// Parameter file acquired during BeginLoad.
+    SharedPtr<XMLFile> loadParameters_;
+};
+
+}

+ 325 - 0
Source/Urho3D/Graphics/TextureCube.cpp

@@ -0,0 +1,325 @@
+//
+// Copyright (c) 2008-2016 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "../Precompiled.h"
+
+#include "../Core/Context.h"
+#include "../Core/Profiler.h"
+#include "../Graphics/Graphics.h"
+#include "../Graphics/GraphicsEvents.h"
+#include "../Graphics/GraphicsImpl.h"
+#include "../Graphics/Renderer.h"
+#include "../Graphics/TextureCube.h"
+#include "../IO/FileSystem.h"
+#include "../IO/Log.h"
+#include "../Resource/ResourceCache.h"
+#include "../Resource/XMLFile.h"
+
+#include "../DebugNew.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable:4355)
+#endif
+
+namespace Urho3D
+{
+
+static const char* cubeMapLayoutNames[] = {
+    "horizontal",
+    "horizontalnvidia",
+    "horizontalcross",
+    "verticalcross",
+    "blender",
+    0
+};
+
+static SharedPtr<Image> GetTileImage(Image* src, int tileX, int tileY, int tileWidth, int tileHeight)
+{
+    return SharedPtr<Image>(
+        src->GetSubimage(IntRect(tileX * tileWidth, tileY * tileHeight, (tileX + 1) * tileWidth, (tileY + 1) * tileHeight)));
+}
+
+TextureCube::TextureCube(Context* context) :
+    Texture(context)
+{
+#ifdef URHO3D_OPENGL
+    target_ = GL_TEXTURE_CUBE_MAP;
+#endif
+
+    // Default to clamp mode addressing
+    addressMode_[COORD_U] = ADDRESS_CLAMP;
+    addressMode_[COORD_V] = ADDRESS_CLAMP;
+    addressMode_[COORD_W] = ADDRESS_CLAMP;
+
+    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
+        faceMemoryUse_[i] = 0;
+}
+
+TextureCube::~TextureCube()
+{
+    Release();
+}
+
+void TextureCube::RegisterObject(Context* context)
+{
+    context->RegisterFactory<TextureCube>();
+}
+
+bool TextureCube::BeginLoad(Deserializer& source)
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+
+    // In headless mode, do not actually load the texture, just return success
+    if (!graphics_)
+        return true;
+
+    // If device is lost, retry later
+    if (graphics_->IsDeviceLost())
+    {
+        URHO3D_LOGWARNING("Texture load while device is lost");
+        dataPending_ = true;
+        return true;
+    }
+
+    cache->ResetDependencies(this);
+
+    String texPath, texName, texExt;
+    SplitPath(GetName(), texPath, texName, texExt);
+
+    loadParameters_ = (new XMLFile(context_));
+    if (!loadParameters_->Load(source))
+    {
+        loadParameters_.Reset();
+        return false;
+    }
+
+    loadImages_.Clear();
+
+    XMLElement textureElem = loadParameters_->GetRoot();
+    XMLElement imageElem = textureElem.GetChild("image");
+    // Single image and multiple faces with layout
+    if (imageElem)
+    {
+        String name = imageElem.GetAttribute("name");
+        // If path is empty, add the XML file path
+        if (GetPath(name).Empty())
+            name = texPath + name;
+
+        SharedPtr<Image> image = cache->GetTempResource<Image>(name);
+        if (!image)
+            return false;
+
+        int faceWidth, faceHeight;
+        loadImages_.Resize(MAX_CUBEMAP_FACES);
+
+        if (image->IsCubemap())
+        {
+            loadImages_[FACE_POSITIVE_X] = image;
+            loadImages_[FACE_NEGATIVE_X] = loadImages_[FACE_POSITIVE_X]->GetNextSibling();
+            loadImages_[FACE_POSITIVE_Y] = loadImages_[FACE_NEGATIVE_X]->GetNextSibling();
+            loadImages_[FACE_NEGATIVE_Y] = loadImages_[FACE_POSITIVE_Y]->GetNextSibling();
+            loadImages_[FACE_POSITIVE_Z] = loadImages_[FACE_NEGATIVE_Y]->GetNextSibling();
+            loadImages_[FACE_NEGATIVE_Z] = loadImages_[FACE_POSITIVE_Z]->GetNextSibling();
+        }
+        else
+        {
+        
+            CubeMapLayout layout =
+                (CubeMapLayout)GetStringListIndex(imageElem.GetAttribute("layout").CString(), cubeMapLayoutNames, CML_HORIZONTAL);
+            
+            switch (layout)
+            {
+            case CML_HORIZONTAL:
+                faceWidth = image->GetWidth() / MAX_CUBEMAP_FACES;
+                faceHeight = image->GetHeight();
+                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 0, 0, faceWidth, faceHeight);
+                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
+                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 2, 0, faceWidth, faceHeight);
+                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 3, 0, faceWidth, faceHeight);
+                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 4, 0, faceWidth, faceHeight);
+                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 5, 0, faceWidth, faceHeight);
+                break;
+
+            case CML_HORIZONTALNVIDIA:
+                faceWidth = image->GetWidth() / MAX_CUBEMAP_FACES;
+                faceHeight = image->GetHeight();
+                for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
+                    loadImages_[i] = GetTileImage(image, i, 0, faceWidth, faceHeight);
+                break;
+
+            case CML_HORIZONTALCROSS:
+                faceWidth = image->GetWidth() / 4;
+                faceHeight = image->GetHeight() / 3;
+                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
+                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
+                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
+                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
+                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 3, 1, faceWidth, faceHeight);
+                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 1, 2, faceWidth, faceHeight);
+                break;
+
+            case CML_VERTICALCROSS:
+                faceWidth = image->GetWidth() / 3;
+                faceHeight = image->GetHeight() / 4;
+                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
+                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
+                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
+                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
+                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 1, 2, faceWidth, faceHeight);
+                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 1, 3, faceWidth, faceHeight);
+                if (loadImages_[FACE_NEGATIVE_Z])
+                {
+                    loadImages_[FACE_NEGATIVE_Z]->FlipVertical();
+                    loadImages_[FACE_NEGATIVE_Z]->FlipHorizontal();
+                }
+                break;
+
+            case CML_BLENDER:
+                faceWidth = image->GetWidth() / 3;
+                faceHeight = image->GetHeight() / 2;
+                loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 0, faceWidth, faceHeight);
+                loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 1, 0, faceWidth, faceHeight);
+                loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 0, faceWidth, faceHeight);
+                loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 0, 1, faceWidth, faceHeight);
+                loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 1, faceWidth, faceHeight);
+                loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 2, 1, faceWidth, faceHeight);
+                break;
+            }
+        }
+    }
+    // Face per image
+    else
+    {
+        XMLElement faceElem = textureElem.GetChild("face");
+        while (faceElem)
+        {
+            String name = faceElem.GetAttribute("name");
+
+            // If path is empty, add the XML file path
+            if (GetPath(name).Empty())
+                name = texPath + name;
+
+            loadImages_.Push(cache->GetTempResource<Image>(name));
+            cache->StoreResourceDependency(this, name);
+
+            faceElem = faceElem.GetNext("face");
+        }
+    }
+
+    // Precalculate mip levels if async loading
+    if (GetAsyncLoadState() == ASYNC_LOADING)
+    {
+        for (unsigned i = 0; i < loadImages_.Size(); ++i)
+        {
+            if (loadImages_[i])
+                loadImages_[i]->PrecalculateLevels();
+        }
+    }
+
+    return true;
+}
+
+bool TextureCube::EndLoad()
+{
+    // In headless mode, do not actually load the texture, just return success
+    if (!graphics_ || graphics_->IsDeviceLost())
+        return true;
+
+    // If over the texture budget, see if materials can be freed to allow textures to be freed
+    CheckTextureBudget(GetTypeStatic());
+
+    SetParameters(loadParameters_);
+
+    for (unsigned i = 0; i < loadImages_.Size() && i < MAX_CUBEMAP_FACES; ++i)
+        SetData((CubeMapFace)i, loadImages_[i]);
+
+    loadImages_.Clear();
+    loadParameters_.Reset();
+
+    return true;
+}
+
+bool TextureCube::SetSize(int size, unsigned format, TextureUsage usage)
+{
+    if (size <= 0)
+    {
+        URHO3D_LOGERROR("Zero or negative cube texture size");
+        return false;
+    }
+    if (usage == TEXTURE_DEPTHSTENCIL)
+    {
+        URHO3D_LOGERROR("Depth-stencil usage not supported for cube maps");
+        return false;
+    }
+
+    // Delete the old rendersurfaces if any
+    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
+    {
+        renderSurfaces_[i].Reset();
+        faceMemoryUse_[i] = 0;
+    }
+
+    usage_ = usage;
+
+    if (usage == TEXTURE_RENDERTARGET)
+    {
+        for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
+        {
+            renderSurfaces_[i] = new RenderSurface(this);
+#ifdef URHO3D_OPENGL
+            renderSurfaces_[i]->target_ = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
+#endif
+        }
+
+        // Nearest filtering and mipmaps disabled by default
+        filterMode_ = FILTER_NEAREST;
+        requestedLevels_ = 1;
+    }
+
+    if (usage == TEXTURE_RENDERTARGET)
+        SubscribeToEvent(E_RENDERSURFACEUPDATE, URHO3D_HANDLER(TextureCube, HandleRenderSurfaceUpdate));
+    else
+        UnsubscribeFromEvent(E_RENDERSURFACEUPDATE);
+
+    width_ = size;
+    height_ = size;
+    format_ = format;
+
+    return Create();
+}
+
+void TextureCube::HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData)
+{
+    Renderer* renderer = GetSubsystem<Renderer>();
+
+    for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
+    {
+        if (renderSurfaces_[i] && (renderSurfaces_[i]->GetUpdateMode() == SURFACE_UPDATEALWAYS || renderSurfaces_[i]->IsUpdateQueued()))
+        {
+            if (renderer)
+                renderer->QueueRenderSurface(renderSurfaces_[i]);
+            renderSurfaces_[i]->ResetUpdateQueued();
+        }
+    }
+}
+
+}

+ 68 - 7
Source/Urho3D/Graphics/TextureCube.h

@@ -22,10 +22,71 @@
 
 #pragma once
 
-#if defined(URHO3D_OPENGL)
-#include "OpenGL/OGLTextureCube.h"
-#elif defined(URHO3D_D3D11)
-#include "Direct3D11/D3D11TextureCube.h"
-#else
-#include "Direct3D9/D3D9TextureCube.h"
-#endif
+#include "../Container/Ptr.h"
+#include "../Graphics/RenderSurface.h"
+#include "../Graphics/Texture.h"
+
+namespace Urho3D
+{
+
+class Deserializer;
+class Image;
+
+/// Cube texture resource.
+class URHO3D_API TextureCube : public Texture
+{
+    URHO3D_OBJECT(TextureCube, Texture);
+
+public:
+    /// Construct.
+    TextureCube(Context* context);
+    /// Destruct.
+    virtual ~TextureCube();
+    /// Register object factory.
+    static void RegisterObject(Context* context);
+
+    /// Load resource from stream. May be called from a worker thread. Return true if successful.
+    virtual bool BeginLoad(Deserializer& source);
+    /// Finish resource loading. Always called from the main thread. Return true if successful.
+    virtual bool EndLoad();
+    /// Mark the GPU resource destroyed on context destruction.
+    virtual void OnDeviceLost();
+    /// Recreate the GPU resource and restore data if applicable.
+    virtual void OnDeviceReset();
+    /// Release the texture.
+    virtual void Release();
+
+    /// Set size, format and usage. Return true if successful.
+    bool SetSize(int size, unsigned format, TextureUsage usage = TEXTURE_STATIC);
+    /// Set data either partially or fully on a face's mip level. Return true if successful.
+    bool SetData(CubeMapFace face, unsigned level, int x, int y, int width, int height, const void* data);
+    /// Set data of one face from a stream. Return true if successful.
+    bool SetData(CubeMapFace face, Deserializer& source);
+    /// Set data of one face from an image. Return true if successful. Optionally make a single channel image alpha-only.
+    bool SetData(CubeMapFace face, Image* image, bool useAlpha = false);
+
+    /// Get data from a face's mip level. The destination buffer must be big enough. Return true if successful.
+    bool GetData(CubeMapFace face, unsigned level, void* dest) const;
+
+    /// Return render surface for one face.
+    RenderSurface* GetRenderSurface(CubeMapFace face) const { return renderSurfaces_[face]; }
+
+protected:
+    /// Create the GPU texture.
+    virtual bool Create();
+
+private:
+    /// Handle render surface update event.
+    void HandleRenderSurfaceUpdate(StringHash eventType, VariantMap& eventData);
+
+    /// Render surfaces.
+    SharedPtr<RenderSurface> renderSurfaces_[MAX_CUBEMAP_FACES];
+    /// Memory use per face.
+    unsigned faceMemoryUse_[MAX_CUBEMAP_FACES];
+    /// Face image files acquired during BeginLoad.
+    Vector<SharedPtr<Image> > loadImages_;
+    /// Parameter file acquired during BeginLoad.
+    SharedPtr<XMLFile> loadParameters_;
+};
+
+}

Some files were not shown because too many files changed in this diff