Ver Fonte

Added create() methods for core thread version of render states
WIP renderAPI manual

BearishSun há 9 anos atrás
pai
commit
b8cb3a82f1

+ 76 - 0
Documentation/Manuals/Native/renderAPI.md

@@ -0,0 +1,76 @@
+Render API									{#renderAPI}
+===============
+[TOC]
+
+Render API is an interface that allows you to perform low-level rendering operations akin to DirectX or OpenGL. In Banshee this API is provided through the @ref BansheeEngine::RenderAPI "RenderAPI" for the simulation thread, and @ref BansheeEngine::RenderAPICore "RenderAPICore" for the core thread. If you are confused by the dual nature of  objects, read the [core thread](@ref coreThread) manual. 
+
+For the remainder of this manual we'll focus on the core thread portion of the API, but both provide essentially identical functionality, with the main difference that the simulation thread one expects a @ref BansheeEngine::CoreThreadAccessor "CoreAccessor" as input, and the execution of the actual commands is delayed.
+
+Render API lets you manipulate the GPU pipeline by setting various states (depth stencil, blend and rasterizer), binding GPU programs, textures and executing draw calls. In this manual we'll cover how to use this API to perform rendering manually. 
+
+To render something using this API you need to:
+ - Create and bind a render target
+  - Set up a viewport (if rendering to a part of a render target)
+  - Clear render target (if we're re-using a render target)
+ - Create and bind depth stencil, blend and/or rasterizer states (optionally)
+ - Create and bind GPU programs
+   - Create and bind vertex/fragment GPU program
+   - Create and bind geometry/hull/domain GPU program (optionally)
+ - Bind GPU program parameters (if any)
+  - Bind textures
+  - Bind samplers
+  - Bind parameter buffers (better known constant/uniform buffers)
+ - Create and bind vertices
+  - Create and bind the vertex declaration
+  - Create and bind the vertex buffer
+ - Create and bind the index buffer (optionally)
+ - Issue a draw command
+ 
+We'll cover each step of this process, and at the end also show an alternate pipeline for compute operations.
+
+# Render targets {#renderAPI_a}
+Before any rendering can be done you must bind at least one render target. To learn more about, and how to create a render target check out the [render target](@ref renderTargets) manual. 
+
+Binding a render target involves calling @ref BansheeEngine::RenderAPICore::setRenderTarget "RenderAPICore::setRenderTarget". This will cause any rendering to be output to the entirety of the render target. Optionally you can also call @ref BansheeEngine::RenderAPICore::setViewport "RenderAPICore::setViewport" to select a sub-rectangle of the target to render to. 
+
+Binding a render target means you cannot use it for reading within a GPU program. However if your render target has a depth-buffer you can optionally set the `readOnlyDepthStencil` parameter of @ref BansheeEngine::RenderAPICore::setRenderTarget "RenderAPICore::setRenderTarget" to true, which will allow you to have a depth buffer be bound for both depth-testing and reading from the GPU program.
+ 
+Before doing any rendering it's always good to clear the render target to some default value. Use @ref BansheeEngine::RenderAPICore::clearRenderTarget "RenderAPICore::clearRenderTarget" to clear the entire target, or @ref BansheeEngine::RenderAPICore::clearViewport "RenderAPICore::clearViewport" to clear just the viewport portion of the target. When clearing you can choose whether to clear color, depth or stencil buffers (or all) determined by @ref BansheeEngine::FrameBufferType "FrameBufferType" flags. You can also choose the values to clear each of the buffers to. And finally if your render target has multiple surfaces, you can choose to clear only some of the surfaces by providing a bitmask.
+
+Once you are done rendering make sure to call @ref BansheeEngine::RenderAPICore::swapBuffers "RenderAPICore::swapBuffers" if your render target has multiple buffers (like a window). This will swap the buffers and present the rendered image on the screen.
+
+A simple example covering all these commands:
+~~~~~~~~~~~~~{.cpp}
+SPtr<RenderTarget> myRt = ...; // Assuming we created this earlier, and its a double-buffered window
+
+RenderAPICore& rapi = RenderAPICore::instance();
+rapi.setRenderTarget(myRt);
+rapi.setViewport(Rect2(0.5f, 0.0f, 0.5f, 1.0f)); // Draw only to the right side of the target
+
+// Clear all buffers: color to white, depth to 1.0, stencil to 0
+rapi.clearViewport(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::White, 1.0f, 0);
+... execute some draw calls ...
+rapi.swapBuffers();
+~~~~~~~~~~~~~
+ 
+# Pipeline states {#renderAPI_b}
+Before executing the drawing operation you can optionally set up depth-stencil, rasterizer or blend states. If you do not set them, the default values will be used.
+
+Use @ref BansheeEngine::RenderAPICore::setDepthStencilState "RenderAPICore::setDepthStencilState" to set a @ref BansheeEngine::DepthStencilStateCore "DepthStencilState".
+Use @ref BansheeEngine::RenderAPICore::setBlendState "RenderAPICore::setBlendState" to set a @ref BansheeEngine::BlendStateCore "BlendState".
+Use @ref BansheeEngine::RenderAPICore::setRasterizerState "RenderAPICore::setRasterizerState" to set a @ref BansheeEngine::RasterizerStateCore "RasterizerState".
+
+We won't explain what each of the states does. For that you can check out the class documentation of the states themselves, or familiarize yourself with the modern GPU pipeline in general, as the states mirror it exactly.
+
+# GPU programs {#renderAPI_c}
+
+## GPU program parameters {#renderAPI_c_a}
+
+# Vertices {#renderAPI_d}
+
+# Indices {#renderAPI_e}
+
+# Drawing {#renderAPI_f}
+ 
+# Compute {#renderAPI_g}
+TODO - Explain compute pipeline

+ 3 - 0
Source/BansheeCore/Include/BsBlendState.h

@@ -214,6 +214,9 @@ namespace BansheeEngine
 		/** Returns a unique state ID. Only the lowest 10 bits are used. */
 		UINT32 getId() const { return mId; }
 
+		/**	Creates a new blend state using the specified blend state description structure. */
+		static SPtr<BlendStateCore> create(const BLEND_STATE_DESC& desc);
+
 		/**	Returns the default blend state that you may use when no other is available. */
 		static const SPtr<BlendStateCore>& getDefault();
 

+ 3 - 3
Source/BansheeCore/Include/BsCommonTypes.h

@@ -78,9 +78,9 @@ namespace BansheeEngine
 	/**	Types of frame buffers. */
 	enum FrameBufferType
 	{
-		FBT_COLOR = 0x1,
-		FBT_DEPTH = 0x2,
-		FBT_STENCIL = 0x4
+		FBT_COLOR = 0x1, /**< Clear the color surface. */
+		FBT_DEPTH = 0x2, /**< Clear the depth surface. */
+		FBT_STENCIL = 0x4 /**< Clear the stencil surface. */
 	};
 
 	/**

+ 3 - 0
Source/BansheeCore/Include/BsDepthStencilState.h

@@ -206,6 +206,9 @@ namespace BansheeEngine
 		/**	Returns a unique state ID. Only the lowest 10 bits are used. */
 		UINT32 getId() const { return mId; }
 
+		/**	Creates a new depth stencil state using the specified depth stencil state description structure. */
+		static SPtr<DepthStencilStateCore> create(const DEPTH_STENCIL_STATE_DESC& desc);
+
 		/**	Returns the default depth stencil state that you may use when no other is available. */
 		static const SPtr<DepthStencilStateCore>& getDefault();
 

+ 3 - 0
Source/BansheeCore/Include/BsRasterizerState.h

@@ -187,6 +187,9 @@ namespace BansheeEngine
 		/**	Returns a unique state ID. Only the lowest 10 bits are used. */
 		UINT32 getId() const { return mId; }
 
+		/** Creates a new rasterizer state using the specified rasterizer state descriptor structure. */
+		static SPtr<RasterizerStateCore> create(const RASTERIZER_STATE_DESC& desc);
+
 		/** Returns the default rasterizer state. */
 		static const SPtr<RasterizerStateCore>& getDefault();
 

+ 3 - 0
Source/BansheeCore/Include/BsSamplerState.h

@@ -166,6 +166,9 @@ namespace BansheeEngine
 		/**	Returns information about the sampler state. */
 		const SamplerProperties& getProperties() const;
 
+		/**	Creates a new sampler state using the provided descriptor structure. */
+		static SPtr<SamplerStateCore> create(const SAMPLER_STATE_DESC& desc);
+
 		/**	Returns the default sampler state. */
 		static const SPtr<SamplerStateCore>& getDefault();
 

+ 5 - 0
Source/BansheeCore/Source/BsBlendState.cpp

@@ -123,6 +123,11 @@ namespace BansheeEngine
 		return mProperties;
 	}
 
+	SPtr<BlendStateCore> BlendStateCore::create(const BLEND_STATE_DESC& desc)
+	{
+		return RenderStateCoreManager::instance()._createBlendState(desc);
+	}
+
 	const SPtr<BlendStateCore>& BlendStateCore::getDefault()
 	{
 		return RenderStateCoreManager::instance().getDefaultBlendState();

+ 5 - 0
Source/BansheeCore/Source/BsDepthStencilState.cpp

@@ -60,6 +60,11 @@ namespace BansheeEngine
 		return mProperties;
 	}
 
+	SPtr<DepthStencilStateCore> DepthStencilStateCore::create(const DEPTH_STENCIL_STATE_DESC& desc)
+	{
+		return RenderStateCoreManager::instance()._createDepthStencilState(desc);
+	}
+
 	const SPtr<DepthStencilStateCore>& DepthStencilStateCore::getDefault()
 	{
 		return RenderStateCoreManager::instance().getDefaultDepthStencilState();

+ 5 - 0
Source/BansheeCore/Source/BsRasterizerState.cpp

@@ -52,6 +52,11 @@ namespace BansheeEngine
 		return mProperties;
 	}
 
+	SPtr<RasterizerStateCore> RasterizerStateCore::create(const RASTERIZER_STATE_DESC& desc)
+	{
+		return RenderStateCoreManager::instance()._createRasterizerState(desc);
+	}
+
 	const SPtr<RasterizerStateCore>& RasterizerStateCore::getDefault()
 	{
 		return RenderStateCoreManager::instance().getDefaultRasterizerState();

+ 5 - 0
Source/BansheeCore/Source/BsSamplerState.cpp

@@ -71,6 +71,11 @@ namespace BansheeEngine
 		return mProperties;
 	}
 
+	SPtr<SamplerStateCore> SamplerStateCore::create(const SAMPLER_STATE_DESC& desc)
+	{
+		return RenderStateCoreManager::instance()._createSamplerState(desc);
+	}
+
 	const SPtr<SamplerStateCore>& SamplerStateCore::getDefault()
 	{
 		return RenderStateCoreManager::instance().getDefaultSamplerState();