#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2013 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library 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 IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License // If the library is compiled as a DLL, this ensures symbols are exported #define NUCLEX_GRAPHICS_SOURCE 1 #include "Nuclex/Graphics/Rasterization/Direct3D11Rasterizer.h" #include "Nuclex/Graphics/Rasterization/Limits.h" #include "Direct3D11/Direct3D11Rasterizer.Impl.h" #include "Direct3D11/Direct3D11RasterizerSettings.h" #include "Direct3D11/Direct3D11RasterizerResources.h" #include "Direct3D11/Direct3D11Converters.h" #include "Direct3D11/Observers/Direct3D11IndexBufferObserver.h" #include "Direct3D11/Observers/Direct3D11VertexBufferObserver.h" #include "Direct3D11/Observers/Direct3D11VertexShaderObserver.h" #include "Direct3D11/Observers/Direct3D11PixelShaderObserver.h" #include "Direct3D11/Observers/Direct3D11RenderTarget2Observer.h" #include namespace Nuclex { namespace Graphics { namespace Rasterization { // ------------------------------------------------------------------------------------------- // #if defined(NUCLEX_GRAPHICS_WINRT) Direct3D11Rasterizer::Direct3D11Rasterizer(Windows::UI::Core::CoreWindow ^window) : impl(ref new Impl(window)) {} #endif // ------------------------------------------------------------------------------------------- // #if !defined(NUCLEX_GRAPHICS_WINRT) Direct3D11Rasterizer::Direct3D11Rasterizer(HWND windowHandle) : impl(new Impl(windowHandle)) {} #endif // ------------------------------------------------------------------------------------------- // Direct3D11Rasterizer::~Direct3D11Rasterizer() { delete this->impl; } // ------------------------------------------------------------------------------------------- // #if defined(NUCLEX_GRAPHICS_WINRT) bool Direct3D11Rasterizer::IsAvailable() { return true; } #endif // ------------------------------------------------------------------------------------------- // #if defined(NUCLEX_GRAPHICS_WIN32) bool Direct3D11Rasterizer::IsAvailable() { #if defined(NUCLEX_GRAPHICS_DIRECT3D11_1) HMODULE libraryHandle = ::LoadLibraryExW( L"D3D11_1.dll", nullptr, DONT_RESOLVE_DLL_REFERENCES ); #else HMODULE libraryHandle = ::LoadLibraryExW( L"D3D11.dll", nullptr, DONT_RESOLVE_DLL_REFERENCES ); #endif if(libraryHandle == nullptr) { return false; } else { ::FreeLibrary(libraryHandle); return true; } } #endif // ------------------------------------------------------------------------------------------- // const RasterizerSettings &Direct3D11Rasterizer::Settings() const { return this->impl->Settings; } // ------------------------------------------------------------------------------------------- // RasterizerSettings &Direct3D11Rasterizer::Settings() { return this->impl->Settings; } // ------------------------------------------------------------------------------------------- // const RasterizerResources &Direct3D11Rasterizer::Resources() const { return this->impl->Resources; } // ------------------------------------------------------------------------------------------- // RasterizerResources &Direct3D11Rasterizer::Resources() { return this->impl->Resources; } // ------------------------------------------------------------------------------------------- // std::size_t Direct3D11Rasterizer::CountAvailableVertexStreams() const { return this->impl->State.CountAvailableVertexStreams(); } // ------------------------------------------------------------------------------------------- // const std::shared_ptr &Direct3D11Rasterizer::GetVertexBuffer( std::size_t index ) const { return this->impl->State.GetVertexBuffer(index); } // ------------------------------------------------------------------------------------------- // void Direct3D11Rasterizer::SetVertexBuffer( std::size_t index, const std::shared_ptr &vertexBuffer ) { this->impl->State.SetVertexBuffer(index, vertexBuffer); } // ------------------------------------------------------------------------------------------- // const std::shared_ptr &Direct3D11Rasterizer::GetIndexBuffer() const { return this->impl->State.GetIndexBuffer(); } // ------------------------------------------------------------------------------------------- // void Direct3D11Rasterizer::SetIndexBuffer( const std::shared_ptr &indexBuffer ) { this->impl->State.SetIndexBuffer(indexBuffer); } // ------------------------------------------------------------------------------------------- // const std::shared_ptr &Direct3D11Rasterizer::GetVertexShader() const { return this->impl->State.GetVertexShader(); } // ------------------------------------------------------------------------------------------- // void Direct3D11Rasterizer::SetVertexShader(const std::shared_ptr &vertexShader) { this->impl->State.SetVertexShader(vertexShader); } // ------------------------------------------------------------------------------------------- // const std::shared_ptr &Direct3D11Rasterizer::GetPixelShader() const { return this->impl->State.GetPixelShader(); } // ------------------------------------------------------------------------------------------- // void Direct3D11Rasterizer::SetPixelShader(const std::shared_ptr &pixelShader) { this->impl->State.SetPixelShader(pixelShader); } // ------------------------------------------------------------------------------------------- // const std::shared_ptr &Direct3D11Rasterizer::GetDefaultRenderTarget() { return this->impl->State.GetDefaultRenderTarget(); } // ------------------------------------------------------------------------------------------- // const std::shared_ptr &Direct3D11Rasterizer::GetRenderTarget() { return this->impl->State.GetRenderTarget(); } // ------------------------------------------------------------------------------------------- // void Direct3D11Rasterizer::SetRenderTarget(const std::shared_ptr &renderTarget) { this->impl->State.SetRenderTarget(renderTarget); } // ------------------------------------------------------------------------------------------- // Topology::Enum Direct3D11Rasterizer::GetTopology() const { return this->impl->State.GetTopology(); } // ------------------------------------------------------------------------------------------- // void Direct3D11Rasterizer::SetTopology(Topology::Enum topology) { this->impl->State.SetTopology(topology); } // ------------------------------------------------------------------------------------------- // const Viewport &Direct3D11Rasterizer::GetViewport() const { return this->impl->State.GetViewport(); } // ------------------------------------------------------------------------------------------- // void Direct3D11Rasterizer::SetViewport(const Viewport &viewport) { this->impl->State.SetViewport(viewport); } // ------------------------------------------------------------------------------------------- // void Direct3D11Rasterizer::Rasterize( std::size_t vertexBufferStartIndex /* = 0 */, std::size_t vertexCount /* = static_cast(-1) */ ) { this->impl->State.ApplyChangesForVertexRasterization(); if(vertexCount == static_cast(-1)) { for(std::size_t index = 0; index < VertexBufferSlotCount; ++index) { const std::shared_ptr &vertexBuffer = this->impl->State.GetVertexBuffer(index); if(vertexBuffer.get() != nullptr) { vertexCount = vertexBuffer->CountUsedVertices(); break; } } if(vertexCount < vertexBufferStartIndex) { throw std::out_of_range("Vertex buffer start index lies outside used vertex range"); } vertexCount -= vertexBufferStartIndex; } this->impl->GetDirect3DDeviceContext()->Draw( static_cast(vertexCount), static_cast(vertexBufferStartIndex) ); } // ------------------------------------------------------------------------------------------- // void Direct3D11Rasterizer::RasterizeIndexed( std::size_t indexBufferStartIndex /* = 0 */, std::size_t indexCount /* = static_cast(-1) */, std::size_t, std::size_t // Direct3D 11 has no use for these, it seems ) { this->impl->State.ApplyChangesForIndexedVertexRasterization(); if(indexCount == static_cast(-1)) { const std::shared_ptr &indexBuffer = this->impl->State.GetIndexBuffer(); if(indexBuffer.get() != nullptr) { indexCount = indexBuffer->CountUsedIndices(); } if(indexCount < indexBufferStartIndex) { throw std::out_of_range("Index buffer start index lies beyond used index range"); } indexCount -= indexBufferStartIndex; } this->impl->GetDirect3DDeviceContext()->DrawIndexed( static_cast(indexCount), static_cast(indexBufferStartIndex), 0 ); } // ------------------------------------------------------------------------------------------- // void Direct3D11Rasterizer::Present() { HRESULT resultHandle = this->impl->GetSwapChain()->Present(1, 0); if(FAILED(resultHandle)) { throw std::runtime_error("Could not present Direct3D 11 back buffer on screen"); } } // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Rasterization