Browse Source

Add "transparent" flag to shaders
Added two packed floating point formats to DX11 and OpenGL
Added RenderTargets type to control all renders targets for a specific view

Marko Pintera 10 years ago
parent
commit
71598ef68e

+ 9 - 0
BansheeCore/Include/BsCommonTypes.h

@@ -321,6 +321,15 @@ namespace BansheeEngine
 		None /**< Objects will not be sorted and will be processed in the order they were added to the queue. */
 	};
 
+	/**
+	 * @brief	Flags that may be assigned to a shader that let the renderer know how to interpret
+	 *			the shader.
+	 */
+	enum class ShaderFlags
+	{
+		Transparent = 0x1 /**< Signifies that the shader is rendering a transparent object. */
+	};
+
 	/**
 	 * @brief	Texture addressing mode, per component.
 	 */

+ 7 - 1
BansheeCore/Include/BsPixelData.h

@@ -90,8 +90,12 @@ namespace BansheeEngine
 		PF_D32 = 31,
 		// Depth format, 16bits
 		PF_D16 = 32,
+		// 32-bit float format, 11 bits (float) for red, 11 bits (float) for green, 10 bits (float) for blue. Framebuffer only format, not for CPU use.
+		PF_FLOAT_R11G11B10 = 33,
+		// 32-bit unsigned normalized format, 10 bits (float) for red, 10 bits (float) for green, 10 bits (float) for blue, and two bits for alpha. Framebuffer only format, not for CPU use.
+		PF_UNORM_R10G10B10A2 = 34,
 		// Number of pixel formats currently defined
-        PF_COUNT = 33
+        PF_COUNT = 35
     };
 	typedef Vector<PixelFormat> PixelFormatList;
 
@@ -122,6 +126,8 @@ namespace BansheeEngine
         PCT_SHORT = 1,   /**< Short per component */
         PCT_FLOAT16 = 2, /**< 16 bit float per component */
         PCT_FLOAT32 = 3, /**< 32 bit float per component */
+		PCT_PACKED_R11G11B10 = 4, /**< 11 bits for first two components, 10 for third component. */
+		PCT_PACKED_R10G10B10A2 = 5, /**< 10 bits for first three components, 2 bits for last component */
         PCT_COUNT = 4    /**< Number of pixel types */
     };
     

+ 11 - 0
BansheeCore/Include/BsShader.h

@@ -182,6 +182,11 @@ namespace BansheeEngine
 		 */
 		bool separablePasses;
 
+		/**
+		 * @brief	Flags that let the renderer know how should it interpret the shader.
+		 */
+		UINT32 flags;
+
 		Map<String, SHADER_DATA_PARAM_DESC> dataParams;
 		Map<String, SHADER_OBJECT_PARAM_DESC> textureParams;
 		Map<String, SHADER_OBJECT_PARAM_DESC> bufferParams;
@@ -264,6 +269,12 @@ namespace BansheeEngine
 		 */
 		bool getAllowSeparablePasses() const { return mDesc.separablePasses; }
 
+		/**
+		 * @brief	Returns flags that control how the renderer interprets the shader.
+		 *			Actual interpretation of the flags depends on the active renderer.
+		 */
+		UINT32 getFlags() const { return mDesc.flags; }
+
 		/**
 		 * @brief	Returns type of the parameter with the specified name. Throws exception if
 		 *			the parameter doesn't exist.

+ 8 - 3
BansheeCore/Include/BsShaderRTTI.h

@@ -235,6 +235,9 @@ namespace BansheeEngine
 		bool& getAllowSeparablePasses(Shader* obj) { return obj->mDesc.separablePasses; }
 		void setAllowSeparablePasses(Shader* obj, bool& value) { obj->mDesc.separablePasses = value; }
 
+		UINT32& getFlags(Shader* obj) { return obj->mDesc.flags; }
+		void setFlags(Shader* obj, UINT32& value) { obj->mDesc.flags = value; }
+
 		Vector<UINT8>& getDataDefaultValues(Shader* obj) { return obj->mDesc.dataDefaultValues; }
 		void setDataDefaultValues(Shader* obj, Vector<UINT8>& value) { obj->mDesc.dataDefaultValues = value; }
 
@@ -275,21 +278,23 @@ namespace BansheeEngine
 				&ShaderRTTI::setDefaultTexture, &ShaderRTTI::setDefaultTextureArraySize);
 			addReflectablePtrArrayField("mSamplerDefaultValues", 12, &ShaderRTTI::getDefaultSampler, &ShaderRTTI::getDefaultSamplerArraySize,
 				&ShaderRTTI::setDefaultSampler, &ShaderRTTI::setDefaultSamplerArraySize);
+
+			addPlainField("mFlags", 13, &ShaderRTTI::getFlags, &ShaderRTTI::setFlags);
 		}
 
-		virtual void onDeserializationEnded(IReflectable* obj)
+		virtual void onDeserializationEnded(IReflectable* obj) override
 		{
 			Shader* shader = static_cast<Shader*>(obj);
 			shader->initialize();
 		}
 
-		virtual const String& getRTTIName()
+		virtual const String& getRTTIName() override
 		{
 			static String name = "Shader";
 			return name;
 		}
 
-		virtual UINT32 getRTTIId()
+		virtual UINT32 getRTTIId() override
 		{
 			return TID_Shader;
 		}

+ 30 - 2
BansheeCore/Source/BsPixelUtil.cpp

@@ -796,6 +796,34 @@ namespace BansheeEngine
 		/* Masks and shifts */
 		0, 0, 0, 0, 0, 0, 0, 0
 		}, 
+	//-----------------------------------------------------------------------
+		{ "PF_FLOAT_R11G11B10",
+		/* Bytes per element */
+		4,
+		/* Flags */
+		PFF_FLOAT,
+		/* Component type and count */
+		PCT_PACKED_R11G11B10, 1,
+		/* rbits, gbits, bbits, abits */
+		11, 11, 10, 0,
+		/* Masks and shifts */
+		0x000007FF, 0x003FF800, 0xFFC00000, 0,
+		0, 11, 22, 0
+		},
+	//-----------------------------------------------------------------------
+		{ "PF_UNORM_R10G10B10A2",
+		/* Bytes per element */
+		4,
+		/* Flags */
+		PFF_FLOAT | PFF_HASALPHA,
+		/* Component type and count */
+		PCT_PACKED_R10G10B10A2, 1,
+		/* rbits, gbits, bbits, abits */
+		10, 10, 10, 2,
+		/* Masks and shifts */
+		0x000003FF, 0x000FFC00, 0x3FF00000, 0xC0000000,
+		0, 10, 20, 30
+		},
     };
 
     static inline const PixelFormatDescription &getDescriptionFor(const PixelFormat fmt)
@@ -815,10 +843,10 @@ namespace BansheeEngine
 			:buffer(buffer), bufferWritePos(buffer), bufferEnd(buffer + sizeBytes)
 		{ }
 
-		virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel)
+		virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel) override
 		{ }
 
-		virtual bool writeData(const void* data, int size)
+		virtual bool writeData(const void* data, int size) override
 		{
 			assert((bufferWritePos + size) <= bufferEnd);
 			memcpy(bufferWritePos, data, size);

+ 1 - 1
BansheeCore/Source/BsShader.cpp

@@ -12,7 +12,7 @@ namespace BansheeEngine
 {
 	template<bool Core>
 	TSHADER_DESC<Core>::TSHADER_DESC()
-		:queuePriority(0), queueSortType(QueueSortType::None), separablePasses(false)
+		:queuePriority(0), queueSortType(QueueSortType::None), separablePasses(false), flags(0)
 	{
 
 	}

+ 6 - 2
BansheeD3D11RenderAPI/Source/BsD3D11Mappings.cpp

@@ -459,11 +459,11 @@ namespace BansheeEngine
 		case DXGI_FORMAT_R10G10B10A2_TYPELESS:
 			return PF_UNKNOWN;
 		case DXGI_FORMAT_R10G10B10A2_UNORM:
-			return PF_UNKNOWN;
+			return PF_UNORM_R10G10B10A2;
 		case DXGI_FORMAT_R10G10B10A2_UINT:
 			return PF_UNKNOWN;
 		case DXGI_FORMAT_R11G11B10_FLOAT:
-			return PF_UNKNOWN;
+			return PF_FLOAT_R11G11B10;
 		case DXGI_FORMAT_R8G8B8A8_TYPELESS:
 			return PF_UNKNOWN;
 		case DXGI_FORMAT_R8G8B8A8_UNORM:
@@ -671,6 +671,10 @@ namespace BansheeEngine
 			return DXGI_FORMAT_D32_FLOAT;
 		case PF_D16:
 			return DXGI_FORMAT_D16_UNORM;
+		case PF_FLOAT_R11G11B10:
+			return DXGI_FORMAT_R11G11B10_FLOAT;
+		case PF_UNORM_R10G10B10A2:
+			return DXGI_FORMAT_R10G10B10A2_UNORM;
 		case PF_UNKNOWN:
 		default:
 			return DXGI_FORMAT_UNKNOWN;

+ 4 - 0
BansheeD3D9RenderAPI/Source/BsD3D9Mappings.cpp

@@ -455,6 +455,8 @@ namespace BansheeEngine
 			return PF_D32;
 		case D3DFMT_D16:
 			return PF_D16;
+		case D3DFMT_A2B10G10R10:
+			return PF_UNORM_R10G10B10A2;
 		default:
 			return PF_UNKNOWN;
 		}
@@ -499,6 +501,8 @@ namespace BansheeEngine
 			return D3DFMT_D32F_LOCKABLE;
 		case PF_D16:
 			return D3DFMT_D16;
+		case PF_UNORM_R10G10B10A2:
+			return D3DFMT_A2B10G10R10;
 		case PF_UNKNOWN:
 		default:
 			return D3DFMT_UNKNOWN;

+ 1 - 0
BansheeEngine/Include/BsRenderQueue.h

@@ -43,6 +43,7 @@ namespace BansheeEngine
 
 	public:
 		RenderQueue();
+		virtual ~RenderQueue() { }
 
 		/**
 		 * @brief	Adds a new entry to the render queue.

+ 20 - 0
BansheeGLRenderAPI/Source/BsGLPixelFormat.cpp

@@ -43,6 +43,10 @@ namespace BansheeEngine
                 return GL_RGB;
             case PF_FLOAT32_RGBA:
                 return GL_RGBA;
+			case PF_FLOAT_R11G11B10:
+				return GL_RGB;
+			case PF_UNORM_R10G10B10A2:
+				return GL_RGBA;
             case PF_BC1:
             case PF_BC1a:
             case PF_BC3:
@@ -88,6 +92,10 @@ namespace BansheeEngine
             case PF_FLOAT32_RGB:
             case PF_FLOAT32_RGBA:
                 return GL_FLOAT;
+			case PF_FLOAT_R11G11B10:
+				return GL_UNSIGNED_INT_10F_11F_11F_REV;
+			case PF_UNORM_R10G10B10A2:
+				return GL_UNSIGNED_INT_2_10_10_10_REV;
             default:
                 return 0;
         }
@@ -194,6 +202,10 @@ namespace BansheeEngine
 				return GL_DEPTH24_STENCIL8;
 			case PF_D32_S8X24:
 				return GL_DEPTH32F_STENCIL8;
+			case PF_FLOAT_R11G11B10:
+				return GL_R11F_G11F_B10F;
+			case PF_UNORM_R10G10B10A2:
+				return GL_RGB10_A2;
             default:
                 return GL_NONE;
         }
@@ -291,6 +303,10 @@ namespace BansheeEngine
 			return PF_D24S8;
 		case GL_DEPTH32F_STENCIL8:
 			return PF_D32_S8X24;
+		case GL_RGB10_A2:
+			return PF_UNORM_R10G10B10A2;
+		case GL_R11F_G11F_B10F:
+			return PF_FLOAT_R11G11B10;
 		default:
 			return PF_R8G8B8A8;
 		};
@@ -350,6 +366,10 @@ namespace BansheeEngine
 			return PF_D24S8;
 		case PF_D32_S8X24:
 			return PF_D32_S8X24;
+		case PF_UNORM_R10G10B10A2:
+			return PF_UNORM_R10G10B10A2;
+		case PF_FLOAT_R11G11B10:
+			return PF_FLOAT_R11G11B10;
 		default:
 			return PF_UNKNOWN;
 		}

+ 1 - 0
BansheeSL/BsLexerFX.l

@@ -74,6 +74,7 @@ Block			{ return TOKEN_PARAMSBLOCK; }
 Separable		{ return TOKEN_SEPARABLE; }
 Queue			{ return TOKEN_QUEUE; }
 Priority		{ return TOKEN_PRIORITY; }
+Transparent		{ return TOKEN_TRANSPARENT; }
 Technique		{ return TOKEN_TECHNIQUE; }
 Parameters		{ return TOKEN_PARAMETERS; }
 Blocks			{ return TOKEN_BLOCKS; }

+ 2 - 1
BansheeSL/BsParserFX.y

@@ -112,7 +112,7 @@ void yyerror(YYLTYPE *locp, ParseState* parse_state, yyscan_t scanner, const cha
 %token TOKEN_AUTO TOKEN_ALIAS TOKEN_SHARED TOKEN_USAGE
 
 	/* Shader keywords */
-%token TOKEN_SEPARABLE TOKEN_QUEUE TOKEN_PRIORITY
+%token TOKEN_SEPARABLE TOKEN_QUEUE TOKEN_PRIORITY TOKEN_TRANSPARENT
 %token TOKEN_PARAMETERS TOKEN_BLOCKS TOKEN_TECHNIQUE
 
 	/* Technique keywords */
@@ -244,6 +244,7 @@ shader_option
 	| TOKEN_QUEUE '=' TOKEN_INTEGER ';'			{ $$.type = OT_Queue; $$.value.intValue = $3; }
 	| TOKEN_PRIORITY '=' TOKEN_INTEGER ';'		{ $$.type = OT_Priority; $$.value.intValue = $3; }
 	| TOKEN_INCLUDE '=' TOKEN_STRING ';'		{ $$.type = OT_Include; $$.value.strValue = $3; }
+	| TOKEN_TRANSPARENT '=' TOKEN_BOOLEAN ';'	{ $$.type = OT_Transparent; $$.value.intValue = $3; }
 	;
 
 	/* Technique */

+ 1 - 0
BansheeSL/Include/BsASTFX.h

@@ -47,6 +47,7 @@ enum tagOptionType
 	OT_Separable,
 	OT_Priority,
 	OT_Queue,
+	OT_Transparent,
 	OT_Technique,
 	OT_Renderer,
 	OT_Language,

+ 1 - 0
BansheeSL/Source/BsASTFX.c

@@ -7,6 +7,7 @@ OptionInfo OPTION_LOOKUP[] =
 	{ OT_Separable, ODT_Bool },
 	{ OT_Priority, ODT_Int },
 	{ OT_Queue, ODT_Int },
+	{ OT_Transparent, ODT_Bool },
 	{ OT_Technique, ODT_Complex }, 
 	{ OT_Renderer, ODT_String }, 
 	{ OT_Language, ODT_String }, 

+ 4 - 0
BansheeSL/Source/BsSLFXCompiler.cpp

@@ -530,6 +530,7 @@ namespace BansheeEngine
 			case OT_Separable:
 			case OT_Queue:
 			case OT_Priority:
+			case OT_Transparent:
 				nodeOptionsAdd(mergeInto->memContext, mergeInto->rootNode->options, option);
 				break;
 			case OT_Technique:
@@ -1588,6 +1589,9 @@ namespace BansheeEngine
 			case OT_Priority:
 				shaderDesc.queuePriority = option->value.intValue;
 				break;
+			case OT_Transparent:
+				shaderDesc.flags |= (UINT32)ShaderFlags::Transparent;
+				break;
 			case OT_Technique:
 			{
 				TechniquePtr technique = parseTechnique(option->value.nodePtr, codeBlocks);

+ 2 - 0
RenderBeast/Include/BsRenderBeastPrerequisites.h

@@ -22,4 +22,6 @@ namespace BansheeEngine
 {
 	class LitTexRenderableController;
 	struct RenderBeastOptions;
+	struct PooledRenderTexture;
+	class RenderTargets;
 }

+ 57 - 0
RenderBeast/Include/BsRenderTargets.h

@@ -0,0 +1,57 @@
+#pragma once
+
+#include "BsRenderBeastPrerequisites.h"
+#include "BsPixelUtil.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Allocates and handles all the required render targets
+	 *			for rendering a scene from a specific viewport.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_BSRND_EXPORT RenderTargets
+	{
+	public:
+		/**
+		 * @brief	Creates a new set of render targets. This will not actually allocate 
+		 *			the internal render targets - this happens the first time you call ::bind.
+		 *
+		 * @param	viewport		Viewport that the render targets will be used for. Determines size of the
+		 *							render targets.
+		 * @param	hdr				Should the render targets support high dynamic range rendering.
+		 * @param	numSamples		Number of samples to use if multisampling is active. Provide 0 or 1 if
+		 *							multisampled targets are not needed.
+		 */
+		static SPtr<RenderTargets> create(const ViewportCore& viewport, bool hdr, UINT32 numSamples);
+
+		/**
+		 * @brief	Binds the render targets for rendering. This will also allocate the render
+		 *			targets if they aren't already allocated.
+		 */
+		void bind();
+
+		/**
+		 * @brief	Frees the render targets so they may be used by another set of render targets. This
+		 *			will not release the render target memory. Memory will only released once all
+		 *			RenderTarget instances pointing to the render target go out of scope.
+		 */
+		void unbind();
+
+	private:
+		RenderTargets(const ViewportCore& viewport, bool hdr, UINT32 numSamples);
+
+		SPtr<PooledRenderTexture> mDiffuseRT;
+		SPtr<PooledRenderTexture> mNormalRT;
+		SPtr<PooledRenderTexture> mDepthRT;
+
+		SPtr<MultiRenderTextureCore> mGBuffer;
+
+		UINT32 mWidth;
+		UINT32 mHeight;
+		PixelFormat mDiffuseFormat;
+		PixelFormat mNormalFormat;
+		UINT32 mNumSamples;
+	};
+}

+ 3 - 2
RenderBeast/Include/BsRenderTexturePool.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include "BsRenderBeastPrerequisites.h"
+#include "BsModule.h"
 #include "BsPixelUtil.h"
 
 namespace BansheeEngine
@@ -15,7 +16,7 @@ namespace BansheeEngine
 		PooledRenderTexture(RenderTexturePool* pool);
 		~PooledRenderTexture();
 
-		SPtr<RenderTextureCore> texture;
+		SPtr<TextureCore> texture;
 
 	private:
 		friend class RenderTexturePool;
@@ -28,7 +29,7 @@ namespace BansheeEngine
 	 * @brief	Contains a pool of render textures meant to accommodate reuse of
 	 *			render textures of the same size and format.
 	 */
-	class RenderTexturePool
+	class RenderTexturePool : public Module<RenderTexturePool>
 	{
 	public:
 		~RenderTexturePool();

+ 2 - 0
RenderBeast/RenderBeast.vcxproj

@@ -244,6 +244,7 @@
     <ClInclude Include="Include\BsRenderBeastFactory.h" />
     <ClInclude Include="Include\BsRenderBeastPrerequisites.h" />
     <ClInclude Include="Include\BsRenderBeastOptions.h" />
+    <ClInclude Include="Include\BsRenderTargets.h" />
     <ClInclude Include="Include\BsRenderTexturePool.h" />
     <ClInclude Include="Include\BsSamplerOverrides.h" />
   </ItemGroup>
@@ -252,6 +253,7 @@
     <ClCompile Include="Source\BsRenderBeast.cpp" />
     <ClCompile Include="Source\BsRenderBeastFactory.cpp" />
     <ClCompile Include="Source\BsRenderBeastPlugin.cpp" />
+    <ClCompile Include="Source\BsRenderTargets.cpp" />
     <ClCompile Include="Source\BsRenderTexturePool.cpp" />
     <ClCompile Include="Source\BsSamplerOverrides.cpp" />
   </ItemGroup>

+ 6 - 0
RenderBeast/RenderBeast.vcxproj.filters

@@ -36,6 +36,9 @@
     <ClInclude Include="Include\BsRenderBeastPrerequisites.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsRenderTargets.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsLitTexRenderableController.cpp">
@@ -56,5 +59,8 @@
     <ClCompile Include="Source\BsRenderBeastPlugin.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsRenderTargets.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 8 - 2
RenderBeast/Source/BsRenderBeast.cpp

@@ -33,6 +33,7 @@
 #include "BsRenderBeastOptions.h"
 #include "BsSamplerOverrides.h"
 #include "BsLightInternal.h"
+#include "BsRenderTexturePool.h"
 
 using namespace std::placeholders;
 
@@ -70,6 +71,8 @@ namespace BansheeEngine
 		mCoreOptions = bs_shared_ptr_new<RenderBeastOptions>();
 		mLitTexHandler = bs_new<LitTexRenderableController>();
 
+		RenderTexturePool::startUp();
+
 		SPtr<ShaderCore> shader = createDefaultShader();
 		mDummyMaterial = MaterialCore::create(shader);
 	}
@@ -83,6 +86,8 @@ namespace BansheeEngine
 		mCameraData.clear();
 		mRenderables.clear();
 
+		RenderTexturePool::shutDown();
+
 		assert(mSamplerOverrides.empty());
 
 		mDummyMaterial = nullptr;
@@ -270,12 +275,13 @@ namespace BansheeEngine
 			HSceneObject cameraSO = cameraData.second.sceneObject;
 
 			DrawListPtr drawList = bs_shared_ptr_new<DrawList>();
+			ViewportPtr viewport = camera->getViewport();
 
 			// Get GUI render operations
-			GUIManager::instance().render(camera->getViewport(), *drawList);
+			GUIManager::instance().render(viewport, *drawList);
 
 			// Get overlay render operations
-			OverlayManager::instance().render(camera->getViewport(), *drawList);
+			OverlayManager::instance().render(viewport, *drawList);
 
 			// Get any operations from hooked up callbacks
 			const Viewport* viewportRawPtr = camera->getViewport().get();

+ 77 - 0
RenderBeast/Source/BsRenderTargets.cpp

@@ -0,0 +1,77 @@
+#include "BsRenderTargets.h"
+#include "BsRenderTexturePool.h"
+#include "BsViewport.h"
+#include "BsRenderAPI.h"
+#include "BsTextureManager.h"
+
+namespace BansheeEngine
+{
+	RenderTargets::RenderTargets(const ViewportCore& viewport, bool hdr, UINT32 numSamples)
+		:mNumSamples(numSamples)
+	{
+		// TODO - Round up width/height so it's divisible by 8?
+		mWidth = (UINT32)viewport.getWidth();
+		mHeight = (UINT32)viewport.getHeight();
+
+		if (hdr)
+			mDiffuseFormat = PF_FLOAT_R11G11B10;
+		else
+			mDiffuseFormat = PF_R8G8B8X8;
+
+		mNormalFormat = PF_FLOAT_R11G11B10;
+	}
+
+	SPtr<RenderTargets> RenderTargets::create(const ViewportCore& viewport, bool hdr, UINT32 numSamples)
+	{
+		return bs_shared_ptr<RenderTargets>(new (bs_alloc<RenderTargets>()) RenderTargets(viewport, hdr, numSamples));
+	}
+
+	void RenderTargets::bind()
+	{
+		RenderTexturePool& texPool = RenderTexturePool::instance();
+
+		mDiffuseRT = texPool.get(mDiffuseFormat, mWidth, mHeight, false, mNumSamples);
+		mNormalRT = texPool.get(mNormalFormat, mWidth, mHeight, false, mNumSamples);
+		mDepthRT = texPool.get(PF_D24S8, mWidth, mHeight, false, mNumSamples);
+
+		// Note: I'm making an assumption here that textures retrieved from render texture pool
+		// won't change, which should be true as long as I don't request these same sizes & formats
+		// somewhere else at the same time while binding the gbuffer (which shouldn't happen).
+		if (mGBuffer == nullptr)
+		{
+			MULTI_RENDER_TEXTURE_CORE_DESC gbufferDesc;
+			gbufferDesc.colorSurfaces.resize(2);
+
+			gbufferDesc.colorSurfaces[0].texture = mDiffuseRT->texture;
+			gbufferDesc.colorSurfaces[0].face = 0;
+			gbufferDesc.colorSurfaces[0].mipLevel = 0;
+
+			gbufferDesc.colorSurfaces[1].texture = mNormalRT->texture;
+			gbufferDesc.colorSurfaces[1].face = 0;
+			gbufferDesc.colorSurfaces[1].mipLevel = 0;
+
+			gbufferDesc.depthStencilSurface.texture = mDepthRT->texture;
+			gbufferDesc.depthStencilSurface.face = 0;
+			gbufferDesc.depthStencilSurface.mipLevel = 0;
+
+			mGBuffer = TextureCoreManager::instance().createMultiRenderTexture(gbufferDesc);
+		}
+
+		RenderAPICore& rapi = RenderAPICore::instance();
+		rapi.setRenderTarget(mGBuffer);
+
+		// TODO - Clear gbuffer?
+	}
+
+	void RenderTargets::unbind()
+	{
+		RenderAPICore& rapi = RenderAPICore::instance();
+		rapi.setRenderTarget(nullptr);
+
+		RenderTexturePool& texPool = RenderTexturePool::instance();
+
+		texPool.release(mDiffuseRT);
+		texPool.release(mNormalRT);
+		texPool.release(mDepthRT);
+	}
+}

+ 4 - 20
RenderBeast/Source/BsRenderTexturePool.cpp

@@ -32,16 +32,10 @@ namespace BansheeEngine
 			if (!textureData->mIsFree)
 				continue;
 
-			SPtr<TextureCore> textureCore;
-			if (!depth)
-				textureCore = textureData->texture->getBindableColorTexture(); 
-			else
-				textureCore = textureData->texture->getBindableDepthStencilTexture();
-
-			if (textureCore == nullptr)
+			if (textureData->texture == nullptr)
 				continue;
 
-			if (matches(textureCore, format, width, height, hwGamma, samples))
+			if (matches(textureData->texture, format, width, height, hwGamma, samples))
 			{
 				textureData->mIsFree = false;
 				return textureData;
@@ -51,19 +45,9 @@ namespace BansheeEngine
 		SPtr<PooledRenderTexture> newTextureData = bs_shared_ptr_new<PooledRenderTexture>(this);
 		_registerTexture(newTextureData);
 
-		RENDER_SURFACE_CORE_DESC surfaceDesc;
-		surfaceDesc.texture = TextureCoreManager::instance().createTexture(TEX_TYPE_2D, width, height, 1, 0, 
+		newTextureData->texture = TextureCoreManager::instance().createTexture(TEX_TYPE_2D, width, height, 1, 0,
 			format, depth ? TU_DEPTHSTENCIL : TU_RENDERTARGET, hwGamma, samples);
-		surfaceDesc.face = 0;
-		surfaceDesc.mipLevel = 0;
-
-		RENDER_TEXTURE_CORE_DESC desc;
-		if (!depth)
-			desc.colorSurface = surfaceDesc;
-		else
-			desc.depthStencilSurface = surfaceDesc;
-
-		newTextureData->texture = TextureCoreManager::instance().createRenderTexture(desc);
+		
 		return newTextureData;
 	}
 

+ 48 - 31
TODOExperimentation.txt

@@ -12,43 +12,59 @@ Lights need getLightMesh() method
 Load up and set up a test-bed with Ribek's scene
 Quantize buffer sizes so they're divideable by 8 when requesting them from RenderTexturePool
 
-Keep a list of all renderables per camera depending on their layer
- - This would be an optimization so I don't need to filter them every frame
- - I'd need to update this list when renderable is added/removed, when camera is added/removed and when layer is changed (camera's or renderable's)
-
-Before any rendering is done generate separate render queues for all elements
- - Iterate over all elements valid for the camera and perform frustum culling
- - Initially this would be different queues for transparent & opaque, but later there might be more types
- - Store these queues per-camera
- - Do the same for lights (separate them by type most likely)
- - Later:
-  - Extend render queues so they also sort by material (if needed, it should be easy to change sort order)
-  - Materials should be transformed into a set of material diffs (e.g. only set new shader, buffer, texture or cbuffer
-    if they don't match the previous material)
-	 - i.e. some elements in the render queue would be renderable elements (with no material info) and others
-	   would be material diffs that change the state
+R11G11B10 and R10G10B10A2 formats haven't been tested
+
+Make sure materials can generate unique "hash" values so I can quickly check if they're equal
+ - Generate unique ID for each shader (32bit)
+ - Limit state IDs to 10 bits
+ - Generate a combined 64bit hash value for the material using shader + 3 states
+
+Make GUI and Overlay render separately without using the main render queue
+ - Get rid of DrawList and make them render similar to how handles/gizmos do it
+ - They should render after everything else
+ - Disable depth test and depth write in their material
+ - Since most GUI elements share a material check if material changed from the last element and don't set new shaders/states otherwise
+   - (changing params and param buffers should still apply)
+   - Since I'm doing the rendering directly in GUIManager I can exactly control which states I modify
+
+Make scene grid rendering more akin to handle & gizmo rendering so I can remove the onRenderViewport callback
+ - Similar thing with dock manager
+
+Add material flag "transparent". 
+ - Priority is always applied within its transparent/opaque queue. Priority and sort order are kept as is. 
+ - Transparent flag just determines the rendering method. Later I can probably also add "animated" and similar.
+ - Depending on set flag populate two different render queues per camera (+ a special render queue for GUI and overlay)
+
+Rendering procedure should be:
+ - For each camera go over each renderable and determine if their layers match
+ - If they match do frustum culling
+ - Add renderables to opaque or transparent queue depending on material
+ - This should happen in renderAllCore before actual rendering starts
+ - When rendering bind gbuffer render targets and render opaque queue
+ - Unbind gbuffer and resolve to scene color
+ - Bind scene color and render transparent queue
+ - Resolve scene color to frame buffer (they could be the same target if no MSAA is used, and gamma correction is properly set)
+ - After rendering is done make sure to clear the queues so I don't hold invalid references
+
+Reduce state switching:
+ - Extend render queues so they compare material hash values and sort accordingly
+ - Add a flag that allows me to control whether the queue should prefer distance sort or material sort
+ - Extend entries output from render queue with a flag that signals that a material should be re-applied
+ - When rendering only apply new shaders & states when that flag is encountered
+ - Switch buffers, textures and sampler for each renderable (possibly ignoring static/per-frame/per-camera ones)
+
+Store RenderTargets per camera
+ - Only create it if camera is rendering some renderables
+ - If none are rendered clear the reference to free the targets
 
 Generate different RenderableController for each set of elements
  - Will likely want to rename current LitTexRenderableController to OpaqueSomething
  - Each controller would be connected to its own render queue (generated in above step)
  - Renderable controller should probably be notified when rendering starts/ends so it may bind gbuffer and/or other resoures.
 
-Create a class RenderTargets
- - ::create(CameraPtr)
- - ::bind (calls RenderTargetPool::get() and sets the render targets)
- - ::unbind (calls RenderTargetPool::free)
- - Holds references to PooledRenderTarget
-
-Store RenderTargets per camera
- - Only create it if camera is rendering some renderables
- - If none are rendered clear the reference to free the targets
-
-I sort rendering based on render targets so I don't need to rebind them
- - I should do something similar with GBuffers
- - First sort by GBuffers, then sort by output render targets
- - This means I'll need to find out what kind of gbuffers cameras need before rendering the camera
-   - Move the renderable by layer filtering in renderAll, or do it when renderers are updated (as described above)
-   - Don't actually allocate targets at this point to avoid allocating a lot of memory at once.
+Light queues:
+ - Will likely need to generate a set of visible lights per camera similar to renderables (separate them by type most likely)
+ - Will also need a set of renderables per light when rendering shadows
 
 --------------------------- DESIGN ---------------------------
 
@@ -67,6 +83,7 @@ How will cameras interact with the renderer? The cameras currently available sho
 Separate GUI rendering into a separate part to be rendered after gbuffer is resolved?
 
 Will likely need an easy way to determine supported feature set (likely just depending on shader model)
+
 Consider encapsulating shaders together with methods for setting their parameters (and possibly retrieving output)
  - So that external code doesn't need to know about its internal and do less work
  - This would contain a reference to the shader and its parameters