From 0080552fa6fda35c01242ec5c42eef2c0fa5dc73 Mon Sep 17 00:00:00 2001 From: Anton Fedchin Date: Wed, 22 Apr 2015 18:26:17 +0300 Subject: [visualization] Vortex: Rework to DirectX11. Also fixed add-on directories to not hard-coded to special://xbmc/addons/ --- .../resources/Presets/Awakenings.vtx | 2 +- .../resources/Presets/HamsterMatic.vtx | 1 + .../resources/Presets/SpectrumCylinder.vtx | 14 +- .../resources/Presets/VoicePrintDonut.vtx | 22 +- .../resources/Presets/WaveRing.vtx | 8 +- .../resources/Textures/kodi_logo.png | Bin 0 -> 8846 bytes xbmc/visualizations/Vortex/.gitignore | 1 + xbmc/visualizations/Vortex/Vortex/Vortex.vcxproj | 229 ++- .../Vortex/Vortex/Vortex.vcxproj.filters | 74 + .../Vortex/VortexVis/Core/CommonStates.cpp | 379 ++++ .../Vortex/VortexVis/Core/CommonStates.h | 71 + .../Vortex/VortexVis/Core/DDSTextureLoader.cpp | 1993 ++++++++++++++++++++ .../Vortex/VortexVis/Core/DDSTextureLoader.h | 156 ++ .../Vortex/VortexVis/Core/DebugConsole.cpp | 4 +- .../Vortex/VortexVis/Core/DemandCreate.h | 48 + .../Vortex/VortexVis/Core/DirectXHelpers.h | 116 ++ .../Vortex/VortexVis/Core/EffectBase.h | 5 +- xbmc/visualizations/Vortex/VortexVis/Core/Mesh.cpp | 4 +- xbmc/visualizations/Vortex/VortexVis/Core/Mesh.h | 4 +- .../Vortex/VortexVis/Core/Renderer.cpp | 1123 +++++------ .../Vortex/VortexVis/Core/Renderer.h | 83 +- .../Vortex/VortexVis/Core/Shader.cpp | 246 +-- xbmc/visualizations/Vortex/VortexVis/Core/Shader.h | 97 +- .../Vortex/VortexVis/Core/SharedResourcePool.h | 105 ++ .../Vortex/VortexVis/Core/Texture.cpp | 4 +- .../visualizations/Vortex/VortexVis/Core/Texture.h | 3 +- .../Vortex/VortexVis/Core/TextureDX.cpp | 71 + .../Vortex/VortexVis/Core/TextureDX.h | 52 + .../Vortex/VortexVis/Core/Vortex.cpp | 69 +- xbmc/visualizations/Vortex/VortexVis/Core/Vortex.h | 5 +- .../Vortex/VortexVis/Core/WICTextureLoader.cpp | 1152 +++++++++++ .../Vortex/VortexVis/Core/WICTextureLoader.h | 154 ++ .../Vortex/VortexVis/Core/XMMatrixStack.cpp | 38 + .../Vortex/VortexVis/Core/XMMatrixStack.h | 99 + .../Vortex/VortexVis/Core/XmlDocument.cpp | 3 +- .../Vortex/VortexVis/Core/XmlDocument.h | 3 +- xbmc/visualizations/Vortex/VortexVis/Core/dds.h | 231 +++ .../Vortex/VortexVis/Effects/Map.cpp | 103 +- xbmc/visualizations/Vortex/VortexVis/Effects/Map.h | 13 +- .../Vortex/VortexVis/Effects/VoicePrint.cpp | 134 +- .../Vortex/VortexVis/Effects/VoicePrint.h | 22 +- .../Vortex/VortexVis/Shaders/ColorPixelShader.hlsl | 31 + .../VortexVis/Shaders/ColourRemapPixelShader.hlsl | 37 + .../Shaders/DiffuseNormalEnvCubeVertexShader.hlsl | 45 + .../Shaders/DiffuseUVCubeVertexShader.hlsl | 46 + .../Shaders/DiffuseUVEnvCubeVertexShader.hlsl | 48 + .../Shaders/DiffuseUVEnvVertexShader.hlsl | 47 + .../VortexVis/Shaders/DiffuseUVVertexShader.hlsl | 45 + .../VortexVis/Shaders/TexturePixelShader.hlsl | 41 + .../VortexVis/Shaders/UVNormalEnvVertexShader.hlsl | 44 + .../Vortex/VortexVis/Shaders/constants_table.fx | 26 + .../Vortex/VortexXBMC/VortexXBMC.cpp | 4 +- 52 files changed, 6278 insertions(+), 1077 deletions(-) create mode 100644 addons/visualization.vortex/resources/Textures/kodi_logo.png create mode 100644 xbmc/visualizations/Vortex/.gitignore create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/CommonStates.cpp create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/CommonStates.h create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/DDSTextureLoader.cpp create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/DDSTextureLoader.h create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/DemandCreate.h create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/DirectXHelpers.h create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/SharedResourcePool.h create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/TextureDX.cpp create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/TextureDX.h create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/WICTextureLoader.cpp create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/WICTextureLoader.h create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/XMMatrixStack.cpp create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/XMMatrixStack.h create mode 100644 xbmc/visualizations/Vortex/VortexVis/Core/dds.h create mode 100644 xbmc/visualizations/Vortex/VortexVis/Shaders/ColorPixelShader.hlsl create mode 100644 xbmc/visualizations/Vortex/VortexVis/Shaders/ColourRemapPixelShader.hlsl create mode 100644 xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseNormalEnvCubeVertexShader.hlsl create mode 100644 xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVCubeVertexShader.hlsl create mode 100644 xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVEnvCubeVertexShader.hlsl create mode 100644 xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVEnvVertexShader.hlsl create mode 100644 xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVVertexShader.hlsl create mode 100644 xbmc/visualizations/Vortex/VortexVis/Shaders/TexturePixelShader.hlsl create mode 100644 xbmc/visualizations/Vortex/VortexVis/Shaders/UVNormalEnvVertexShader.hlsl create mode 100644 xbmc/visualizations/Vortex/VortexVis/Shaders/constants_table.fx diff --git a/addons/visualization.vortex/resources/Presets/Awakenings.vtx b/addons/visualization.vortex/resources/Presets/Awakenings.vtx index e052516855..ee43b20cf2 100644 --- a/addons/visualization.vortex/resources/Presets/Awakenings.vtx +++ b/addons/visualization.vortex/resources/Presets/Awakenings.vtx @@ -30,7 +30,7 @@ void MakeNew(int n) void Init() { - envTexture.LoadTexture("xbmc_icon.png"); + envTexture.LoadTexture("kodi_logo.png"); for (x=0;x<256;x=x+1) { diff --git a/addons/visualization.vortex/resources/Presets/HamsterMatic.vtx b/addons/visualization.vortex/resources/Presets/HamsterMatic.vtx index 7e8cd8d9ec..0816c178bd 100644 --- a/addons/visualization.vortex/resources/Presets/HamsterMatic.vtx +++ b/addons/visualization.vortex/resources/Presets/HamsterMatic.vtx @@ -42,6 +42,7 @@ void quad(float rt, float sz) dyx = Sin(rt)*sz; dyy = 0.0f-Cos(rt)*sz; + gfxColour(1.0f,1.0f,1.0f,1.0f); gfxTexCoord((0.0f-dxx)+(0.0f+dyx),(0.0f-dxy)+(0.0f+dyy)); gfxVertex(1.0,-1,0); gfxTexCoord((0.0f+dxx)+(0.0f+dyx),(0.0f+dxy)+(0.0f+dyy)); diff --git a/addons/visualization.vortex/resources/Presets/SpectrumCylinder.vtx b/addons/visualization.vortex/resources/Presets/SpectrumCylinder.vtx index 3d588754f8..a848b9a4d6 100644 --- a/addons/visualization.vortex/resources/Presets/SpectrumCylinder.vtx +++ b/addons/visualization.vortex/resources/Presets/SpectrumCylinder.vtx @@ -25,13 +25,6 @@ void Init() envTexture.LoadTexture("env3.png"); currBuffer = 0; - for (y=0;y<24;y=y+1) - { - for (x=0;x<32;x=x+1) - { - map.SetValues(x, y, Sin((x-15.5)*3)*0.01, Sin((y-11.5)*3)*0.01, 1, 1, 1); - } - } rxamt = 1; ryamt = -1; } @@ -40,6 +33,13 @@ void Render() { time += TIMEPASS; + for (y=0;y<24;y=y+1) + { + for (x=0;x<32;x=x+1) + { + map.SetValues(x, y, Sin((x-15.5)*3)*0.01, Sin((y-11.5)*3)*0.01, 1, 1, 1); + } + } map.Render(); gfxSetRenderTarget(map); diff --git a/addons/visualization.vortex/resources/Presets/VoicePrintDonut.vtx b/addons/visualization.vortex/resources/Presets/VoicePrintDonut.vtx index d144c85c05..cc09b5f3b6 100644 --- a/addons/visualization.vortex/resources/Presets/VoicePrintDonut.vtx +++ b/addons/visualization.vortex/resources/Presets/VoicePrintDonut.vtx @@ -13,18 +13,6 @@ void Init() { vp.LoadColourMap("huemap.jpg"); vp.SetSpeed(0.5); - - for (int y=0;y<24;y=y+1) - { - for (int x=0;x<32;x=x+1) - { - float dx = (x-16)/16.0; - float dy = (y-12)/12.0; - float s = (Mag(dx,dy))-1.5; - map.SetValues(x, y, dx*s, dy*s, 1, 1, 1); - } - } - } void Render() @@ -44,6 +32,16 @@ void Render() gfxTranslate(0, 0, 2.414); gfxTexRect(-1, 1, 1, -1); + for (int y=0;y<24;y=y+1) + { + for (int x=0;x<32;x=x+1) + { + float dx = (x-16)/16.0; + float dy = (y-12)/12.0; + float s = (Mag(dx,dy))-1.5; + map.SetValues(x, y, dx*s, dy*s, 1, 1, 1); + } + } map.Render(); gfxSetRenderTarget(0); gfxSetTexture(map); diff --git a/addons/visualization.vortex/resources/Presets/WaveRing.vtx b/addons/visualization.vortex/resources/Presets/WaveRing.vtx index 792adbbf2c..4e80075b29 100644 --- a/addons/visualization.vortex/resources/Presets/WaveRing.vtx +++ b/addons/visualization.vortex/resources/Presets/WaveRing.vtx @@ -8,6 +8,10 @@ float theta,rad,dx,dy; float mx, my; void Init() +{ +} + +void Render() { for (y=0;y<24;y=y+1) { @@ -22,10 +26,6 @@ void Init() map.SetValues(x, y, mx, my, (3.0+Cos(theta))*0.275, (3.0+Cos(theta*2.0))*0.275, (3.0+Cos(theta*4.0))*0.275); } } -} - -void Render() -{ map.Render(); gfxSetRenderTarget(map); diff --git a/addons/visualization.vortex/resources/Textures/kodi_logo.png b/addons/visualization.vortex/resources/Textures/kodi_logo.png new file mode 100644 index 0000000000..74e5f08ca5 Binary files /dev/null and b/addons/visualization.vortex/resources/Textures/kodi_logo.png differ diff --git a/xbmc/visualizations/Vortex/.gitignore b/xbmc/visualizations/Vortex/.gitignore new file mode 100644 index 0000000000..2a06e93b55 --- /dev/null +++ b/xbmc/visualizations/Vortex/.gitignore @@ -0,0 +1 @@ +*.inc diff --git a/xbmc/visualizations/Vortex/Vortex/Vortex.vcxproj b/xbmc/visualizations/Vortex/Vortex/Vortex.vcxproj index e588c3c4e4..57d14334bf 100644 --- a/xbmc/visualizations/Vortex/Vortex/Vortex.vcxproj +++ b/xbmc/visualizations/Vortex/Vortex/Vortex.vcxproj @@ -43,8 +43,8 @@ true - $(DXSDK_DIR)Include;$(IncludePath) - $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(WindowsSDK_IncludePath);$(IncludePath) + $(WindowsSDK_LibraryPath_x86);$(LibraryPath) $(SolutionDir)libs\$(TargetName)\$(Configuration)\ $(SolutionDir)objs\$(TargetName)\$(Configuration)\ Vortex_win32dx @@ -52,8 +52,8 @@ false - $(DXSDK_DIR)Include;$(IncludePath) - $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(WindowsSDK_IncludePath);$(IncludePath) + $(WindowsSDK_LibraryPath_x86);$(LibraryPath) $(SolutionDir)libs\$(TargetName)\$(Configuration)\ $(SolutionDir)objs\$(TargetName)\$(Configuration)\ Vortex_win32dx @@ -65,7 +65,7 @@ ..\VortexVis\core;..\VortexVis\effects;..\angelscript\angelscript\include;..\..\..\;%(AdditionalIncludeDirectories) - D3dx9.lib;winmm.lib;%(AdditionalDependencies) + d3d11.lib;winmm.lib;%(AdditionalDependencies) libcmtd @@ -78,7 +78,7 @@ ..\VortexVis\core;..\VortexVis\effects;..\angelscript\angelscript\include;..\..\..\;%(AdditionalIncludeDirectories) - D3dx9.lib;winmm.lib;%(AdditionalDependencies) + d3d11.lib;winmm.lib;%(AdditionalDependencies) copy "$(TargetPath)" "$(SolutionDir)..\..\addons\visualization.vortex\$(TargetFileName)" @@ -124,6 +124,8 @@ + + @@ -132,7 +134,9 @@ + + @@ -141,17 +145,26 @@ + + + + + + + + + @@ -161,6 +174,210 @@ {034b1d02-ca92-455d-8866-db95bee49c10} + + + Main + false + false + Pixel + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + Main + Pixel + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + 4.0_level_9_1 + + + 4.0_level_9_1 + + + + + Main + false + false + Pixel + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + Main + Pixel + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + + + + + 4.0_level_9_1 + 4.0_level_9_1 + + + true + true + + + Main + false + false + Vertex + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + Main + Vertex + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + 4.0_level_9_1 + + + 4.0_level_9_1 + + + + + Main + false + false + Vertex + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + Main + Vertex + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + 4.0_level_9_1 + + + 4.0_level_9_1 + + + + + Main + false + false + Vertex + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + Main + Vertex + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + 4.0_level_9_1 + + + 4.0_level_9_1 + + + + + Main + false + false + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + Main + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + Vertex + Vertex + 4.0_level_9_1 + + + 4.0_level_9_1 + + + + + Main + Vertex + Main + Vertex + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + false + false + 4.0_level_9_1 + + + 4.0_level_9_1 + + + + + Main + false + false + Pixel + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + Main + Pixel + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + 4.0_level_9_1 + + + 4.0_level_9_1 + + + + + Main + false + false + Vertex + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + Main + Vertex + %(Filename)Code + %(RelativeDir)%(Filename).inc + + + 4.0_level_9_1 + + + 4.0_level_9_1 + + + + diff --git a/xbmc/visualizations/Vortex/Vortex/Vortex.vcxproj.filters b/xbmc/visualizations/Vortex/Vortex/Vortex.vcxproj.filters index df6200c695..97878835d5 100644 --- a/xbmc/visualizations/Vortex/Vortex/Vortex.vcxproj.filters +++ b/xbmc/visualizations/Vortex/Vortex/Vortex.vcxproj.filters @@ -28,6 +28,9 @@ {98e8d217-f32e-4eec-87cd-05369f120e4a} + + {46ba7657-b896-4fb3-bffb-eebe8ee61eab} + @@ -189,6 +192,18 @@ Source Files\Effects + + Source Files\Core + + + Source Files\Core + + + Source Files\Core + + + Source Files\Core + @@ -236,5 +251,64 @@ Source Files\Effects + + Source Files\Core + + + Source Files\Core + + + Source Files\Core + + + Source Files\Core + + + Source Files\Core + + + Source Files\Core + + + Source Files\Core + + + Source Files\Core + + + Source Files\Core + + + + + Source Files\Shaders + + + Source Files\Shaders + + + Source Files\Shaders + + + Source Files\Shaders + + + Source Files\Shaders + + + Source Files\Shaders + + + Source Files\Shaders + + + Source Files\Shaders + + + Source Files\Shaders + + + Source Files\Shaders + \ No newline at end of file diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/CommonStates.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/CommonStates.cpp new file mode 100644 index 0000000000..55fdbbfae0 --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/CommonStates.cpp @@ -0,0 +1,379 @@ +//-------------------------------------------------------------------------------------- +// File: CommonStates.cpp +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#include +#include "CommonStates.h" +#include "DirectXHelpers.h" +#include "DemandCreate.h" +#include "SharedResourcePool.h" +#include + +using namespace DirectX; +using namespace Microsoft::WRL; + + +// Internal state object implementation class. Only one of these helpers is allocated +// per D3D device, even if there are multiple public facing CommonStates instances. +class CommonStates::Impl +{ +public: + Impl(_In_ ID3D11Device* device) + : device(device) + { } + + HRESULT CreateBlendState(D3D11_BLEND srcBlend, D3D11_BLEND destBlend, D3D11_BLEND_OP blendOp, _Out_ ID3D11BlendState** pResult); + HRESULT CreateDepthStencilState(bool enable, bool writeEnable, _Out_ ID3D11DepthStencilState** pResult); + HRESULT CreateRasterizerState(D3D11_CULL_MODE cullMode, D3D11_FILL_MODE fillMode, _Out_ ID3D11RasterizerState** pResult); + HRESULT CreateSamplerState(D3D11_FILTER filter, D3D11_TEXTURE_ADDRESS_MODE addressMode, _Out_ ID3D11SamplerState** pResult); + + ComPtr device; + + ComPtr opaque; + ComPtr alphaBlend; + ComPtr additive; + ComPtr nonPremultiplied; + ComPtr maximize; + + ComPtr depthNone; + ComPtr depthDefault; + ComPtr depthRead; + + ComPtr cullNone; + ComPtr cullClockwise; + ComPtr cullCounterClockwise; + ComPtr wireframe; + + ComPtr pointWrap; + ComPtr pointClamp; + ComPtr linearWrap; + ComPtr linearClamp; + ComPtr anisotropicWrap; + ComPtr anisotropicClamp; + + std::mutex mutex; + + static SharedResourcePool instancePool; +}; + + +// Global instance pool. +SharedResourcePool CommonStates::Impl::instancePool; + + +// Helper for creating blend state objects. +HRESULT CommonStates::Impl::CreateBlendState(D3D11_BLEND srcBlend, D3D11_BLEND destBlend, D3D11_BLEND_OP blendOp, _Out_ ID3D11BlendState** pResult) +{ + D3D11_BLEND_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + + desc.RenderTarget[0].BlendEnable = (srcBlend != D3D11_BLEND_ONE) || + (destBlend != D3D11_BLEND_ZERO); + + desc.RenderTarget[0].SrcBlend = desc.RenderTarget[0].SrcBlendAlpha = srcBlend; + desc.RenderTarget[0].DestBlend = desc.RenderTarget[0].DestBlendAlpha = destBlend; + desc.RenderTarget[0].BlendOp = desc.RenderTarget[0].BlendOpAlpha = blendOp; + + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + HRESULT hr = device->CreateBlendState(&desc, pResult); + + if (SUCCEEDED(hr)) + SetDebugObjectName(*pResult, "Vortex:CommonStates"); + + return hr; +} + + +// Helper for creating depth stencil state objects. +HRESULT CommonStates::Impl::CreateDepthStencilState(bool enable, bool writeEnable, _Out_ ID3D11DepthStencilState** pResult) +{ + D3D11_DEPTH_STENCIL_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + + desc.DepthEnable = enable; + desc.DepthWriteMask = writeEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; + desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; + + desc.StencilEnable = false; + desc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + desc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + + desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + + desc.BackFace = desc.FrontFace; + + HRESULT hr = device->CreateDepthStencilState(&desc, pResult); + + if (SUCCEEDED(hr)) + SetDebugObjectName(*pResult, "Vortex:CommonStates"); + + return hr; +} + + +// Helper for creating rasterizer state objects. +HRESULT CommonStates::Impl::CreateRasterizerState(D3D11_CULL_MODE cullMode, D3D11_FILL_MODE fillMode, _Out_ ID3D11RasterizerState** pResult) +{ + D3D11_RASTERIZER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + + desc.CullMode = cullMode; + desc.FillMode = fillMode; + desc.DepthClipEnable = true; + desc.MultisampleEnable = true; + + HRESULT hr = device->CreateRasterizerState(&desc, pResult); + + if (SUCCEEDED(hr)) + SetDebugObjectName(*pResult, "Vortex:CommonStates"); + + return hr; +} + + +// Helper for creating sampler state objects. +HRESULT CommonStates::Impl::CreateSamplerState(D3D11_FILTER filter, D3D11_TEXTURE_ADDRESS_MODE addressMode, _Out_ ID3D11SamplerState** pResult) +{ + D3D11_SAMPLER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + + desc.Filter = filter; + + desc.AddressU = addressMode; + desc.AddressV = addressMode; + desc.AddressW = addressMode; + + desc.MaxAnisotropy = (device->GetFeatureLevel() > D3D_FEATURE_LEVEL_9_1) ? 16 : 2; + + desc.MaxLOD = FLT_MAX; + desc.ComparisonFunc = D3D11_COMPARISON_NEVER; + + HRESULT hr = device->CreateSamplerState(&desc, pResult); + + if (SUCCEEDED(hr)) + SetDebugObjectName(*pResult, "Vortex:CommonStates"); + + return hr; +} + + +//-------------------------------------------------------------------------------------- +// CommonStates +//-------------------------------------------------------------------------------------- + +// Public constructor. +CommonStates::CommonStates(_In_ ID3D11Device* device) + : pImpl(Impl::instancePool.DemandCreate(device)) +{ +} + + +// Move constructor. +CommonStates::CommonStates(CommonStates&& moveFrom) + : pImpl(std::move(moveFrom.pImpl)) +{ +} + + +// Move assignment. +CommonStates& CommonStates::operator= (CommonStates&& moveFrom) +{ + pImpl = std::move(moveFrom.pImpl); + return *this; +} + + +// Public destructor. +CommonStates::~CommonStates() +{ +} + + +//-------------------------------------------------------------------------------------- +// Blend states +//-------------------------------------------------------------------------------------- + +ID3D11BlendState* CommonStates::Opaque() const +{ + return DemandCreate(pImpl->opaque, pImpl->mutex, [&](ID3D11BlendState** pResult) + { + return pImpl->CreateBlendState(D3D11_BLEND_ONE, D3D11_BLEND_ZERO, D3D11_BLEND_OP_ADD, pResult); + }); +} + + +ID3D11BlendState* CommonStates::AlphaBlend() const +{ + return DemandCreate(pImpl->alphaBlend, pImpl->mutex, [&](ID3D11BlendState** pResult) + { + return pImpl->CreateBlendState(D3D11_BLEND_ONE, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD, pResult); + }); +} + + +ID3D11BlendState* CommonStates::Additive() const +{ + return DemandCreate(pImpl->additive, pImpl->mutex, [&](ID3D11BlendState** pResult) + { + return pImpl->CreateBlendState(D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_ONE, D3D11_BLEND_OP_ADD, pResult); + }); +} + + +ID3D11BlendState* CommonStates::NonPremultiplied() const +{ + return DemandCreate(pImpl->nonPremultiplied, pImpl->mutex, [&](ID3D11BlendState** pResult) + { + return pImpl->CreateBlendState(D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD, pResult); + }); +} + +ID3D11BlendState* CommonStates::Maximize() const +{ + return DemandCreate(pImpl->maximize, pImpl->mutex, [&](ID3D11BlendState** pResult) + { + return pImpl->CreateBlendState(D3D11_BLEND_ONE, D3D11_BLEND_ONE, D3D11_BLEND_OP_MAX, pResult); + }); +} + + +//-------------------------------------------------------------------------------------- +// Depth stencil states +//-------------------------------------------------------------------------------------- + +ID3D11DepthStencilState* CommonStates::DepthNone() const +{ + return DemandCreate(pImpl->depthNone, pImpl->mutex, [&](ID3D11DepthStencilState** pResult) + { + return pImpl->CreateDepthStencilState(false, false, pResult); + }); +} + + +ID3D11DepthStencilState* CommonStates::DepthDefault() const +{ + return DemandCreate(pImpl->depthDefault, pImpl->mutex, [&](ID3D11DepthStencilState** pResult) + { + return pImpl->CreateDepthStencilState(true, true, pResult); + }); +} + + +ID3D11DepthStencilState* CommonStates::DepthRead() const +{ + return DemandCreate(pImpl->depthRead, pImpl->mutex, [&](ID3D11DepthStencilState** pResult) + { + return pImpl->CreateDepthStencilState(true, false, pResult); + }); +} + + +//-------------------------------------------------------------------------------------- +// Rasterizer states +//-------------------------------------------------------------------------------------- + +ID3D11RasterizerState* CommonStates::CullNone() const +{ + return DemandCreate(pImpl->cullNone, pImpl->mutex, [&](ID3D11RasterizerState** pResult) + { + return pImpl->CreateRasterizerState(D3D11_CULL_NONE, D3D11_FILL_SOLID, pResult); + }); +} + + +ID3D11RasterizerState* CommonStates::CullClockwise() const +{ + return DemandCreate(pImpl->cullClockwise, pImpl->mutex, [&](ID3D11RasterizerState** pResult) + { + return pImpl->CreateRasterizerState(D3D11_CULL_FRONT, D3D11_FILL_SOLID, pResult); + }); +} + + +ID3D11RasterizerState* CommonStates::CullCounterClockwise() const +{ + return DemandCreate(pImpl->cullCounterClockwise, pImpl->mutex, [&](ID3D11RasterizerState** pResult) + { + return pImpl->CreateRasterizerState(D3D11_CULL_BACK, D3D11_FILL_SOLID, pResult); + }); +} + + +ID3D11RasterizerState* CommonStates::Wireframe() const +{ + return DemandCreate(pImpl->wireframe, pImpl->mutex, [&](ID3D11RasterizerState** pResult) + { + return pImpl->CreateRasterizerState(D3D11_CULL_NONE, D3D11_FILL_WIREFRAME, pResult); + }); +} + + +//-------------------------------------------------------------------------------------- +// Sampler states +//-------------------------------------------------------------------------------------- + +ID3D11SamplerState* CommonStates::PointWrap() const +{ + return DemandCreate(pImpl->pointWrap, pImpl->mutex, [&](ID3D11SamplerState** pResult) + { + return pImpl->CreateSamplerState(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_WRAP, pResult); + }); +} + + +ID3D11SamplerState* CommonStates::PointClamp() const +{ + return DemandCreate(pImpl->pointClamp, pImpl->mutex, [&](ID3D11SamplerState** pResult) + { + return pImpl->CreateSamplerState(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_CLAMP, pResult); + }); +} + + +ID3D11SamplerState* CommonStates::LinearWrap() const +{ + return DemandCreate(pImpl->linearWrap, pImpl->mutex, [&](ID3D11SamplerState** pResult) + { + return pImpl->CreateSamplerState(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_WRAP, pResult); + }); +} + + +ID3D11SamplerState* CommonStates::LinearClamp() const +{ + return DemandCreate(pImpl->linearClamp, pImpl->mutex, [&](ID3D11SamplerState** pResult) + { + return pImpl->CreateSamplerState(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP, pResult); + }); +} + + +ID3D11SamplerState* CommonStates::AnisotropicWrap() const +{ + return DemandCreate(pImpl->anisotropicWrap, pImpl->mutex, [&](ID3D11SamplerState** pResult) + { + return pImpl->CreateSamplerState(D3D11_FILTER_ANISOTROPIC, D3D11_TEXTURE_ADDRESS_WRAP, pResult); + }); +} + + +ID3D11SamplerState* CommonStates::AnisotropicClamp() const +{ + return DemandCreate(pImpl->anisotropicClamp, pImpl->mutex, [&](ID3D11SamplerState** pResult) + { + return pImpl->CreateSamplerState(D3D11_FILTER_ANISOTROPIC, D3D11_TEXTURE_ADDRESS_CLAMP, pResult); + }); +} diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/CommonStates.h b/xbmc/visualizations/Vortex/VortexVis/Core/CommonStates.h new file mode 100644 index 0000000000..ac8c51fcee --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/CommonStates.h @@ -0,0 +1,71 @@ +//-------------------------------------------------------------------------------------- +// File: CommonStates.h +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#include + + +namespace DirectX +{ + class CommonStates + { + public: + explicit CommonStates(_In_ ID3D11Device* device); + CommonStates(CommonStates&& moveFrom); + CommonStates& operator= (CommonStates&& moveFrom); + virtual ~CommonStates(); + + // Blend states. + ID3D11BlendState* __cdecl Opaque() const; + ID3D11BlendState* __cdecl AlphaBlend() const; + ID3D11BlendState* __cdecl Additive() const; + ID3D11BlendState* __cdecl NonPremultiplied() const; + ID3D11BlendState* __cdecl Maximize() const; + + // Depth stencil states. + ID3D11DepthStencilState* __cdecl DepthNone() const; + ID3D11DepthStencilState* __cdecl DepthDefault() const; + ID3D11DepthStencilState* __cdecl DepthRead() const; + + // Rasterizer states. + ID3D11RasterizerState* __cdecl CullNone() const; + ID3D11RasterizerState* __cdecl CullClockwise() const; + ID3D11RasterizerState* __cdecl CullCounterClockwise() const; + ID3D11RasterizerState* __cdecl Wireframe() const; + + // Sampler states. + ID3D11SamplerState* __cdecl PointWrap() const; + ID3D11SamplerState* __cdecl PointClamp() const; + ID3D11SamplerState* __cdecl LinearWrap() const; + ID3D11SamplerState* __cdecl LinearClamp() const; + ID3D11SamplerState* __cdecl AnisotropicWrap() const; + ID3D11SamplerState* __cdecl AnisotropicClamp() const; + + private: + // Private implementation. + class Impl; + + std::shared_ptr pImpl; + + // Prevent copying. + CommonStates(CommonStates const&); + CommonStates& operator= (CommonStates const&); + }; +} diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/DDSTextureLoader.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/DDSTextureLoader.cpp new file mode 100644 index 0000000000..25eb5e3548 --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/DDSTextureLoader.cpp @@ -0,0 +1,1993 @@ +//-------------------------------------------------------------------------------------- +// File: DDSTextureLoader.cpp +// +// Functions for loading a DDS texture and creating a Direct3D 11 runtime resource for it +// +// Note these functions are useful as a light-weight runtime loader for DDS files. For +// a full-featured DDS file reader, writer, and texture processing pipeline see +// the 'Texconv' sample and the 'DirectXTex' library. +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkId=248926 +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#include "DDSTextureLoader.h" +#include "DirectXHelpers.h" +#include "dds.h" +#include +#include +#include + +using namespace DirectX; + +//-------------------------------------------------------------------------------------- +static HRESULT LoadTextureDataFromFile( _In_z_ const wchar_t* fileName, + std::unique_ptr& ddsData, + DDS_HEADER** header, + uint8_t** bitData, + size_t* bitSize + ) +{ + if (!header || !bitData || !bitSize) + { + return E_POINTER; + } + + // open the file +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) + HANDLE hFile = CreateFile2( fileName, + GENERIC_READ, + FILE_SHARE_READ, + OPEN_EXISTING, + nullptr ); +#else + HANDLE hFile = CreateFileW( fileName, + GENERIC_READ, + FILE_SHARE_READ, + nullptr, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + nullptr ); +#endif + + if ( !hFile ) + { + return HRESULT_FROM_WIN32( GetLastError() ); + } + + // Get the file size + LARGE_INTEGER FileSize = { 0 }; + +#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) + FILE_STANDARD_INFO fileInfo; + if ( !GetFileInformationByHandleEx( hFile, FileStandardInfo, &fileInfo, sizeof(fileInfo) ) ) + { + return HRESULT_FROM_WIN32( GetLastError() ); + } + FileSize = fileInfo.EndOfFile; +#else + GetFileSizeEx( hFile.get(), &FileSize ); +#endif + + // File is too big for 32-bit allocation, so reject read + if (FileSize.HighPart > 0) + { + return E_FAIL; + } + + // Need at least enough data to fill the header and magic number to be a valid DDS + if (FileSize.LowPart < ( sizeof(DDS_HEADER) + sizeof(uint32_t) ) ) + { + return E_FAIL; + } + + // create enough space for the file data + ddsData.reset( new (std::nothrow) uint8_t[ FileSize.LowPart ] ); + if (!ddsData) + { + return E_OUTOFMEMORY; + } + + // read the data in + DWORD BytesRead = 0; + if (!ReadFile( hFile, + ddsData.get(), + FileSize.LowPart, + &BytesRead, + nullptr + )) + { + return HRESULT_FROM_WIN32( GetLastError() ); + } + + if (BytesRead < FileSize.LowPart) + { + return E_FAIL; + } + + // DDS files always start with the same magic number ("DDS ") + uint32_t dwMagicNumber = *( const uint32_t* )( ddsData.get() ); + if (dwMagicNumber != DDS_MAGIC) + { + return E_FAIL; + } + + auto hdr = reinterpret_cast( ddsData.get() + sizeof( uint32_t ) ); + + // Verify header to validate DDS file + if (hdr->size != sizeof(DDS_HEADER) || + hdr->ddspf.size != sizeof(DDS_PIXELFORMAT)) + { + return E_FAIL; + } + + // Check for DX10 extension + bool bDXT10Header = false; + if ((hdr->ddspf.flags & DDS_FOURCC) && + (MAKEFOURCC( 'D', 'X', '1', '0' ) == hdr->ddspf.fourCC)) + { + // Must be long enough for both headers and magic value + if (FileSize.LowPart < ( sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_DXT10) ) ) + { + return E_FAIL; + } + + bDXT10Header = true; + } + + // setup the pointers in the process request + *header = hdr; + ptrdiff_t offset = sizeof( uint32_t ) + sizeof( DDS_HEADER ) + + (bDXT10Header ? sizeof( DDS_HEADER_DXT10 ) : 0); + *bitData = ddsData.get() + offset; + *bitSize = FileSize.LowPart - offset; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Return the BPP for a particular format +//-------------------------------------------------------------------------------------- +static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt ) +{ + switch( fmt ) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + return 128; + + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return 96; + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DXGI_FORMAT_Y416: + case DXGI_FORMAT_Y210: + case DXGI_FORMAT_Y216: + return 64; + + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + case DXGI_FORMAT_AYUV: + case DXGI_FORMAT_Y410: + case DXGI_FORMAT_YUY2: + return 32; + + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + return 24; + + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + case DXGI_FORMAT_A8P8: + case DXGI_FORMAT_B4G4R4A4_UNORM: + return 16; + + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_420_OPAQUE: + case DXGI_FORMAT_NV11: + return 12; + + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: + case DXGI_FORMAT_AI44: + case DXGI_FORMAT_IA44: + case DXGI_FORMAT_P8: + return 8; + + case DXGI_FORMAT_R1_UNORM: + return 1; + + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + return 4; + + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return 8; + +#if defined(_XBOX_ONE) && defined(_TITLE) + + case DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT: + case DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT: + return 32; + + case DXGI_FORMAT_D16_UNORM_S8_UINT: + case DXGI_FORMAT_R16_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X16_TYPELESS_G8_UINT: + return 24; + +#endif // _XBOX_ONE && _TITLE + + default: + return 0; + } +} + + +//-------------------------------------------------------------------------------------- +// Get surface information for a particular format +//-------------------------------------------------------------------------------------- +static void GetSurfaceInfo( _In_ size_t width, + _In_ size_t height, + _In_ DXGI_FORMAT fmt, + _Out_opt_ size_t* outNumBytes, + _Out_opt_ size_t* outRowBytes, + _Out_opt_ size_t* outNumRows ) +{ + size_t numBytes = 0; + size_t rowBytes = 0; + size_t numRows = 0; + + bool bc = false; + bool packed = false; + bool planar = false; + size_t bpe = 0; + switch (fmt) + { + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + bc=true; + bpe = 8; + break; + + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + bc = true; + bpe = 16; + break; + + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_YUY2: + packed = true; + bpe = 4; + break; + + case DXGI_FORMAT_Y210: + case DXGI_FORMAT_Y216: + packed = true; + bpe = 8; + break; + + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_420_OPAQUE: + planar = true; + bpe = 2; + break; + + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + planar = true; + bpe = 4; + break; + +#if defined(_XBOX_ONE) && defined(_TITLE) + + case DXGI_FORMAT_D16_UNORM_S8_UINT: + case DXGI_FORMAT_R16_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X16_TYPELESS_G8_UINT: + planar = true; + bpe = 4; + break; + +#endif + } + + if (bc) + { + size_t numBlocksWide = 0; + if (width > 0) + { + numBlocksWide = std::max( 1, (width + 3) / 4 ); + } + size_t numBlocksHigh = 0; + if (height > 0) + { + numBlocksHigh = std::max( 1, (height + 3) / 4 ); + } + rowBytes = numBlocksWide * bpe; + numRows = numBlocksHigh; + numBytes = rowBytes * numBlocksHigh; + } + else if (packed) + { + rowBytes = ( ( width + 1 ) >> 1 ) * bpe; + numRows = height; + numBytes = rowBytes * height; + } + else if ( fmt == DXGI_FORMAT_NV11 ) + { + rowBytes = ( ( width + 3 ) >> 2 ) * 4; + numRows = height * 2; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data + numBytes = rowBytes * numRows; + } + else if (planar) + { + rowBytes = ( ( width + 1 ) >> 1 ) * bpe; + numBytes = ( rowBytes * height ) + ( ( rowBytes * height + 1 ) >> 1 ); + numRows = height + ( ( height + 1 ) >> 1 ); + } + else + { + size_t bpp = BitsPerPixel( fmt ); + rowBytes = ( width * bpp + 7 ) / 8; // round up to nearest byte + numRows = height; + numBytes = rowBytes * height; + } + + if (outNumBytes) + { + *outNumBytes = numBytes; + } + if (outRowBytes) + { + *outRowBytes = rowBytes; + } + if (outNumRows) + { + *outNumRows = numRows; + } +} + + +//-------------------------------------------------------------------------------------- +#define ISBITMASK( r,g,b,a ) ( ddpf.RBitMask == r && ddpf.GBitMask == g && ddpf.BBitMask == b && ddpf.ABitMask == a ) + +static DXGI_FORMAT GetDXGIFormat( const DDS_PIXELFORMAT& ddpf ) +{ + if (ddpf.flags & DDS_RGB) + { + // Note that sRGB formats are written using the "DX10" extended header + + switch (ddpf.RGBBitCount) + { + case 32: + if (ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0xff000000)) + { + return DXGI_FORMAT_R8G8B8A8_UNORM; + } + + if (ISBITMASK(0x00ff0000,0x0000ff00,0x000000ff,0xff000000)) + { + return DXGI_FORMAT_B8G8R8A8_UNORM; + } + + if (ISBITMASK(0x00ff0000,0x0000ff00,0x000000ff,0x00000000)) + { + return DXGI_FORMAT_B8G8R8X8_UNORM; + } + + // No DXGI format maps to ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0x00000000) aka D3DFMT_X8B8G8R8 + + // Note that many common DDS reader/writers (including D3DX) swap the + // the RED/BLUE masks for 10:10:10:2 formats. We assumme + // below that the 'backwards' header mask is being used since it is most + // likely written by D3DX. The more robust solution is to use the 'DX10' + // header extension and specify the DXGI_FORMAT_R10G10B10A2_UNORM format directly + + // For 'correct' writers, this should be 0x000003ff,0x000ffc00,0x3ff00000 for RGB data + if (ISBITMASK(0x3ff00000,0x000ffc00,0x000003ff,0xc0000000)) + { + return DXGI_FORMAT_R10G10B10A2_UNORM; + } + + // No DXGI format maps to ISBITMASK(0x000003ff,0x000ffc00,0x3ff00000,0xc0000000) aka D3DFMT_A2R10G10B10 + + if (ISBITMASK(0x0000ffff,0xffff0000,0x00000000,0x00000000)) + { + return DXGI_FORMAT_R16G16_UNORM; + } + + if (ISBITMASK(0xffffffff,0x00000000,0x00000000,0x00000000)) + { + // Only 32-bit color channel format in D3D9 was R32F + return DXGI_FORMAT_R32_FLOAT; // D3DX writes this out as a FourCC of 114 + } + break; + + case 24: + // No 24bpp DXGI formats aka D3DFMT_R8G8B8 + break; + + case 16: + if (ISBITMASK(0x7c00,0x03e0,0x001f,0x8000)) + { + return DXGI_FORMAT_B5G5R5A1_UNORM; + } + if (ISBITMASK(0xf800,0x07e0,0x001f,0x0000)) + { + return DXGI_FORMAT_B5G6R5_UNORM; + } + + // No DXGI format maps to ISBITMASK(0x7c00,0x03e0,0x001f,0x0000) aka D3DFMT_X1R5G5B5 + + if (ISBITMASK(0x0f00,0x00f0,0x000f,0xf000)) + { + return DXGI_FORMAT_B4G4R4A4_UNORM; + } + + // No DXGI format maps to ISBITMASK(0x0f00,0x00f0,0x000f,0x0000) aka D3DFMT_X4R4G4B4 + + // No 3:3:2, 3:3:2:8, or paletted DXGI formats aka D3DFMT_A8R3G3B2, D3DFMT_R3G3B2, D3DFMT_P8, D3DFMT_A8P8, etc. + break; + } + } + else if (ddpf.flags & DDS_LUMINANCE) + { + if (8 == ddpf.RGBBitCount) + { + if (ISBITMASK(0x000000ff,0x00000000,0x00000000,0x00000000)) + { + return DXGI_FORMAT_R8_UNORM; // D3DX10/11 writes this out as DX10 extension + } + + // No DXGI format maps to ISBITMASK(0x0f,0x00,0x00,0xf0) aka D3DFMT_A4L4 + } + + if (16 == ddpf.RGBBitCount) + { + if (ISBITMASK(0x0000ffff,0x00000000,0x00000000,0x00000000)) + { + return DXGI_FORMAT_R16_UNORM; // D3DX10/11 writes this out as DX10 extension + } + if (ISBITMASK(0x000000ff,0x00000000,0x00000000,0x0000ff00)) + { + return DXGI_FORMAT_R8G8_UNORM; // D3DX10/11 writes this out as DX10 extension + } + } + } + else if (ddpf.flags & DDS_ALPHA) + { + if (8 == ddpf.RGBBitCount) + { + return DXGI_FORMAT_A8_UNORM; + } + } + else if (ddpf.flags & DDS_FOURCC) + { + if (MAKEFOURCC( 'D', 'X', 'T', '1' ) == ddpf.fourCC) + { + return DXGI_FORMAT_BC1_UNORM; + } + if (MAKEFOURCC( 'D', 'X', 'T', '3' ) == ddpf.fourCC) + { + return DXGI_FORMAT_BC2_UNORM; + } + if (MAKEFOURCC( 'D', 'X', 'T', '5' ) == ddpf.fourCC) + { + return DXGI_FORMAT_BC3_UNORM; + } + + // While pre-mulitplied alpha isn't directly supported by the DXGI formats, + // they are basically the same as these BC formats so they can be mapped + if (MAKEFOURCC( 'D', 'X', 'T', '2' ) == ddpf.fourCC) + { + return DXGI_FORMAT_BC2_UNORM; + } + if (MAKEFOURCC( 'D', 'X', 'T', '4' ) == ddpf.fourCC) + { + return DXGI_FORMAT_BC3_UNORM; + } + + if (MAKEFOURCC( 'A', 'T', 'I', '1' ) == ddpf.fourCC) + { + return DXGI_FORMAT_BC4_UNORM; + } + if (MAKEFOURCC( 'B', 'C', '4', 'U' ) == ddpf.fourCC) + { + return DXGI_FORMAT_BC4_UNORM; + } + if (MAKEFOURCC( 'B', 'C', '4', 'S' ) == ddpf.fourCC) + { + return DXGI_FORMAT_BC4_SNORM; + } + + if (MAKEFOURCC( 'A', 'T', 'I', '2' ) == ddpf.fourCC) + { + return DXGI_FORMAT_BC5_UNORM; + } + if (MAKEFOURCC( 'B', 'C', '5', 'U' ) == ddpf.fourCC) + { + return DXGI_FORMAT_BC5_UNORM; + } + if (MAKEFOURCC( 'B', 'C', '5', 'S' ) == ddpf.fourCC) + { + return DXGI_FORMAT_BC5_SNORM; + } + + // BC6H and BC7 are written using the "DX10" extended header + + if (MAKEFOURCC( 'R', 'G', 'B', 'G' ) == ddpf.fourCC) + { + return DXGI_FORMAT_R8G8_B8G8_UNORM; + } + if (MAKEFOURCC( 'G', 'R', 'G', 'B' ) == ddpf.fourCC) + { + return DXGI_FORMAT_G8R8_G8B8_UNORM; + } + + if (MAKEFOURCC('Y','U','Y','2') == ddpf.fourCC) + { + return DXGI_FORMAT_YUY2; + } + + // Check for D3DFORMAT enums being set here + switch( ddpf.fourCC ) + { + case 36: // D3DFMT_A16B16G16R16 + return DXGI_FORMAT_R16G16B16A16_UNORM; + + case 110: // D3DFMT_Q16W16V16U16 + return DXGI_FORMAT_R16G16B16A16_SNORM; + + case 111: // D3DFMT_R16F + return DXGI_FORMAT_R16_FLOAT; + + case 112: // D3DFMT_G16R16F + return DXGI_FORMAT_R16G16_FLOAT; + + case 113: // D3DFMT_A16B16G16R16F + return DXGI_FORMAT_R16G16B16A16_FLOAT; + + case 114: // D3DFMT_R32F + return DXGI_FORMAT_R32_FLOAT; + + case 115: // D3DFMT_G32R32F + return DXGI_FORMAT_R32G32_FLOAT; + + case 116: // D3DFMT_A32B32G32R32F + return DXGI_FORMAT_R32G32B32A32_FLOAT; + } + } + + return DXGI_FORMAT_UNKNOWN; +} + + +//-------------------------------------------------------------------------------------- +static DXGI_FORMAT MakeSRGB( _In_ DXGI_FORMAT format ) +{ + switch( format ) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + + case DXGI_FORMAT_BC1_UNORM: + return DXGI_FORMAT_BC1_UNORM_SRGB; + + case DXGI_FORMAT_BC2_UNORM: + return DXGI_FORMAT_BC2_UNORM_SRGB; + + case DXGI_FORMAT_BC3_UNORM: + return DXGI_FORMAT_BC3_UNORM_SRGB; + + case DXGI_FORMAT_B8G8R8A8_UNORM: + return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + + case DXGI_FORMAT_B8G8R8X8_UNORM: + return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + + case DXGI_FORMAT_BC7_UNORM: + return DXGI_FORMAT_BC7_UNORM_SRGB; + + default: + return format; + } +} + + +//-------------------------------------------------------------------------------------- +static HRESULT FillInitData( _In_ size_t width, + _In_ size_t height, + _In_ size_t depth, + _In_ size_t mipCount, + _In_ size_t arraySize, + _In_ DXGI_FORMAT format, + _In_ size_t maxsize, + _In_ size_t bitSize, + _In_reads_bytes_(bitSize) const uint8_t* bitData, + _Out_ size_t& twidth, + _Out_ size_t& theight, + _Out_ size_t& tdepth, + _Out_ size_t& skipMip, + _Out_writes_(mipCount*arraySize) D3D11_SUBRESOURCE_DATA* initData ) +{ + if ( !bitData || !initData ) + { + return E_POINTER; + } + + skipMip = 0; + twidth = 0; + theight = 0; + tdepth = 0; + + size_t NumBytes = 0; + size_t RowBytes = 0; + const uint8_t* pSrcBits = bitData; + const uint8_t* pEndBits = bitData + bitSize; + + size_t index = 0; + for( size_t j = 0; j < arraySize; j++ ) + { + size_t w = width; + size_t h = height; + size_t d = depth; + for( size_t i = 0; i < mipCount; i++ ) + { + GetSurfaceInfo( w, + h, + format, + &NumBytes, + &RowBytes, + nullptr + ); + + if ( (mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize) ) + { + if ( !twidth ) + { + twidth = w; + theight = h; + tdepth = d; + } + + assert(index < mipCount * arraySize); + _Analysis_assume_(index < mipCount * arraySize); + initData[index].pSysMem = ( const void* )pSrcBits; + initData[index].SysMemPitch = static_cast( RowBytes ); + initData[index].SysMemSlicePitch = static_cast( NumBytes ); + ++index; + } + else if ( !j ) + { + // Count number of skipped mipmaps (first item only) + ++skipMip; + } + + if (pSrcBits + (NumBytes*d) > pEndBits) + { + return HRESULT_FROM_WIN32( ERROR_HANDLE_EOF ); + } + + pSrcBits += NumBytes * d; + + w = w >> 1; + h = h >> 1; + d = d >> 1; + if (w == 0) + { + w = 1; + } + if (h == 0) + { + h = 1; + } + if (d == 0) + { + d = 1; + } + } + } + + return (index > 0) ? S_OK : E_FAIL; +} + + +//-------------------------------------------------------------------------------------- +static HRESULT CreateD3DResources( _In_ ID3D11Device* d3dDevice, + _In_ uint32_t resDim, + _In_ size_t width, + _In_ size_t height, + _In_ size_t depth, + _In_ size_t mipCount, + _In_ size_t arraySize, + _In_ DXGI_FORMAT format, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _In_ bool isCubeMap, + _In_reads_opt_(mipCount*arraySize) D3D11_SUBRESOURCE_DATA* initData, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView ) +{ + if ( !d3dDevice ) + return E_POINTER; + + HRESULT hr = E_FAIL; + + if ( forceSRGB ) + { + format = MakeSRGB( format ); + } + + switch ( resDim ) + { + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + { + D3D11_TEXTURE1D_DESC desc; + desc.Width = static_cast( width ); + desc.MipLevels = static_cast( mipCount ); + desc.ArraySize = static_cast( arraySize ); + desc.Format = format; + desc.Usage = usage; + desc.BindFlags = bindFlags; + desc.CPUAccessFlags = cpuAccessFlags; + desc.MiscFlags = miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE; + + ID3D11Texture1D* tex = nullptr; + hr = d3dDevice->CreateTexture1D( &desc, + initData, + &tex + ); + if (SUCCEEDED( hr ) && tex != 0) + { + if (textureView != 0) + { + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + memset( &SRVDesc, 0, sizeof( SRVDesc ) ); + SRVDesc.Format = format; + + if (arraySize > 1) + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; + SRVDesc.Texture1DArray.MipLevels = (!mipCount) ? -1 : desc.MipLevels; + SRVDesc.Texture1DArray.ArraySize = static_cast( arraySize ); + } + else + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; + SRVDesc.Texture1D.MipLevels = (!mipCount) ? -1 : desc.MipLevels; + } + + hr = d3dDevice->CreateShaderResourceView( tex, + &SRVDesc, + textureView + ); + if ( FAILED(hr) ) + { + tex->Release(); + return hr; + } + } + + if (texture != 0) + { + *texture = tex; + } + else + { + SetDebugObjectName(tex, "DDSTextureLoader"); + tex->Release(); + } + } + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + { + D3D11_TEXTURE2D_DESC desc; + desc.Width = static_cast( width ); + desc.Height = static_cast( height ); + desc.MipLevels = static_cast( mipCount ); + desc.ArraySize = static_cast( arraySize ); + desc.Format = format; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = usage; + desc.BindFlags = bindFlags; + desc.CPUAccessFlags = cpuAccessFlags; + if ( isCubeMap ) + { + desc.MiscFlags = miscFlags | D3D11_RESOURCE_MISC_TEXTURECUBE; + } + else + { + desc.MiscFlags = miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE; + } + + ID3D11Texture2D* tex = nullptr; + hr = d3dDevice->CreateTexture2D( &desc, + initData, + &tex + ); + if (SUCCEEDED( hr ) && tex != 0) + { + if (textureView != 0) + { + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + memset( &SRVDesc, 0, sizeof( SRVDesc ) ); + SRVDesc.Format = format; + + if ( isCubeMap ) + { + if (arraySize > 6) + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; + SRVDesc.TextureCubeArray.MipLevels = (!mipCount) ? -1 : desc.MipLevels; + + // Earlier we set arraySize to (NumCubes * 6) + SRVDesc.TextureCubeArray.NumCubes = static_cast( arraySize / 6 ); + } + else + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + SRVDesc.TextureCube.MipLevels = (!mipCount) ? -1 : desc.MipLevels; + } + } + else if (arraySize > 1) + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + SRVDesc.Texture2DArray.MipLevels = (!mipCount) ? -1 : desc.MipLevels; + SRVDesc.Texture2DArray.ArraySize = static_cast( arraySize ); + } + else + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + SRVDesc.Texture2D.MipLevels = (!mipCount) ? -1 : desc.MipLevels; + } + + hr = d3dDevice->CreateShaderResourceView( tex, + &SRVDesc, + textureView + ); + if ( FAILED(hr) ) + { + tex->Release(); + return hr; + } + } + + if (texture != 0) + { + *texture = tex; + } + else + { + SetDebugObjectName(tex, "DDSTextureLoader"); + tex->Release(); + } + } + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + { + D3D11_TEXTURE3D_DESC desc; + desc.Width = static_cast( width ); + desc.Height = static_cast( height ); + desc.Depth = static_cast( depth ); + desc.MipLevels = static_cast( mipCount ); + desc.Format = format; + desc.Usage = usage; + desc.BindFlags = bindFlags; + desc.CPUAccessFlags = cpuAccessFlags; + desc.MiscFlags = miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE; + + ID3D11Texture3D* tex = nullptr; + hr = d3dDevice->CreateTexture3D( &desc, + initData, + &tex + ); + if (SUCCEEDED( hr ) && tex != 0) + { + if (textureView != 0) + { + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + memset( &SRVDesc, 0, sizeof( SRVDesc ) ); + SRVDesc.Format = format; + + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + SRVDesc.Texture3D.MipLevels = (!mipCount) ? -1 : desc.MipLevels; + + hr = d3dDevice->CreateShaderResourceView( tex, + &SRVDesc, + textureView + ); + if ( FAILED(hr) ) + { + tex->Release(); + return hr; + } + } + + if (texture != 0) + { + *texture = tex; + } + else + { + SetDebugObjectName(tex, "DDSTextureLoader"); + tex->Release(); + } + } + } + break; + } + + return hr; +} + + +//-------------------------------------------------------------------------------------- +static HRESULT CreateTextureFromDDS( _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, +#if defined(_XBOX_ONE) && defined(_TITLE) + _In_opt_ ID3D11DeviceX* d3dDeviceX, + _In_opt_ ID3D11DeviceContextX* d3dContextX, +#endif + _In_ const DDS_HEADER* header, + _In_reads_bytes_(bitSize) const uint8_t* bitData, + _In_ size_t bitSize, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView ) +{ + HRESULT hr = S_OK; + + UINT width = header->width; + UINT height = header->height; + UINT depth = header->depth; + + uint32_t resDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + UINT arraySize = 1; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + bool isCubeMap = false; + + size_t mipCount = header->mipMapCount; + if (0 == mipCount) + { + mipCount = 1; + } + + if ((header->ddspf.flags & DDS_FOURCC) && + (MAKEFOURCC( 'D', 'X', '1', '0' ) == header->ddspf.fourCC )) + { + auto d3d10ext = reinterpret_cast( (const char*)header + sizeof(DDS_HEADER) ); + + arraySize = d3d10ext->arraySize; + if (arraySize == 0) + { + return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + } + + switch( d3d10ext->dxgiFormat ) + { + case DXGI_FORMAT_AI44: + case DXGI_FORMAT_IA44: + case DXGI_FORMAT_P8: + case DXGI_FORMAT_A8P8: + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + + default: + if ( BitsPerPixel( d3d10ext->dxgiFormat ) == 0 ) + { + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + } + + format = d3d10ext->dxgiFormat; + + switch ( d3d10ext->resourceDimension ) + { + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + // D3DX writes 1D textures with a fixed Height of 1 + if ((header->flags & DDS_HEIGHT) && height != 1) + { + return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + } + height = depth = 1; + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + if (d3d10ext->miscFlag & D3D11_RESOURCE_MISC_TEXTURECUBE) + { + arraySize *= 6; + isCubeMap = true; + } + depth = 1; + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + if (!(header->flags & DDS_HEADER_FLAGS_VOLUME)) + { + return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + } + + if (arraySize > 1) + { + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + break; + + default: + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + + resDim = d3d10ext->resourceDimension; + } + else + { + format = GetDXGIFormat( header->ddspf ); + + if (format == DXGI_FORMAT_UNKNOWN) + { + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + + if (header->flags & DDS_HEADER_FLAGS_VOLUME) + { + resDim = D3D11_RESOURCE_DIMENSION_TEXTURE3D; + } + else + { + if (header->caps2 & DDS_CUBEMAP) + { + // We require all six faces to be defined + if ((header->caps2 & DDS_CUBEMAP_ALLFACES ) != DDS_CUBEMAP_ALLFACES) + { + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + + arraySize = 6; + isCubeMap = true; + } + + depth = 1; + resDim = D3D11_RESOURCE_DIMENSION_TEXTURE2D; + + // Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture + } + + assert( BitsPerPixel( format ) != 0 ); + } + + // Bound sizes (for security purposes we don't trust DDS file metadata larger than the D3D 11.x hardware requirements) + if (mipCount > D3D11_REQ_MIP_LEVELS) + { + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + + switch ( resDim ) + { + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + if ((arraySize > D3D11_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION) || + (width > D3D11_REQ_TEXTURE1D_U_DIMENSION) ) + { + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + if ( isCubeMap ) + { + // This is the right bound because we set arraySize to (NumCubes*6) above + if ((arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) || + (width > D3D11_REQ_TEXTURECUBE_DIMENSION) || + (height > D3D11_REQ_TEXTURECUBE_DIMENSION)) + { + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + } + else if ((arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) || + (width > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION) || + (height > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION)) + { + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + if ((arraySize > 1) || + (width > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) || + (height > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) || + (depth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) ) + { + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + break; + + default: + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + + bool autogen = false; + if ( mipCount == 1 && d3dContext != 0 && textureView != 0 ) // Must have context and shader-view to auto generate mipmaps + { + // See if format is supported for auto-gen mipmaps (varies by feature level) + UINT fmtSupport = 0; + hr = d3dDevice->CheckFormatSupport( format, &fmtSupport ); + if ( SUCCEEDED(hr) && ( fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) ) + { + // 10level9 feature levels do not support auto-gen mipgen for volume textures + if ( ( resDim != D3D11_RESOURCE_DIMENSION_TEXTURE3D ) + || ( d3dDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 ) ) + { + autogen = true; +#if defined(_XBOX_ONE) && defined(_TITLE) + if ( !d3dDeviceX || !d3dContextX ) + return E_INVALIDARG; +#endif + } + } + } + + if ( autogen ) + { + // Create texture with auto-generated mipmaps + ID3D11Resource* tex = nullptr; + hr = CreateD3DResources( d3dDevice, resDim, width, height, depth, 0, arraySize, + format, usage, + bindFlags | D3D11_BIND_RENDER_TARGET, + cpuAccessFlags, + miscFlags | D3D11_RESOURCE_MISC_GENERATE_MIPS, forceSRGB, + isCubeMap, nullptr, &tex, textureView ); + if ( SUCCEEDED(hr) ) + { + size_t numBytes = 0; + size_t rowBytes = 0; + GetSurfaceInfo( width, height, format, &numBytes, &rowBytes, nullptr ); + + if ( numBytes > bitSize ) + { + (*textureView)->Release(); + *textureView = nullptr; + tex->Release(); + return HRESULT_FROM_WIN32( ERROR_HANDLE_EOF ); + } + + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + (*textureView)->GetDesc( &desc ); + + UINT mipLevels = 1; + + switch( desc.ViewDimension ) + { + case D3D_SRV_DIMENSION_TEXTURE1D: mipLevels = desc.Texture1D.MipLevels; break; + case D3D_SRV_DIMENSION_TEXTURE1DARRAY: mipLevels = desc.Texture1DArray.MipLevels; break; + case D3D_SRV_DIMENSION_TEXTURE2D: mipLevels = desc.Texture2D.MipLevels; break; + case D3D_SRV_DIMENSION_TEXTURE2DARRAY: mipLevels = desc.Texture2DArray.MipLevels; break; + case D3D_SRV_DIMENSION_TEXTURECUBE: mipLevels = desc.TextureCube.MipLevels; break; + case D3D_SRV_DIMENSION_TEXTURECUBEARRAY:mipLevels = desc.TextureCubeArray.MipLevels; break; + case D3D_SRV_DIMENSION_TEXTURE3D: mipLevels = desc.Texture3D.MipLevels; break; + default: + (*textureView)->Release(); + *textureView = nullptr; + tex->Release(); + return E_UNEXPECTED; + } + +#if defined(_XBOX_ONE) && defined(_TITLE) + + std::unique_ptr initData( new (std::nothrow) D3D11_SUBRESOURCE_DATA[ arraySize ] ); + if ( !initData ) + { + return E_OUTOFMEMORY; + } + + const uint8_t* pSrcBits = bitData; + const uint8_t* pEndBits = bitData + bitSize; + for( UINT item = 0; item < arraySize; ++item ) + { + if ( (pSrcBits + numBytes) > pEndBits ) + { + (*textureView)->Release(); + *textureView = nullptr; + tex->Release(); + return HRESULT_FROM_WIN32( ERROR_HANDLE_EOF ); + } + + initData[item].pSysMem = pSrcBits; + initData[item].SysMemPitch = static_cast(rowBytes); + initData[item].SysMemSlicePitch = static_cast(numBytes); + pSrcBits += numBytes; + } + + ID3D11Resource* pStaging = nullptr; + switch( resDim ) + { + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + { + ID3D11Texture1D *temp = nullptr; + CD3D11_TEXTURE1D_DESC stagingDesc( format, width, arraySize, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ ); + hr = d3dDevice->CreateTexture1D( &stagingDesc, initData.get(), &temp ); + if ( SUCCEEDED(hr) ) + pStaging = temp; + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + { + ID3D11Texture2D *temp = nullptr; + CD3D11_TEXTURE2D_DESC stagingDesc( format, width, height, arraySize, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ, 1, 0, isCubeMap ? D3D11_RESOURCE_MISC_TEXTURECUBE : 0 ); + hr = d3dDevice->CreateTexture2D( &stagingDesc, initData.get(), &temp ); + if ( SUCCEEDED(hr) ) + pStaging = temp; + } + break; + + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + { + ID3D11Texture3D *temp = nullptr; + CD3D11_TEXTURE3D_DESC stagingDesc( format, width, height, depth, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ ); + hr = d3dDevice->CreateTexture3D( &stagingDesc, initData.get(), &temp ); + if ( SUCCEEDED(hr) ) + pStaging = temp; + } + break; + }; + + if ( SUCCEEDED(hr) ) + { + for( UINT item = 0; item < arraySize; ++item ) + { + UINT res = D3D11CalcSubresource( 0, item, mipLevels ); + d3dContext->CopySubresourceRegion( tex, res, 0, 0, 0, pStaging, item, nullptr ); + } + + UINT64 copyFence = d3dContextX->InsertFence(0); + while( d3dDeviceX->IsFencePending( copyFence ) ) { SwitchToThread(); } + pStaging->Release(); + } +#else + if ( arraySize > 1 ) + { + const uint8_t* pSrcBits = bitData; + const uint8_t* pEndBits = bitData + bitSize; + for( UINT item = 0; item < arraySize; ++item ) + { + if ( (pSrcBits + numBytes) > pEndBits ) + { + (*textureView)->Release(); + *textureView = nullptr; + tex->Release(); + return HRESULT_FROM_WIN32( ERROR_HANDLE_EOF ); + } + + UINT res = D3D11CalcSubresource( 0, item, mipLevels ); + d3dContext->UpdateSubresource( tex, res, nullptr, pSrcBits, static_cast(rowBytes), static_cast(numBytes) ); + pSrcBits += numBytes; + } + } + else + { + d3dContext->UpdateSubresource( tex, 0, nullptr, bitData, static_cast(rowBytes), static_cast(numBytes) ); + } +#endif + + d3dContext->GenerateMips( *textureView ); + + if ( texture ) + { + *texture = tex; + } + else + { + tex->Release(); + } + } + } + else + { + // Create the texture + std::unique_ptr initData( new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] ); + if ( !initData ) + { + return E_OUTOFMEMORY; + } + + size_t skipMip = 0; + size_t twidth = 0; + size_t theight = 0; + size_t tdepth = 0; + hr = FillInitData( width, height, depth, mipCount, arraySize, format, maxsize, bitSize, bitData, + twidth, theight, tdepth, skipMip, initData.get() ); + + if ( SUCCEEDED(hr) ) + { + hr = CreateD3DResources( d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize, + format, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, + isCubeMap, initData.get(), texture, textureView ); + + if ( FAILED(hr) && !maxsize && (mipCount > 1) ) + { + // Retry with a maxsize determined by feature level + switch( d3dDevice->GetFeatureLevel() ) + { + case D3D_FEATURE_LEVEL_9_1: + case D3D_FEATURE_LEVEL_9_2: + if ( isCubeMap ) + { + maxsize = 512 /*D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION*/; + } + else + { + maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) + ? 256 /*D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/ + : 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; + } + break; + + case D3D_FEATURE_LEVEL_9_3: + maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) + ? 256 /*D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/ + : 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; + break; + + default: // D3D_FEATURE_LEVEL_10_0 & D3D_FEATURE_LEVEL_10_1 + maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) + ? 2048 /*D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/ + : 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; + break; + } + + hr = FillInitData( width, height, depth, mipCount, arraySize, format, maxsize, bitSize, bitData, + twidth, theight, tdepth, skipMip, initData.get() ); + if ( SUCCEEDED(hr) ) + { + hr = CreateD3DResources( d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize, + format, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, + isCubeMap, initData.get(), texture, textureView ); + } + } + } + } + + return hr; +} + + +//-------------------------------------------------------------------------------------- +static DDS_ALPHA_MODE GetAlphaMode( _In_ const DDS_HEADER* header ) +{ + if ( header->ddspf.flags & DDS_FOURCC ) + { + if ( MAKEFOURCC( 'D', 'X', '1', '0' ) == header->ddspf.fourCC ) + { + auto d3d10ext = reinterpret_cast( (const char*)header + sizeof(DDS_HEADER) ); + auto mode = static_cast( d3d10ext->miscFlags2 & DDS_MISC_FLAGS2_ALPHA_MODE_MASK ); + switch( mode ) + { + case DDS_ALPHA_MODE_STRAIGHT: + case DDS_ALPHA_MODE_PREMULTIPLIED: + case DDS_ALPHA_MODE_OPAQUE: + case DDS_ALPHA_MODE_CUSTOM: + return mode; + } + } + else if ( ( MAKEFOURCC( 'D', 'X', 'T', '2' ) == header->ddspf.fourCC ) + || ( MAKEFOURCC( 'D', 'X', 'T', '4' ) == header->ddspf.fourCC ) ) + { + return DDS_ALPHA_MODE_PREMULTIPLIED; + } + } + + return DDS_ALPHA_MODE_UNKNOWN; +} + + +//-------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT DirectX::CreateDDSTextureFromMemory( ID3D11Device* d3dDevice, + const uint8_t* ddsData, + size_t ddsDataSize, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + size_t maxsize, + DDS_ALPHA_MODE* alphaMode ) +{ + return CreateDDSTextureFromMemoryEx( d3dDevice, ddsData, ddsDataSize, maxsize, + D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, + texture, textureView, alphaMode ); +} + +_Use_decl_annotations_ +#if defined(_XBOX_ONE) && defined(_TITLE) +HRESULT DirectX::CreateDDSTextureFromMemory( ID3D11DeviceX* d3dDevice, + ID3D11DeviceContextX* d3dContext, +#else +HRESULT DirectX::CreateDDSTextureFromMemory( ID3D11Device* d3dDevice, + ID3D11DeviceContext* d3dContext, +#endif + const uint8_t* ddsData, + size_t ddsDataSize, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + size_t maxsize, + DDS_ALPHA_MODE* alphaMode ) +{ + return CreateDDSTextureFromMemoryEx( d3dDevice, d3dContext, ddsData, ddsDataSize, maxsize, + D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, + texture, textureView, alphaMode ); +} + +_Use_decl_annotations_ +HRESULT DirectX::CreateDDSTextureFromMemoryEx( ID3D11Device* d3dDevice, + const uint8_t* ddsData, + size_t ddsDataSize, + size_t maxsize, + D3D11_USAGE usage, + unsigned int bindFlags, + unsigned int cpuAccessFlags, + unsigned int miscFlags, + bool forceSRGB, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + DDS_ALPHA_MODE* alphaMode ) +{ + if ( texture ) + { + *texture = nullptr; + } + if ( textureView ) + { + *textureView = nullptr; + } + if ( alphaMode ) + { + *alphaMode = DDS_ALPHA_MODE_UNKNOWN; + } + + if (!d3dDevice || !ddsData || (!texture && !textureView)) + { + return E_INVALIDARG; + } + + // Validate DDS file in memory + if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER))) + { + return E_FAIL; + } + + uint32_t dwMagicNumber = *( const uint32_t* )( ddsData ); + if (dwMagicNumber != DDS_MAGIC) + { + return E_FAIL; + } + + auto header = reinterpret_cast( ddsData + sizeof( uint32_t ) ); + + // Verify header to validate DDS file + if (header->size != sizeof(DDS_HEADER) || + header->ddspf.size != sizeof(DDS_PIXELFORMAT)) + { + return E_FAIL; + } + + // Check for DX10 extension + bool bDXT10Header = false; + if ((header->ddspf.flags & DDS_FOURCC) && + (MAKEFOURCC( 'D', 'X', '1', '0' ) == header->ddspf.fourCC) ) + { + // Must be long enough for both headers and magic value + if (ddsDataSize < (sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_DXT10))) + { + return E_FAIL; + } + + bDXT10Header = true; + } + + ptrdiff_t offset = sizeof( uint32_t ) + + sizeof( DDS_HEADER ) + + (bDXT10Header ? sizeof( DDS_HEADER_DXT10 ) : 0); + + HRESULT hr = CreateTextureFromDDS( d3dDevice, nullptr, +#if defined(_XBOX_ONE) && defined(_TITLE) + nullptr, nullptr, +#endif + header, ddsData + offset, ddsDataSize - offset, maxsize, + usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, + texture, textureView ); + if ( SUCCEEDED(hr) ) + { + if (texture != 0 && *texture != 0) + { + SetDebugObjectName(*texture, "DDSTextureLoader"); + } + + if (textureView != 0 && *textureView != 0) + { + SetDebugObjectName(*textureView, "DDSTextureLoader"); + } + + if ( alphaMode ) + *alphaMode = GetAlphaMode( header ); + } + + return hr; +} + +_Use_decl_annotations_ +#if defined(_XBOX_ONE) && defined(_TITLE) +HRESULT DirectX::CreateDDSTextureFromMemoryEx( ID3D11DeviceX* d3dDevice, + ID3D11DeviceContextX* d3dContext, +#else +HRESULT DirectX::CreateDDSTextureFromMemoryEx( ID3D11Device* d3dDevice, + ID3D11DeviceContext* d3dContext, +#endif + const uint8_t* ddsData, + size_t ddsDataSize, + size_t maxsize, + D3D11_USAGE usage, + unsigned int bindFlags, + unsigned int cpuAccessFlags, + unsigned int miscFlags, + bool forceSRGB, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + DDS_ALPHA_MODE* alphaMode ) +{ + if ( texture ) + { + *texture = nullptr; + } + if ( textureView ) + { + *textureView = nullptr; + } + if ( alphaMode ) + { + *alphaMode = DDS_ALPHA_MODE_UNKNOWN; + } + + if (!d3dDevice || !ddsData || (!texture && !textureView)) + { + return E_INVALIDARG; + } + + // Validate DDS file in memory + if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER))) + { + return E_FAIL; + } + + uint32_t dwMagicNumber = *( const uint32_t* )( ddsData ); + if (dwMagicNumber != DDS_MAGIC) + { + return E_FAIL; + } + + auto header = reinterpret_cast( ddsData + sizeof( uint32_t ) ); + + // Verify header to validate DDS file + if (header->size != sizeof(DDS_HEADER) || + header->ddspf.size != sizeof(DDS_PIXELFORMAT)) + { + return E_FAIL; + } + + // Check for DX10 extension + bool bDXT10Header = false; + if ((header->ddspf.flags & DDS_FOURCC) && + (MAKEFOURCC( 'D', 'X', '1', '0' ) == header->ddspf.fourCC) ) + { + // Must be long enough for both headers and magic value + if (ddsDataSize < (sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_DXT10))) + { + return E_FAIL; + } + + bDXT10Header = true; + } + + ptrdiff_t offset = sizeof( uint32_t ) + + sizeof( DDS_HEADER ) + + (bDXT10Header ? sizeof( DDS_HEADER_DXT10 ) : 0); + + HRESULT hr = CreateTextureFromDDS( d3dDevice, d3dContext, +#if defined(_XBOX_ONE) && defined(_TITLE) + d3dDevice, d3dContext, +#endif + header, ddsData + offset, ddsDataSize - offset, maxsize, + usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, + texture, textureView ); + if ( SUCCEEDED(hr) ) + { + if (texture != 0 && *texture != 0) + { + SetDebugObjectName(*texture, "DDSTextureLoader"); + } + + if (textureView != 0 && *textureView != 0) + { + SetDebugObjectName(*textureView, "DDSTextureLoader"); + } + + if ( alphaMode ) + *alphaMode = GetAlphaMode( header ); + } + + return hr; +} + +//-------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT DirectX::CreateDDSTextureFromFile( ID3D11Device* d3dDevice, + const wchar_t* fileName, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + size_t maxsize, + DDS_ALPHA_MODE* alphaMode ) +{ + return CreateDDSTextureFromFileEx( d3dDevice, fileName, maxsize, + D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, + texture, textureView, alphaMode ); +} + +_Use_decl_annotations_ +#if defined(_XBOX_ONE) && defined(_TITLE) +HRESULT DirectX::CreateDDSTextureFromFile( ID3D11DeviceX* d3dDevice, + ID3D11DeviceContextX* d3dContext, +#else +HRESULT DirectX::CreateDDSTextureFromFile( ID3D11Device* d3dDevice, + ID3D11DeviceContext* d3dContext, +#endif + const wchar_t* fileName, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + size_t maxsize, + DDS_ALPHA_MODE* alphaMode ) +{ + return CreateDDSTextureFromFileEx( d3dDevice, d3dContext, fileName, maxsize, + D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, + texture, textureView, alphaMode ); +} + +_Use_decl_annotations_ +HRESULT DirectX::CreateDDSTextureFromFileEx( ID3D11Device* d3dDevice, + const wchar_t* fileName, + size_t maxsize, + D3D11_USAGE usage, + unsigned int bindFlags, + unsigned int cpuAccessFlags, + unsigned int miscFlags, + bool forceSRGB, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + DDS_ALPHA_MODE* alphaMode ) +{ + if ( texture ) + { + *texture = nullptr; + } + if ( textureView ) + { + *textureView = nullptr; + } + if ( alphaMode ) + { + *alphaMode = DDS_ALPHA_MODE_UNKNOWN; + } + + if (!d3dDevice || !fileName || (!texture && !textureView)) + { + return E_INVALIDARG; + } + + DDS_HEADER* header = nullptr; + uint8_t* bitData = nullptr; + size_t bitSize = 0; + + std::unique_ptr ddsData; + HRESULT hr = LoadTextureDataFromFile( fileName, + ddsData, + &header, + &bitData, + &bitSize + ); + if (FAILED(hr)) + { + return hr; + } + + hr = CreateTextureFromDDS( d3dDevice, nullptr, +#if defined(_XBOX_ONE) && defined(_TITLE) + nullptr, nullptr, +#endif + header, bitData, bitSize, maxsize, + usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, + texture, textureView ); + + if ( SUCCEEDED(hr) ) + { +#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) + if (texture != 0 || textureView != 0) + { + CHAR strFileA[MAX_PATH]; + int result = WideCharToMultiByte( CP_ACP, + WC_NO_BEST_FIT_CHARS, + fileName, + -1, + strFileA, + MAX_PATH, + nullptr, + FALSE + ); + if ( result > 0 ) + { + const CHAR* pstrName = strrchr( strFileA, '\\' ); + if (!pstrName) + { + pstrName = strFileA; + } + else + { + pstrName++; + } + + if (texture != 0 && *texture != 0) + { + (*texture)->SetPrivateData( WKPDID_D3DDebugObjectName, + static_cast( strnlen_s(pstrName, MAX_PATH) ), + pstrName + ); + } + + if (textureView != 0 && *textureView != 0 ) + { + (*textureView)->SetPrivateData( WKPDID_D3DDebugObjectName, + static_cast( strnlen_s(pstrName, MAX_PATH) ), + pstrName + ); + } + } + } +#endif + + if ( alphaMode ) + *alphaMode = GetAlphaMode( header ); + } + + return hr; +} + +_Use_decl_annotations_ +#if defined(_XBOX_ONE) && defined(_TITLE) +HRESULT DirectX::CreateDDSTextureFromFileEx( ID3D11DeviceX* d3dDevice, + ID3D11DeviceContextX* d3dContext, +#else +HRESULT DirectX::CreateDDSTextureFromFileEx( ID3D11Device* d3dDevice, + ID3D11DeviceContext* d3dContext, +#endif + const wchar_t* fileName, + size_t maxsize, + D3D11_USAGE usage, + unsigned int bindFlags, + unsigned int cpuAccessFlags, + unsigned int miscFlags, + bool forceSRGB, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + DDS_ALPHA_MODE* alphaMode ) +{ + if ( texture ) + { + *texture = nullptr; + } + if ( textureView ) + { + *textureView = nullptr; + } + if ( alphaMode ) + { + *alphaMode = DDS_ALPHA_MODE_UNKNOWN; + } + + if (!d3dDevice || !fileName || (!texture && !textureView)) + { + return E_INVALIDARG; + } + + DDS_HEADER* header = nullptr; + uint8_t* bitData = nullptr; + size_t bitSize = 0; + + std::unique_ptr ddsData; + HRESULT hr = LoadTextureDataFromFile( fileName, + ddsData, + &header, + &bitData, + &bitSize + ); + if (FAILED(hr)) + { + return hr; + } + + hr = CreateTextureFromDDS( d3dDevice, d3dContext, +#if defined(_XBOX_ONE) && defined(_TITLE) + d3dDevice, d3dContext, +#endif + header, bitData, bitSize, maxsize, + usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, + texture, textureView ); + + if ( SUCCEEDED(hr) ) + { +#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) + if (texture != 0 || textureView != 0) + { + CHAR strFileA[MAX_PATH]; + int result = WideCharToMultiByte( CP_ACP, + WC_NO_BEST_FIT_CHARS, + fileName, + -1, + strFileA, + MAX_PATH, + nullptr, + FALSE + ); + if ( result > 0 ) + { + const CHAR* pstrName = strrchr( strFileA, '\\' ); + if (!pstrName) + { + pstrName = strFileA; + } + else + { + pstrName++; + } + + if (texture != 0 && *texture != 0) + { + (*texture)->SetPrivateData( WKPDID_D3DDebugObjectName, + static_cast( strnlen_s(pstrName, MAX_PATH) ), + pstrName + ); + } + + if (textureView != 0 && *textureView != 0 ) + { + (*textureView)->SetPrivateData( WKPDID_D3DDebugObjectName, + static_cast( strnlen_s(pstrName, MAX_PATH) ), + pstrName + ); + } + } + } +#endif + + if ( alphaMode ) + *alphaMode = GetAlphaMode( header ); + } + + return hr; +} diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/DDSTextureLoader.h b/xbmc/visualizations/Vortex/VortexVis/Core/DDSTextureLoader.h new file mode 100644 index 0000000000..3fd76ff3da --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/DDSTextureLoader.h @@ -0,0 +1,156 @@ +//-------------------------------------------------------------------------------------- +// File: DDSTextureLoader.h +// +// Functions for loading a DDS texture and creating a Direct3D 11 runtime resource for it +// +// Note these functions are useful as a light-weight runtime loader for DDS files. For +// a full-featured DDS file reader, writer, and texture processing pipeline see +// the 'Texconv' sample and the 'DirectXTex' library. +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkId=248926 +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#include + +#pragma warning(push) +#pragma warning(disable : 4005) +#include +#pragma warning(pop) + +namespace DirectX +{ + enum DDS_ALPHA_MODE + { + DDS_ALPHA_MODE_UNKNOWN = 0, + DDS_ALPHA_MODE_STRAIGHT = 1, + DDS_ALPHA_MODE_PREMULTIPLIED = 2, + DDS_ALPHA_MODE_OPAQUE = 3, + DDS_ALPHA_MODE_CUSTOM = 4, + }; + + // Standard version + HRESULT __cdecl CreateDDSTextureFromMemory( _In_ ID3D11Device* d3dDevice, + _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, + _In_ size_t ddsDataSize, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr + ); + + HRESULT __cdecl CreateDDSTextureFromFile( _In_ ID3D11Device* d3dDevice, + _In_z_ const wchar_t* szFileName, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr + ); + + // Standard version with optional auto-gen mipmap support + #if defined(_XBOX_ONE) && defined(_TITLE) + HRESULT __cdecl CreateDDSTextureFromMemory( _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + HRESULT __cdecl CreateDDSTextureFromMemory( _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, + _In_ size_t ddsDataSize, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr + ); + + #if defined(_XBOX_ONE) && defined(_TITLE) + HRESULT __cdecl CreateDDSTextureFromFile( _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + HRESULT __cdecl CreateDDSTextureFromFile( _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_z_ const wchar_t* szFileName, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr + ); + + // Extended version + HRESULT __cdecl CreateDDSTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, + _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, + _In_ size_t ddsDataSize, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr + ); + + HRESULT __cdecl CreateDDSTextureFromFileEx( _In_ ID3D11Device* d3dDevice, + _In_z_ const wchar_t* szFileName, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr + ); + + // Extended version with optional auto-gen mipmap support + #if defined(_XBOX_ONE) && defined(_TITLE) + HRESULT __cdecl CreateDDSTextureFromMemoryEx( _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + HRESULT __cdecl CreateDDSTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, + _In_ size_t ddsDataSize, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr + ); + + #if defined(_XBOX_ONE) && defined(_TITLE) + HRESULT __cdecl CreateDDSTextureFromFileEx( _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + HRESULT __cdecl CreateDDSTextureFromFileEx( _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_z_ const wchar_t* szFileName, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr + ); +} \ No newline at end of file diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/DebugConsole.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/DebugConsole.cpp index 09ba6734c1..8eac61b25a 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/DebugConsole.cpp +++ b/xbmc/visualizations/Vortex/VortexVis/Core/DebugConsole.cpp @@ -92,14 +92,14 @@ void DebugConsole::Render() // if ( bHasError == false ) // return; - int iViewportHeight = Renderer::GetViewportHeight(); + float iViewportHeight = Renderer::GetViewportHeight(); int iLineToDraw = iCurrentLine - 1; if ( iLineToDraw < 0 ) iLineToDraw += NUM_LINES; for ( int iLine = NUM_LINES - 1; iLine >= 0; iLine-- ) { - Renderer::DrawText( 0, ( float )iViewportHeight - ( ( NUM_LINES - iLine )* iLineHeight ), Lines[ iLineToDraw ].Txt, Lines[ iLineToDraw ].Col ); + Renderer::DrawText( 0, iViewportHeight - ( ( NUM_LINES - iLine )* iLineHeight ), Lines[ iLineToDraw ].Txt, Lines[ iLineToDraw ].Col ); iLineToDraw = ( iLineToDraw - 1 ); if ( iLineToDraw < 0 ) iLineToDraw += NUM_LINES; diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/DemandCreate.h b/xbmc/visualizations/Vortex/VortexVis/Core/DemandCreate.h new file mode 100644 index 0000000000..ea9fe0fab3 --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/DemandCreate.h @@ -0,0 +1,48 @@ +//-------------------------------------------------------------------------------------- +// File: DemandCreate.h +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#include + +namespace DirectX +{ + // Helper for lazily creating a D3D resource. + template + static T* DemandCreate(Microsoft::WRL::ComPtr& comPtr, std::mutex& mutex, TCreateFunc createFunc) + { + T* result = comPtr.Get(); + + // Double-checked lock pattern. + MemoryBarrier(); + + if (!result) + { + std::lock_guard lock(mutex); + + result = comPtr.Get(); + + if (!result) + { + // Create the new object. + createFunc(&result); + + MemoryBarrier(); + + comPtr.Attach(result); + } + } + + return result; + } +} diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/DirectXHelpers.h b/xbmc/visualizations/Vortex/VortexVis/Core/DirectXHelpers.h new file mode 100644 index 0000000000..2d1559971c --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/DirectXHelpers.h @@ -0,0 +1,116 @@ +//-------------------------------------------------------------------------------------- +// File: DirectXHelpers.h +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#define NO_D3D11_DEBUG_NAME +#else +#include +#endif + +#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) +#pragma comment(lib,"dxguid.lib") +#endif + +#include + +#pragma warning(push) +#pragma warning(disable : 4005) +#include +#pragma warning(pop) + +#include +#include + +namespace DirectX +{ + // simliar to std::lock_guard for exception-safe Direct3D 11 resource locking + class MapGuard : public D3D11_MAPPED_SUBRESOURCE + { + public: + MapGuard( _In_ ID3D11DeviceContext* context, + _In_ ID3D11Resource *resource, + _In_ UINT subresource, + _In_ D3D11_MAP mapType, + _In_ UINT mapFlags ) + : mContext(context), mResource(resource), mSubresource(subresource) + { + HRESULT hr = mContext->Map( resource, subresource, mapType, mapFlags, this ); + if (FAILED(hr)) + { + throw std::exception(); + } + } + + ~MapGuard() + { + mContext->Unmap( mResource, mSubresource ); + } + + uint8_t* get() const + { + return reinterpret_cast( pData ); + } + uint8_t* get(size_t slice) const + { + return reinterpret_cast( pData ) + ( slice * DepthPitch ); + } + + uint8_t* scanline(size_t row) const + { + return reinterpret_cast( pData ) + ( row * RowPitch ); + } + uint8_t* scanline(size_t slice, size_t row) const + { + return reinterpret_cast( pData ) + ( slice * DepthPitch ) + ( row * RowPitch ); + } + + private: + ID3D11DeviceContext* mContext; + ID3D11Resource* mResource; + UINT mSubresource; + + MapGuard(MapGuard const&); + MapGuard& operator= (MapGuard const&); + }; + + + // Helper sets a D3D resource name string (used by PIX and debug layer leak reporting). + template + inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_ const char (&name)[TNameLength]) + { + #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) + resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, name); + #else + UNREFERENCED_PARAMETER(resource); + UNREFERENCED_PARAMETER(name); + #endif + } + + inline std::string GetExtension(std::string& filename) + { + size_t lastDotIndex = filename.rfind('.'); + if (lastDotIndex != std::string::npos) + { + std::unique_ptr extension(new char[filename.size() - lastDotIndex]); + for (unsigned int i = 0; i < filename.size() - lastDotIndex; i++) + { + extension[i] = tolower(*(filename.c_str() + lastDotIndex + 1 + i)); + } + return std::string(extension.get()); + } + return ""; + } +} \ No newline at end of file diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/EffectBase.h b/xbmc/visualizations/Vortex/VortexVis/Core/EffectBase.h index c58c696f6f..691d1b513e 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/EffectBase.h +++ b/xbmc/visualizations/Vortex/VortexVis/Core/EffectBase.h @@ -20,7 +20,7 @@ #ifndef _EFFECT_H_ #define _EFFECT_H_ -struct IDirect3DTexture9; +#include "TextureDX.h" class EffectBase { @@ -44,8 +44,7 @@ public: delete this; } - virtual IDirect3DTexture9* GetTexture() { return 0; } - virtual IDirect3DTexture9* GetRenderTarget() { return 0; } + virtual TextureDX* GetTexture() { return 0; } protected: int m_iRefCount; diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/Mesh.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/Mesh.cpp index 411851e2f6..b51a6d114d 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/Mesh.cpp +++ b/xbmc/visualizations/Vortex/VortexVis/Core/Mesh.cpp @@ -21,8 +21,6 @@ #include #include -using namespace std; - Mesh::Mesh() { m_iRefCount = 1; @@ -53,7 +51,7 @@ void Mesh::Release() delete this; } -void Mesh::CreateTextMesh( string& InString, bool bCentered ) +void Mesh::CreateTextMesh( std::string& InString, bool bCentered ) { if ( m_pMesh ) { diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/Mesh.h b/xbmc/visualizations/Vortex/VortexVis/Core/Mesh.h index ff63266fdf..047f5e142a 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/Mesh.h +++ b/xbmc/visualizations/Vortex/VortexVis/Core/Mesh.h @@ -31,12 +31,12 @@ public: void AddRef(); void Release(); - LPD3DXMESH GetMesh() { return m_pMesh; }; + IUnknown* GetMesh() { return m_pMesh; }; protected: ~Mesh(); int m_iRefCount; - LPD3DXMESH m_pMesh; + IUnknown* m_pMesh; }; diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/Renderer.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/Renderer.cpp index ffd39b99c8..55839e82ce 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/Renderer.cpp +++ b/xbmc/visualizations/Vortex/VortexVis/Core/Renderer.cpp @@ -18,71 +18,98 @@ */ #include "Renderer.h" -#include #include "DebugConsole.h" #include #include "Shader.h" - -D3DVERTEXELEMENT9 declPosNormalColUV[] = -{ // stream, offset, type, method, usage, usage index - { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, - { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, -// { 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, - { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, - { 0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, - D3DDECL_END() +#include "DirectXHelpers.h" +#include +#include +#include "DDSTextureLoader.h" +#include "WICTextureLoader.h" +#include "XMMatrixStack.h" + +using namespace DirectX; +using namespace DirectX::PackedVector; + +D3D11_INPUT_ELEMENT_DESC declPosNormalColUV[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; -D3DVERTEXELEMENT9 declPosColUV[] = -{ // stream, offset, type, method, usage, usage index - { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, -// { 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, - { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, - { 0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, - D3DDECL_END() +D3D11_INPUT_ELEMENT_DESC declPosColUV[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; -D3DVERTEXELEMENT9 declPosNormal[] = -{ // stream, offset, type, method, usage, usage index - { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, - { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, - D3DDECL_END() +D3D11_INPUT_ELEMENT_DESC declPosNormal[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; +ID3D11InputLayout* g_pPosNormalColUVDeclaration = NULL; +ID3D11InputLayout* g_pPosColUVDeclaration = NULL; +ID3D11InputLayout* g_pPosNormalDeclaration = NULL; + +namespace +{ + #include "../Shaders/ColorPixelShader.inc" + #include "../Shaders/TexturePixelShader.inc" +} + +class ColorPixelShader : public Shader +{ + DECLARE_SHADER(ColorPixelShader); +public: + ColorPixelShader(EShaderType ShaderType, const void* pShaderCode, unsigned int iCodeLen) : Shader(ShaderType, pShaderCode, iCodeLen){}; +}; +class TexturePixelShader : public Shader +{ + DECLARE_SHADER(TexturePixelShader); +public: + TexturePixelShader(EShaderType ShaderType, const void* pShaderCode, unsigned int iCodeLen) : Shader(ShaderType, pShaderCode, iCodeLen){}; +}; -LPDIRECT3DVERTEXDECLARATION9 g_pPosNormalColUVDeclaration = NULL; -LPDIRECT3DVERTEXDECLARATION9 g_pPosColUVDeclaration = NULL; -LPDIRECT3DVERTEXDECLARATION9 g_pPosNormalDeclaration = NULL; +IMPLEMENT_SHADER(ColorPixelShader, ColorPixelShaderCode, sizeof(ColorPixelShaderCode), ST_PIXEL); +IMPLEMENT_SHADER(TexturePixelShader, TexturePixelShaderCode, sizeof(TexturePixelShaderCode), ST_PIXEL); namespace { - LPDIRECT3DVERTEXBUFFER9 g_pCubeVbuffer = NULL; - LPDIRECT3DINDEXBUFFER9 g_pCubeIbuffer = NULL; - LPDIRECT3DDEVICE9 m_pD3DDevice = NULL; - IDirect3DSurface9* g_backBuffer; - IDirect3DSurface9* g_depthBuffer; - IDirect3DSurface9* g_oldDepthBuffer; - LPDIRECT3DTEXTURE9 m_pTextureFont = NULL; - D3DVIEWPORT9 g_viewport; - D3DXMATRIX g_matProj; - D3DXMATRIX g_matView; + ID3D11Buffer* g_pCubeVbuffer = NULL; + ID3D11Buffer* g_pCubeIbuffer = NULL; + ID3D11Buffer* g_pFanIbuffer = NULL; + ID3D11Buffer* g_pFixVbuffer = NULL; + ID3D11Device* m_pD3D11Device = NULL; + ID3D11DeviceContext* m_pD3D11Contex = NULL; + ID3D11RenderTargetView* g_backBuffer = NULL; + ID3D11DepthStencilView* g_depthView = NULL; + ID3D11DepthStencilView* g_oldDepthBuffer = NULL; + TextureDX* m_pTextureFont = NULL; + D3D11_VIEWPORT g_viewport; + XMMATRIX g_matProj; + XMMATRIX g_matView; float g_aspect; float g_defaultAspect; float g_aspectValue; float g_tex0U; float g_tex0V; - DWORD g_colour; - D3DXVECTOR4 g_fColour; - D3DXVECTOR3 g_normal; - ID3DXMatrixStack* g_matrixStack; + XMFLOAT4 g_fColour; + XMVECTOR g_normal; + XMMatrixStack* g_matrixStack = NULL; int g_matrixStackLevel; bool g_envMapSet; bool g_textureSet; + std::shared_ptr states; D3DPRIMITIVETYPE g_primType; - LPDIRECT3DTEXTURE9 g_scratchTexture; + TextureDX* g_scratchTexture = NULL; HFONT g_hFont; // Vertices @@ -100,44 +127,40 @@ namespace ETextureStageMode CurrentTextureStageMode = TSM_INVALID; } -void Renderer::Init( LPDIRECT3DDEVICE9 pD3DDevice, int iXPos, int iYPos, int iWidth, int iHeight, float fPixelRatio ) +void Renderer::Init( ID3D11DeviceContext* pD3DContext, int iXPos, int iYPos, int iWidth, int iHeight, float fPixelRatio ) { DebugConsole::Log("Renderer: Viewport x%d, y%d, w%d, h%d, pixel%f\n", iXPos, iYPos, iWidth, iHeight, fPixelRatio ); - m_pD3DDevice = pD3DDevice; - g_viewport.X = iXPos; - g_viewport.Y = iYPos; - g_viewport.Width = iWidth; - g_viewport.Height = iHeight; - g_viewport.MinZ = 0; - g_viewport.MaxZ = 1; + m_pD3D11Contex = pD3DContext; + pD3DContext->GetDevice(&m_pD3D11Device); + g_viewport.TopLeftX = (float)iXPos; + g_viewport.TopLeftY = (float)iYPos; + g_viewport.Width = (float)iWidth; + g_viewport.Height = (float)iHeight; + g_viewport.MinDepth = 0.0f; + g_viewport.MaxDepth = 1.0f; g_defaultAspect = ((float)iWidth / iHeight) * fPixelRatio; - m_pD3DDevice->CreateDepthStencilSurface(1024, 1024, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, TRUE, &g_depthBuffer, NULL); -/* - if (D3D_OK != m_pD3DDevice->GetDepthStencilSurface(&g_oldDepthBuffer)) - { - DebugConsole::Log("Renderer: No default depth buffer\n", iXPos, iYPos, iWidth, iHeight, fPixelRatio ); - //OutputDebugString("Vortex INFO: Renderer::Init - Failed to Get old depth stencil\n"); - // Create our own -// D3DSURFACE_DESC desc; -// g_backBuffer->GetDesc(&desc); -// g_device->CreateDepthStencilSurface(desc.Width, desc.Height, D3DFMT_LIN_D24S8, 0, &g_oldDepthBuffer); -// g_ownDepth = true; - } - else - { -// g_ownDepth = false; - } -*/ + ID3D11Texture2D* depthStencilBuffer = NULL; + + // Initialize the description of the depth buffer. + CD3D11_TEXTURE2D_DESC depthBufferDesc(DXGI_FORMAT_D24_UNORM_S8_UINT, 1024, 512, 1, 1, D3D11_BIND_DEPTH_STENCIL); + // Create the texture for the depth buffer using the filled out description. + m_pD3D11Device->CreateTexture2D(&depthBufferDesc, NULL, &depthStencilBuffer); + + // Create the depth stencil view. + CD3D11_DEPTH_STENCIL_VIEW_DESC viewDesc(D3D11_DSV_DIMENSION_TEXTURE2D); + m_pD3D11Device->CreateDepthStencilView(depthStencilBuffer, &viewDesc, &g_depthView); + depthStencilBuffer->Release(); + { char fullname[512]; sprintf_s(fullname, 512, "%sfont.bmp", g_TexturePath ); m_pTextureFont = LoadTexture( fullname, false ); } - D3DXCreateMatrixStack(0, &g_matrixStack); - g_matrixStackLevel = 0; + g_matrixStack = new XMMatrixStack(); + g_matrixStackLevel = 0; g_scratchTexture = CreateTexture( 512, 512 ); @@ -145,12 +168,36 @@ void Renderer::Init( LPDIRECT3DDEVICE9 pD3DDevice, int iXPos, int iYPos, int iWi CreateCubeBuffers(); - CreateFonts(); + // create indecies buffer for FAN topology + unsigned short indicies[6 * 512]; + for (unsigned int i = 0; i < 512; i += 6) + { + indicies[i] = i; + indicies[i + 1] = i + 1; + indicies[i + 2] = i + 2; + indicies[i + 3] = i; + indicies[i + 4] = i + 2; + indicies[i + 5] = i + 3; + } + CD3D11_BUFFER_DESC bDesc(sizeof(indicies), D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_IMMUTABLE); + D3D11_SUBRESOURCE_DATA bData = { indicies }; + m_pD3D11Device->CreateBuffer(&bDesc, &bData, &g_pFanIbuffer); + + // create vertecies buffer + bDesc.ByteWidth = sizeof(g_vertices); + bDesc.Usage = D3D11_USAGE_DYNAMIC; + bDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + m_pD3D11Device->CreateBuffer(&bDesc, NULL, &g_pFixVbuffer); + + CreateFonts(); + + states.reset(new CommonStates(m_pD3D11Device)); } void Renderer::CreateFonts() { - HDC hdc = CreateCompatibleDC( NULL ); + /*HDC hdc = CreateCompatibleDC( NULL ); if( hdc == NULL ) return; @@ -162,15 +209,15 @@ void Renderer::CreateFonts() g_hFont = CreateFontA( nHeight, 0, 0, 0, bBold ? FW_BOLD : FW_NORMAL, bItalic, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, - "Arial" ); + "Arial" );*/ } -LPD3DXMESH Renderer::CreateD3DXTextMesh( const char* pString, bool bCentered ) +IUnknown* Renderer::CreateD3DXTextMesh(const char* pString, bool bCentered) { - HRESULT hr; - LPD3DXMESH pMeshNew = NULL; + //HRESULT hr; + IUnknown* pMeshNew = NULL; - HDC hdc = CreateCompatibleDC( NULL ); + /*HDC hdc = CreateCompatibleDC( NULL ); if( hdc == NULL ) return NULL; @@ -217,49 +264,31 @@ LPD3DXMESH Renderer::CreateD3DXTextMesh( const char* pString, bool bCentered ) } pMeshNew->UnlockVertexBuffer(); } - } + }*/ return pMeshNew; } -void Renderer::DrawMesh( LPD3DXMESH pMesh ) +void Renderer::DrawMesh(IUnknown* pMesh) { if ( pMesh == NULL ) { return; } - UVNormalEnvVertexShader* pShader = &UVNormalEnvVertexShader::StaticType; + /*UVNormalEnvVertexShader* pShader = &UVNormalEnvVertexShader::StaticType; CommitTransforms( pShader ); CommitTextureState(); - m_pD3DDevice->SetVertexShader( pShader->GetVertexShader() ); - m_pD3DDevice->SetVertexDeclaration( g_pPosNormalDeclaration ); + m_pD3D11Contex->VSSetShader(pShader->GetVertexShader(), NULL, 0); + m_pD3D11Contex->IASetInputLayout( g_pPosNormalDeclaration );*/ - pMesh->DrawSubset( 0 ); + //pMesh->DrawSubset( 0 ); } void Renderer::CreateCubeBuffers() { - m_pD3DDevice->CreateVertexBuffer( 24 * sizeof( PosColNormalUVVertex ), - D3DUSAGE_WRITEONLY, - 0, - D3DPOOL_DEFAULT, - &g_pCubeVbuffer, - NULL ); - - m_pD3DDevice->CreateIndexBuffer( 36 * sizeof( short ), - D3DUSAGE_WRITEONLY, - D3DFMT_INDEX16, - D3DPOOL_DEFAULT, - &g_pCubeIbuffer, - NULL ); - - - PosColNormalUVVertex* v; - g_pCubeVbuffer->Lock( 0, 0, (void**)&v, 0 ); - - short* indices; - g_pCubeIbuffer->Lock( 0, 0, (void**)&indices, 0 ); + PosColNormalUVVertex v[24]; + short ind[36], *indices = ind; float nx = -1.0f; float ny = -1.0f; @@ -268,32 +297,27 @@ void Renderer::CreateCubeBuffers() float y = 1.0f; float z = 1.0f; - g_colour = 0xfffffff; - g_fColour = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f); + g_fColour = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f); // Front Face - v[0].Coord = D3DXVECTOR3(nx, y, nz); -// v[0].Diffuse = g_colour; - v[0].FDiffuse = g_fColour; - v[0].Normal = D3DXVECTOR3(0, 0, -1); + v[0].Coord = XMFLOAT3(nx, y, nz); + v[0].FDiffuse = g_fColour; + v[0].Normal = XMFLOAT3(0, 0, -1); v[0].u = 0; v[0].v = 0; - v[1].Coord = D3DXVECTOR3(x, y, nz); -// v[1].Diffuse = g_colour; - v[1].FDiffuse = g_fColour; - v[1].Normal = D3DXVECTOR3(0, 0, -1); + v[1].Coord = XMFLOAT3(x, y, nz); + v[1].FDiffuse = g_fColour; + v[1].Normal = XMFLOAT3(0, 0, -1); v[1].u = 1; v[1].v = 0; - v[2].Coord = D3DXVECTOR3(x, ny, nz); -// v[2].Diffuse = g_colour; - v[2].FDiffuse = g_fColour; - v[2].Normal = D3DXVECTOR3(0, 0, -1); + v[2].Coord = XMFLOAT3(x, ny, nz); + v[2].FDiffuse = g_fColour; + v[2].Normal = XMFLOAT3(0, 0, -1); v[2].u = 1; v[2].v = 1; - v[3].Coord = D3DXVECTOR3(nx, ny, nz); -// v[3].Diffuse = g_colour; - v[3].FDiffuse = g_fColour; - v[3].Normal = D3DXVECTOR3(0, 0, -1); + v[3].Coord = XMFLOAT3(nx, ny, nz); + v[3].FDiffuse = g_fColour; + v[3].Normal = XMFLOAT3(0, 0, -1); v[3].u = 0; v[3].v = 1; @@ -305,28 +329,24 @@ void Renderer::CreateCubeBuffers() *indices++ = 3; // Back Face - v[4].Coord = D3DXVECTOR3(x, y, z); -// v[4].Diffuse = g_colour; - v[4].FDiffuse = g_fColour; - v[4].Normal = D3DXVECTOR3(0, 0, 1); + v[4].Coord = XMFLOAT3(x, y, z); + v[4].FDiffuse = g_fColour; + v[4].Normal = XMFLOAT3(0, 0, 1); v[4].u = 0; v[4].v = 0; - v[5].Coord = D3DXVECTOR3(nx, y, z); -// v[5].Diffuse = g_colour; - v[5].FDiffuse = g_fColour; - v[5].Normal = D3DXVECTOR3(0, 0, 1); + v[5].Coord = XMFLOAT3(nx, y, z); + v[5].FDiffuse = g_fColour; + v[5].Normal = XMFLOAT3(0, 0, 1); v[5].u = 1; v[5].v = 0; - v[6].Coord = D3DXVECTOR3(nx, ny, z); -// v[6].Diffuse = g_colour; - v[6].FDiffuse = g_fColour; - v[6].Normal = D3DXVECTOR3(0, 0, 1); + v[6].Coord = XMFLOAT3(nx, ny, z); + v[6].FDiffuse = g_fColour; + v[6].Normal = XMFLOAT3(0, 0, 1); v[6].u = 1; v[6].v = 1; - v[7].Coord = D3DXVECTOR3(x, ny, z); -// v[7].Diffuse = g_colour; - v[7].FDiffuse = g_fColour; - v[7].Normal = D3DXVECTOR3(0, 0, 1); + v[7].Coord = XMFLOAT3(x, ny, z); + v[7].FDiffuse = g_fColour; + v[7].Normal = XMFLOAT3(0, 0, 1); v[7].u = 0; v[7].v = 1; @@ -338,28 +358,24 @@ void Renderer::CreateCubeBuffers() *indices++ = 7; // Top Face - v[8].Coord = D3DXVECTOR3(nx, y, z); -// v[8].Diffuse = g_colour; - v[8].FDiffuse = g_fColour; - v[8].Normal = D3DXVECTOR3(0, 1, 0); + v[8].Coord = XMFLOAT3(nx, y, z); + v[8].FDiffuse = g_fColour; + v[8].Normal = XMFLOAT3(0, 1, 0); v[8].u = 0; v[8].v = 0; - v[9].Coord = D3DXVECTOR3(x, y, z); -// v[9].Diffuse = g_colour; - v[9].FDiffuse = g_fColour; - v[9].Normal = D3DXVECTOR3(0, 1, 0); + v[9].Coord = XMFLOAT3(x, y, z); + v[9].FDiffuse = g_fColour; + v[9].Normal = XMFLOAT3(0, 1, 0); v[9].u = 1; v[9].v = 0; - v[10].Coord = D3DXVECTOR3(x, y, nz); -// v[10].Diffuse = g_colour; - v[10].FDiffuse = g_fColour; - v[10].Normal = D3DXVECTOR3(0, 1, 0); + v[10].Coord = XMFLOAT3(x, y, nz); + v[10].FDiffuse = g_fColour; + v[10].Normal = XMFLOAT3(0, 1, 0); v[10].u = 1; v[10].v = 1; - v[11].Coord = D3DXVECTOR3(nx, y, nz); -// v[11].Diffuse = g_colour; - v[11].FDiffuse = g_fColour; - v[11].Normal = D3DXVECTOR3(0, 1, 0); + v[11].Coord = XMFLOAT3(nx, y, nz); + v[11].FDiffuse = g_fColour; + v[11].Normal = XMFLOAT3(0, 1, 0); v[11].u = 0; v[11].v = 1; @@ -371,28 +387,24 @@ void Renderer::CreateCubeBuffers() *indices++ = 11; // Bottom Face - v[12].Coord = D3DXVECTOR3(nx, ny, nz); -// v[12].Diffuse = g_colour; - v[12].FDiffuse = g_fColour; - v[12].Normal = D3DXVECTOR3(0, -1, 0); + v[12].Coord = XMFLOAT3(nx, ny, nz); + v[12].FDiffuse = g_fColour; + v[12].Normal = XMFLOAT3(0, -1, 0); v[12].u = 0; v[12].v = 0; - v[13].Coord = D3DXVECTOR3(x, ny, nz); -// v[13].Diffuse = g_colour; - v[13].FDiffuse = g_fColour; - v[13].Normal = D3DXVECTOR3(0, -1, 0); + v[13].Coord = XMFLOAT3(x, ny, nz); + v[13].FDiffuse = g_fColour; + v[13].Normal = XMFLOAT3(0, -1, 0); v[13].u = 1; v[13].v = 0; - v[14].Coord = D3DXVECTOR3(x, ny, z); -// v[14].Diffuse = g_colour; - v[14].FDiffuse = g_fColour; - v[14].Normal = D3DXVECTOR3(0, -1, 0); + v[14].Coord = XMFLOAT3(x, ny, z); + v[14].FDiffuse = g_fColour; + v[14].Normal = XMFLOAT3(0, -1, 0); v[14].u = 1; v[14].v = 1; - v[15].Coord = D3DXVECTOR3(nx, ny, z); -// v[15].Diffuse = g_colour; - v[15].FDiffuse = g_fColour; - v[15].Normal = D3DXVECTOR3(0, -1, 0); + v[15].Coord = XMFLOAT3(nx, ny, z); + v[15].FDiffuse = g_fColour; + v[15].Normal = XMFLOAT3(0, -1, 0); v[15].u = 0; v[15].v = 1; @@ -404,28 +416,24 @@ void Renderer::CreateCubeBuffers() *indices++ = 15; // Left Face - v[16].Coord = D3DXVECTOR3(nx, y, z); -// v[16].Diffuse = g_colour; - v[16].FDiffuse = g_fColour; - v[16].Normal = D3DXVECTOR3(-1, 0, 0); + v[16].Coord = XMFLOAT3(nx, y, z); + v[16].FDiffuse = g_fColour; + v[16].Normal = XMFLOAT3(-1, 0, 0); v[16].u = 0; v[16].v = 0; - v[17].Coord = D3DXVECTOR3(nx, y, nz); -// v[17].Diffuse = g_colour; - v[17].FDiffuse = g_fColour; - v[17].Normal = D3DXVECTOR3(-1, 0, 0); + v[17].Coord = XMFLOAT3(nx, y, nz); + v[17].FDiffuse = g_fColour; + v[17].Normal = XMFLOAT3(-1, 0, 0); v[17].u = 1; v[17].v = 0; - v[18].Coord = D3DXVECTOR3(nx, ny, nz); -// v[18].Diffuse = g_colour; - v[18].FDiffuse = g_fColour; - v[18].Normal = D3DXVECTOR3(-1, 0, 0); + v[18].Coord = XMFLOAT3(nx, ny, nz); + v[18].FDiffuse = g_fColour; + v[18].Normal = XMFLOAT3(-1, 0, 0); v[18].u = 1; v[18].v = 1; - v[19].Coord = D3DXVECTOR3(nx, ny, z); -// v[19].Diffuse = g_colour; - v[19].FDiffuse = g_fColour; - v[19].Normal = D3DXVECTOR3(-1, 0, 0); + v[19].Coord = XMFLOAT3(nx, ny, z); + v[19].FDiffuse = g_fColour; + v[19].Normal = XMFLOAT3(-1, 0, 0); v[19].u = 0; v[19].v = 1; @@ -437,28 +445,24 @@ void Renderer::CreateCubeBuffers() *indices++ = 19; // Right Face - v[20].Coord = D3DXVECTOR3(x, y, nz); -// v[20].Diffuse = g_colour; - v[20].FDiffuse = g_fColour; - v[20].Normal = D3DXVECTOR3(1, 0, 0); + v[20].Coord = XMFLOAT3(x, y, nz); + v[20].FDiffuse = g_fColour; + v[20].Normal = XMFLOAT3(1, 0, 0); v[20].u = 0; v[20].v = 0; - v[21].Coord = D3DXVECTOR3(x, y, z); -// v[21].Diffuse = g_colour; - v[21].FDiffuse = g_fColour; - v[21].Normal = D3DXVECTOR3(1, 0, 0); + v[21].Coord = XMFLOAT3(x, y, z); + v[21].FDiffuse = g_fColour; + v[21].Normal = XMFLOAT3(1, 0, 0); v[21].u = 1; v[21].v = 0; - v[22].Coord = D3DXVECTOR3(x, ny, z); -// v[22].Diffuse = g_colour; - v[22].FDiffuse = g_fColour; - v[22].Normal = D3DXVECTOR3(1, 0, 0); + v[22].Coord = XMFLOAT3(x, ny, z); + v[22].FDiffuse = g_fColour; + v[22].Normal = XMFLOAT3(1, 0, 0); v[22].u = 1; v[22].v = 1; - v[23].Coord = D3DXVECTOR3(x, ny, nz); -// v[23].Diffuse = g_colour; - v[23].FDiffuse = g_fColour; - v[23].Normal = D3DXVECTOR3(1, 0, 0); + v[23].Coord = XMFLOAT3(x, ny, nz); + v[23].FDiffuse = g_fColour; + v[23].Normal = XMFLOAT3(1, 0, 0); v[23].u = 0; v[23].v = 1; @@ -469,21 +473,20 @@ void Renderer::CreateCubeBuffers() *indices++ = 22; *indices++ = 23; - g_pCubeVbuffer->Unlock(); - g_pCubeIbuffer->Unlock(); + CD3D11_BUFFER_DESC bDesc(sizeof(v), D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_IMMUTABLE); + D3D11_SUBRESOURCE_DATA bData = { v }; + m_pD3D11Device->CreateBuffer( &bDesc, &bData, &g_pCubeVbuffer ); + bDesc.ByteWidth = sizeof(ind); + bDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + bData.pSysMem = ind; + m_pD3D11Device->CreateBuffer(&bDesc, &bData, &g_pCubeIbuffer); } void Renderer::Exit() { DeleteObject( g_hFont ); - if ( m_pD3DDevice ) - { - m_pD3DDevice->SetPixelShader( NULL ); - m_pD3DDevice->SetVertexShader( NULL ); - } - if ( g_pPosNormalColUVDeclaration ) g_pPosNormalColUVDeclaration->Release(); @@ -497,17 +500,21 @@ void Renderer::Exit() if ( g_pCubeIbuffer ) g_pCubeIbuffer->Release(); + if ( g_pCubeVbuffer ) g_pCubeVbuffer->Release(); -// if ( g_backBuffer ) -// g_backBuffer->Release(); + if ( g_pFanIbuffer ) + g_pFanIbuffer->Release(); -// if ( g_oldDepthBuffer ) -// g_oldDepthBuffer->Release(); + if ( g_pFixVbuffer ) + g_pFixVbuffer->Release(); - if ( g_matrixStack ) - g_matrixStack->Release(); + if (g_matrixStack) + delete g_matrixStack; + + if (states.get()) + states.reset(); if ( g_scratchTexture ) { @@ -521,8 +528,11 @@ void Renderer::Exit() m_pTextureFont = NULL; } - if ( g_depthBuffer ) - g_depthBuffer->Release(); + if ( g_depthView ) + g_depthView->Release(); + + if ( m_pD3D11Device ) + m_pD3D11Device->Release(); } //-- SetDrawMode2d ------------------------------------------------------------ @@ -530,10 +540,9 @@ void Renderer::Exit() //----------------------------------------------------------------------------- void Renderer::SetDrawMode2d() { - D3DXMATRIX Ortho2D; - D3DXMatrixOrthoLH(&Ortho2D, 2.0f, -2.0f, 0.0f, 1.0f); - m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); - Renderer::SetProjection( Ortho2D ); + XMMATRIX Ortho2D = XMMatrixOrthographicLH(2.0f, -2.0f, 0.0f, 1.0f); + m_pD3D11Contex->OMSetDepthStencilState(states->DepthNone(), 0); + Renderer::SetProjection(Ortho2D); } // SetDrawMode2d @@ -542,57 +551,67 @@ void Renderer::SetDrawMode2d() //----------------------------------------------------------------------------- void Renderer::SetDrawMode3d() { - D3DXMATRIX matProj; - D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, g_aspect, 0.25f, 2000.0f ); + XMMATRIX matProj = XMMatrixPerspectiveFovLH(XM_PI / 4, g_aspect, 0.25f, 2000.0f); Renderer::SetProjection(matProj); - m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + m_pD3D11Contex->OMSetDepthStencilState(states->DepthDefault(), 0); } // SetDrawMode3d void Renderer::Clear( DWORD Col ) { Col |= 0xff000000; - m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, Col, 1.0f, 0 ); + ID3D11RenderTargetView* rtView = NULL; + ID3D11DepthStencilView* depthView = NULL; + m_pD3D11Contex->OMGetRenderTargets(1, &rtView, &depthView); + + if (rtView != NULL) + { + XMCOLOR xcolor(Col); + float color[4] = { xcolor.r / 255.0f, xcolor.g / 255.0f, xcolor.b / 255.0f, 1.0f }; + m_pD3D11Contex->ClearRenderTargetView(rtView, color); + rtView->Release(); + } + if (depthView != NULL) + { + m_pD3D11Contex->ClearDepthStencilView(depthView, D3D11_CLEAR_DEPTH, 1.0, 0); + depthView->Release(); + } } void Renderer::ClearDepth() { - m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0 ); + m_pD3D11Contex->ClearDepthStencilView(g_depthView, D3D11_CLEAR_DEPTH, 1.0, 0); } void Renderer::Rect( float x1, float y1, float x2, float y2, DWORD Col ) { unsigned char* pCol = (unsigned char*)&Col; - D3DXVECTOR4 FColour(pCol[2],pCol[1], pCol[0], pCol[3] ); + XMFLOAT4 FColour(pCol[2],pCol[1], pCol[0], pCol[3] ); PosColNormalUVVertex v[4]; v[0].Coord.x = x1; v[0].Coord.y = y1; v[0].Coord.z = 0.0f; -// v[0].Diffuse = Col; v[0].FDiffuse = FColour; v[1].Coord.x = x2; v[1].Coord.y = y1; v[1].Coord.z = 0.0f; -// v[1].Diffuse = Col; v[1].FDiffuse = FColour; v[2].Coord.x = x2; v[2].Coord.y = y2; v[2].Coord.z = 0.0f; -// v[2].Diffuse = Col; v[2].FDiffuse = FColour; v[3].Coord.x = x1; v[3].Coord.y = y2; v[3].Coord.z = 0.0f; -// v[3].Diffuse = Col; v[3].FDiffuse = FColour; - m_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, &v, sizeof(PosColNormalUVVertex)); - + UpdateVBuffer( v, 4 ); + DrawPrimitive( D3DPT_TRIANGLEFAN, 6, 0 ); } // Rect void Renderer::Line( float x1, float y1, float x2, float y2, DWORD Col ) @@ -628,41 +647,31 @@ void Renderer::Point( float x, float y, DWORD Col ) */ } // Point -LPDIRECT3DTEXTURE9 Renderer::CreateTexture( int iWidth, int iHeight, D3DFORMAT Format /* = D3DFMT_X8R8G8B8 */, bool bDynamic /* = false */ ) +TextureDX* Renderer::CreateTexture( int iWidth, int iHeight, DXGI_FORMAT Format /* = DXGI_FORMAT_B8G8R8A8_UNORM */, bool bDynamic /* = false */ ) { - LPDIRECT3DTEXTURE9 pTexture; -// IDirect3DSurface9* pSurface; -// D3DLOCKED_RECT lock; + ID3D11Texture2D* pTexture2D = NULL; - if ( bDynamic == false ) - { - m_pD3DDevice->CreateTexture( iWidth, iHeight, 1, D3DUSAGE_RENDERTARGET, Format, D3DPOOL_DEFAULT, &pTexture, NULL ); - } - else - { - m_pD3DDevice->CreateTexture( iWidth, iHeight, 1, D3DUSAGE_DYNAMIC, Format, D3DPOOL_DEFAULT, &pTexture, NULL ); - } + unsigned int bindFlag = D3D11_BIND_SHADER_RESOURCE; + if (!bDynamic) + bindFlag |= D3D11_BIND_RENDER_TARGET; + + CD3D11_TEXTURE2D_DESC texDesc(Format, iWidth, iHeight, 1, 1, bindFlag, + bDynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT, + bDynamic ? D3D11_CPU_ACCESS_WRITE : 0); + m_pD3D11Device->CreateTexture2D(&texDesc, NULL, &pTexture2D); - if ( pTexture == NULL ) + if ( pTexture2D == NULL ) { DebugConsole::Log("Renderer: Failed to create texture, Width:%d, Height:%d\n", iWidth, iHeight); return NULL; } - // TODO: Clear target - -// pTexture->GetSurfaceLevel( 0, &pSurface ); -// pSurface->LockRect( &lock, NULL, 0 ); -// int iTexSize = ( iWidth * iHeight * 4 ); -// memset( lock.pBits, 0, iTexSize ); -// pSurface->UnlockRect(); -// pSurface->Release(); - return pTexture; + return new TextureDX(pTexture2D); } -LPDIRECT3DTEXTURE9 Renderer::LoadTexture( char* pFilename, bool bAutoResize ) +TextureDX* Renderer::LoadTexture(char* pFilename, bool bAutoResize) { - LPDIRECT3DTEXTURE9 pTexture = NULL; + ID3D11Texture2D* pTexture2D = NULL; FILE* iS; iS = fopen( pFilename, "rb" ); @@ -671,38 +680,41 @@ LPDIRECT3DTEXTURE9 Renderer::LoadTexture( char* pFilename, bool bAutoResize ) fseek( iS, 0, SEEK_END ); int iLength = ftell( iS ); fseek( iS, 0, SEEK_SET ); - BYTE* pTextureInMem = new BYTE[ iLength ]; - int iReadLength = fread( pTextureInMem, 1, iLength, iS ); + uint8_t* pTextureInMem = new uint8_t[iLength]; + size_t iReadLength = fread( pTextureInMem, 1, iLength, iS ); fclose( iS ); - D3DXCreateTextureFromFileInMemoryEx(m_pD3DDevice, // device - pTextureInMem, // SrcData - iReadLength, // SrcDataSize - 0, // Width - 0, // Height - 1, // MipLevels - 0, // Usage - D3DFMT_UNKNOWN, // Format - D3DPOOL_DEFAULT, // Pool - bAutoResize ? D3DX_FILTER_POINT : D3DX_FILTER_NONE, // Filter - D3DX_FILTER_NONE, // MipFilter - 0x00000000, // ColorKey - NULL, // SrcInfo - NULL, // Palette - &pTexture ); // DestTexture + std::string strFileName(pFilename); + if (GetExtension(strFileName) == "dds") + { + CreateDDSTextureFromMemory( m_pD3D11Device, + pTextureInMem, + iReadLength, + reinterpret_cast(&pTexture2D), + NULL ); + } + else + { + CreateWICTextureFromMemory( m_pD3D11Device, + pTextureInMem, + iReadLength, + reinterpret_cast(&pTexture2D), + NULL ); + } delete[] pTextureInMem; } - if ( pTexture == NULL ) + if (pTexture2D == NULL) { DebugConsole::Log( "Renderer: Failed to load texture: %s\n", pFilename ); + return NULL; } - return pTexture; + return new TextureDX(pTexture2D); } -void Renderer::ReleaseTexture( LPDIRECT3DTEXTURE9 pTexture ) +void Renderer::ReleaseTexture( TextureDX* pTexture ) { if ( pTexture ) { @@ -713,15 +725,14 @@ void Renderer::ReleaseTexture( LPDIRECT3DTEXTURE9 pTexture ) void Renderer::DrawText( float x, float y, char* txt, DWORD Col ) { unsigned char* pCol = (unsigned char*)&Col; - D3DXVECTOR4 FColour(pCol[2],pCol[1], pCol[0], pCol[3] ); -// D3DXVECTOR4 FColour(1,1, 0, 1 ); + XMFLOAT4 FColour(pCol[2],pCol[1], pCol[0], pCol[3] ); SetTexture( m_pTextureFont ); DiffuseUVVertexShader* pShader = &DiffuseUVVertexShader::StaticType; - CommitTransforms( pShader ); + + SetShader(pShader); + CommitTransforms(pShader); CommitTextureState(); - m_pD3DDevice->SetVertexShader( pShader->GetVertexShader() ); - m_pD3DDevice->SetVertexDeclaration( g_pPosColUVDeclaration ); x = ( x / g_viewport.Width ) * 2 - 1; y = ( y / g_viewport.Height ) * 2 -1; @@ -747,7 +758,6 @@ void Renderer::DrawText( float x, float y, char* txt, DWORD Col ) v[0].Coord.z = 0.0f; v[0].u = cx; v[0].v = cy; -// v[0].Diffuse = Col; v[0].FDiffuse = FColour; v[1].Coord.x = x + 9.0f / (g_viewport.Width * 0.5f); @@ -755,7 +765,6 @@ void Renderer::DrawText( float x, float y, char* txt, DWORD Col ) v[1].Coord.z = 0.0f; v[1].u = cx + sizeX; v[1].v = cy; -// v[1].Diffuse = Col; v[1].FDiffuse = FColour; v[2].Coord.x = x + 9.0f / (g_viewport.Width * 0.5f); @@ -763,7 +772,6 @@ void Renderer::DrawText( float x, float y, char* txt, DWORD Col ) v[2].Coord.z = 0.0f; v[2].u = cx + sizeX; v[2].v = cy + sizeY; -// v[2].Diffuse = Col; v[2].FDiffuse = FColour; v[3].Coord.x = x; @@ -771,22 +779,22 @@ void Renderer::DrawText( float x, float y, char* txt, DWORD Col ) v[3].Coord.z = 0.0f; v[3].u = cx; v[3].v = cy + sizeY; -// v[3].Diffuse = Col; v[3].FDiffuse = FColour; - m_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, &v, sizeof(PosColNormalUVVertex)); + UpdateVBuffer( v, 4 ); + DrawPrimitive( D3DPT_TRIANGLEFAN, 6, 0 ); x += 9.0f / (g_viewport.Width * 0.5f); txt++; } } -int Renderer::GetViewportHeight() +float Renderer::GetViewportHeight() { return g_viewport.Height; } -int Renderer::GetViewportWidth() +float Renderer::GetViewportWidth() { return g_viewport.Width; } @@ -796,16 +804,12 @@ int Renderer::GetViewportWidth() //----------------------------------------------------------------------------- void Renderer::SetAspect(float aspect) { - D3DXMATRIX matProj; - aspect = min(aspect, 1); aspect = max(aspect, 0); g_aspectValue = aspect; - // g_aspect = 1.0f + aspect * ((4.0f / 3.0f) - 1.0f); g_aspect = 1.0f + aspect * ((g_defaultAspect) - 1.0f); - D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, g_aspect, 0.25f, 2000.0f ); - // D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian(60), g_aspect, 0.25f, 2000.0f ); + XMMATRIX matProj = XMMatrixPerspectiveFovLH(XM_PI / 4, g_aspect, 0.25f, 2000.0f); Renderer::SetProjection(matProj); } // SetAspect @@ -815,12 +819,11 @@ void Renderer::SetAspect(float aspect) //----------------------------------------------------------------------------- void Renderer::LookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) { - D3DXVECTOR3 eye(eyeX, eyeY, eyeZ); - D3DXVECTOR3 center(centerX, centerY, centerZ); - D3DXVECTOR3 up(upX, upY, upZ); - D3DXMATRIX matOut; - D3DXMatrixLookAtLH(&matOut, &eye, ¢er, &up); - g_matrixStack->MultMatrix(&matOut); + XMVECTOR eye = XMVectorSet(eyeX, eyeY, eyeZ, 1.0f); + XMVECTOR center = XMVectorSet(centerX, centerY, centerZ, 1.0f); + XMVECTOR up = XMVectorSet(upX, upY, upZ*2, 1.0f); + XMMATRIX matOut = XMMatrixLookAtLH(eye, center, up); + g_matrixStack->MultMatrix(&matOut); } // LookAt @@ -837,68 +840,41 @@ void Renderer::SetDefaults() g_matrixStack->LoadIdentity(); - // Renderstates - m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); - // d3dSetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); - m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); - m_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); - m_pD3DDevice->SetRenderState(D3DRS_ALPHAREF, 0); - m_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - - m_pD3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE); - - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - - for (int i = 0; i < 4; i++) - { - m_pD3DDevice->SetSamplerState( i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); - m_pD3DDevice->SetSamplerState( i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); - m_pD3DDevice->SetSamplerState( i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - m_pD3DDevice->SetSamplerState( i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - m_pD3DDevice->SetTexture(i, NULL); - } + // Renderstates + m_pD3D11Contex->RSSetState(states->CullNone()); + m_pD3D11Contex->OMSetBlendState(states->Opaque(), 0, 0xFFFFFFFF); + m_pD3D11Contex->OMSetDepthStencilState(states->DepthDefault(), 0); + + ID3D11SamplerState* samplerState[1] = { states->LinearWrap() }; + m_pD3D11Contex->PSSetSamplers(0, 1, samplerState); + + SetShader( &TexturePixelShader::StaticType ); + CurrentTextureStageMode = TSM_TEXTURE; - CurrentTextureStageMode = TSM_TEXTURE; g_envMapSet = false; g_textureSet = false; // Globals - g_colour = 0xffffffff; - g_fColour = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f); + g_fColour = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f); g_aspect = g_defaultAspect; g_aspectValue = 1.0f; SetDrawMode3d(); - D3DXMATRIX matView; - D3DXMatrixIdentity( &matView ); - SetView( matView ); - + SetView( XMMatrixIdentity() ); SetBlendMode( BLEND_OFF ); -// m_pD3DDevice->SetVertexDeclaration( g_pVertexDeclaration ); - } // SetDefaults //-- SetProjection ------------------------------------------------------------ // //----------------------------------------------------------------------------- -void Renderer::SetProjection(D3DXMATRIX& matProj) +void Renderer::SetProjection(const XMMATRIX& matProj) { g_matProj = matProj; } // SetProjection -void Renderer::GetProjection(D3DXMATRIX& matProj) +void Renderer::GetProjection(XMMATRIX& matProj) { matProj = g_matProj; @@ -907,7 +883,7 @@ void Renderer::GetProjection(D3DXMATRIX& matProj) //-- SetView ------------------------------------------------------------------ // //----------------------------------------------------------------------------- -void Renderer::SetView(D3DXMATRIX& matView) +void Renderer::SetView(const XMMATRIX& matView) { g_matView = matView; @@ -934,18 +910,17 @@ void Renderer::Scale(float x, float y, float z) //-- CommitTransforms --------------------------------------------------------- // //----------------------------------------------------------------------------- -void Renderer::CommitTransforms( DiffuseUVVertexShader* pShader ) +void Renderer::CommitTransforms( Shader* pShader ) { - D3DXMATRIX worldView, worldViewProjection; - D3DXMATRIX* worldMat = g_matrixStack->GetTop(); - D3DXMatrixMultiply( &worldView, worldMat, &g_matView); - D3DXMatrixMultiply( &worldViewProjection, &worldView, &g_matProj ); + XMMATRIX worldView, worldViewProjection; + XMMATRIX worldMat = *(g_matrixStack->GetTop()); - D3DXMatrixTranspose( &worldViewProjection, &worldViewProjection ); - D3DXMatrixTranspose( &worldView, &worldView ); + worldView = XMMatrixMultiply(worldMat, g_matView); + worldViewProjection = XMMatrixMultiply(worldMat, g_matProj); pShader->SetWV( &worldView ); pShader->SetWVP( &worldViewProjection ); + pShader->CommitConstants( m_pD3D11Contex ); } //-- CommitTextureState ------------------------------------------------------- @@ -956,20 +931,12 @@ void Renderer::CommitTextureState() if ( ( g_textureSet || g_envMapSet ) && CurrentTextureStageMode != TSM_TEXTURE ) { CurrentTextureStageMode = TSM_TEXTURE; - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + SetShader( &TexturePixelShader::StaticType ); } else if ( !g_textureSet && !g_envMapSet && CurrentTextureStageMode != TSM_COLOUR ) { CurrentTextureStageMode = TSM_COLOUR; - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE ); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); + SetShader( &ColorPixelShader::StaticType ); } } @@ -982,41 +949,47 @@ void Renderer::SetBlendMode(eBlendMode blendMode) { case BLEND_OFF: { - m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); + m_pD3D11Contex->OMSetBlendState(states->Opaque(), 0, 0xFFFFFF); + //m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + //m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); break; } case BLEND_ADD: { - m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + m_pD3D11Contex->OMSetBlendState(states->Additive(), 0, 0xFFFFFF); + /*m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); m_pD3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); - m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);*/ break; } case BLEND_MOD: { - m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + m_pD3D11Contex->OMSetBlendState(states->NonPremultiplied(), 0, 0xFFFFFF); + /*m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); m_pD3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);*/ break; } case BLEND_MAX: { - m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + m_pD3D11Contex->OMSetBlendState(states->Maximize(), 0, 0xFFFFFF); + /*m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); m_pD3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX); m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); - m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);*/ break; } default: { - m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + m_pD3D11Contex->OMSetBlendState(states->AlphaBlend(), 0, 0xFFFFFF); + /* + m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);*/ break; } } @@ -1106,76 +1079,42 @@ void Renderer::End() if ( primCount == -1 ) return; - DiffuseUVVertexShader* pShader = NULL; - if ( g_envMapSet ) - { - pShader = &DiffuseUVEnvVertexShader::StaticType; - m_pD3DDevice->SetVertexDeclaration( g_pPosNormalColUVDeclaration ); - } - else - { - pShader = &DiffuseUVVertexShader::StaticType; - m_pD3DDevice->SetVertexDeclaration( g_pPosColUVDeclaration ); - } - + DiffuseUVVertexShader* pShader = g_envMapSet + ? &DiffuseUVEnvVertexShader::StaticType + : &DiffuseUVVertexShader::StaticType; + SetShader( pShader ); CommitTransforms( pShader ); CommitTextureState(); - m_pD3DDevice->SetVertexShader( pShader->GetVertexShader() ); - if ( g_primType == 8 ) // QUADLIST + UpdateVBuffer(g_vertices, g_currentVertex); + + if (g_primType == 8) // QUADLIST { for ( INT i = 0; i < primCount; i++ ) { - m_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, &g_vertices[ i * 4], sizeof(PosColNormalUVVertex)); + DrawPrimitive( D3DPT_TRIANGLEFAN, 6, i * 4 ); } } else if ( g_primType == 9 ) // QUADSTRIP { - for ( INT i = 0; i < primCount; i++ ) + for (INT i = 0; i < primCount; i++) { - m_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, &g_vertices[ i * 2], sizeof(PosColNormalUVVertex)); + DrawPrimitive( D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, 4, i * 2 ); } } - else { - m_pD3DDevice->DrawPrimitiveUP(g_primType, primCount, g_vertices, sizeof(PosColNormalUVVertex)); + DrawPrimitive( g_primType, g_currentVertex, 0 ); } - } // End -/* -__forceinline float ClampCol(float c) -{ - if (c < 0) - { - c = 0; - } - else if (c > 1) - { - c = 1; - } - - return c; -} -*/ - //-- Colour ------------------------------------------------------------------- // //----------------------------------------------------------------------------- void Renderer::Colour(float r, float g, float b, float a) { -// r = ClampCol(r); -// g = ClampCol(g); -// b = ClampCol(b); -// a = ClampCol(a); -// unsigned char cr = (unsigned char) (r * 255.0f); -// unsigned char cg = (unsigned char) (g * 255.0f); -// unsigned char cb = (unsigned char) (b * 255.0f); -// unsigned char ca = (unsigned char) (a * 255.0f); -// g_colour = D3DCOLOR_ARGB(ca, cr, cg, cb); - g_fColour = D3DXVECTOR4(r, g, b, a); + g_fColour = XMFLOAT4(r, g, b, a); } // Colour @@ -1194,8 +1133,7 @@ void Renderer::Vertex( float x, float y, float z ) v.Coord.x = x; v.Coord.y = y; v.Coord.z = z; -// v.Diffuse = g_colour; - v.Normal = g_normal; + XMStoreFloat3(&v.Normal, g_normal); v.u = g_tex0U; v.v = g_tex0V; v.FDiffuse = g_fColour; @@ -1207,8 +1145,8 @@ void Renderer::Vertex( float x, float y, float z ) //----------------------------------------------------------------------------- void Renderer::RotateAxis( float angle, float x, float y, float z ) { - D3DXVECTOR3 axis( x, y, z ); - g_matrixStack->RotateAxisLocal( &axis, D3DXToRadian( angle ) ); + XMVECTOR axis = XMVectorSet( x, y, z, 1.0f ); + g_matrixStack->RotateAxisLocal(&axis, XMConvertToRadians(angle)); } // RotateAxis @@ -1226,60 +1164,44 @@ void Renderer::Cube( float nx, float ny, float nz, float x, float y, float z ) PushMatrix(); - Translate( ( nx + x ) * 0.5f, - ( ny + y ) * 0.5f, - ( nz + z ) * 0.5f ); + Translate( ( nx + x ) * 0.5f, + ( ny + y ) * 0.5f, + ( nz + z ) * 0.5f ); - DiffuseUVCubeVertexShader* pShader = NULL; - if ( g_envMapSet ) - { - pShader = &DiffuseUVEnvCubeVertexShader::StaticType; - } - else - { - pShader = &DiffuseUVCubeVertexShader::StaticType; - } + DiffuseUVCubeVertexShader* pShader = g_envMapSet + ? &DiffuseUVEnvCubeVertexShader::StaticType + : &DiffuseUVCubeVertexShader::StaticType; - CommitTransforms( pShader ); - CommitTextureState(); - - PopMatrix(); - - D3DXVECTOR4 vScale( ( x - nx ) * 0.5f, ( y - ny ) * 0.5f, ( z - nz ) * 0.5f, 1.0f ); - - pShader->SetScale( &vScale ); - pShader->SetColour( &g_fColour ); + XMVECTOR vScale = XMVectorSet((x - nx) * 0.5f, (y - ny) * 0.5f, (z - nz) * 0.5f, 1.0f); - m_pD3DDevice->SetVertexShader( pShader->GetVertexShader() ); - m_pD3DDevice->SetVertexDeclaration( g_pPosNormalColUVDeclaration ); + pShader->SetScale(&vScale); + pShader->SetColour(&g_fColour); - m_pD3DDevice->SetStreamSource( 0, - g_pCubeVbuffer, - 0, - sizeof( PosColNormalUVVertex ) ); - - m_pD3DDevice->SetIndices( g_pCubeIbuffer ); + SetShader( pShader ); + CommitTransforms(pShader); + CommitTextureState(); - m_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12 ); + PopMatrix(); - m_pD3DDevice->SetStreamSource( 0, - NULL, - 0, - sizeof( PosColNormalUVVertex ) ); + unsigned int strides = sizeof(PosColNormalUVVertex), offsets = 0; + m_pD3D11Contex->IASetVertexBuffers(0, 1, &g_pCubeVbuffer, &strides, &offsets); + m_pD3D11Contex->IASetIndexBuffer( g_pCubeIbuffer, DXGI_FORMAT_R16_UINT, 0 ); + m_pD3D11Contex->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + m_pD3D11Contex->IASetInputLayout( g_pPosNormalColUVDeclaration ); - m_pD3DDevice->SetIndices( NULL ); + m_pD3D11Contex->DrawIndexed(36, 0, 0); } // Cube #define PI180 0.0174532925199432957692369076848861f // pi / 180 -inline void RotY( const float angle, D3DXVECTOR3& vec) +inline void RotY( const float angle, XMVECTOR& vec) { float s = (float) sin( PI180*angle ); float c = (float) cos( PI180*angle ); - float X = vec.x; - vec.x = vec.x*c + vec.z*s; - vec.z = -X*s + vec.z*c; + float X = XMVectorGetX(vec); + vec = XMVectorSetX(vec, XMVectorGetX(vec)*c + XMVectorGetZ(vec)*s); + vec = XMVectorSetZ(vec, -X*s + XMVectorGetZ(vec)*c); } void Renderer::SimpleSphere(float size) { @@ -1293,23 +1215,23 @@ void Renderer::Sphere(int del_uhol_x, int del_uhol_y, float size) // Vertex_t v[del_uhol_x*2*(del_uhol_y+1)]; PosColNormalUVVertex* v = new PosColNormalUVVertex[del_uhol_x*2*(del_uhol_y+1)]; - D3DXVECTOR3 a,b,ay,by; + XMVECTOR a, b, ay, by; float dy=360.f/del_uhol_y; float dx=180.f*PI180/del_uhol_x; for(int x=0; xSetVertexDeclaration( g_pPosNormalColUVDeclaration ); } else { pShader = &DiffuseUVVertexShader::StaticType; - m_pD3DDevice->SetVertexDeclaration( g_pPosColUVDeclaration ); } - CommitTransforms( pShader ); + SetShader( pShader ); + CommitTransforms(pShader); CommitTextureState(); - m_pD3DDevice->SetVertexShader( pShader->GetVertexShader() ); - for(int i=0; iDrawPrimitive(D3DPT_TRIANGLESTRIP, i*2*(del_y+1), 2*del_y ); - m_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2*del_uhol_y, &v[i*2*(del_uhol_y+1)], sizeof(PosColNormalUVVertex)); + + UpdateVBuffer(v, del_uhol_x * 2 * (del_uhol_y + 1)); + for (int i = 0; i < del_uhol_x; i++) + DrawPrimitive(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, 6 * del_uhol_y, i * 2 * (del_uhol_y + 1)); delete [] v; - // pd->DrawPrimitive( D3DPT_TRIANGLESTRIP, i*2*(del_y+1), 2*del_y ); } //-- SetEnvTexture --------------------------------------------------------------- // //----------------------------------------------------------------------------- -void Renderer::SetEnvTexture( LPDIRECT3DTEXTURE9 texture ) +void Renderer::SetEnvTexture(TextureDX* texture) { if ( texture == SCRATCH_TEXTURE ) { - m_pD3DDevice->SetTexture(0, g_scratchTexture); - } - else + SetShaderTexture( 0, g_scratchTexture ); + } + else { - m_pD3DDevice->SetTexture( 0, texture ); - } - g_envMapSet = texture != NULL; + SetShaderTexture( 0, texture ); + } + g_envMapSet = texture != NULL; } // SetEnvTexture //-- SetTexture --------------------------------------------------------------- // //----------------------------------------------------------------------------- -void Renderer::SetTexture (LPDIRECT3DTEXTURE9 texture ) +void Renderer::SetTexture(TextureDX* texture) { if ( texture == SCRATCH_TEXTURE ) { - m_pD3DDevice->SetTexture( 0, g_scratchTexture ); + SetShaderTexture( 0, g_scratchTexture ); } - else - { - m_pD3DDevice->SetTexture( 0, texture ); - } - g_textureSet = texture != NULL; + else + { + SetShaderTexture( 0, texture ); + } + g_textureSet = texture != NULL; } // SetTexture //-- SetRenderTarget ---------------------------------------------------------- // //----------------------------------------------------------------------------- -void Renderer::SetRenderTarget( LPDIRECT3DTEXTURE9 texture ) +void Renderer::SetRenderTarget(TextureDX* texture) { - IDirect3DSurface9* surface; - texture->GetSurfaceLevel( 0, &surface ); + if (texture == NULL || texture->GetRenderTarget() == NULL) + return; + + ID3D11Texture2D* pTexture = texture->GetTexture(); + D3D11_TEXTURE2D_DESC txDesc, dtxDesc; + pTexture->GetDesc(&txDesc); + + ID3D11Resource* pResource = NULL; ID3D11Texture2D* pDepthTexture = NULL; + g_depthView->GetResource(&pResource); + pResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast(&pDepthTexture)); + pDepthTexture->GetDesc(&dtxDesc); + pDepthTexture->Release(); + pResource->Release(); - m_pD3DDevice->SetRenderTarget( 0, surface ); - m_pD3DDevice->SetDepthStencilSurface( g_depthBuffer ); - m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0, 1.0f, 0 ); + // depth view dimension must be equals render target dimension + if (txDesc.Width != dtxDesc.Width || txDesc.Height != dtxDesc.Height) + { + g_depthView->Release(); - surface->Release(); + CD3D11_TEXTURE2D_DESC depthBufferDesc(DXGI_FORMAT_D24_UNORM_S8_UINT, txDesc.Width, txDesc.Height, 1, 1, D3D11_BIND_DEPTH_STENCIL); + m_pD3D11Device->CreateTexture2D(&depthBufferDesc, NULL, &pDepthTexture); - // m_renderTargetWidth = texture->Width(); - // m_renderTargetHeight = texture->Height(); + CD3D11_DEPTH_STENCIL_VIEW_DESC viewDesc(D3D11_DSV_DIMENSION_TEXTURE2D); + m_pD3D11Device->CreateDepthStencilView(pDepthTexture, &viewDesc, &g_depthView); + pDepthTexture->Release(); + } + else + m_pD3D11Contex->ClearDepthStencilView(g_depthView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0, 0); + + ID3D11RenderTargetView* rtView = texture->GetRenderTarget(); + + // change view port to render target dimension like dx9 does + CD3D11_VIEWPORT vp(pTexture, rtView); + m_pD3D11Contex->RSSetViewports(1, &vp); + + m_pD3D11Contex->OMSetRenderTargets(1, &rtView, g_depthView); } // SetRenderTarget void Renderer::GetBackBuffer() { - m_pD3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &g_backBuffer); - m_pD3DDevice->GetDepthStencilSurface(&g_oldDepthBuffer); + m_pD3D11Contex->OMGetRenderTargets(1, &g_backBuffer, &g_oldDepthBuffer); } void Renderer::ReleaseBackbuffer() @@ -1421,23 +1365,26 @@ void Renderer::ReleaseBackbuffer() //----------------------------------------------------------------------------- void Renderer::SetRenderTargetBackBuffer() { - - m_pD3DDevice->SetRenderTarget(0, g_backBuffer); - m_pD3DDevice->SetDepthStencilSurface( g_oldDepthBuffer ); - -// m_pD3DDevice->SetViewport(&g_viewport); - - // m_renderTargetWidth = 640; - // m_renderTargetHeight = 480; - + // change view port to render target dimension like dx9 does + m_pD3D11Contex->RSSetViewports(1, &g_viewport); + m_pD3D11Contex->OMSetRenderTargets(1, &g_backBuffer, g_oldDepthBuffer); } // SetRenderTargetBackBuffer void Renderer::CompileShaders() { - m_pD3DDevice->CreateVertexDeclaration( declPosNormalColUV, &g_pPosNormalColUVDeclaration ); - m_pD3DDevice->CreateVertexDeclaration( declPosColUV, &g_pPosColUVDeclaration ); - m_pD3DDevice->CreateVertexDeclaration( declPosNormal, &g_pPosNormalDeclaration ); + m_pD3D11Device->CreateInputLayout( declPosNormalColUV, ARRAYSIZE(declPosNormalColUV), + DiffuseUVEnvVertexShaderCode, + sizeof(DiffuseUVEnvVertexShaderCode), + &g_pPosNormalColUVDeclaration ); + /*m_pD3D11Device->CreateInputLayout( declPosColUV, ARRAYSIZE(declPosColUV), + DiffuseUVVertexShaderCode, + sizeof(DiffuseUVVertexShaderCode), + &g_pPosColUVDeclaration ); + m_pD3D11Device->CreateInputLayout( declPosNormal, ARRAYSIZE(declPosNormal), + DiffuseNormalEnvCubeVertexShaderCode, + sizeof(DiffuseNormalEnvCubeVertexShaderCode), + &g_pPosNormalDeclaration );*/ Shader::CompileAllShaders(); } @@ -1448,7 +1395,6 @@ void Renderer::CompileShaders() void Renderer::PushMatrix() { g_matrixStack->Push(); - } // PushMatrix //-- PopMatrix ---------------------------------------------------------------- @@ -1470,10 +1416,8 @@ void Renderer::TexCoord( float u, float v ) void Renderer::Normal( float nx, float ny, float nz ) { - g_normal.x = nx; - g_normal.y = ny; - g_normal.z = nz; - D3DXVec3Normalize( &g_normal, &g_normal ); + g_normal = XMVectorSet(nx, ny, nz, 1.0f); + g_normal = XMVector3Normalize(g_normal); } //-- ClearFloat --------------------------------------------------------------- @@ -1481,14 +1425,21 @@ void Renderer::Normal( float nx, float ny, float nz ) //----------------------------------------------------------------------------- void Renderer::ClearFloat(float r, float g, float b) { - unsigned char cr = (unsigned char) (r * 255.0f); - unsigned char cg = (unsigned char) (g * 255.0f); - unsigned char cb = (unsigned char) (b * 255.0f); - unsigned char ca = (unsigned char) (1.0f * 255.0f); - unsigned int colour = D3DCOLOR_ARGB(ca, cr, cg, cb); - - m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, colour, 1.0f, 0); - + ID3D11RenderTargetView* rtView = NULL; + ID3D11DepthStencilView* depthView = NULL; + m_pD3D11Contex->OMGetRenderTargets(1, &rtView, &depthView); + + if (rtView != NULL) + { + float color[4] = { r, g, b, 1.0 }; + m_pD3D11Contex->ClearRenderTargetView(rtView, color); + rtView->Release(); + } + if (depthView != NULL) + { + m_pD3D11Contex->ClearDepthStencilView(depthView, D3D11_CLEAR_DEPTH, 1.0, 0); + depthView->Release(); + } } // ClearFloat //-- TexRect ---------------------------------------------------------------- @@ -1501,7 +1452,6 @@ void Renderer::TexRect(float x1, float y1, float x2, float y2) v[0].Coord.x = x1; v[0].Coord.y = y1; v[0].Coord.z = 0.0f; -// v[0].Diffuse = g_colour; v[0].FDiffuse = g_fColour; v[0].u = 0.5f / 256.0f; v[0].v = 0.5f / 256.0f; @@ -1509,7 +1459,6 @@ void Renderer::TexRect(float x1, float y1, float x2, float y2) v[1].Coord.x = x2; v[1].Coord.y = y1; v[1].Coord.z = 0.0f; -// v[1].Diffuse = g_colour; v[1].FDiffuse = g_fColour; v[1].u = 1.0f; v[1].v = 0.5f / 256.0f; @@ -1517,7 +1466,6 @@ void Renderer::TexRect(float x1, float y1, float x2, float y2) v[2].Coord.x = x2; v[2].Coord.y = y2; v[2].Coord.z = 0.0f; -// v[2].Diffuse = g_colour; v[2].FDiffuse = g_fColour; v[2].u = 1.0f; v[2].v = 1.0f; @@ -1525,20 +1473,20 @@ void Renderer::TexRect(float x1, float y1, float x2, float y2) v[3].Coord.x = x1; v[3].Coord.y = y2; v[3].Coord.z = 0.0f; -// v[3].Diffuse = g_colour; v[3].FDiffuse = g_fColour; v[3].u = 0.5f / 256.0f; v[3].v = 1.0f; DiffuseUVVertexShader* pShader = &DiffuseUVVertexShader::StaticType; + SetShader( pShader ); CommitTransforms( pShader ); CommitTextureState(); - m_pD3DDevice->SetVertexShader( pShader->GetVertexShader() ); - m_pD3DDevice->SetVertexDeclaration( g_pPosColUVDeclaration ); - m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); - m_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, &v, sizeof(PosColNormalUVVertex)); - m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + UpdateVBuffer( v, 4 ); + + m_pD3D11Contex->OMSetDepthStencilState( states->DepthNone(), 0 ); + DrawPrimitive( D3DPT_TRIANGLEFAN, 6, 0 ); + m_pD3D11Contex->OMSetDepthStencilState( states->DepthDefault(), 0 ); } // TexRect @@ -1575,12 +1523,21 @@ void Renderer::CopyToScratch() //-- GetDevice ---------------------------------------------------------------- // //----------------------------------------------------------------------------- -LPDIRECT3DDEVICE9 Renderer::GetDevice() +ID3D11Device* Renderer::GetDevice() { - return m_pD3DDevice; + return m_pD3D11Device; } // GetDevice +//-- GetContext ---------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +ID3D11DeviceContext* Renderer::GetContext() +{ + return m_pD3D11Contex; + +} // GetContext + //-- GetAspect ---------------------------------------------------------------- // //----------------------------------------------------------------------------- @@ -1600,38 +1557,94 @@ void Renderer::SetIdentity() } // SetIdentity -IDirect3DPixelShader9* Renderer::CreatePixelShader( DWORD* pCode ) +//-- CreatePixelShader -------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void Renderer::CreatePixelShader( const void* pCode, unsigned int iCodeLen, ID3D11PixelShader** ppPixelShader ) { - IDirect3DPixelShader9* pPixelShader; - m_pD3DDevice->CreatePixelShader( pCode, &pPixelShader ); - return pPixelShader; -} + m_pD3D11Device->CreatePixelShader( pCode, iCodeLen, NULL, ppPixelShader ); -IDirect3DVertexShader9* Renderer::CreateVertexShader( DWORD* pCode ) -{ - IDirect3DVertexShader9* pVertexShader; - m_pD3DDevice->CreateVertexShader( pCode, &pVertexShader ); - return pVertexShader; -} +} // CreatePixelShader -void Renderer::SetConstantTableMatrix( LPD3DXCONSTANTTABLE pConstantTable, char* pConstantName, D3DXMATRIX* pMatrix ) +//-- CreateVertexShader -------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void Renderer::CreateVertexShader( const void* pCode, unsigned int iCodeLen, ID3D11VertexShader** ppVertexShader ) { - pConstantTable->SetMatrix( m_pD3DDevice, pConstantName, pMatrix ); -} + m_pD3D11Device->CreateVertexShader( pCode, iCodeLen, NULL, ppVertexShader ); -void Renderer::SetConstantTableVector( LPD3DXCONSTANTTABLE pConstantTable, char* pConstantName, D3DXVECTOR4* pVector) -{ - pConstantTable->SetVector( m_pD3DDevice, pConstantName, pVector ); -} +} // CreateVertexShader void Renderer::SetFillMode( int fillMode ) { if ( fillMode == 0 ) { - m_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + m_pD3D11Contex->RSSetState(states->CullNone()); } else { - m_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); + m_pD3D11Contex->RSSetState(states->Wireframe()); } } + +void Renderer::CreateRenderTarget(ID3D11Texture2D* pTexture, ID3D11RenderTargetView** ppRTView) +{ + CD3D11_RENDER_TARGET_VIEW_DESC rtDesc(pTexture, D3D11_RTV_DIMENSION_TEXTURE2D); + m_pD3D11Device->CreateRenderTargetView(pTexture, &rtDesc, ppRTView); +} + +void Renderer::CreateShaderView(ID3D11Texture2D* pTexture, ID3D11ShaderResourceView** ppSRView) +{ + CD3D11_SHADER_RESOURCE_VIEW_DESC srDesc(pTexture, D3D11_SRV_DIMENSION_TEXTURE2D); + m_pD3D11Device->CreateShaderResourceView(pTexture, &srDesc, ppSRView); +} + +CommonStates* Renderer::GetStates() +{ + return states.get(); +} + +void Renderer::UpdateVBuffer(PosColNormalUVVertex* verticies, unsigned int iNum) +{ + D3D11_MAPPED_SUBRESOURCE res; + if (S_OK == m_pD3D11Contex->Map(g_pFixVbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &res)) + { + memcpy(res.pData, verticies, sizeof(PosColNormalUVVertex) * iNum); + m_pD3D11Contex->Unmap(g_pFixVbuffer, 0); + } +} + +void Renderer::SetShader(Shader* pShader) +{ + if (pShader->m_ShaderType == ST_VERTEX) + m_pD3D11Contex->VSSetShader(pShader->GetVertexShader(), NULL, 0); + else if (pShader->m_ShaderType == ST_PIXEL) + m_pD3D11Contex->PSSetShader(pShader->GetPixelShader(), NULL, 0); +} + +void Renderer::SetShaderTexture(unsigned int iStartSlot, TextureDX* pTexture) +{ + ID3D11ShaderResourceView* views[1] = { NULL }; + if (pTexture != NULL && pTexture->GetTexture() != NULL) + views[0] = pTexture->GetShaderView(); + m_pD3D11Contex->PSSetShaderResources(iStartSlot, 1, views); +} + +void Renderer::DrawPrimitive(unsigned int primType, unsigned int numPrims, unsigned int startIndex) +{ + unsigned int strides = sizeof(PosColNormalUVVertex), offsets = 0; + m_pD3D11Contex->IASetVertexBuffers( 0, 1, &g_pFixVbuffer, &strides, &offsets ); + m_pD3D11Contex->IASetInputLayout( g_pPosNormalColUVDeclaration ); + + if (primType == D3DPT_TRIANGLEFAN) + { + m_pD3D11Contex->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); + m_pD3D11Contex->IASetIndexBuffer( g_pFanIbuffer, DXGI_FORMAT_R16_UINT, 0 ); + m_pD3D11Contex->DrawIndexed( numPrims, 0, startIndex ); + } + else + { + m_pD3D11Contex->IASetPrimitiveTopology( (D3D_PRIMITIVE_TOPOLOGY)primType ); + m_pD3D11Contex->Draw( numPrims, startIndex ); + } +} \ No newline at end of file diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/Renderer.h b/xbmc/visualizations/Vortex/VortexVis/Core/Renderer.h index cf1484e88b..cbf291d24b 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/Renderer.h +++ b/xbmc/visualizations/Vortex/VortexVis/Core/Renderer.h @@ -21,7 +21,10 @@ #define _RENDERER_H_ #include -#include +#include +#include +#include "TextureDX.h" +#include "CommonStates.h" enum eBlendMode { @@ -33,48 +36,50 @@ enum eBlendMode struct PosColNormalUVVertex { - D3DXVECTOR3 Coord; - D3DXVECTOR3 Normal; -// DWORD Diffuse; // diffuse color - float u, v; // Texture 0 coords - D3DXVECTOR4 FDiffuse; // float diffuse color + DirectX::XMFLOAT3 Coord; + DirectX::XMFLOAT3 Normal; + float u, v; // Texture 0 coords + DirectX::XMFLOAT4 FDiffuse; // float diffuse color }; struct PosNormalVertex { - D3DXVECTOR3 Coord; - D3DXVECTOR3 Normal; + DirectX::XMFLOAT3 Coord; + DirectX::XMFLOAT3 Normal; }; -#define SCRATCH_TEXTURE ((LPDIRECT3DTEXTURE9)-1) +#define SCRATCH_TEXTURE ((TextureDX*)-1) -extern LPDIRECT3DVERTEXDECLARATION9 g_pPosNormalColUVDeclaration; -extern LPDIRECT3DVERTEXDECLARATION9 g_pPosColUVDeclaration; -extern LPDIRECT3DVERTEXDECLARATION9 g_pPosNormalDeclaration; +extern ID3D11InputLayout* g_pPosNormalColUVDeclaration; +extern ID3D11InputLayout* g_pPosColUVDeclaration; +extern ID3D11InputLayout* g_pPosNormalDeclaration; extern char g_TexturePath[]; +class Shader; + class Renderer { public: - static void Init( LPDIRECT3DDEVICE9 pD3DDevice, int iXPos, int iYPos, int iWidth, int iHeight, float fPixelRatio ); - static void Exit(); + static void Init( ID3D11DeviceContext* pD3DContext, int iXPos, int iYPos, int iWidth, int iHeight, float fPixelRatio); + static void Exit(); static void GetBackBuffer(); static void ReleaseBackbuffer(); static void SetDefaults(); - static LPDIRECT3DDEVICE9 GetDevice(); + static ID3D11Device* GetDevice(); + static ID3D11DeviceContext* GetContext(); - static void SetRenderTarget(LPDIRECT3DTEXTURE9 texture); + static void SetRenderTarget(TextureDX* texture); static void SetRenderTargetBackBuffer(); static void SetDrawMode2d(); static void SetDrawMode3d(); - static void SetProjection(D3DXMATRIX& matProj); - static void SetView(D3DXMATRIX& matView); + static void SetProjection(const DirectX::XMMATRIX& matProj); + static void SetView(const DirectX::XMMATRIX& matView); - static void GetProjection( D3DXMATRIX& matProj ); - static LPD3DXMESH CreateD3DXTextMesh( const char* pString, bool bCentered ); - static void DrawMesh( LPD3DXMESH pMesh ); + static void GetProjection(DirectX::XMMATRIX& matProj); + static IUnknown* CreateD3DXTextMesh(const char* pString, bool bCentered); + static void DrawMesh(IUnknown* pMesh); static void Clear( DWORD Col ); @@ -84,19 +89,19 @@ public: static void Line( float x1, float y1, float x2, float y2, DWORD Col ); static void Point( float x, float y, DWORD Col ); - static LPDIRECT3DTEXTURE9 CreateTexture( int iWidth, int iHeight, D3DFORMAT Format = D3DFMT_X8R8G8B8, bool bDynamic = FALSE ); - static LPDIRECT3DTEXTURE9 LoadTexture( char* pFilename, bool bAutoResize = true ); - static void ReleaseTexture( LPDIRECT3DTEXTURE9 pTexture ); + static TextureDX* CreateTexture( int iWidth, int iHeight, DXGI_FORMAT Format = DXGI_FORMAT_B8G8R8A8_UNORM, bool bDynamic = FALSE ); + static TextureDX* LoadTexture(char* pFilename, bool bAutoResize = true); + static void ReleaseTexture( TextureDX* pTexture ); static void DrawText( float x, float y, char* txt, DWORD Col = 0xffffffff); - static int GetViewportWidth(); - static int GetViewportHeight(); + static float GetViewportWidth(); + static float GetViewportHeight(); static void SetBlendMode(eBlendMode blendMode); static float GetAspect(); static void SetAspect(float aspect); - static void SetTexture(LPDIRECT3DTEXTURE9 texture); - static void SetEnvTexture(LPDIRECT3DTEXTURE9 texture); + static void SetTexture(TextureDX* texture); + static void SetEnvTexture(TextureDX* texture); static void CopyToScratch(); @@ -114,7 +119,7 @@ public: static void Sphere(int del_uhol_x, int del_uhol_y, float size); static void SimpleSphere(float size); - static void Circle(float radius, int numSides, D3DXVECTOR3& dir); + static void Circle(float radius, int numSides, DirectX::XMFLOAT3& dir); static void PushMatrix(); static void PopMatrix(); static void SetIdentity(); @@ -127,23 +132,29 @@ public: static void Rect(float x1, float y1, float x2, float y2); static void TexRect(float x1, float y1, float x2, float y2); - static void DrawPrimitive(D3DPRIMITIVETYPE primType, unsigned int startIndex, unsigned int numPrims); + static void DrawPrimitive(unsigned int primType, unsigned int numPrims, unsigned int startIndex); static void SetLineWidth(float width); static void SetFillMode(int fillMode); - static void CommitTransforms( class DiffuseUVVertexShader* pShader ); + static void CommitTransforms( class Shader* pShader ); static void CommitTextureState(); - static IDirect3DPixelShader9* CreatePixelShader( DWORD* pCode ); - static IDirect3DVertexShader9* CreateVertexShader( DWORD* pCode ); - static void SetConstantTableMatrix( LPD3DXCONSTANTTABLE pConstantTable, char* pConstantName, D3DXMATRIX* pMatrix ); - static void SetConstantTableVector( LPD3DXCONSTANTTABLE pConstantTable, char* pConstantName, D3DXVECTOR4* pVector ); + static void CreatePixelShader( const void* pCode, unsigned int iCodeLen, ID3D11PixelShader** ppPixelShader ); + static void CreateVertexShader( const void* pCode, unsigned int iCodeLen, ID3D11VertexShader** ppVertexShader ); + + static void CreateRenderTarget(ID3D11Texture2D* pTexture, ID3D11RenderTargetView** ppRTView); + static void CreateShaderView(ID3D11Texture2D* pTexture, ID3D11ShaderResourceView** ppSRView); + + static DirectX::CommonStates* GetStates(); + static void UpdateVBuffer(PosColNormalUVVertex* verticies, unsigned int iNum); + + static void SetShader( Shader* pShader ); + static void SetShaderTexture(unsigned int iStartSlot, TextureDX* pTextures); private: static void CreateCubeBuffers(); static void CreateFonts(); static void CompileShaders(); - }; #endif diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/Shader.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/Shader.cpp index 3c7949ea3b..e83cc6bc43 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/Shader.cpp +++ b/xbmc/visualizations/Vortex/VortexVis/Core/Shader.cpp @@ -34,7 +34,9 @@ void Shader::ReleaseAllShaders() (*ShaderIterator)->m_pVShader->Release(); if ( (*ShaderIterator)->m_pPShader ) (*ShaderIterator)->m_pPShader->Release(); - } + if ((*ShaderIterator)->m_pConstantBuffer) + (*ShaderIterator)->m_pConstantBuffer->Release(); + } } bool Shader::CompileAllShaders() @@ -55,235 +57,45 @@ bool Shader::CompileAllShaders() bool Shader::CompileShader() { - DWORD dwShaderFlags = D3DXSHADER_PARTIALPRECISION; - LPD3DXBUFFER pCode; - LPD3DXBUFFER pErrors; - - int iSrcLen = strlen( m_pShaderSrc ); - if ( iSrcLen == 0 ) + if ( m_iCodeLen == 0 ) return false; - HRESULT hr = ( D3DXCompileShader( m_pShaderSrc, - iSrcLen, - NULL, // defines - NULL, // include - "Main", // Function name - m_ShaderType == ST_PIXEL ? "ps_2_0": "vs_2_0", // profile - dwShaderFlags, // Flags - &pCode, // Output compiled shader - &pErrors, // error messages - &m_pConstantTable // constant table - ) ); - - if( FAILED( hr ) ) - { - char* errors = (char*)pErrors->GetBufferPointer(); - OutputDebugStringA( errors ); - return false; - } - if ( m_ShaderType == ST_PIXEL ) - { - m_pPShader = Renderer::CreatePixelShader( ( DWORD* )pCode->GetBufferPointer() ); - } + Renderer::CreatePixelShader( m_pShaderSrc, m_iCodeLen, &m_pPShader ); else - { - m_pVShader = Renderer::CreateVertexShader( ( DWORD* )pCode->GetBufferPointer() ); - } + Renderer::CreateVertexShader( m_pShaderSrc, m_iCodeLen, &m_pVShader ); - pCode->Release(); return true; } -char DiffuseUVVertexShaderSrc[] = +void Shader::CommitConstants(ID3D11DeviceContext* pContext) { - " struct VS_INPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 Colour : COLOR; \n" - " float2 Tex0 : TEXCOORD0; \n" - " }; \n" - " struct VS_OUTPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 Colour : COLOR; \n" - " float2 Tex0 : TEXCOORD0; \n" - " }; \n" - " \n" - " float4x4 WVPMat; \n" - " VS_OUTPUT Main( VS_INPUT input ) \n" - " { \n" - " VS_OUTPUT output; \n" - " // Transform coord \n" - " output.vPosition = mul(WVPMat, float4(input.vPosition.xyz, 1.0f)); \n" - " output.Colour = input.Colour; \n" - " output.Tex0 = input.Tex0; \n" - " return output; \n" - " } \n" - " \n" -}; + if (m_ShaderType != ST_VERTEX) + return; -char DiffuseUVEnvVertexShaderSrc[] = -{ - " struct VS_INPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 vNormal : NORMAL; \n" - " float4 Colour : COLOR; \n" - " float2 Tex0 : TEXCOORD0; \n" - " }; \n" - " struct VS_OUTPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 Colour : COLOR; \n" - " float2 Tex0 : TEXCOORD0; \n" - " }; \n" - " \n" - " float4x4 WVMat; \n" - " float4x4 WVPMat; \n" - " VS_OUTPUT Main( VS_INPUT input ) \n" - " { \n" - " VS_OUTPUT output; \n" - " // Transform coord \n" - " output.vPosition = mul(WVPMat, float4(input.vPosition.xyz, 1.0f)); \n" - " output.Colour = input.Colour; \n" - " float4 NormalCamSpace = mul(WVMat, float4(input.vNormal.xyz, 0.0f));\n" - " output.Tex0.xy = (NormalCamSpace.xy * 0.8f) + 0.5f; \n" -// " output.Colour = float4(NormalCamSpace.xyz, 1); \n" - " return output; \n" - " } \n" - " \n" -}; + if (!m_pConstantBuffer) + CreateConstantBuffer(); -char DiffuseUVCubeVertexShaderSrc[] = -{ - " struct VS_INPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 Colour : COLOR; \n" - " float2 Tex0 : TEXCOORD0; \n" - " }; \n" - " struct VS_OUTPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 Colour : COLOR; \n" - " float2 Tex0 : TEXCOORD0; \n" - " }; \n" - " \n" - " float4 Col; \n" - " float4 vScale; \n" - " float4x4 WVMat; \n" - " float4x4 WVPMat; \n" - " VS_OUTPUT Main( VS_INPUT input ) \n" - " { \n" - " VS_OUTPUT output; \n" - " float4 vPos = float4(input.vPosition.xyz * vScale, 1); \n" - " // Transform coord \n" - " output.vPosition = mul(WVPMat, vPos); \n" - " output.Colour = Col; \n" - " output.Tex0.xy = input.Tex0; \n" - " return output; \n" - " } \n" - " \n" -}; + D3D11_MAPPED_SUBRESOURCE res; + if (S_OK == pContext->Map(m_pConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &res)) + { + *(ShaderContants*)res.pData = m_ShaderContants; + pContext->Unmap(m_pConstantBuffer, 0); + } -char DiffuseUVEnvCubeVertexShaderSrc[] = -{ - " struct VS_INPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 vNormal : NORMAL; \n" - " float4 Colour : COLOR; \n" - " float2 Tex0 : TEXCOORD0; \n" - " }; \n" - " struct VS_OUTPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 Colour : COLOR; \n" - " float2 Tex0 : TEXCOORD0; \n" - " }; \n" - " \n" - " float4 Col; \n" - " float4 vScale; \n" - " float4x4 WVMat; \n" - " float4x4 WVPMat; \n" - " VS_OUTPUT Main( VS_INPUT input ) \n" - " { \n" - " VS_OUTPUT output; \n" - " float4 vPos = float4(input.vPosition.xyz * vScale, 1); \n" - " // Transform coord \n" - " output.vPosition = mul(WVPMat, vPos); \n" - " output.Colour = Col; \n" - " float4 NormalCamSpace = mul(WVMat, float4(input.vNormal.xyz, 0.0f));\n" - " output.Tex0.xy = (NormalCamSpace.xy * 0.5f) + 0.5f; \n" - " return output; \n" - " } \n" - " \n" -}; + pContext->VSSetConstantBuffers(0, 1, &m_pConstantBuffer); +} -char DiffuseNormalEnvCubeVertexShaderSrc[] = +void Shader::CreateConstantBuffer() { - " struct VS_INPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 vNormal : NORMAL; \n" - " }; \n" - " struct VS_OUTPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 Colour : COLOR; \n" - " float2 Tex0 : TEXCOORD0; \n" - " }; \n" - " \n" - " float4 Col; \n" - " float4x4 WVMat; \n" - " float4x4 WVPMat; \n" - " VS_OUTPUT Main( VS_INPUT input ) \n" - " { \n" - " VS_OUTPUT output; \n" - " float4 vPos = float4(input.vPosition.xyz, 1); \n" - " // Transform coord \n" - " output.vPosition = mul(WVPMat, vPos); \n" - " output.Colour = 0xffffffff; \n" - " float4 NormalCamSpace = mul(WVMat, float4(input.vNormal.xyz, 0.0f));\n" - " output.Tex0.xy = (NormalCamSpace.xy * 0.2f) + 0.5f; \n" - " return output; \n" - " } \n" - " \n" -}; + CD3D11_BUFFER_DESC bDesc(sizeof(ShaderContants), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); + Renderer::GetDevice()->CreateBuffer(&bDesc, NULL, &m_pConstantBuffer); +} -char UVNormalEnvVertexShaderSrc[] = -{ - " struct VS_INPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 vNormal : NORMAL; \n" - " }; \n" - " struct VS_OUTPUT \n" - " { \n" - " float4 vPosition : POSITION; \n" - " float4 Colour : COLOR; \n" - " float2 Tex0 : TEXCOORD0; \n" - " }; \n" - " \n" - " float4x4 WVMat; \n" - " float4x4 WVPMat; \n" - " VS_OUTPUT Main( VS_INPUT input ) \n" - " { \n" - " VS_OUTPUT output; \n" - " // Transform coord \n" - " output.vPosition = mul(WVPMat, float4(input.vPosition.xyz, 1.0f)); \n" - " output.Colour = 0xffffffff; \n" - " float4 NormalCamSpace = mul(WVMat, float4(input.vNormal.xyz, 0.0f));\n" - " output.Tex0.xy = (NormalCamSpace.xy * 0.2f) + 0.5f; \n" - " return output; \n" - " } \n" - " \n" -}; -IMPLEMENT_SHADER(DiffuseUVVertexShader, DiffuseUVVertexShaderSrc, ST_VERTEX); -IMPLEMENT_SHADER(DiffuseUVEnvVertexShader, DiffuseUVEnvVertexShaderSrc, ST_VERTEX); -IMPLEMENT_SHADER(DiffuseUVCubeVertexShader, DiffuseUVCubeVertexShaderSrc, ST_VERTEX); -IMPLEMENT_SHADER(DiffuseUVEnvCubeVertexShader, DiffuseUVEnvCubeVertexShaderSrc, ST_VERTEX); -IMPLEMENT_SHADER(DiffuseNormalEnvCubeVertexShader, DiffuseNormalEnvCubeVertexShaderSrc, ST_VERTEX); -IMPLEMENT_SHADER(UVNormalEnvVertexShader, UVNormalEnvVertexShaderSrc, ST_VERTEX); +IMPLEMENT_SHADER(DiffuseUVVertexShader, DiffuseUVVertexShaderCode, sizeof(DiffuseUVVertexShaderCode), ST_VERTEX); +IMPLEMENT_SHADER(DiffuseUVEnvVertexShader, DiffuseUVEnvVertexShaderCode, sizeof(DiffuseUVEnvVertexShaderCode), ST_VERTEX); +IMPLEMENT_SHADER(DiffuseUVCubeVertexShader, DiffuseUVCubeVertexShaderCode, sizeof(DiffuseUVCubeVertexShaderCode), ST_VERTEX); +IMPLEMENT_SHADER(DiffuseUVEnvCubeVertexShader, DiffuseUVEnvCubeVertexShaderCode, sizeof(DiffuseUVEnvCubeVertexShaderCode), ST_VERTEX); +IMPLEMENT_SHADER(DiffuseNormalEnvCubeVertexShader, DiffuseNormalEnvCubeVertexShaderCode, sizeof(DiffuseNormalEnvCubeVertexShaderCode), ST_VERTEX); +IMPLEMENT_SHADER(UVNormalEnvVertexShader, UVNormalEnvVertexShaderCode, sizeof(UVNormalEnvVertexShaderCode), ST_VERTEX); diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/Shader.h b/xbmc/visualizations/Vortex/VortexVis/Core/Shader.h index 423a1c8e88..019b25c1b3 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/Shader.h +++ b/xbmc/visualizations/Vortex/VortexVis/Core/Shader.h @@ -21,9 +21,18 @@ #define _SHADER_H_ #include -#include #include "Renderer.h" +namespace +{ + #include "../Shaders/DiffuseUVVertexShader.inc" + #include "../Shaders/DiffuseUVEnvVertexShader.inc" + #include "../Shaders/DiffuseUVCubeVertexShader.inc" + #include "../Shaders/DiffuseUVEnvCubeVertexShader.inc" + #include "../Shaders/DiffuseNormalEnvCubeVertexShader.inc" + #include "../Shaders/UVNormalEnvVertexShader.inc" +} + enum EShaderType { ST_VERTEX, @@ -34,15 +43,16 @@ enum EShaderType public: \ static InShaderName StaticType; -#define IMPLEMENT_SHADER(ShaderName, ShaderSrc, ShaderType)\ - ShaderName ShaderName::StaticType = ShaderName( ShaderType, ShaderSrc ); +#define IMPLEMENT_SHADER(ShaderName, ShaderCode, iLenght, ShaderType) \ + ShaderName ShaderName::StaticType = ShaderName( ShaderType, ShaderCode, iLenght ); class Shader { public: - Shader( EShaderType ShaderType, char* pShaderSrc ) : + Shader( EShaderType ShaderType, const void* pShaderCode, unsigned int iCodeLen ) : m_ShaderType( ShaderType ), - m_pShaderSrc( pShaderSrc ) + m_pShaderSrc( pShaderCode ), + m_iCodeLen( iCodeLen ) { std::vector& ShaderList = GetShaderList(); ShaderList.push_back( this ); @@ -57,80 +67,89 @@ public: static bool CompileAllShaders(); static void ReleaseAllShaders(); - LPDIRECT3DVERTEXSHADER9 GetVertexShader() { return m_pVShader; } - LPDIRECT3DPIXELSHADER9 GetPixelShader() { return m_pPShader; } - + ID3D11VertexShader* GetVertexShader() { return m_pVShader; } + ID3D11PixelShader* GetPixelShader() { return m_pPShader; } + void CommitConstants(ID3D11DeviceContext* pContext); + + void SetWVP(DirectX::XMMATRIX* pWVPMat) + { + XMStoreFloat4x4(&m_ShaderContants.WVPMat, *pWVPMat); + } + void SetWV(DirectX::XMMATRIX* pWVMat) + { + XMStoreFloat4x4(&m_ShaderContants.WVMat, *pWVMat); + } + void SetScale(DirectX::XMVECTOR* pvScale) + { + XMStoreFloat4(&m_ShaderContants.vScale, *pvScale); + } + void SetColour(DirectX::XMFLOAT4* pvCol) + { + m_ShaderContants.Col = *pvCol; + } + + EShaderType m_ShaderType; protected: - EShaderType m_ShaderType; - char* m_pShaderSrc; + struct ShaderContants + { + DirectX::XMFLOAT4 Col; + DirectX::XMFLOAT4 vScale; + DirectX::XMFLOAT4X4 WVPMat; + DirectX::XMFLOAT4X4 WVMat; + }; + + const void* m_pShaderSrc; + unsigned int m_iCodeLen; + ShaderContants m_ShaderContants; bool CompileShader(); + void CreateConstantBuffer(); - LPDIRECT3DVERTEXSHADER9 m_pVShader; - LPDIRECT3DPIXELSHADER9 m_pPShader; - LPD3DXCONSTANTTABLE m_pConstantTable; -// LPDIRECT3DVERTEXDECLARATION9* m_ppVertexDecl; + ID3D11VertexShader* m_pVShader; + ID3D11PixelShader* m_pPShader; + ID3D11Buffer* m_pConstantBuffer; }; class DiffuseUVVertexShader : public Shader { DECLARE_SHADER(DiffuseUVVertexShader); public: - DiffuseUVVertexShader( EShaderType ShaderType, char* pShaderSrc ) : Shader( ShaderType, pShaderSrc ){}; - - void SetWVP( D3DXMATRIX* pWVPMat ) - { - Renderer::SetConstantTableMatrix( m_pConstantTable, "WVPMat", pWVPMat ); - } - void SetWV( D3DXMATRIX* pWVMat ) - { - Renderer::SetConstantTableMatrix( m_pConstantTable, "WVMat", pWVMat ); - } + DiffuseUVVertexShader( EShaderType ShaderType, const void* pShaderCode, unsigned int iLengh ) : Shader( ShaderType, pShaderCode, iLengh ){}; }; class DiffuseUVEnvVertexShader : public DiffuseUVVertexShader { DECLARE_SHADER(DiffuseUVEnvVertexShader); public: - DiffuseUVEnvVertexShader( EShaderType ShaderType, char* pShaderSrc ) : DiffuseUVVertexShader( ShaderType, pShaderSrc ){}; + DiffuseUVEnvVertexShader( EShaderType ShaderType, const void* pShaderCode, unsigned int iLenght ) : DiffuseUVVertexShader( ShaderType, pShaderCode, iLenght ){}; }; class DiffuseUVCubeVertexShader : public DiffuseUVVertexShader { DECLARE_SHADER(DiffuseUVCubeVertexShader); public: - DiffuseUVCubeVertexShader( EShaderType ShaderType, char* pShaderSrc ) : DiffuseUVVertexShader( ShaderType, pShaderSrc ){}; - - void SetScale( D3DXVECTOR4* pvScale ) - { - Renderer::SetConstantTableVector( m_pConstantTable, "vScale", pvScale); - } - void SetColour( D3DXVECTOR4* pvCol ) - { - Renderer::SetConstantTableVector( m_pConstantTable, "Col", pvCol); - } - + DiffuseUVCubeVertexShader( EShaderType ShaderType, const void* pShaderCode, unsigned int iLenght ) : DiffuseUVVertexShader( ShaderType, pShaderCode, iLenght ){}; }; class DiffuseUVEnvCubeVertexShader : public DiffuseUVCubeVertexShader { DECLARE_SHADER(DiffuseUVEnvCubeVertexShader); public: - DiffuseUVEnvCubeVertexShader( EShaderType ShaderType, char* pShaderSrc ) : DiffuseUVCubeVertexShader( ShaderType, pShaderSrc ){}; + DiffuseUVEnvCubeVertexShader( EShaderType ShaderType, const void* pShaderCode, unsigned int iLenght ) : DiffuseUVCubeVertexShader( ShaderType, pShaderCode, iLenght ){}; }; class DiffuseNormalEnvCubeVertexShader : public DiffuseUVCubeVertexShader { DECLARE_SHADER(DiffuseNormalEnvCubeVertexShader); public: - DiffuseNormalEnvCubeVertexShader( EShaderType ShaderType, char* pShaderSrc ) : DiffuseUVCubeVertexShader( ShaderType, pShaderSrc ){}; + DiffuseNormalEnvCubeVertexShader( EShaderType ShaderType, const void* pShaderCode, unsigned int iLenght ) : DiffuseUVCubeVertexShader( ShaderType, pShaderCode, iLenght ){}; }; class UVNormalEnvVertexShader : public DiffuseUVVertexShader { DECLARE_SHADER(UVNormalEnvVertexShader); public: - UVNormalEnvVertexShader( EShaderType ShaderType, char* pShaderSrc ) : DiffuseUVVertexShader( ShaderType, pShaderSrc ){}; + UVNormalEnvVertexShader( EShaderType ShaderType, const void* pShaderCode, unsigned int iLenght ) : DiffuseUVVertexShader( ShaderType, pShaderCode, iLenght ){}; }; #endif _SHADER_H_ diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/SharedResourcePool.h b/xbmc/visualizations/Vortex/VortexVis/Core/SharedResourcePool.h new file mode 100644 index 0000000000..a7c15886d0 --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/SharedResourcePool.h @@ -0,0 +1,105 @@ +//-------------------------------------------------------------------------------------- +// File: SharedResourcePool.h +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#include +#include + +namespace DirectX +{ + // Pool manager ensures that only a single TData instance is created for each unique TKey. + // This is used to avoid duplicate resource creation, so that for instance a caller can + // create any number of SpriteBatch instances, but these can internally share shaders and + // vertex buffer if more than one SpriteBatch uses the same underlying D3D device. + template + class SharedResourcePool + { + public: + SharedResourcePool() + : mResourceMap(std::make_shared()) + { } + + + // Allocates or looks up the shared TData instance for the specified key. + std::shared_ptr DemandCreate(TKey key) + { + std::lock_guard lock(mResourceMap->mutex); + + // Return an existing instance? + auto pos = mResourceMap->find(key); + + if (pos != mResourceMap->end()) + { + auto existingValue = pos->second.lock(); + + if (existingValue) + return existingValue; + else + mResourceMap->erase(pos); + } + + // Allocate a new instance. + auto newValue = std::make_shared(key, mResourceMap); + + mResourceMap->insert(std::make_pair(key, newValue)); + + return newValue; + } + + + private: + // Keep track of all allocated TData instances. + struct ResourceMap : public std::map> + { + std::mutex mutex; + }; + + std::shared_ptr mResourceMap; + + + // Wrap TData with our own subclass, so we can hook the destructor + // to remove instances from our pool before they are freed. + struct WrappedData : public TData + { + WrappedData(TKey key, std::shared_ptr const& resourceMap) + : mKey(key), + mResourceMap(resourceMap), + TData(key) + { } + + ~WrappedData() + { + std::lock_guard lock(mResourceMap->mutex); + + auto pos = mResourceMap->find(mKey); + + // Check for weak reference expiry before erasing, in case DemandCreate runs on + // a different thread at the same time as a previous instance is being destroyed. + // We mustn't erase replacement objects that have just been added! + if (pos != mResourceMap->end() && pos->second.expired()) + { + mResourceMap->erase(pos); + } + } + + TKey mKey; + std::shared_ptr mResourceMap; + }; + + + // Prevent copying. + SharedResourcePool(SharedResourcePool const&); + SharedResourcePool& operator= (SharedResourcePool const&); + }; +} diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/Texture.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/Texture.cpp index 0090b64244..30de82281a 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/Texture.cpp +++ b/xbmc/visualizations/Vortex/VortexVis/Core/Texture.cpp @@ -22,8 +22,6 @@ #include #include -using namespace std; - Texture::Texture() { m_iRefCount = 1; @@ -68,7 +66,7 @@ void Texture::CreateTexture() } // CreateTexture -void Texture::LoadTexture(string& filename) +void Texture::LoadTexture(std::string& filename) { char fullname[ 512 ]; sprintf_s(fullname, 512, "%s%s", g_TexturePath, filename.c_str() ); diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/Texture.h b/xbmc/visualizations/Vortex/VortexVis/Core/Texture.h index 44c88b168b..294bfb9d10 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/Texture.h +++ b/xbmc/visualizations/Vortex/VortexVis/Core/Texture.h @@ -21,6 +21,7 @@ #define _TEXTURE_H_ #include "Renderer.h" +#include "TextureDX.h" #include class Texture @@ -33,7 +34,7 @@ public: void AddRef(); void Release(); - LPDIRECT3DTEXTURE9 m_pTexture; + TextureDX* m_pTexture; bool m_renderTarget; protected: diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/TextureDX.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/TextureDX.cpp new file mode 100644 index 0000000000..88e4ff98bd --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/TextureDX.cpp @@ -0,0 +1,71 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#include "TextureDX.h" +#include "Renderer.h" + +TextureDX::TextureDX(ID3D11Texture2D* pTexture) + : m_iRefCount(1), + m_texture(pTexture), + m_renderTarget(NULL), + m_shaderView(NULL) +{ +} + +TextureDX::~TextureDX() +{ + if (m_texture) + m_texture->Release(); + if (m_renderTarget) + m_renderTarget->Release(); + if (m_shaderView) + m_shaderView->Release(); +} + +ID3D11RenderTargetView* TextureDX::GetRenderTarget() +{ + if (!m_renderTarget) + Renderer::CreateRenderTarget(m_texture, &m_renderTarget); + + return m_renderTarget; +} + +ID3D11ShaderResourceView* TextureDX::GetShaderView() +{ + if (!m_shaderView) + Renderer::CreateShaderView(m_texture, &m_shaderView); + + return m_shaderView; +} + +bool TextureDX::LockRect(UINT subRes, D3D11_MAPPED_SUBRESOURCE* res) +{ + if (!m_texture) + return false; + + return S_OK == Renderer::GetContext()->Map(m_texture, 0, D3D11_MAP_WRITE_DISCARD, 0, res); +} + +void TextureDX::UnlockRect(UINT subRes) +{ + if (!m_texture) + return; + + Renderer::GetContext()->Unmap(m_texture, 0); +} diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/TextureDX.h b/xbmc/visualizations/Vortex/VortexVis/Core/TextureDX.h new file mode 100644 index 0000000000..578709a6f0 --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/TextureDX.h @@ -0,0 +1,52 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#pragma once + +#include + +class TextureDX +{ +public: + TextureDX(ID3D11Texture2D* pTexture); + virtual ~TextureDX(); + + void AddRef() + { + m_iRefCount++; + } + + void Release() + { + if (--m_iRefCount == 0) + delete this; + } + + ID3D11Texture2D* GetTexture() { return m_texture; } + ID3D11RenderTargetView* GetRenderTarget(); + ID3D11ShaderResourceView* GetShaderView(); + bool LockRect(UINT subRes, D3D11_MAPPED_SUBRESOURCE* res); + void UnlockRect(UINT subRes); + +protected: + int m_iRefCount; + ID3D11Texture2D* m_texture; + ID3D11RenderTargetView* m_renderTarget; + ID3D11ShaderResourceView* m_shaderView; +}; diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/Vortex.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/Vortex.cpp index f2189a6d40..834cd8a9e2 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/Vortex.cpp +++ b/xbmc/visualizations/Vortex/VortexVis/Core/Vortex.cpp @@ -31,7 +31,6 @@ #include "XmlDocument.h" #include -using namespace std; #include "angelscript.h" #include "../../angelscript/add_on/scriptstring/scriptstring.h" @@ -80,13 +79,13 @@ public: Rating = pVisTrack->rating; } - string Title; - string Artist; - string Album; - string AlbumArtist; - string Genre; - string Comment; - string Lyrics; + std::string Title; + std::string Artist; + std::string Album; + std::string AlbumArtist; + std::string Genre; + std::string Comment; + std::string Lyrics; int TrackNumber; int DiscNumber; @@ -95,10 +94,11 @@ public: char Rating; }; -char g_TexturePath[ 512 ] = "special://xbmc/addons/visualization.vortex/resources/Textures/"; -char g_PresetPath[ 512 ] = "special://xbmc/addons/visualization.vortex/resources/Presets/"; -char g_TransitionPath[ 512 ] = "special://xbmc//addons/visualization.vortex/resources/Transitions/"; -char g_AnnouncePath[ 512 ] = "special://xbmc/addons/visualization.vortex/resources/Announcements/"; +char g_pluginPath[ MAX_PATH ]; +char g_TexturePath[ MAX_PATH ]; +char g_PresetPath[ MAX_PATH ]; +char g_TransitionPath[ MAX_PATH ]; +char g_AnnouncePath[ MAX_PATH ]; class FileHolder { @@ -123,7 +123,7 @@ public: } } - void GetFiles( const string fileDir, const string fileExt ) + void GetFiles( const std::string fileDir, const std::string fileExt ) { if ( m_AllFilenames ) { @@ -138,7 +138,7 @@ public: } m_Filenames.clear(); - string path = fileDir + "*." + fileExt; + std::string path = fileDir + "*." + fileExt; WIN32_FIND_DATA findData; HANDLE hFind = FindFirstFile( path.c_str(), &findData ); @@ -197,7 +197,7 @@ public: } private: - vector m_Filenames; + std::vector m_Filenames; char* m_AllFilenames; char** m_FilenameAddresses; }; @@ -211,10 +211,10 @@ namespace Preset g_AnnouncePreset; Preset* g_presets[2] = {&g_preset1, &g_preset2}; - LPDIRECT3DTEXTURE9 g_currPresetTex; - LPDIRECT3DTEXTURE9 g_newPresetTex; - LPDIRECT3DTEXTURE9 g_albumArt = NULL; - LPDIRECT3DTEXTURE9 g_vortexLogo = NULL; + TextureDX* g_currPresetTex; + TextureDX* g_newPresetTex; + TextureDX* g_albumArt = NULL; + TextureDX* g_vortexLogo = NULL; int g_renderTarget = 0; int g_currPresetId = 0; @@ -307,12 +307,28 @@ int GetRandomPreset() return nextPreset; } -void Vortex::Init( LPDIRECT3DDEVICE9 pD3DDevice, int iPosX, int iPosY, int iWidth, int iHeight, float fPixelRatio ) +void Vortex::InitPaths(void) +{ + strcpy(g_TexturePath, g_pluginPath); + strcat(g_TexturePath, "/resources/Textures/"); + + strcpy(g_PresetPath, g_pluginPath); + strcat(g_PresetPath, "/resources/Presets/"); + + strcpy(g_TransitionPath, g_pluginPath); + strcat(g_TransitionPath, "/resources/Transitions/"); + + strcpy(g_AnnouncePath, g_pluginPath); + strcat(g_AnnouncePath, "/resources/Announcements/"); +} + +void Vortex::Init( ID3D11DeviceContext* pD3DContext, int iPosX, int iPosY, int iWidth, int iHeight, float fPixelRatio) { InitTime(); + InitPaths(); DebugConsole::Init(); - Renderer::Init( pD3DDevice, iPosX, iPosY, iWidth, iHeight, fPixelRatio ); + Renderer::Init( pD3DContext, iPosX, iPosY, iWidth, iHeight, fPixelRatio ); InitAngelScript(); g_fftobj.Init(576, NUM_FREQUENCIES); @@ -1010,7 +1026,7 @@ void Vortex::Render() } // Function implementation with native calling convention -void PrintString(string &str) +void PrintString(std::string &str) { DebugConsole::Log( str.c_str() ); } @@ -1018,7 +1034,7 @@ void PrintString(string &str) // Function implementation with generic script interface void PrintString_Generic(asIScriptGeneric *gen) { - string *str = (string*)gen->GetArgAddress(0); + std::string *str = (std::string*)gen->GetArgAddress(0); DebugConsole::Log( str->c_str() ); } @@ -1210,8 +1226,7 @@ void SetEnvTexture(int textureId) if ( g_albumArt /*&& g_useAlbumArt*/ ) Renderer::SetTexture( g_albumArt ); else - // Renderer_c::SetTexture(g_vortexLogo); - Renderer::SetEnvTexture( NULL ); + Renderer::SetEnvTexture( g_vortexLogo ); } else { @@ -1250,12 +1265,13 @@ int IntClamp(int val, int min, int max) void SetEffectTexture( EffectBase& rEffect ) { Renderer::SetTexture( rEffect.GetTexture() ); + rEffect.Release(); } void SetEffectRenderTarget( EffectBase& rEffect ) { - Renderer::SetRenderTarget( rEffect.GetRenderTarget() ); + Renderer::SetRenderTarget( rEffect.GetTexture() ); rEffect.Release(); } @@ -1263,6 +1279,7 @@ void SetEffectRenderTarget( EffectBase& rEffect ) void DrawMesh( Mesh& pMesh ) { Renderer::DrawMesh( pMesh.GetMesh() ); + pMesh.Release(); } diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/Vortex.h b/xbmc/visualizations/Vortex/VortexVis/Core/Vortex.h index 83912ac784..fa1b9bd3f4 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/Vortex.h +++ b/xbmc/visualizations/Vortex/VortexVis/Core/Vortex.h @@ -19,7 +19,7 @@ #ifndef _VORTEX_H_ -#include +#include class asIScriptEngine; class VisTrack; @@ -54,7 +54,7 @@ struct UserSettings class Vortex { public: - void Init( LPDIRECT3DDEVICE9 pD3DDevice, int iPosX, int iPosY, int iWidth, int iHeight, float fPixelRatio ); + void Init( ID3D11DeviceContext* pD3DContext, int iPosX, int iPosY, int iWidth, int iHeight, float fPixelRatio); void Start( int iChannels, int iSamplesPerSec, int iBitsPerSample, const char* szSongName ); void Shutdown(); void AudioData( const float* pAudioData, int iAudioDataLength, float* pFreq, int iFreqDataLength ); @@ -74,6 +74,7 @@ public: void SaveSettings(); private: + void InitPaths(void); bool InitAngelScript(); asIScriptEngine* m_pScriptEngine; }; diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/WICTextureLoader.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/WICTextureLoader.cpp new file mode 100644 index 0000000000..67ccd8f35d --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/WICTextureLoader.cpp @@ -0,0 +1,1152 @@ +//-------------------------------------------------------------------------------------- +// File: WICTextureLoader.cpp +// +// Function for loading a WIC image and creating a Direct3D 11 runtime texture for it +// (auto-generating mipmaps if possible) +// +// Note: Assumes application has already called CoInitializeEx +// +// Warning: CreateWICTexture* functions are not thread-safe if given a d3dContext instance for +// auto-gen mipmap support. +// +// Note these functions are useful for images created as simple 2D textures. For +// more complex resources, DDSTextureLoader is an excellent light-weight runtime loader. +// For a full-featured DDS file reader, writer, and texture processing pipeline see +// the 'Texconv' sample and the 'DirectXTex' library. +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkId=248926 +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +// We could load multi-frame images (TIFF/GIF) into a texture array. +// For now, we just load the first frame (note: DirectXTex supports multi-frame images) + +// VS 2010's stdint.h conflicts with intsafe.h +#pragma warning(push) +#pragma warning(disable : 4005) +#include +#pragma warning(pop) + +#include "WICTextureLoader.h" +#include "DirectXHelpers.h" +#include +#include +#include + +using Microsoft::WRL::ComPtr; +using namespace DirectX; + +//------------------------------------------------------------------------------------- +// WIC Pixel Format Translation Data +//------------------------------------------------------------------------------------- +struct WICTranslate +{ + GUID wic; + DXGI_FORMAT format; +}; + +static WICTranslate g_WICFormats[] = +{ + { GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT }, + + { GUID_WICPixelFormat64bppRGBAHalf, DXGI_FORMAT_R16G16B16A16_FLOAT }, + { GUID_WICPixelFormat64bppRGBA, DXGI_FORMAT_R16G16B16A16_UNORM }, + + { GUID_WICPixelFormat32bppRGBA, DXGI_FORMAT_R8G8B8A8_UNORM }, + { GUID_WICPixelFormat32bppBGRA, DXGI_FORMAT_B8G8R8A8_UNORM }, // DXGI 1.1 + { GUID_WICPixelFormat32bppBGR, DXGI_FORMAT_B8G8R8X8_UNORM }, // DXGI 1.1 + + { GUID_WICPixelFormat32bppRGBA1010102XR, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM }, // DXGI 1.1 + { GUID_WICPixelFormat32bppRGBA1010102, DXGI_FORMAT_R10G10B10A2_UNORM }, + + { GUID_WICPixelFormat16bppBGRA5551, DXGI_FORMAT_B5G5R5A1_UNORM }, + { GUID_WICPixelFormat16bppBGR565, DXGI_FORMAT_B5G6R5_UNORM }, + + { GUID_WICPixelFormat32bppGrayFloat, DXGI_FORMAT_R32_FLOAT }, + { GUID_WICPixelFormat16bppGrayHalf, DXGI_FORMAT_R16_FLOAT }, + { GUID_WICPixelFormat16bppGray, DXGI_FORMAT_R16_UNORM }, + { GUID_WICPixelFormat8bppGray, DXGI_FORMAT_R8_UNORM }, + + { GUID_WICPixelFormat8bppAlpha, DXGI_FORMAT_A8_UNORM }, +}; + +//------------------------------------------------------------------------------------- +// WIC Pixel Format nearest conversion table +//------------------------------------------------------------------------------------- + +struct WICConvert +{ + GUID source; + GUID target; +}; + +static WICConvert g_WICConvert[] = +{ + // Note target GUID in this conversion table must be one of those directly supported formats (above). + + { GUID_WICPixelFormatBlackWhite, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM + + { GUID_WICPixelFormat1bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat2bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + + { GUID_WICPixelFormat2bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM + { GUID_WICPixelFormat4bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM + + { GUID_WICPixelFormat16bppGrayFixedPoint, GUID_WICPixelFormat16bppGrayHalf }, // DXGI_FORMAT_R16_FLOAT + { GUID_WICPixelFormat32bppGrayFixedPoint, GUID_WICPixelFormat32bppGrayFloat }, // DXGI_FORMAT_R32_FLOAT + + { GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat16bppBGRA5551 }, // DXGI_FORMAT_B5G5R5A1_UNORM + + { GUID_WICPixelFormat32bppBGR101010, GUID_WICPixelFormat32bppRGBA1010102 }, // DXGI_FORMAT_R10G10B10A2_UNORM + + { GUID_WICPixelFormat24bppBGR, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat24bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat32bppPBGRA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat32bppPRGBA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + + { GUID_WICPixelFormat48bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat48bppBGR, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat64bppBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat64bppPRGBA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat64bppPBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + + { GUID_WICPixelFormat48bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat48bppBGRFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat64bppRGBAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat64bppBGRAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat64bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat64bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat48bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + + { GUID_WICPixelFormat128bppPRGBAFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT + { GUID_WICPixelFormat128bppRGBFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT + { GUID_WICPixelFormat128bppRGBAFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT + { GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT + { GUID_WICPixelFormat32bppRGBE, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT + + { GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) + { GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT +#endif + + // We don't support n-channel formats +}; + +static bool g_WIC2 = false; + +//-------------------------------------------------------------------------------------- +namespace DirectX +{ + +bool _IsWIC2() +{ + return g_WIC2; +} + +IWICImagingFactory* _GetWIC() +{ + static IWICImagingFactory* s_Factory = nullptr; + + if ( s_Factory ) + return s_Factory; + +#if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) + HRESULT hr = CoCreateInstance( + CLSID_WICImagingFactory2, + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWICImagingFactory2), + (LPVOID*)&s_Factory + ); + + if ( SUCCEEDED(hr) ) + { + // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed + g_WIC2 = true; + } + else + { + hr = CoCreateInstance( + CLSID_WICImagingFactory1, + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWICImagingFactory), + (LPVOID*)&s_Factory + ); + + if ( FAILED(hr) ) + { + s_Factory = nullptr; + return nullptr; + } + } +#else + HRESULT hr = CoCreateInstance( + CLSID_WICImagingFactory, + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWICImagingFactory), + (LPVOID*)&s_Factory + ); + + if ( FAILED(hr) ) + { + s_Factory = nullptr; + return nullptr; + } +#endif + + return s_Factory; +} + +} // namespace DirectX + + +//--------------------------------------------------------------------------------- +static DXGI_FORMAT _WICToDXGI( const GUID& guid ) +{ + for( size_t i=0; i < _countof(g_WICFormats); ++i ) + { + if ( memcmp( &g_WICFormats[i].wic, &guid, sizeof(GUID) ) == 0 ) + return g_WICFormats[i].format; + } + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) + if ( g_WIC2 ) + { + if ( memcmp( &GUID_WICPixelFormat96bppRGBFloat, &guid, sizeof(GUID) ) == 0 ) + return DXGI_FORMAT_R32G32B32_FLOAT; + } +#endif + + return DXGI_FORMAT_UNKNOWN; +} + +//--------------------------------------------------------------------------------- +static size_t _WICBitsPerPixel( REFGUID targetGuid ) +{ + IWICImagingFactory* pWIC = _GetWIC(); + if ( !pWIC ) + return 0; + + ComPtr cinfo; + if ( FAILED( pWIC->CreateComponentInfo( targetGuid, cinfo.GetAddressOf() ) ) ) + return 0; + + WICComponentType type; + if ( FAILED( cinfo->GetComponentType( &type ) ) ) + return 0; + + if ( type != WICPixelFormat ) + return 0; + + ComPtr pfinfo; + if ( FAILED( cinfo.As( &pfinfo ) ) ) + return 0; + + UINT bpp; + if ( FAILED( pfinfo->GetBitsPerPixel( &bpp ) ) ) + return 0; + + return bpp; +} + + +//-------------------------------------------------------------------------------------- +static DXGI_FORMAT MakeSRGB( _In_ DXGI_FORMAT format ) +{ + switch( format ) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + + case DXGI_FORMAT_BC1_UNORM: + return DXGI_FORMAT_BC1_UNORM_SRGB; + + case DXGI_FORMAT_BC2_UNORM: + return DXGI_FORMAT_BC2_UNORM_SRGB; + + case DXGI_FORMAT_BC3_UNORM: + return DXGI_FORMAT_BC3_UNORM_SRGB; + + case DXGI_FORMAT_B8G8R8A8_UNORM: + return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + + case DXGI_FORMAT_B8G8R8X8_UNORM: + return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + + case DXGI_FORMAT_BC7_UNORM: + return DXGI_FORMAT_BC7_UNORM_SRGB; + + default: + return format; + } +} + + +//--------------------------------------------------------------------------------- +static HRESULT CreateTextureFromWIC( _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, +#if defined(_XBOX_ONE) && defined(_TITLE) + _In_opt_ ID3D11DeviceX* d3dDeviceX, + _In_opt_ ID3D11DeviceContextX* d3dContextX, +#endif + _In_ IWICBitmapFrameDecode *frame, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _Out_opt_ ID3D11Resource** texture, + _Out_opt_ ID3D11ShaderResourceView** textureView ) +{ + UINT width, height; + HRESULT hr = frame->GetSize( &width, &height ); + if ( FAILED(hr) ) + return hr; + + assert( width > 0 && height > 0 ); + + if ( !maxsize ) + { + // This is a bit conservative because the hardware could support larger textures than + // the Feature Level defined minimums, but doing it this way is much easier and more + // performant for WIC than the 'fail and retry' model used by DDSTextureLoader + + switch( d3dDevice->GetFeatureLevel() ) + { + case D3D_FEATURE_LEVEL_9_1: + case D3D_FEATURE_LEVEL_9_2: + maxsize = 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; + break; + + case D3D_FEATURE_LEVEL_9_3: + maxsize = 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; + break; + + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_10_1: + maxsize = 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; + break; + + default: + maxsize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; + break; + } + } + + assert( maxsize > 0 ); + + UINT twidth, theight; + if ( width > maxsize || height > maxsize ) + { + float ar = static_cast(height) / static_cast(width); + if ( width > height ) + { + twidth = static_cast( maxsize ); + theight = static_cast( static_cast(maxsize) * ar ); + } + else + { + theight = static_cast( maxsize ); + twidth = static_cast( static_cast(maxsize) / ar ); + } + assert( twidth <= maxsize && theight <= maxsize ); + } + else + { + twidth = width; + theight = height; + } + + // Determine format + WICPixelFormatGUID pixelFormat; + hr = frame->GetPixelFormat( &pixelFormat ); + if ( FAILED(hr) ) + return hr; + + WICPixelFormatGUID convertGUID; + memcpy( &convertGUID, &pixelFormat, sizeof(WICPixelFormatGUID) ); + + size_t bpp = 0; + + DXGI_FORMAT format = _WICToDXGI( pixelFormat ); + if ( format == DXGI_FORMAT_UNKNOWN ) + { + if ( memcmp( &GUID_WICPixelFormat96bppRGBFixedPoint, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) + { +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) + if ( g_WIC2 ) + { + memcpy( &convertGUID, &GUID_WICPixelFormat96bppRGBFloat, sizeof(WICPixelFormatGUID) ); + format = DXGI_FORMAT_R32G32B32_FLOAT; + } + else +#endif + { + memcpy( &convertGUID, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID) ); + format = DXGI_FORMAT_R32G32B32A32_FLOAT; + } + } + else + { + for( size_t i=0; i < _countof(g_WICConvert); ++i ) + { + if ( memcmp( &g_WICConvert[i].source, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) + { + memcpy( &convertGUID, &g_WICConvert[i].target, sizeof(WICPixelFormatGUID) ); + + format = _WICToDXGI( g_WICConvert[i].target ); + assert( format != DXGI_FORMAT_UNKNOWN ); + bpp = _WICBitsPerPixel( convertGUID ); + break; + } + } + } + + if ( format == DXGI_FORMAT_UNKNOWN ) + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + else + { + bpp = _WICBitsPerPixel( pixelFormat ); + } + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) + if ( (format == DXGI_FORMAT_R32G32B32_FLOAT) && d3dContext != 0 && textureView != 0 ) + { + // Special case test for optional device support for autogen mipchains for R32G32B32_FLOAT + UINT fmtSupport = 0; + hr = d3dDevice->CheckFormatSupport( DXGI_FORMAT_R32G32B32_FLOAT, &fmtSupport ); + if ( FAILED(hr) || !( fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) ) + { + // Use R32G32B32A32_FLOAT instead which is required for Feature Level 10.0 and up + memcpy( &convertGUID, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID) ); + format = DXGI_FORMAT_R32G32B32A32_FLOAT; + bpp = 128; + } + } +#endif + + if ( !bpp ) + return E_FAIL; + + // Handle sRGB formats + if ( forceSRGB ) + { + format = MakeSRGB( format ); + } + else + { + ComPtr metareader; + if ( SUCCEEDED( frame->GetMetadataQueryReader( metareader.GetAddressOf() ) ) ) + { + GUID containerFormat; + if ( SUCCEEDED( metareader->GetContainerFormat( &containerFormat ) ) ) + { + // Check for sRGB colorspace metadata + bool sRGB = false; + + PROPVARIANT value; + PropVariantInit( &value ); + + if ( memcmp( &containerFormat, &GUID_ContainerFormatPng, sizeof(GUID) ) == 0 ) + { + // Check for sRGB chunk + if ( SUCCEEDED( metareader->GetMetadataByName( L"/sRGB/RenderingIntent", &value ) ) && value.vt == VT_UI1 ) + { + sRGB = true; + } + } +#if defined(_XBOX_ONE) && defined(_TITLE) + else if ( memcmp( &containerFormat, &GUID_ContainerFormatJpeg, sizeof(GUID) ) == 0 ) + { + if ( SUCCEEDED( metareader->GetMetadataByName( L"/app1/ifd/exif/{ushort=40961}", &value ) ) && value.vt == VT_UI2 && value.uiVal == 1 ) + { + sRGB = true; + } + } + else if ( memcmp( &containerFormat, &GUID_ContainerFormatTiff, sizeof(GUID) ) == 0 ) + { + if ( SUCCEEDED( metareader->GetMetadataByName( L"/ifd/exif/{ushort=40961}", &value ) ) && value.vt == VT_UI2 && value.uiVal == 1 ) + { + sRGB = true; + } + } +#else + else if ( SUCCEEDED( metareader->GetMetadataByName( L"System.Image.ColorSpace", &value ) ) && value.vt == VT_UI2 && value.uiVal == 1 ) + { + sRGB = true; + } +#endif + + PropVariantClear( &value ); + + if ( sRGB ) + format = MakeSRGB( format ); + } + } + } + + // Verify our target format is supported by the current device + // (handles WDDM 1.0 or WDDM 1.1 device driver cases as well as DirectX 11.0 Runtime without 16bpp format support) + UINT support = 0; + hr = d3dDevice->CheckFormatSupport( format, &support ); + if ( FAILED(hr) || !(support & D3D11_FORMAT_SUPPORT_TEXTURE2D) ) + { + // Fallback to RGBA 32-bit format which is supported by all devices + memcpy( &convertGUID, &GUID_WICPixelFormat32bppRGBA, sizeof(WICPixelFormatGUID) ); + format = DXGI_FORMAT_R8G8B8A8_UNORM; + bpp = 32; + } + + // Allocate temporary memory for image + size_t rowPitch = ( twidth * bpp + 7 ) / 8; + size_t imageSize = rowPitch * theight; + + std::unique_ptr temp( new (std::nothrow) uint8_t[ imageSize ] ); + if (!temp) + return E_OUTOFMEMORY; + + // Load image data + if ( memcmp( &convertGUID, &pixelFormat, sizeof(GUID) ) == 0 + && twidth == width + && theight == height ) + { + // No format conversion or resize needed + hr = frame->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); + if ( FAILED(hr) ) + return hr; + } + else if ( twidth != width || theight != height ) + { + // Resize + IWICImagingFactory* pWIC = _GetWIC(); + if ( !pWIC ) + return E_NOINTERFACE; + + ComPtr scaler; + hr = pWIC->CreateBitmapScaler( scaler.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + hr = scaler->Initialize( frame, twidth, theight, WICBitmapInterpolationModeFant ); + if ( FAILED(hr) ) + return hr; + + WICPixelFormatGUID pfScaler; + hr = scaler->GetPixelFormat( &pfScaler ); + if ( FAILED(hr) ) + return hr; + + if ( memcmp( &convertGUID, &pfScaler, sizeof(GUID) ) == 0 ) + { + // No format conversion needed + hr = scaler->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); + if ( FAILED(hr) ) + return hr; + } + else + { + ComPtr FC; + hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + BOOL canConvert = FALSE; + hr = FC->CanConvert( pfScaler, convertGUID, &canConvert ); + if ( FAILED(hr) || !canConvert ) + { + return E_UNEXPECTED; + } + + hr = FC->Initialize( scaler.Get(), convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom ); + if ( FAILED(hr) ) + return hr; + + hr = FC->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); + if ( FAILED(hr) ) + return hr; + } + } + else + { + // Format conversion but no resize + IWICImagingFactory* pWIC = _GetWIC(); + if ( !pWIC ) + return E_NOINTERFACE; + + ComPtr FC; + hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + BOOL canConvert = FALSE; + hr = FC->CanConvert( pixelFormat, convertGUID, &canConvert ); + if ( FAILED(hr) || !canConvert ) + { + return E_UNEXPECTED; + } + + hr = FC->Initialize( frame, convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom ); + if ( FAILED(hr) ) + return hr; + + hr = FC->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); + if ( FAILED(hr) ) + return hr; + } + + // See if format is supported for auto-gen mipmaps (varies by feature level) + bool autogen = false; + if ( d3dContext != 0 && textureView != 0 ) // Must have context and shader-view to auto generate mipmaps + { + UINT fmtSupport = 0; + hr = d3dDevice->CheckFormatSupport( format, &fmtSupport ); + if ( SUCCEEDED(hr) && ( fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) ) + { + autogen = true; +#if defined(_XBOX_ONE) && defined(_TITLE) + if ( !d3dDeviceX || !d3dContextX ) + return E_INVALIDARG; +#endif + } + } + + // Create texture + D3D11_TEXTURE2D_DESC desc; + desc.Width = twidth; + desc.Height = theight; + desc.MipLevels = (autogen) ? 0 : 1; + desc.ArraySize = 1; + desc.Format = format; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = usage; + desc.CPUAccessFlags = cpuAccessFlags; + + if ( autogen ) + { + desc.BindFlags = bindFlags | D3D11_BIND_RENDER_TARGET; + desc.MiscFlags = miscFlags | D3D11_RESOURCE_MISC_GENERATE_MIPS; + } + else + { + desc.BindFlags = bindFlags; + desc.MiscFlags = miscFlags; + } + + D3D11_SUBRESOURCE_DATA initData; + initData.pSysMem = temp.get(); + initData.SysMemPitch = static_cast( rowPitch ); + initData.SysMemSlicePitch = static_cast( imageSize ); + + ID3D11Texture2D* tex = nullptr; + hr = d3dDevice->CreateTexture2D( &desc, (autogen) ? nullptr : &initData, &tex ); + if ( SUCCEEDED(hr) && tex != 0 ) + { + if (textureView != 0) + { + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + memset( &SRVDesc, 0, sizeof( SRVDesc ) ); + SRVDesc.Format = desc.Format; + + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + SRVDesc.Texture2D.MipLevels = (autogen) ? -1 : 1; + + hr = d3dDevice->CreateShaderResourceView( tex, &SRVDesc, textureView ); + if ( FAILED(hr) ) + { + tex->Release(); + return hr; + } + + if ( autogen ) + { + assert( d3dContext != 0 ); + +#if defined(_XBOX_ONE) && defined(_TITLE) + ID3D11Texture2D *pStaging = nullptr; + CD3D11_TEXTURE2D_DESC stagingDesc( format, twidth, theight, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ, 1, 0, 0 ); + D3D11_SUBRESOURCE_DATA initData; + initData.pSysMem = temp.get(); + initData.SysMemPitch = static_cast(rowPitch); + initData.SysMemSlicePitch = static_cast(imageSize); + + hr = d3dDevice->CreateTexture2D( &stagingDesc, &initData, &pStaging ); + if ( SUCCEEDED(hr) ) + { + d3dContext->CopySubresourceRegion( tex, 0, 0, 0, 0, pStaging, 0, nullptr ); + + UINT64 copyFence = d3dContextX->InsertFence(0); + while( d3dDeviceX->IsFencePending( copyFence ) ) { SwitchToThread(); } + pStaging->Release(); + } +#else + d3dContext->UpdateSubresource( tex, 0, nullptr, temp.get(), static_cast(rowPitch), static_cast(imageSize) ); +#endif + d3dContext->GenerateMips( *textureView ); + } + } + + if (texture != 0) + { + *texture = tex; + } + else + { + SetDebugObjectName(tex, "WICTextureLoader"); + tex->Release(); + } + } + + return hr; +} + +//-------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT DirectX::CreateWICTextureFromMemory( ID3D11Device* d3dDevice, + const uint8_t* wicData, + size_t wicDataSize, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + size_t maxsize ) +{ + return CreateWICTextureFromMemoryEx( d3dDevice, wicData, wicDataSize, maxsize, + D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, + texture, textureView ); +} + +_Use_decl_annotations_ +#if defined(_XBOX_ONE) && defined(_TITLE) +HRESULT DirectX::CreateWICTextureFromMemory( ID3D11DeviceX* d3dDevice, + ID3D11DeviceContextX* d3dContext, +#else +HRESULT DirectX::CreateWICTextureFromMemory( ID3D11Device* d3dDevice, + ID3D11DeviceContext* d3dContext, +#endif + const uint8_t* wicData, + size_t wicDataSize, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + size_t maxsize ) +{ + return CreateWICTextureFromMemoryEx( d3dDevice, d3dContext, wicData, wicDataSize, maxsize, + D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, + texture, textureView ); +} + +_Use_decl_annotations_ +HRESULT DirectX::CreateWICTextureFromMemoryEx( ID3D11Device* d3dDevice, + const uint8_t* wicData, + size_t wicDataSize, + size_t maxsize, + D3D11_USAGE usage, + unsigned int bindFlags, + unsigned int cpuAccessFlags, + unsigned int miscFlags, + bool forceSRGB, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView ) +{ + if ( texture ) + { + *texture = nullptr; + } + if ( textureView ) + { + *textureView = nullptr; + } + + if (!d3dDevice || !wicData || (!texture && !textureView)) + return E_INVALIDARG; + + if ( !wicDataSize ) + return E_FAIL; + +#ifdef _M_AMD64 + if ( wicDataSize > 0xFFFFFFFF ) + return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); +#endif + + IWICImagingFactory* pWIC = _GetWIC(); + if ( !pWIC ) + return E_NOINTERFACE; + + // Create input stream for memory + ComPtr stream; + HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + hr = stream->InitializeFromMemory( const_cast( wicData ), static_cast( wicDataSize ) ); + if ( FAILED(hr) ) + return hr; + + // Initialize WIC + ComPtr decoder; + hr = pWIC->CreateDecoderFromStream( stream.Get(), 0, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + ComPtr frame; + hr = decoder->GetFrame( 0, frame.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + hr = CreateTextureFromWIC( d3dDevice, nullptr, +#if defined(_XBOX_ONE) && defined(_TITLE) + nullptr, nullptr, +#endif + frame.Get(), maxsize, + usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, + texture, textureView ); + if ( FAILED(hr)) + return hr; + + if (texture != 0 && *texture != 0) + { + SetDebugObjectName(*texture, "WICTextureLoader"); + } + + if (textureView != 0 && *textureView != 0) + { + SetDebugObjectName(*textureView, "WICTextureLoader"); + } + + return hr; +} + +_Use_decl_annotations_ +#if defined(_XBOX_ONE) && defined(_TITLE) +HRESULT DirectX::CreateWICTextureFromMemoryEx( ID3D11DeviceX* d3dDevice, + ID3D11DeviceContextX* d3dContext, +#else +HRESULT DirectX::CreateWICTextureFromMemoryEx( ID3D11Device* d3dDevice, + ID3D11DeviceContext* d3dContext, +#endif + const uint8_t* wicData, + size_t wicDataSize, + size_t maxsize, + D3D11_USAGE usage, + unsigned int bindFlags, + unsigned int cpuAccessFlags, + unsigned int miscFlags, + bool forceSRGB, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView ) +{ + if ( texture ) + { + *texture = nullptr; + } + if ( textureView ) + { + *textureView = nullptr; + } + + if (!d3dDevice || !wicData || (!texture && !textureView)) + return E_INVALIDARG; + + if ( !wicDataSize ) + return E_FAIL; + +#ifdef _M_AMD64 + if ( wicDataSize > 0xFFFFFFFF ) + return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); +#endif + + IWICImagingFactory* pWIC = _GetWIC(); + if ( !pWIC ) + return E_NOINTERFACE; + + // Create input stream for memory + ComPtr stream; + HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + hr = stream->InitializeFromMemory( const_cast( wicData ), static_cast( wicDataSize ) ); + if ( FAILED(hr) ) + return hr; + + // Initialize WIC + ComPtr decoder; + hr = pWIC->CreateDecoderFromStream( stream.Get(), 0, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + ComPtr frame; + hr = decoder->GetFrame( 0, frame.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + hr = CreateTextureFromWIC( d3dDevice, d3dContext, +#if defined(_XBOX_ONE) && defined(_TITLE) + d3dDevice, d3dContext, +#endif + frame.Get(), maxsize, + usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, + texture, textureView ); + if ( FAILED(hr)) + return hr; + + if (texture != 0 && *texture != 0) + { + SetDebugObjectName(*texture, "WICTextureLoader"); + } + + if (textureView != 0 && *textureView != 0) + { + SetDebugObjectName(*textureView, "WICTextureLoader"); + } + + return hr; +} + +//-------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT DirectX::CreateWICTextureFromFile( ID3D11Device* d3dDevice, + const wchar_t* fileName, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + size_t maxsize ) +{ + return CreateWICTextureFromFileEx( d3dDevice, fileName, maxsize, + D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, + texture, textureView ); +} + +_Use_decl_annotations_ +#if defined(_XBOX_ONE) && defined(_TITLE) +HRESULT DirectX::CreateWICTextureFromFile( ID3D11DeviceX* d3dDevice, + ID3D11DeviceContextX* d3dContext, +#else +HRESULT DirectX::CreateWICTextureFromFile( ID3D11Device* d3dDevice, + ID3D11DeviceContext* d3dContext, +#endif + const wchar_t* fileName, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView, + size_t maxsize ) +{ + return CreateWICTextureFromFileEx( d3dDevice, d3dContext, fileName, maxsize, + D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, + texture, textureView ); +} + +_Use_decl_annotations_ +HRESULT DirectX::CreateWICTextureFromFileEx( ID3D11Device* d3dDevice, + const wchar_t* fileName, + size_t maxsize, + D3D11_USAGE usage, + unsigned int bindFlags, + unsigned int cpuAccessFlags, + unsigned int miscFlags, + bool forceSRGB, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView ) +{ + if ( texture ) + { + *texture = nullptr; + } + if ( textureView ) + { + *textureView = nullptr; + } + + if (!d3dDevice || !fileName || (!texture && !textureView)) + return E_INVALIDARG; + + IWICImagingFactory* pWIC = _GetWIC(); + if ( !pWIC ) + return E_NOINTERFACE; + + // Initialize WIC + ComPtr decoder; + HRESULT hr = pWIC->CreateDecoderFromFilename( fileName, 0, GENERIC_READ, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + ComPtr frame; + hr = decoder->GetFrame( 0, frame.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + hr = CreateTextureFromWIC( d3dDevice, nullptr, +#if defined(_XBOX_ONE) && defined(_TITLE) + nullptr, nullptr, +#endif + frame.Get(), maxsize, + usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, + texture, textureView ); + +#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) + if ( SUCCEEDED(hr) ) + { + if (texture != 0 || textureView != 0) + { + CHAR strFileA[MAX_PATH]; + int result = WideCharToMultiByte( CP_ACP, + WC_NO_BEST_FIT_CHARS, + fileName, + -1, + strFileA, + MAX_PATH, + nullptr, + FALSE + ); + if ( result > 0 ) + { + const CHAR* pstrName = strrchr( strFileA, '\\' ); + if (!pstrName) + { + pstrName = strFileA; + } + else + { + pstrName++; + } + + if (texture != 0 && *texture != 0) + { + (*texture)->SetPrivateData( WKPDID_D3DDebugObjectName, + static_cast( strnlen_s(pstrName, MAX_PATH) ), + pstrName + ); + } + + if (textureView != 0 && *textureView != 0 ) + { + (*textureView)->SetPrivateData( WKPDID_D3DDebugObjectName, + static_cast( strnlen_s(pstrName, MAX_PATH) ), + pstrName + ); + } + } + } + } +#endif + + return hr; +} + +_Use_decl_annotations_ +#if defined(_XBOX_ONE) && defined(_TITLE) +HRESULT DirectX::CreateWICTextureFromFileEx( ID3D11DeviceX* d3dDevice, + ID3D11DeviceContextX* d3dContext, +#else +HRESULT DirectX::CreateWICTextureFromFileEx( ID3D11Device* d3dDevice, + ID3D11DeviceContext* d3dContext, +#endif + const wchar_t* fileName, + size_t maxsize, + D3D11_USAGE usage, + unsigned int bindFlags, + unsigned int cpuAccessFlags, + unsigned int miscFlags, + bool forceSRGB, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView ) +{ + if ( texture ) + { + *texture = nullptr; + } + if ( textureView ) + { + *textureView = nullptr; + } + + if (!d3dDevice || !fileName || (!texture && !textureView)) + return E_INVALIDARG; + + IWICImagingFactory* pWIC = _GetWIC(); + if ( !pWIC ) + return E_NOINTERFACE; + + // Initialize WIC + ComPtr decoder; + HRESULT hr = pWIC->CreateDecoderFromFilename( fileName, 0, GENERIC_READ, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + ComPtr frame; + hr = decoder->GetFrame( 0, frame.GetAddressOf() ); + if ( FAILED(hr) ) + return hr; + + hr = CreateTextureFromWIC( d3dDevice, d3dContext, +#if defined(_XBOX_ONE) && defined(_TITLE) + d3dDevice, d3dContext, +#endif + frame.Get(), maxsize, + usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, + texture, textureView ); + +#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) + if ( SUCCEEDED(hr) ) + { + if (texture != 0 || textureView != 0) + { + CHAR strFileA[MAX_PATH]; + int result = WideCharToMultiByte( CP_ACP, + WC_NO_BEST_FIT_CHARS, + fileName, + -1, + strFileA, + MAX_PATH, + nullptr, + FALSE + ); + if ( result > 0 ) + { + const CHAR* pstrName = strrchr( strFileA, '\\' ); + if (!pstrName) + { + pstrName = strFileA; + } + else + { + pstrName++; + } + + if (texture != 0 && *texture != 0) + { + (*texture)->SetPrivateData( WKPDID_D3DDebugObjectName, + static_cast( strnlen_s(pstrName, MAX_PATH) ), + pstrName + ); + } + + if (textureView != 0 && *textureView != 0 ) + { + (*textureView)->SetPrivateData( WKPDID_D3DDebugObjectName, + static_cast( strnlen_s(pstrName, MAX_PATH) ), + pstrName + ); + } + } + } + } +#endif + + return hr; +} diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/WICTextureLoader.h b/xbmc/visualizations/Vortex/VortexVis/Core/WICTextureLoader.h new file mode 100644 index 0000000000..ae8b705faf --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/WICTextureLoader.h @@ -0,0 +1,154 @@ +//-------------------------------------------------------------------------------------- +// File: WICTextureLoader.h +// +// Function for loading a WIC image and creating a Direct3D 11 runtime texture for it +// (auto-generating mipmaps if possible) +// +// Note: Assumes application has already called CoInitializeEx +// +// Warning: CreateWICTexture* functions are not thread-safe if given a d3dContext instance for +// auto-gen mipmap support. +// +// Note these functions are useful for images created as simple 2D textures. For +// more complex resources, DDSTextureLoader is an excellent light-weight runtime loader. +// For a full-featured DDS file reader, writer, and texture processing pipeline see +// the 'Texconv' sample and the 'DirectXTex' library. +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkId=248926 +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (_WIN32_WINNT <= _WIN32_WINNT_WIN8) +#error WIC is not supported on Windows Phone 8.0 +#endif + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#pragma warning(push) +#pragma warning(disable : 4005) +#include +#pragma warning(pop) + +namespace DirectX +{ + // Standard version + HRESULT __cdecl CreateWICTextureFromMemory( _In_ ID3D11Device* d3dDevice, + _In_reads_bytes_(wicDataSize) const uint8_t* wicData, + _In_ size_t wicDataSize, + _Out_opt_ ID3D11Resource** texture, + _Out_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0 + ); + + HRESULT __cdecl CreateWICTextureFromFile( _In_ ID3D11Device* d3dDevice, + _In_z_ const wchar_t* szFileName, + _Out_opt_ ID3D11Resource** texture, + _Out_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0 + ); + + // Standard version with optional auto-gen mipmap support + #if defined(_XBOX_ONE) && defined(_TITLE) + HRESULT __cdecl CreateWICTextureFromMemory( _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + HRESULT __cdecl CreateWICTextureFromMemory( _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_reads_bytes_(wicDataSize) const uint8_t* wicData, + _In_ size_t wicDataSize, + _Out_opt_ ID3D11Resource** texture, + _Out_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0 + ); + + #if defined(_XBOX_ONE) && defined(_TITLE) + HRESULT __cdecl CreateWICTextureFromFile( _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + HRESULT __cdecl CreateWICTextureFromFile( _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_z_ const wchar_t* szFileName, + _Out_opt_ ID3D11Resource** texture, + _Out_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0 + ); + + // Extended version + HRESULT __cdecl CreateWICTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, + _In_reads_bytes_(wicDataSize) const uint8_t* wicData, + _In_ size_t wicDataSize, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _Out_opt_ ID3D11Resource** texture, + _Out_opt_ ID3D11ShaderResourceView** textureView + ); + + HRESULT __cdecl CreateWICTextureFromFileEx( _In_ ID3D11Device* d3dDevice, + _In_z_ const wchar_t* szFileName, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _Out_opt_ ID3D11Resource** texture, + _Out_opt_ ID3D11ShaderResourceView** textureView + ); + + // Extended version with optional auto-gen mipmap support + #if defined(_XBOX_ONE) && defined(_TITLE) + HRESULT __cdecl CreateWICTextureFromMemoryEx( _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + HRESULT __cdecl CreateWICTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_reads_bytes_(wicDataSize) const uint8_t* wicData, + _In_ size_t wicDataSize, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _Out_opt_ ID3D11Resource** texture, + _Out_opt_ ID3D11ShaderResourceView** textureView + ); + + #if defined(_XBOX_ONE) && defined(_TITLE) + HRESULT __cdecl CreateWICTextureFromFileEx( _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + HRESULT __cdecl CreateWICTextureFromFileEx( _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_z_ const wchar_t* szFileName, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _Out_opt_ ID3D11Resource** texture, + _Out_opt_ ID3D11ShaderResourceView** textureView + ); +} \ No newline at end of file diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/XMMatrixStack.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/XMMatrixStack.cpp new file mode 100644 index 0000000000..65ef2859b9 --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/XMMatrixStack.cpp @@ -0,0 +1,38 @@ +/* +* Copyright © 2010-2015 Team XBMC +* http://xbmc.org +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#include "XMMatrixStack.h" + +using namespace DirectX; + +/*XMMatrixStack::XMMatrixStack() +{ + m_current = XMMatrixIdentity(); +} + +XMMatrixStack::~XMMatrixStack() +{ + while (!m_stack.empty()) + m_stack.pop(); +} + +void XMMatrixStack::MultMatrix(const XMMATRIX* pMat) +{ + m_current = XMMatrixMultiply(m_current, *pMat); +}*/ \ No newline at end of file diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/XMMatrixStack.h b/xbmc/visualizations/Vortex/VortexVis/Core/XMMatrixStack.h new file mode 100644 index 0000000000..e02f7548b0 --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/XMMatrixStack.h @@ -0,0 +1,99 @@ +/* +* Copyright © 2010-2015 Team XBMC +* http://xbmc.org +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#include +#include + +namespace DirectX +{ +// replacement of D3DXMatrixStack which implements only used methods. +__declspec(align(16)) class XMMatrixStack +{ +public: + XMMatrixStack() : m_current(XMMatrixIdentity()) + { + } + + ~XMMatrixStack() + { + while (!m_stack.empty()) + m_stack.pop(); + } + + XMMATRIX* GetTop() + { + return &m_current; + } + + void Pop() + { + if (!m_stack.empty()) + { + m_current = m_stack.top(); + m_stack.pop(); + } + } + + void Push() + { + m_stack.push(m_current); + } + + void MultMatrix(const XMMATRIX* pMat) + { + m_current = XMMatrixMultiply(m_current, *pMat); + } + + void LoadIdentity() + { + m_current = XMMatrixIdentity(); + } + + void TranslateLocal(float x, float y, float z) + { + m_current = XMMatrixMultiply(XMMatrixTranslation(x, y, z), m_current); + } + + void ScaleLocal(float x, float y, float z) + { + m_current = XMMatrixMultiply(XMMatrixScaling(x, y, z), m_current); + } + + void RotateAxisLocal(const XMVECTOR *pV, float angle) + { + m_current = XMMatrixMultiply(XMMatrixRotationAxis(*pV, angle), m_current); + } + + void* operator new(size_t i) + { + return _aligned_malloc(i, 16); + } + + void operator delete(void* p) + { + _aligned_free(p); + } + +private: + XMMATRIX m_current; + std::stack m_stack; + +}; // class XMMatrixStack + +}; // namespace DirectX \ No newline at end of file diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/XmlDocument.cpp b/xbmc/visualizations/Vortex/VortexVis/Core/XmlDocument.cpp index 1a2555aad7..b8cbdd690b 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/XmlDocument.cpp +++ b/xbmc/visualizations/Vortex/VortexVis/Core/XmlDocument.cpp @@ -21,7 +21,8 @@ // ////////////////////////////////////////////////////////////////////// #include "XmlDocument.h" -#include +#include +#include ////////////////////////////////////////////////////////////////////// // Construction/Destruction diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/XmlDocument.h b/xbmc/visualizations/Vortex/VortexVis/Core/XmlDocument.h index dacdb32dff..640e579ee9 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Core/XmlDocument.h +++ b/xbmc/visualizations/Vortex/VortexVis/Core/XmlDocument.h @@ -28,9 +28,8 @@ #pragma once #endif // _MSC_VER > 1000 -#include - #include +#include #define XML_ROOT_NODE 0 #define XML_MAX_TAGNAME_SIZE 32 diff --git a/xbmc/visualizations/Vortex/VortexVis/Core/dds.h b/xbmc/visualizations/Vortex/VortexVis/Core/dds.h new file mode 100644 index 0000000000..ca74a54d6e --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Core/dds.h @@ -0,0 +1,231 @@ +//-------------------------------------------------------------------------------------- +// dds.h +// +// This header defines constants and structures that are useful when parsing +// DDS files. DDS files were originally designed to use several structures +// and constants that are native to DirectDraw and are defined in ddraw.h, +// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar +// (compatible) constants and structures so that one can use DDS files +// without needing to include ddraw.h. +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/?LinkId=248926 +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#if defined(_MSC_VER) +#pragma once +#endif + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +// VS 2010's stdint.h conflicts with intsafe.h +#pragma warning(push) +#pragma warning(disable : 4005) +#include +#pragma warning(pop) + +namespace DirectX +{ + +#pragma pack(push,1) + +const uint32_t DDS_MAGIC = 0x20534444; // "DDS " + +struct DDS_PIXELFORMAT +{ + uint32_t size; + uint32_t flags; + uint32_t fourCC; + uint32_t RGBBitCount; + uint32_t RBitMask; + uint32_t GBitMask; + uint32_t BBitMask; + uint32_t ABitMask; +}; + +#define DDS_FOURCC 0x00000004 // DDPF_FOURCC +#define DDS_RGB 0x00000040 // DDPF_RGB +#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS +#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE +#define DDS_LUMINANCEA 0x00020001 // DDPF_LUMINANCE | DDPF_ALPHAPIXELS +#define DDS_ALPHA 0x00000002 // DDPF_ALPHA +#define DDS_PAL8 0x00000020 // DDPF_PALETTEINDEXED8 + +#ifndef MAKEFOURCC + #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \ + ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 )) +#endif /* defined(MAKEFOURCC) */ + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT1 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT2 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','2'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT3 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT4 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT5 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_UNORM = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','U'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_SNORM = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','S'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_UNORM = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','U'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_SNORM = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','S'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R','G','B','G'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_YUY2 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8R8G8B8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8R8G8B8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8B8G8R8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8B8G8R8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G16R16 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R5G6B5 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A1R5G5B5 = + { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A4R4G4B4 = + { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8B8 = + { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L8 = + { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0xff, 0x00, 0x00, 0x00 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L16 = + { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 16, 0xffff, 0x0000, 0x0000, 0x0000 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8L8 = + { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 16, 0x00ff, 0x0000, 0x0000, 0xff00 }; + +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8 = + { sizeof(DDS_PIXELFORMAT), DDS_ALPHA, 0, 8, 0x00, 0x00, 0x00, 0xff }; + +// D3DFMT_A2R10G10B10/D3DFMT_A2B10G10R10 should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue + +// This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat) +extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DX10 = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0 }; + +#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT +#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT +#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH +#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH +#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE + +#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT +#define DDS_WIDTH 0x00000004 // DDSD_WIDTH + +#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE +#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP +#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX + +#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX +#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX +#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY +#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY +#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ +#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ + +#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\ + DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\ + DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ ) + +#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP + +#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME + +// Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION +enum DDS_RESOURCE_DIMENSION +{ + DDS_DIMENSION_TEXTURE1D = 2, + DDS_DIMENSION_TEXTURE2D = 3, + DDS_DIMENSION_TEXTURE3D = 4, +}; + +// Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG +enum DDS_RESOURCE_MISC_FLAG +{ + DDS_RESOURCE_MISC_TEXTURECUBE = 0x4L, +}; + +enum DDS_MISC_FLAGS2 +{ + DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L, +}; + +struct DDS_HEADER +{ + uint32_t size; + uint32_t flags; + uint32_t height; + uint32_t width; + uint32_t pitchOrLinearSize; + uint32_t depth; // only if DDS_HEADER_FLAGS_VOLUME is set in flags + uint32_t mipMapCount; + uint32_t reserved1[11]; + DDS_PIXELFORMAT ddspf; + uint32_t caps; + uint32_t caps2; + uint32_t caps3; + uint32_t caps4; + uint32_t reserved2; +}; + +struct DDS_HEADER_DXT10 +{ + DXGI_FORMAT dxgiFormat; + uint32_t resourceDimension; + uint32_t miscFlag; // see D3D11_RESOURCE_MISC_FLAG + uint32_t arraySize; + uint32_t miscFlags2; // see DDS_MISC_FLAGS2 +} ; + +#pragma pack(pop) + +static_assert( sizeof(DDS_HEADER) == 124, "DDS Header size mismatch" ); +static_assert( sizeof(DDS_HEADER_DXT10) == 20, "DDS DX10 Extended Header size mismatch"); + +}; // namespace diff --git a/xbmc/visualizations/Vortex/VortexVis/Effects/Map.cpp b/xbmc/visualizations/Vortex/VortexVis/Effects/Map.cpp index 5e418b57e9..dfdb035f44 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Effects/Map.cpp +++ b/xbmc/visualizations/Vortex/VortexVis/Effects/Map.cpp @@ -41,13 +41,19 @@ Map::Map() m_vertices = NULL; - Renderer::GetDevice()->CreateIndexBuffer( NUM_INDICES * 2, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_iBuffer, NULL ); - Renderer::GetDevice()->CreateVertexBuffer( GRID_WIDTH * GRID_HEIGHT * sizeof( PosColNormalUVVertex ), - D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, - &m_vBuffer, NULL ); - - PosColNormalUVVertex* v; - m_vBuffer->Lock( 0, 0, (void**)&v, 0 ); + //--------------------------------------------------------------------------- + // Create verticies buffer + CD3D11_BUFFER_DESC bDesc(GRID_WIDTH * GRID_HEIGHT * sizeof(PosColNormalUVVertex), + D3D11_BIND_VERTEX_BUFFER, + D3D11_USAGE_DYNAMIC, + D3D11_CPU_ACCESS_WRITE ); + Renderer::GetDevice()->CreateBuffer(&bDesc, NULL, &m_vBuffer); + + //--------------------------------------------------------------------------- + // Build verticies + D3D11_MAPPED_SUBRESOURCE res; + Renderer::GetContext()->Map(m_vBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &res); + PosColNormalUVVertex* v = (PosColNormalUVVertex*)res.pData; for (int y = 0; y < GRID_HEIGHT; y++) { @@ -57,12 +63,10 @@ Map::Map() // 15-(32 / 2) / (32 / 2) = -1 v->Coord.x = ((float)x - ((GRID_WIDTH -1 ) / 2.0f)) / ((GRID_WIDTH -1 ) / 2.0f); v->Coord.y = -(((float)y - ((GRID_HEIGHT -1 ) / 2.0f)) / ((GRID_HEIGHT -1 ) / 2.0f)); -// v->Diffuse= 0xffffffff; v->FDiffuse.x = 1.0f; v->FDiffuse.y = 1.0f; v->FDiffuse.z = 1.0f; v->FDiffuse.w = 1.0f; - // v->coord. = 1.0f; v->Coord.z = 0.0f; // v->u = ((((float)x - ((GRID_WIDTH -1 ) / 2.0f)) / ((GRID_WIDTH -1 ) / 2.0f) * 256 + 256) * (1.0f / 512)) + (0.5f / 512); // v->v = ((((float)y - ((GRID_HEIGHT -1 ) / 2.0f)) / ((GRID_HEIGHT -1 ) / 2.0f) * 256 + 256) * (1.0f / 512)) + (0.5f / 512); @@ -71,17 +75,15 @@ Map::Map() v++; } } - m_vBuffer->Unlock(); - + Renderer::GetContext()->Unmap(m_vBuffer, 0); //--------------------------------------------------------------------------- // Build indices - unsigned short* pIndices; - m_iBuffer->Lock( 0, 0, (void**)&pIndices, 0 ); + unsigned short indices[NUM_INDICES * 2], *pIndices = indices; int numIndices = 0; unsigned short iIndex = 0; - for (int a = 0; a < GRID_HEIGHT; ++a) + for (int a = 0; a < GRID_HEIGHT - 1; ++a) { for (int i = 0; i < GRID_WIDTH; ++i, pIndices += 2, ++iIndex ) { @@ -103,14 +105,22 @@ Map::Map() m_numIndices = numIndices - 2; - m_iBuffer->Unlock(); + //--------------------------------------------------------------------------- + // Create indices buffer + bDesc.ByteWidth = sizeof(indices); + bDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + bDesc.Usage = D3D11_USAGE_IMMUTABLE; + bDesc.CPUAccessFlags = 0; + D3D11_SUBRESOURCE_DATA bData = { 0 }; + bData.pSysMem = indices; + Renderer::GetDevice()->CreateBuffer(&bDesc, &bData, &m_iBuffer); } Map::~Map() { if ( m_vertices != NULL ) { - m_vBuffer->Unlock(); + Renderer::GetContext()->Unmap(m_vBuffer, 0); m_vertices = NULL; } m_vBuffer->Release(); @@ -154,7 +164,9 @@ void Map::SetValues(unsigned int x, unsigned int y, float uOffset, float vOffset if( m_vertices == NULL ) { - m_vBuffer->Lock( 0, 0, (void**)&m_vertices, 0 ); + D3D11_MAPPED_SUBRESOURCE res; + Renderer::GetContext()->Map(m_vBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &res); + m_vertices = (PosColNormalUVVertex*)res.pData; } PosColNormalUVVertex* v = &m_vertices[ index ]; @@ -166,12 +178,6 @@ void Map::SetValues(unsigned int x, unsigned int y, float uOffset, float vOffset { v->u = ((float)x * invWidth ) + (0.5f / TEX_WIDTH) + ( ( uOffset ) * invWidth ); v->v = ((float)y * invHeight ) + (0.5f / TEX_HEIGHT) + ( ( vOffset ) * invHeight ); -/* unsigned char* col = (unsigned char*)&v->Diffuse; - col[3] = 0xff; - col[2] = int(MapCol(r) * 255); - col[1] = int(MapCol(g) * 255); - col[0] = int(MapCol(b) * 255); -*/ v->FDiffuse.x = MapCol(r); v->FDiffuse.y = MapCol(g); v->FDiffuse.z = MapCol(b); @@ -181,11 +187,6 @@ void Map::SetValues(unsigned int x, unsigned int y, float uOffset, float vOffset { v->u = ((float)x * invWidth ) + (0.5f / TEX_WIDTH) + ((uOffset)); v->v = ((float)y * invHeight ) + (0.5f / TEX_HEIGHT) + ((vOffset)); -// unsigned char* col = (unsigned char*)&v->Diffuse; -// col[3] = 0xff; -// col[2] = int(Clamp(r) * 255); -// col[1] = int(Clamp(g) * 255); -// col[0] = int(Clamp(b) * 255); v->FDiffuse.x = r; v->FDiffuse.y = g; v->FDiffuse.z = b; @@ -197,20 +198,20 @@ void Map::Render() { if ( m_vertices != NULL ) { - m_vBuffer->Unlock(); - m_vertices = NULL; - } + Renderer::GetContext()->Unmap( m_vBuffer, 0 ); + m_vertices = NULL; + } if ( m_iCurrentTexture == 0 ) { - Renderer::SetRenderTarget(m_tex1); - Renderer::SetTexture(m_tex2); + Renderer::SetRenderTarget( m_tex1 ); + Renderer::SetTexture( m_tex2 ); m_texture = m_tex1; } else { - Renderer::SetRenderTarget(m_tex2); - Renderer::SetTexture(m_tex1); + Renderer::SetRenderTarget( m_tex2 ); + Renderer::SetTexture( m_tex1 ); m_texture = m_tex2; } @@ -220,31 +221,21 @@ void Map::Render() Renderer::SetAspect(0); Renderer::Translate(0, 0, 2.414f); - DiffuseUVVertexShader* pShader = &DiffuseUVVertexShader::StaticType; - Renderer::CommitTransforms( pShader ); + DiffuseUVVertexShader* pShader = &DiffuseUVVertexShader::StaticType; + Renderer::SetShader( pShader ); + Renderer::CommitTransforms( pShader ); Renderer::CommitTextureState(); - Renderer::GetDevice()->SetVertexShader( pShader->GetVertexShader() ); - Renderer::GetDevice()->SetVertexDeclaration( g_pPosColUVDeclaration ); - - Renderer::GetDevice()->SetStreamSource( 0, - m_vBuffer, - 0, - sizeof( PosColNormalUVVertex ) ); - - Renderer::GetDevice()->SetIndices( m_iBuffer ); - - Renderer::GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, GRID_WIDTH * GRID_HEIGHT, 0, 1514 ); - - Renderer::GetDevice()->SetStreamSource( 0, - NULL, - 0, - 0 ); - Renderer::GetDevice()->SetIndices( NULL ); + unsigned int strides = sizeof(PosColNormalUVVertex), offsets = 0; + Renderer::GetContext()->IASetInputLayout( g_pPosNormalColUVDeclaration ); + Renderer::GetContext()->IASetVertexBuffers( 0, 1, &m_vBuffer, &strides, &offsets ); + Renderer::GetContext()->IASetIndexBuffer( m_iBuffer, DXGI_FORMAT_R16_UINT, 0 ); + Renderer::GetContext()->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ); + Renderer::GetContext()->DrawIndexed( m_numIndices, 0, 0 ); - Renderer::SetTexture(NULL); + Renderer::SetTexture( NULL ); Renderer::PopMatrix(); - Renderer::SetAspect(oldAspect); + Renderer::SetAspect( oldAspect ); m_iCurrentTexture = 1 - m_iCurrentTexture; diff --git a/xbmc/visualizations/Vortex/VortexVis/Effects/Map.h b/xbmc/visualizations/Vortex/VortexVis/Effects/Map.h index 99760e8d89..9960525863 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Effects/Map.h +++ b/xbmc/visualizations/Vortex/VortexVis/Effects/Map.h @@ -35,15 +35,14 @@ public: void Render(); void SetValues( unsigned int x, unsigned int y, float uOffset, float vOffset, float r, float g, float b); void SetTimed(); - IDirect3DTexture9* GetTexture() { return m_texture; } - IDirect3DTexture9* GetRenderTarget() { return m_texture; } + TextureDX* GetTexture() { return m_texture; } private: - IDirect3DVertexBuffer9* m_vBuffer; - IDirect3DIndexBuffer9* m_iBuffer; - LPDIRECT3DTEXTURE9 m_texture; - LPDIRECT3DTEXTURE9 m_tex1; - LPDIRECT3DTEXTURE9 m_tex2; + ID3D11Buffer* m_vBuffer; + ID3D11Buffer* m_iBuffer; + TextureDX* m_texture; + TextureDX* m_tex1; + TextureDX* m_tex2; int m_iCurrentTexture; PosColNormalUVVertex* m_vertices; int m_numIndices; diff --git a/xbmc/visualizations/Vortex/VortexVis/Effects/VoicePrint.cpp b/xbmc/visualizations/Vortex/VortexVis/Effects/VoicePrint.cpp index 6b6b19a011..c19eae671c 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Effects/VoicePrint.cpp +++ b/xbmc/visualizations/Vortex/VortexVis/Effects/VoicePrint.cpp @@ -21,35 +21,21 @@ #include #include "Shader.h" #include "angelscript.h" +#include "CommonStates.h" -using namespace std; - -char ColourRemapPixelShaderSrc[] = +namespace { - " sampler2D SpectrumTexture : tex0; \n" - " sampler2D RemapTexture : tex1; \n" - " struct PS_INPUT \n" - " { \n" - " float2 Tex0 : TEXCOORD0; \n" - " }; \n" - " \n" - " void Main( PS_INPUT input, out float4 OutColor : COLOR0 ) \n" - " { \n" - " float4 SpecCol = tex2D( SpectrumTexture, input.Tex0 ); \n" - " OutColor = tex2D( RemapTexture, SpecCol.ra ); \n" - " } \n" - " \n" -}; - + #include "../Shaders/ColourRemapPixelShader.inc" +} class ColourRemapPixelShader : public Shader { DECLARE_SHADER(ColourRemapPixelShader); public: - ColourRemapPixelShader( EShaderType ShaderType, char* pShaderSrc ) : Shader( ShaderType, pShaderSrc ){}; + ColourRemapPixelShader( EShaderType ShaderType, const void* pShaderCode, unsigned int iCodeLen ) : Shader( ShaderType, pShaderCode, iCodeLen ){}; }; -IMPLEMENT_SHADER(ColourRemapPixelShader, ColourRemapPixelShaderSrc, ST_PIXEL); +IMPLEMENT_SHADER(ColourRemapPixelShader, ColourRemapPixelShaderCode, sizeof(ColourRemapPixelShaderCode), ST_PIXEL); // TODO float GetSpecLeft(int index); @@ -62,7 +48,7 @@ VoicePrint::VoicePrint() m_tex2 = Renderer::CreateTexture(512, 512); m_colourMap = NULL; - m_spectrumTexture = Renderer::CreateTexture(1, 512, D3DFMT_A8R8G8B8, true); + m_spectrumTexture = Renderer::CreateTexture(1, 512, DXGI_FORMAT_B8G8R8A8_UNORM, true); m_speed = 0.008f; m_minX = 0.99f; @@ -74,10 +60,8 @@ VoicePrint::VoicePrint() VoicePrint::~VoicePrint() { - if (m_colourMap) - { - Renderer::ReleaseTexture( m_colourMap ); - } + if ( m_colourMap ) + m_colourMap->Release(); if ( m_tex1 ) m_tex1->Release(); @@ -90,7 +74,7 @@ VoicePrint::~VoicePrint() } // Destructor -void VoicePrint::LoadColourMap(string& filename) +void VoicePrint::LoadColourMap(std::string& filename) { char fullname[ 512 ]; sprintf_s(fullname, 512, "%s%s", g_TexturePath, filename.c_str() ); @@ -126,25 +110,27 @@ void VoicePrint::Render() //--------------------------------------------------------------------------- // Update spectrum texture - D3DLOCKED_RECT lockedRect; - m_spectrumTexture->LockRect(0, &lockedRect, NULL, 0); - - unsigned char* data = (unsigned char*)lockedRect.pBits; - - for (int i=0; i<512; i++) - { - int val = ((int)(GetSpecLeft(i) * 0.8f * 255.0f)); - val = min(val, 255); - val = max(0, val); - - float xVal = (m_minX * 255) + (val * (m_maxX - m_minX)); - float yVal = ((m_minY * 255) + (val * (m_maxY - m_minY))); - - data[3] = (char)yVal; // r = y - data[2] = (char)xVal; // a = x - data += lockedRect.Pitch; - } - m_spectrumTexture->UnlockRect( 0 ); + D3D11_MAPPED_SUBRESOURCE lockedRect; + if (m_spectrumTexture->LockRect(0, &lockedRect)) + { + unsigned char* data = (unsigned char*)lockedRect.pData; + + for (int i = 0; i < 512; i++) + { + int val = ((int)(GetSpecLeft(i) * 0.8f * 255.0f)); + val = min(val, 255); + val = max(0, val); + + float xVal = (m_minX * 255) + (val * (m_maxX - m_minX)); + float yVal = ((m_minY * 255) + (val * (m_maxY - m_minY))); + + // 0 - b, 1 - g, 2 - r, 3 - a + data[3] = (char)yVal; // r = y + data[2] = (char)xVal; // a = x + data += lockedRect.RowPitch; + } + m_spectrumTexture->UnlockRect(0); + } //--------------------------------------------------------------------------- // Shift voiceprint texture to the left a bit @@ -162,29 +148,22 @@ void VoicePrint::Render() } m_iCurrentTexture = 1 - m_iCurrentTexture; - Renderer::SetDrawMode2d(); DiffuseUVVertexShader* pShader = &DiffuseUVVertexShader::StaticType; - Renderer::CommitTransforms( pShader ); + Renderer::SetShader( pShader ); + Renderer::CommitTransforms( pShader ); Renderer::CommitTextureState(); - Renderer::GetDevice()->SetVertexShader( pShader->GetVertexShader() ); - Renderer::GetDevice()->SetVertexDeclaration( g_pPosColUVDeclaration ); - - for (int i = 0; i < 2; i++) - { - Renderer::GetDevice()->SetSamplerState( i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - Renderer::GetDevice()->SetSamplerState( i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - Renderer::GetDevice()->SetSamplerState( i, D3DSAMP_MINFILTER, D3DTEXF_POINT); - Renderer::GetDevice()->SetSamplerState( i, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - } + { + ID3D11SamplerState* states[1] = { Renderer::GetStates()->PointClamp() }; + Renderer::GetContext()->PSSetSamplers(0, ARRAYSIZE(states), states); + } PosColNormalUVVertex v[4]; v[0].Coord.x = -1 - mySpeed; v[0].Coord.y = -1; v[0].Coord.z = 0.0f; -// v[0].Diffuse = 0xffffffff; v[0].FDiffuse.x = 1.0f; v[0].FDiffuse.y = 1.0f; v[0].FDiffuse.z = 1.0f; @@ -195,7 +174,6 @@ void VoicePrint::Render() v[1].Coord.x = 1 - mySpeed; v[1].Coord.y = -1; v[1].Coord.z = 0.0f; -// v[1].Diffuse = 0xffffffff; v[1].FDiffuse = v[0].FDiffuse; v[1].u = 1.0f + (0.5f / 512); v[1].v = 0.0f + (0.5f / 512); @@ -203,7 +181,6 @@ void VoicePrint::Render() v[2].Coord.x = 1 - mySpeed; v[2].Coord.y = 1; v[2].Coord.z = 0.0f; -// v[2].Diffuse = 0xffffffff; v[2].FDiffuse = v[0].FDiffuse; v[2].u = 1.0f + (0.5f / 512); v[2].v = 1.0f + (0.5f / 512); @@ -211,22 +188,21 @@ void VoicePrint::Render() v[3].Coord.x = -1 - mySpeed; v[3].Coord.y = 1; v[3].Coord.z = 0.0f; -// v[3].Diffuse = 0xffffffff; v[3].FDiffuse = v[0].FDiffuse; v[3].u = 0.0f + (0.5f / 512); v[3].v = 1.0f + (0.5f / 512); - Renderer::GetDevice()->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, &v, sizeof(PosColNormalUVVertex)); - + Renderer::UpdateVBuffer(v, 4); + Renderer::DrawPrimitive(D3DPT_TRIANGLEFAN, 6, 0); //--------------------------------------------------------------------------- // Draw this frame's voiceprint data to right hand side of voice print texture - Renderer::SetTexture(m_spectrumTexture); - Renderer::GetDevice()->SetTexture(1, m_colourMap); - ColourRemapPixelShader* pPShader = &ColourRemapPixelShader::StaticType; + ColourRemapPixelShader* pPShader = &ColourRemapPixelShader::StaticType; + Renderer::SetShader(pPShader); + Renderer::SetTexture(m_spectrumTexture); + Renderer::SetShaderTexture(1, m_colourMap); - Renderer::GetDevice()->SetPixelShader( pPShader->GetPixelShader() ); - v[0].Coord.x = (1-mySpeed); + v[0].Coord.x = (1-mySpeed); v[0].Coord.y = (-1); v[1].Coord.x = (1); v[1].Coord.y = (-1); @@ -235,18 +211,16 @@ void VoicePrint::Render() v[3].Coord.x = (1-mySpeed); v[3].Coord.y = (1); - Renderer::GetDevice()->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, &v, sizeof(PosColNormalUVVertex)); - for (int i = 0; i < 2; i++) - { - Renderer::GetDevice()->SetSamplerState( i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); - Renderer::GetDevice()->SetSamplerState( i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); - Renderer::GetDevice()->SetSamplerState( i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - Renderer::GetDevice()->SetSamplerState( i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - } - Renderer::GetDevice()->SetTexture(1, NULL); - Renderer::SetTexture(NULL); - Renderer::GetDevice()->SetPixelShader( NULL ); - Renderer::SetRenderTargetBackBuffer(); + Renderer::UpdateVBuffer(v, 4); + Renderer::DrawPrimitive(D3DPT_TRIANGLEFAN, 6, 0); + { + ID3D11SamplerState* states[1] = { Renderer::GetStates()->LinearWrap() }; + Renderer::GetContext()->PSSetSamplers(0, ARRAYSIZE(states), states); + } + Renderer::SetShaderTexture(1, NULL); + Renderer::SetTexture(NULL); + Renderer::CommitTextureState(); // need to unbind color remap shader + Renderer::SetRenderTargetBackBuffer(); } // Render diff --git a/xbmc/visualizations/Vortex/VortexVis/Effects/VoicePrint.h b/xbmc/visualizations/Vortex/VortexVis/Effects/VoicePrint.h index 4a135462f9..d8dfe3f410 100644 --- a/xbmc/visualizations/Vortex/VortexVis/Effects/VoicePrint.h +++ b/xbmc/visualizations/Vortex/VortexVis/Effects/VoicePrint.h @@ -37,20 +37,20 @@ public: void SetRect(float minX, float minY, float maxX, float maxY); void SetSpeed(float speed); - IDirect3DTexture9* GetTexture() { return m_texture; } + TextureDX* GetTexture() { return m_texture; } private: int m_iCurrentTexture; - LPDIRECT3DTEXTURE9 m_texture; - LPDIRECT3DTEXTURE9 m_tex1; - LPDIRECT3DTEXTURE9 m_tex2; - LPDIRECT3DTEXTURE9 m_colourMap; - LPDIRECT3DTEXTURE9 m_spectrumTexture; - float m_speed; - float m_minX; - float m_maxX; - float m_minY; - float m_maxY; + TextureDX* m_texture; + TextureDX* m_tex1; + TextureDX* m_tex2; + TextureDX* m_colourMap; + TextureDX* m_spectrumTexture; + float m_speed; + float m_minX; + float m_maxX; + float m_minY; + float m_maxY; }; #endif diff --git a/xbmc/visualizations/Vortex/VortexVis/Shaders/ColorPixelShader.hlsl b/xbmc/visualizations/Vortex/VortexVis/Shaders/ColorPixelShader.hlsl new file mode 100644 index 0000000000..b9cf75d6f8 --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Shaders/ColorPixelShader.hlsl @@ -0,0 +1,31 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +struct PS_INPUT +{ + float4 vPosition : SV_POSITION; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +void Main( PS_INPUT input, out float4 OutColor : SV_TARGET ) +{ + OutColor = input.Colour; +} + diff --git a/xbmc/visualizations/Vortex/VortexVis/Shaders/ColourRemapPixelShader.hlsl b/xbmc/visualizations/Vortex/VortexVis/Shaders/ColourRemapPixelShader.hlsl new file mode 100644 index 0000000000..af7163cf1f --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Shaders/ColourRemapPixelShader.hlsl @@ -0,0 +1,37 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +Texture2D SpectrumTexture : register(t0); +Texture2D ColorMapTexture : register(t1); + +SamplerState tSampler : register(s0); + +struct PS_INPUT +{ + float4 vPosition : SV_POSITION; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +void Main( PS_INPUT input, out float4 OutColor : SV_TARGET ) +{ + float4 SpecCol = SpectrumTexture.Sample(tSampler, input.Tex0); + OutColor = ColorMapTexture.Sample(tSampler, SpecCol.ra); +} + diff --git a/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseNormalEnvCubeVertexShader.hlsl b/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseNormalEnvCubeVertexShader.hlsl new file mode 100644 index 0000000000..542bf15387 --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseNormalEnvCubeVertexShader.hlsl @@ -0,0 +1,45 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#include "constants_table.fx" + +struct VS_INPUT +{ + float4 vPosition : POSITION; + float4 vNormal : NORMAL; +}; + +struct VS_OUTPUT +{ + float4 vPosition : SV_POSITION; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +VS_OUTPUT Main( VS_INPUT input ) +{ + VS_OUTPUT output; + float4 vPos = float4(input.vPosition.xyz, 1); + // Transform coord + output.vPosition = mul(WVPMat, vPos); + output.Colour = 0xffffffff; + float4 NormalCamSpace = mul(WVMat, float4(input.vNormal.xyz, 0.0f)); + output.Tex0.xy = (NormalCamSpace.xy * 0.2f) + 0.5f; + return output; +} \ No newline at end of file diff --git a/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVCubeVertexShader.hlsl b/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVCubeVertexShader.hlsl new file mode 100644 index 0000000000..78b88b481e --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVCubeVertexShader.hlsl @@ -0,0 +1,46 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#include "constants_table.fx" + +struct VS_INPUT +{ + float4 vPosition : POSITION; + float4 vNormal : NORMAL; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vPosition : SV_POSITION; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +VS_OUTPUT Main( VS_INPUT input ) +{ + VS_OUTPUT output; + float4 vPos = float4(input.vPosition.xyz * vScale.xyz, 1); + // Transform coord + output.vPosition = mul(WVPMat, vPos); + output.Colour = Col; + output.Tex0.xy = input.Tex0; + return output; +} diff --git a/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVEnvCubeVertexShader.hlsl b/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVEnvCubeVertexShader.hlsl new file mode 100644 index 0000000000..083c6e641d --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVEnvCubeVertexShader.hlsl @@ -0,0 +1,48 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#include "constants_table.fx" + +struct VS_INPUT +{ + float4 vPosition : POSITION; + float4 vNormal : NORMAL; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vPosition : SV_POSITION; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +VS_OUTPUT Main( VS_INPUT input ) +{ + VS_OUTPUT output; + float4 vPos = float4(input.vPosition.xyz * vScale.xyz, 1); + // Transform coord + output.vPosition = mul(WVPMat, vPos); + output.Colour = Col; + float4 NormalCamSpace = mul(WVMat, float4(input.vNormal.xyz, 0.0f)); + output.Tex0.xy = (NormalCamSpace.xy * 0.5f) + 0.5f; + return output; +} + diff --git a/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVEnvVertexShader.hlsl b/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVEnvVertexShader.hlsl new file mode 100644 index 0000000000..2979697a34 --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVEnvVertexShader.hlsl @@ -0,0 +1,47 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#include "constants_table.fx" + +struct VS_INPUT +{ + float4 vPosition : POSITION; + float4 vNormal : NORMAL; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vPosition : SV_POSITION; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +VS_OUTPUT Main( VS_INPUT input ) +{ + VS_OUTPUT output; + // Transform coord + output.vPosition = mul(WVPMat, float4(input.vPosition.xyz, 1.0f)); + output.Colour = input.Colour; + float4 NormalCamSpace = mul(WVMat, float4(input.vNormal.xyz, 0.0f)); + output.Tex0.xy = (NormalCamSpace.xy * 0.8f) + 0.5f; + return output; +} + diff --git a/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVVertexShader.hlsl b/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVVertexShader.hlsl new file mode 100644 index 0000000000..4fb140d6ad --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Shaders/DiffuseUVVertexShader.hlsl @@ -0,0 +1,45 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#include "constants_table.fx" + +struct VS_INPUT +{ + float4 vPosition : POSITION; + float4 vNormal : NORMAL; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vPosition : SV_POSITION; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +VS_OUTPUT Main( VS_INPUT input ) +{ + VS_OUTPUT output; + // Transform coord + output.vPosition = mul(WVPMat, float4(input.vPosition.xyz, 1.0f)); + output.Colour = input.Colour; + output.Tex0 = input.Tex0; + return output; +} diff --git a/xbmc/visualizations/Vortex/VortexVis/Shaders/TexturePixelShader.hlsl b/xbmc/visualizations/Vortex/VortexVis/Shaders/TexturePixelShader.hlsl new file mode 100644 index 0000000000..cf18189638 --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Shaders/TexturePixelShader.hlsl @@ -0,0 +1,41 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +Texture2D MainTexture : register(t0); + +SamplerState tSampler : register(s0) +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = CLAMP; + AddressV = CLAMP; + Comparison = NEVER; +}; + +struct PS_INPUT +{ + float4 vPosition : SV_POSITION; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +void Main( PS_INPUT input, out float4 OutColor : SV_TARGET ) +{ + OutColor = MainTexture.Sample( tSampler, input.Tex0 ) * input.Colour; +} + diff --git a/xbmc/visualizations/Vortex/VortexVis/Shaders/UVNormalEnvVertexShader.hlsl b/xbmc/visualizations/Vortex/VortexVis/Shaders/UVNormalEnvVertexShader.hlsl new file mode 100644 index 0000000000..7d699670cf --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Shaders/UVNormalEnvVertexShader.hlsl @@ -0,0 +1,44 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#include "constants_table.fx" + +struct VS_INPUT +{ + float4 vPosition : POSITION; + float4 vNormal : NORMAL; +}; + +struct VS_OUTPUT +{ + float4 vPosition : SV_POSITION; + float4 Colour : COLOR; + float2 Tex0 : TEXCOORD0; +}; + +VS_OUTPUT Main( VS_INPUT input ) +{ + VS_OUTPUT output; + // Transform coord + output.vPosition = mul(WVPMat, float4(input.vPosition.xyz, 1.0f)); + output.Colour = 0xffffffff; + float4 NormalCamSpace = mul(WVMat, float4(input.vNormal.xyz, 0.0f)); + output.Tex0.xy = (NormalCamSpace.xy * 0.2f) + 0.5f; + return output; +} \ No newline at end of file diff --git a/xbmc/visualizations/Vortex/VortexVis/Shaders/constants_table.fx b/xbmc/visualizations/Vortex/VortexVis/Shaders/constants_table.fx new file mode 100644 index 0000000000..17f15d5e7e --- /dev/null +++ b/xbmc/visualizations/Vortex/VortexVis/Shaders/constants_table.fx @@ -0,0 +1,26 @@ +/* +* Copyright © 2010-2015 Team Kodi +* http://kodi.tv +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +cbuffer ConstantsTable : register(b0) +{ + float4 Col; + float4 vScale; + float4x4 WVPMat; + float4x4 WVMat; +} diff --git a/xbmc/visualizations/Vortex/VortexXBMC/VortexXBMC.cpp b/xbmc/visualizations/Vortex/VortexXBMC/VortexXBMC.cpp index aedf17f8d5..f1a8b5ccac 100644 --- a/xbmc/visualizations/Vortex/VortexXBMC/VortexXBMC.cpp +++ b/xbmc/visualizations/Vortex/VortexXBMC/VortexXBMC.cpp @@ -27,6 +27,7 @@ Vortex* g_Vortex = NULL; +extern char g_pluginPath[]; // settings vector //StructSetting** g_structSettings; @@ -39,7 +40,8 @@ extern "C" ADDON_STATUS ADDON_Create(void* hdl, void* props) VIS_PROPS* visprops = (VIS_PROPS*)props; g_Vortex = new Vortex; - g_Vortex->Init( ( LPDIRECT3DDEVICE9 )visprops->device, visprops->x, visprops->y, visprops->width, visprops->height, visprops->pixelRatio ); + strcpy(g_pluginPath, visprops->presets); + g_Vortex->Init(reinterpret_cast(visprops->device), visprops->x, visprops->y, visprops->width, visprops->height, visprops->pixelRatio); return ADDON_STATUS_NEED_SAVEDSETTINGS; } -- cgit v1.2.3