Browse Source

Windows updates

JoshEngebretson 10 years ago
parent
commit
2e6c1e410d

+ 66 - 35
Source/Atomic/Graphics/Direct3D11/D3D11Graphics.cpp

@@ -305,6 +305,11 @@ Graphics::~Graphics()
         impl_->defaultDepthTexture_->Release();
         impl_->defaultDepthTexture_->Release();
         impl_->defaultDepthTexture_ = 0;
         impl_->defaultDepthTexture_ = 0;
     }
     }
+    if (impl_->resolveTexture_)
+    {
+        impl_->resolveTexture_->Release();
+        impl_->resolveTexture_ = 0;
+    }
     if (impl_->swapChain_)
     if (impl_->swapChain_)
     {
     {
         impl_->swapChain_->Release();
         impl_->swapChain_->Release();
@@ -619,21 +624,18 @@ bool Graphics::TakeScreenShot(Image* destImage)
     if (multiSample_ > 1)
     if (multiSample_ > 1)
     {
     {
         // If backbuffer is multisampled, need another DEFAULT usage texture to resolve the data to first
         // If backbuffer is multisampled, need another DEFAULT usage texture to resolve the data to first
-        textureDesc.Usage = D3D11_USAGE_DEFAULT;
-        textureDesc.CPUAccessFlags = 0;
-        ID3D11Texture2D* resolveTexture = 0;
+        CreateResolveTexture();
 
 
-        impl_->device_->CreateTexture2D(&textureDesc, 0, &resolveTexture);
-        if (!resolveTexture)
+        if (!impl_->resolveTexture_)
         {
         {
             LOGERROR("Could not create intermediate texture for multisampled screenshot");
             LOGERROR("Could not create intermediate texture for multisampled screenshot");
             stagingTexture->Release();
             stagingTexture->Release();
+            source->Release();
             return false;
             return false;
         }
         }
 
 
-        impl_->deviceContext_->ResolveSubresource(resolveTexture, 0, source, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
-        impl_->deviceContext_->CopyResource(stagingTexture, resolveTexture);
-        resolveTexture->Release();
+        impl_->deviceContext_->ResolveSubresource(impl_->resolveTexture_, 0, source, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
+        impl_->deviceContext_->CopyResource(stagingTexture, impl_->resolveTexture_);
     }
     }
     else
     else
         impl_->deviceContext_->CopyResource(stagingTexture, source);
         impl_->deviceContext_->CopyResource(stagingTexture, source);
@@ -795,41 +797,45 @@ bool Graphics::ResolveToTexture(Texture2D* destination, const IntRect& viewport)
     if (vpCopy.bottom_ <= vpCopy.top_)
     if (vpCopy.bottom_ <= vpCopy.top_)
         vpCopy.bottom_ = vpCopy.top_ + 1;
         vpCopy.bottom_ = vpCopy.top_ + 1;
 
 
-    RECT rect;
-    rect.left = Clamp(vpCopy.left_, 0, width_);
-    rect.top = Clamp(vpCopy.top_, 0, height_);
-    rect.right = Clamp(vpCopy.right_, 0, width_);
-    rect.bottom = Clamp(vpCopy.bottom_, 0, height_);
-
-    RECT destRect;
-    destRect.left = 0;
-    destRect.top = 0;
-    destRect.right = destination->GetWidth();
-    destRect.bottom = destination->GetHeight();
+    D3D11_BOX srcBox;
+    srcBox.left = Clamp(vpCopy.left_, 0, width_);
+    srcBox.top = Clamp(vpCopy.top_, 0, height_);
+    srcBox.right = Clamp(vpCopy.right_, 0, width_);
+    srcBox.bottom = Clamp(vpCopy.bottom_, 0, height_);
+    srcBox.front = 0;
+    srcBox.back = 1;
 
 
     ID3D11Resource* source = 0;
     ID3D11Resource* source = 0;
-    bool resolve = false;
-    bool needRelease = false;
+    bool resolve = multiSample_ > 1;
+    impl_->defaultRenderTargetView_->GetResource(&source);
 
 
-    if (renderTargets_[0])
-        source = (ID3D11Resource*)renderTargets_[0]->GetParentTexture()->GetGPUObject();
-    else
+    if (!resolve)
     {
     {
-        impl_->defaultRenderTargetView_->GetResource(&source);
-        resolve = multiSample_ > 1;
-        needRelease = true;
+        if (!srcBox.left && !srcBox.top && srcBox.right == width_ && srcBox.bottom == height_)
+            impl_->deviceContext_->CopyResource((ID3D11Resource*)destination->GetGPUObject(), source);
+        else
+            impl_->deviceContext_->CopySubresourceRegion((ID3D11Resource*)destination->GetGPUObject(), 0, 0, 0, 0, source, 0, &srcBox);
     }
     }
-
-    if (!resolve)
-        impl_->deviceContext_->CopyResource((ID3D11Resource*)destination->GetGPUObject(), source);
     else
     else
     {
     {
-        impl_->deviceContext_->ResolveSubresource((ID3D11Resource*)destination->GetGPUObject(), 0, source, 0, (DXGI_FORMAT)
-            destination->GetFormat());
+        if (!srcBox.left && !srcBox.top && srcBox.right == width_ && srcBox.bottom == height_)
+        {
+            impl_->deviceContext_->ResolveSubresource((ID3D11Resource*)destination->GetGPUObject(), 0, source, 0, (DXGI_FORMAT)
+                destination->GetFormat());
+        }
+        else
+        {
+            CreateResolveTexture();
+
+            if (impl_->resolveTexture_)
+            {
+                impl_->deviceContext_->ResolveSubresource(impl_->resolveTexture_, 0, source, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
+                impl_->deviceContext_->CopySubresourceRegion((ID3D11Resource*)destination->GetGPUObject(), 0, 0, 0, 0, impl_->resolveTexture_, 0, &srcBox);
+            }
+        }
     }
     }
 
 
-    if (needRelease)
-        source->Release();
+    source->Release();
 
 
     return true;
     return true;
 }
 }
@@ -1296,7 +1302,7 @@ bool Graphics::HasShaderParameter(StringHash param)
 
 
 bool Graphics::HasTextureUnit(TextureUnit unit)
 bool Graphics::HasTextureUnit(TextureUnit unit)
 {
 {
-    return pixelShader_ && pixelShader_->HasTextureUnit(unit);
+    return (vertexShader_ && vertexShader_->HasTextureUnit(unit)) || (pixelShader_ && pixelShader_->HasTextureUnit(unit));
 }
 }
 
 
 void Graphics::ClearParameterSource(ShaderParameterGroup group)
 void Graphics::ClearParameterSource(ShaderParameterGroup group)
@@ -2353,6 +2359,11 @@ bool Graphics::UpdateSwapChain(int width, int height)
         impl_->defaultDepthTexture_->Release();
         impl_->defaultDepthTexture_->Release();
         impl_->defaultDepthTexture_ = 0;
         impl_->defaultDepthTexture_ = 0;
     }
     }
+    if (impl_->resolveTexture_)
+    {
+        impl_->resolveTexture_->Release();
+        impl_->resolveTexture_ = 0;
+    }
 
 
     impl_->depthStencilView_ = 0;
     impl_->depthStencilView_ = 0;
     for (unsigned i = 0; i < MAX_RENDERTARGETS; ++i)
     for (unsigned i = 0; i < MAX_RENDERTARGETS; ++i)
@@ -2714,6 +2725,26 @@ void Graphics::PrepareDraw()
     dirtyConstantBuffers_.Clear();
     dirtyConstantBuffers_.Clear();
 }
 }
 
 
+void Graphics::CreateResolveTexture()
+{
+    if (impl_->resolveTexture_)
+        return;
+
+    D3D11_TEXTURE2D_DESC textureDesc;
+    memset(&textureDesc, 0, sizeof textureDesc);
+    textureDesc.Width = (UINT)width_;
+    textureDesc.Height = (UINT)height_;
+    textureDesc.MipLevels = 1;
+    textureDesc.ArraySize = 1;
+    textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+    textureDesc.SampleDesc.Count = 1;
+    textureDesc.SampleDesc.Quality = 0;
+    textureDesc.Usage = D3D11_USAGE_DEFAULT;
+    textureDesc.CPUAccessFlags = 0;
+
+    impl_->device_->CreateTexture2D(&textureDesc, 0, &impl_->resolveTexture_);
+}
+
 void Graphics::SetTextureUnitMappings()
 void Graphics::SetTextureUnitMappings()
 {
 {
     textureUnits_["DiffMap"] = TU_DIFFUSE;
     textureUnits_["DiffMap"] = TU_DIFFUSE;

+ 3 - 1
Source/Atomic/Graphics/Direct3D11/D3D11Graphics.h

@@ -175,7 +175,7 @@ public:
     bool NeedParameterUpdate(ShaderParameterGroup group, const void* source);
     bool NeedParameterUpdate(ShaderParameterGroup group, const void* source);
     /// Check whether a shader parameter exists on the currently set shaders.
     /// Check whether a shader parameter exists on the currently set shaders.
     bool HasShaderParameter(StringHash param);
     bool HasShaderParameter(StringHash param);
-    /// Check whether the current pixel shader uses a texture unit.
+    /// Check whether the current vertex or pixel shader uses a texture unit.
     bool HasTextureUnit(TextureUnit unit);
     bool HasTextureUnit(TextureUnit unit);
     /// Clear remembered shader parameter source group.
     /// Clear remembered shader parameter source group.
     void ClearParameterSource(ShaderParameterGroup group);
     void ClearParameterSource(ShaderParameterGroup group);
@@ -518,6 +518,8 @@ private:
     void SetTextureUnitMappings();
     void SetTextureUnitMappings();
     /// Process dirtied state before draw.
     /// Process dirtied state before draw.
     void PrepareDraw();
     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 for accessing the GPU objects vector from several threads.
     Mutex gpuObjectMutex_;
     Mutex gpuObjectMutex_;

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

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

+ 2 - 0
Source/Atomic/Graphics/Direct3D11/D3D11GraphicsImpl.h

@@ -78,6 +78,8 @@ private:
     HashMap<unsigned, ID3D11DepthStencilState*> depthStates_;
     HashMap<unsigned, ID3D11DepthStencilState*> depthStates_;
     /// Created rasterizer state objects.
     /// Created rasterizer state objects.
     HashMap<unsigned, ID3D11RasterizerState*> rasterizerStates_;
     HashMap<unsigned, ID3D11RasterizerState*> rasterizerStates_;
+    /// Intermediate texture for multisampled screenshots and less than whole viewport multisampled resolve, created on demand.
+    ID3D11Texture2D* resolveTexture_;
     /// Bound shader resource views.
     /// Bound shader resource views.
     ID3D11ShaderResourceView* shaderResourceViews_[MAX_TEXTURE_UNITS];
     ID3D11ShaderResourceView* shaderResourceViews_[MAX_TEXTURE_UNITS];
     /// Bound sampler state objects.
     /// Bound sampler state objects.

+ 1 - 1
Source/Atomic/Graphics/Direct3D11/D3D11ShaderVariation.cpp

@@ -366,7 +366,7 @@ void ShaderVariation::ParseParameters(unsigned char* bufData, unsigned bufSize)
         String resourceName(resourceDesc.Name);
         String resourceName(resourceDesc.Name);
         if (resourceDesc.Type == D3D_SIT_CBUFFER)
         if (resourceDesc.Type == D3D_SIT_CBUFFER)
             cbRegisterMap[resourceName] = resourceDesc.BindPoint;
             cbRegisterMap[resourceName] = resourceDesc.BindPoint;
-        else if (type_ == PS && resourceDesc.Type == D3D_SIT_SAMPLER && resourceDesc.BindPoint < MAX_TEXTURE_UNITS)
+        else if (resourceDesc.Type == D3D_SIT_SAMPLER && resourceDesc.BindPoint < MAX_TEXTURE_UNITS)
             useTextureUnit_[resourceDesc.BindPoint] = true;
             useTextureUnit_[resourceDesc.BindPoint] = true;
     }
     }
 
 

+ 68 - 54
Source/Atomic/Graphics/Direct3D11/D3D11TextureCube.cpp

@@ -113,8 +113,6 @@ bool TextureCube::BeginLoad(Deserializer& source)
         if (GetPath(name).Empty())
         if (GetPath(name).Empty())
             name = texPath + name;
             name = texPath + name;
 
 
-        CubeMapLayout layout =
-            (CubeMapLayout)GetStringListIndex(imageElem.GetAttribute("layout").CString(), cubeMapLayoutNames, CML_HORIZONTAL);
         SharedPtr<Image> image = cache->GetTempResource<Image>(name);
         SharedPtr<Image> image = cache->GetTempResource<Image>(name);
         if (!image)
         if (!image)
             return false;
             return false;
@@ -122,63 +120,79 @@ bool TextureCube::BeginLoad(Deserializer& source)
         int faceWidth, faceHeight;
         int faceWidth, faceHeight;
         loadImages_.Resize(MAX_CUBEMAP_FACES);
         loadImages_.Resize(MAX_CUBEMAP_FACES);
 
 
-        switch (layout)
+        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
         {
         {
-        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;
+            CubeMapLayout layout =
+                (CubeMapLayout)GetStringListIndex(imageElem.GetAttribute("layout").CString(), cubeMapLayoutNames, CML_HORIZONTAL);
 
 
-        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])
+            switch (layout)
             {
             {
-                loadImages_[FACE_NEGATIVE_Z]->FlipVertical();
-                loadImages_[FACE_NEGATIVE_Z]->FlipHorizontal();
+            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;
             }
             }
-            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
     // Face per image

+ 67 - 56
Source/Atomic/Graphics/Direct3D9/D3D9TextureCube.cpp

@@ -121,8 +121,6 @@ bool TextureCube::BeginLoad(Deserializer& source)
         if (GetPath(name).Empty())
         if (GetPath(name).Empty())
             name = texPath + name;
             name = texPath + name;
 
 
-        CubeMapLayout layout =
-            (CubeMapLayout)GetStringListIndex(imageElem.GetAttribute("layout").CString(), cubeMapLayoutNames, CML_HORIZONTAL);
         SharedPtr<Image> image = cache->GetTempResource<Image>(name);
         SharedPtr<Image> image = cache->GetTempResource<Image>(name);
         if (!image)
         if (!image)
             return false;
             return false;
@@ -130,63 +128,76 @@ bool TextureCube::BeginLoad(Deserializer& source)
         int faceWidth, faceHeight;
         int faceWidth, faceHeight;
         loadImages_.Resize(MAX_CUBEMAP_FACES);
         loadImages_.Resize(MAX_CUBEMAP_FACES);
 
 
-        switch (layout)
+        if (image->IsCubemap())
         {
         {
-        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_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)
             {
             {
-                loadImages_[FACE_NEGATIVE_Z]->FlipVertical();
-                loadImages_[FACE_NEGATIVE_Z]->FlipHorizontal();
+            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;
             }
             }
-            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
     // Face per image