#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 #ifndef NUCLEX_GRAPHICS_RASTERIZATION_DIRECT3D11RASTERIZERSTATE_H #define NUCLEX_GRAPHICS_RASTERIZATION_DIRECT3D11RASTERIZERSTATE_H #include "Nuclex/Graphics/Config.h" #include "Nuclex/Graphics/Rasterization/Topology.h" #include "Nuclex/Graphics/Rasterization/Viewport.h" #include "Nuclex/Graphics/Rasterization/Shader.h" #include "Direct3D11Api.h" #include #include namespace Nuclex { namespace Graphics { namespace Rasterization { // ------------------------------------------------------------------------------------------- // class GenericIndexBuffer; class GenericVertexBuffer; class VertexShader; class PixelShader; class RenderTarget2; class Direct3D11RasterizerResources; class Direct3D11InputLayoutManager; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Rasterization namespace Nuclex { namespace Graphics { namespace Rasterization { // ------------------------------------------------------------------------------------------- // ///Manages the selected resources of the rasterizer class Direct3D11RasterizerState { /// Initializes the rasterizer state management system public: Direct3D11RasterizerState(); /// Frees all resources owned by the state management system public: ~Direct3D11RasterizerState(); /// Sets the Direct3D device whose state will be managed /// Direct3D 11 device whose state will be managed public: void SetDirect3DDevice(const ID3D11DeviceNPtr &device) { this->device = device; } /// Sets the Direct3D device context for which the state will be managed /// Direct3D 11 device context the state will be managed for public: void SetDirect3DDeviceContext(const ID3D11DeviceContextNPtr &context) { this->context = context; } /// Sets the vertex input layout manager that will be used /// Input layout manager the state manager will use public: void SetInputLayouts(Direct3D11InputLayoutManager *inputLayouts) { this->inputLayouts = inputLayouts; } /// Creates the render target for the back buffer /// Swap chain the back buffer belongs to public: void CreateBackBufferRenderTarget(const IDXGISwapChainNPtr &swapChain); /// /// Called by the rasterizer to shut down before the swap chain is recreated. /// public: void ShutdownForSwapChainRecreation(); /// Called by the rasterizer after the swap chain has been recreated /// New width of the swap chain /// New height of the swap chain public: void RestoreAfterSwapChainRecreation( std::size_t width, std::size_t height ); /// Sets the resource manager the state manager will use /// Resource manager that will be used public: void SetResorces(Direct3D11RasterizerResources *resources) { this->resources = resources; } /// Counts the number of vertex streams usable by the rasterizer /// The number of vertex streams the rasterizer can access public: std::size_t CountAvailableVertexStreams() const; /// Returns the vertex buffer currently bound to the specified stream /// Index of the stream whose bound vertex buffer is returned /// The vertex buffer bound to the specified stream public: const std::shared_ptr &GetVertexBuffer( std::size_t index ) const; /// Binds a vertex buffer to the specified stream /// Index of the stream the vertex buffer will be bound to /// Vertex buffer that will be bound to the stream public: void SetVertexBuffer( std::size_t index, const std::shared_ptr &vertexBuffer ); /// Returns the index buffer currently bound /// The index buffer currently bound public: const std::shared_ptr &GetIndexBuffer() const { return this->indexBuffer; } /// Binds the index buffer that defines the vertex order /// Index buffer that will be bound public: void SetIndexBuffer(const std::shared_ptr &indexBuffer) { this->indexBuffer = indexBuffer; } /// /// Retrieves the vertex shader the rasterizer is using to transform vertices /// /// The vertex shader that the rasterizer is using public: const std::shared_ptr &GetVertexShader() const { return this->vertexShader; } /// Assigns the vertex shader that will be used to transform vertices /// Vertex shader the rasterizer will use public: void SetVertexShader(const std::shared_ptr &vertexShader) { this->vertexShader = vertexShader; } /// /// Retrieves the pixel shader the rasterizer is using to determine pixel colors /// /// The pixel shader that the rasterizer is using public: const std::shared_ptr &GetPixelShader() const { return this->pixelShader; } /// Assigns the pixel shader that will be used to determine pixel colors /// Pixel shader the rasterizer will use public: void SetPixelShader(const std::shared_ptr &pixelShader) { this->pixelShader = pixelShader; } /// Retrieves the render target for the primary rendering surface /// The render target representing the primary rendering surface public: const std::shared_ptr &GetDefaultRenderTarget() { return this->backBufferRenderTarget; } /// Retrieves the current render target /// The current render target of the rasterizer public: const std::shared_ptr &GetRenderTarget() { return this->renderTarget; } /// Selects the render target onto which the rasterize will draw /// New render target to draw on public: void SetRenderTarget(const std::shared_ptr &renderTarget) { this->renderTarget = renderTarget; } /// Returns the currently configured vertex topology /// The topology currently used to connect vertices public: Topology::Enum GetTopology() const { return this->topology; } /// Changes the configured vertex topology /// The topology to be used for connecting vertices public: void SetTopology(Topology::Enum topology) { this->topology = topology; } /// Retrieves the current viewport the rasterizer renders to /// The rasterizer's current viewport public: const Viewport &GetViewport() const { return this->viewport; } /// Sets the viewport the rasterizer will render to /// Viewport the rasterizer will render to public: void SetViewport(const Viewport &viewport) { this->viewport = viewport; this->viewportChanged = true; this->isUsingDefaultViewport = false; } /// /// Applies the changes affecting the rasterization of vertices to the device /// public: void ApplyChangesForVertexRasterization() { assignViewportIfChanged(); assignTopologyIfChanged(); assignVertexBufferIfChanged(); assignVertexShaderConstantBufferIfChanged(); assignVertexShaderTextureIfChanged(); assignVertexShaderIfChanged(); assignPixelShaderConstantBufferIfChanged(); assignPixelShaderTextureIfChanged(); assignPixelShaderIfChanged(); assignRenderTargetIfChanged(); } /// /// Applies the changes affecting the rasterization of indexed vertices to the device /// public: void ApplyChangesForIndexedVertexRasterization() { assignViewportIfChanged(); assignTopologyIfChanged(); assignIndexBufferIfChanged(); assignVertexBufferIfChanged(); assignVertexShaderConstantBufferIfChanged(); assignVertexShaderTextureIfChanged(); assignVertexShaderIfChanged(); assignPixelShaderConstantBufferIfChanged(); assignPixelShaderTextureIfChanged(); assignPixelShaderIfChanged(); assignRenderTargetIfChanged(); } /// Creates the render target responsible for the backbuffer private: void createBackBufferRenderTarget(); /// Destroys the render target responsible for the backbuffer private: void destroyBackBufferRenderTarget(); /// Assigns the topology to the Direct3D device if it has changed private: void assignViewportIfChanged(); /// Assigns the topology to the Direct3D device if it has changed private: void assignTopologyIfChanged(); /// Assigns the index buffer to the Direct3D device if it has changed private: void assignIndexBufferIfChanged(); /// Assigns the vertex buffer to the Direct3D device if it has changed private: void assignVertexBufferIfChanged(); /// Assigns the vertex shader to the Direct3D device if it has changed private: void assignVertexShaderIfChanged(); /// Assigns the pixel shader to the Direct3D device if it has changed private: void assignPixelShaderIfChanged(); /// Assigns the render target to the Direct3D device if it has changed private: void assignRenderTargetIfChanged(); /// Assigns the constant buffer to the vertex shader if it has changed private: void assignVertexShaderConstantBufferIfChanged(); /// Assigns the constant buffer to the pixel shader if it has changed private: void assignPixelShaderConstantBufferIfChanged(); /// Assigns the texture to the vertex shader if it has changed private: void assignVertexShaderTextureIfChanged(); /// Assigns the texture to the pixel shader if it has changed private: void assignPixelShaderTextureIfChanged(); /// Topology currently selected for any Rasterize() calls private: Topology::Enum topology; /// Whether the topology has changed since the last draw call private: bool topologyChanged; /// Vertex buffers the user has currently selected private: std::unique_ptr[]> vertexBuffers; /// Vertex buffers currently assigned to the graphics device private: std::unique_ptr[]> pinnedVertexBuffers; /// Whether the user has changed any of the vertex buffers private: std::size_t highestChangedVertexBufferIndex; /// Constant buffers in the currently assigned vertex shader private: std::unique_ptr< std::shared_ptr[] > pinnedVertexShaderConstantBuffers; /// Constant buffers in the currently assigned pixel shader private: std::unique_ptr< std::shared_ptr[] > pinnedPixelShaderConstantBuffers; /// Textures in the currently assigned vertex shader private: std::unique_ptr[]> pinnedVertexShaderTextures; /// Textures in the currently assigned pixel shader private: std::unique_ptr[]> pinnedPixelShaderTextures; /// Index buffer the user has currently selected private: std::shared_ptr indexBuffer; /// Index buffer currently assigned to the graphics device private: std::shared_ptr pinnedIndexBuffer; /// Vertex shader that will be used to transform vertices private: std::shared_ptr vertexShader; /// Vertex shader currently assigned to graphics device private: std::shared_ptr pinnedVertexShader; /// Pixel shader that will be used for rasterization private: std::shared_ptr pixelShader; /// Pixel shader currently assigned to the graphics device private: std::shared_ptr pinnedPixelShader; /// Render target onto which the rasterizer will draw private: std::shared_ptr renderTarget; /// Render target currently assigned to the graphics device private: std::shared_ptr pinnedRenderTarget; /// Render target that represents the swap chain's back buffer private: std::shared_ptr backBufferRenderTarget; /// Set when the render target used for the back buffer has changed private: bool backBufferRenderTargetChanged; /// Viewport into which rendering will take place private: Viewport viewport; /// Whether the viewport has changed since the last draw call private: bool viewportChanged; /// /// Remains true until the user sets a custom viewport for the first time /// private: bool isUsingDefaultViewport; /// Direct3D device the state will be managed for private: ID3D11DeviceNPtr device; /// Direct3D device context that contains the device's state private: ID3D11DeviceContextNPtr context; /// Resource manager the state will pull its device objects from private: Direct3D11RasterizerResources *resources; /// Input layout manager used to generated input layouts for shaders private: Direct3D11InputLayoutManager *inputLayouts; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Rasterization #endif // NUCLEX_GRAPHICS_RASTERIZATION_DIRECT3D11RASTERIZERSTATE_H