Browse Source

Render system now allows you to set multiple vertex buffers at once

Marko Pintera 12 years ago
parent
commit
a659b5bac7

+ 0 - 18
CamelotCore/Include/CmCoreThreadAccessor.h

@@ -81,24 +81,6 @@ namespace CamelotFramework
 			mCommandQueue->queue(boost::bind(&RenderSystem::setViewport, RenderSystem::instancePtr(), vp));
 			mCommandQueue->queue(boost::bind(&RenderSystem::setViewport, RenderSystem::instancePtr(), vp));
 		}
 		}
 
 
-		/** @copydoc RenderSystem::setVertexBuffer() */
-		void setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer)
-		{
-			mCommandQueue->queue(boost::bind(&RenderSystem::setVertexBuffer, RenderSystem::instancePtr(), index, buffer));
-		}
-
-		/** @copydoc RenderSystem::setIndexBuffer() */
-		void setIndexBuffer(const IndexBufferPtr& buffer)
-		{
-			mCommandQueue->queue(boost::bind(&RenderSystem::setIndexBuffer, RenderSystem::instancePtr(), buffer));
-		}
-
-		/** @copydoc RenderSystem::setVertexDeclaration() */
-		void setVertexDeclaration(VertexDeclarationPtr vertexDeclaration)
-		{
-			mCommandQueue->queue(boost::bind(&RenderSystem::setVertexDeclaration, RenderSystem::instancePtr(), vertexDeclaration));
-		}
-
 		/** @copydoc RenderSystem::setDrawOperation() */
 		/** @copydoc RenderSystem::setDrawOperation() */
 		void setDrawOperation(DrawOperationType op)
 		void setDrawOperation(DrawOperationType op)
 		{
 		{

+ 2 - 2
CamelotCore/Include/CmRenderSystem.h

@@ -157,9 +157,9 @@ namespace CamelotFramework
 		*/
 		*/
 		virtual void setViewport(const ViewportPtr& vp) = 0;
 		virtual void setViewport(const ViewportPtr& vp) = 0;
 
 
-		/** Sets the current vertex buffer for the specified source index.   
+		/** Sets the provided vertex buffers starting at the specified source index.   
 		/** @note Set buffer to nullptr to clear the buffer at the specified index.*/
 		/** @note Set buffer to nullptr to clear the buffer at the specified index.*/
-		virtual void setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer) = 0;
+		virtual void setVertexBuffers(UINT32 index, VertexBufferPtr* buffers, UINT32 numBuffers) = 0;
 
 
 		/**
 		/**
 		 * @brief	Sets an index buffer to use when drawing. Indices in an index buffer
 		 * @brief	Sets an index buffer to use when drawing. Indices in an index buffer

+ 2 - 0
CamelotCore/Include/CmRenderSystemCapabilities.h

@@ -46,6 +46,8 @@ THE SOFTWARE.
 #define CAPS_CATEGORY_MASK (((1 << CAPS_CATEGORY_SIZE) - 1) << CM_CAPS_BITSHIFT)
 #define CAPS_CATEGORY_MASK (((1 << CAPS_CATEGORY_SIZE) - 1) << CM_CAPS_BITSHIFT)
 #define CM_CAPS_VALUE(cat, val) ((cat << CM_CAPS_BITSHIFT) | (1 << val))
 #define CM_CAPS_VALUE(cat, val) ((cat << CM_CAPS_BITSHIFT) | (1 << val))
 
 
+#define MAX_BOUND_VERTEX_BUFFERS 32
+
 namespace CamelotFramework 
 namespace CamelotFramework 
 {
 {
 	/** \addtogroup Core
 	/** \addtogroup Core

+ 22 - 2
CamelotCore/Source/CmRenderSystem.cpp

@@ -229,8 +229,28 @@ namespace CamelotFramework {
 		setVertexDeclaration(subMesh.vertexData->vertexDeclaration);
 		setVertexDeclaration(subMesh.vertexData->vertexDeclaration);
 		auto vertexBuffers = subMesh.vertexData->getBuffers();
 		auto vertexBuffers = subMesh.vertexData->getBuffers();
 
 
-		for(auto iter = vertexBuffers.begin(); iter != vertexBuffers.end() ; ++iter)
-			setVertexBuffer(iter->first, iter->second);
+		if(vertexBuffers.size() > 0)
+		{
+			VertexBufferPtr buffers[MAX_BOUND_VERTEX_BUFFERS];
+
+			UINT32 endSlot = 0;
+			UINT32 startSlot = MAX_BOUND_VERTEX_BUFFERS;
+			for(auto iter = vertexBuffers.begin(); iter != vertexBuffers.end() ; ++iter)
+			{
+				if(iter->first >= MAX_BOUND_VERTEX_BUFFERS)
+					CM_EXCEPT(InvalidParametersException, "Buffer index out of range");
+
+				startSlot = std::min(iter->first, startSlot);
+				endSlot = std::max(iter->first, endSlot);
+			}
+
+			for(auto iter = vertexBuffers.begin(); iter != vertexBuffers.end() ; ++iter)
+			{
+				buffers[iter->first - startSlot] = iter->second;
+			}
+
+			setVertexBuffers(startSlot, buffers, endSlot - startSlot + 1);
+		}
 
 
 		setDrawOperation(subMesh.drawOp);
 		setDrawOperation(subMesh.drawOp);
 
 

+ 1 - 1
CamelotD3D11RenderSystem/Include/CmD3D11RenderSystem.h

@@ -45,7 +45,7 @@ namespace CamelotFramework
 		void setViewport(const ViewportPtr& vp);
 		void setViewport(const ViewportPtr& vp);
 		void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom);
 		void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom);
 
 
-		void setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer);
+		void setVertexBuffers(UINT32 index, VertexBufferPtr* buffers, UINT32 numBuffers);
 		void setIndexBuffer(const IndexBufferPtr& buffer);
 		void setIndexBuffer(const IndexBufferPtr& buffer);
 		void setVertexDeclaration(VertexDeclarationPtr vertexDeclaration);
 		void setVertexDeclaration(VertexDeclarationPtr vertexDeclaration);
 		void setDrawOperation(DrawOperationType op);
 		void setDrawOperation(DrawOperationType op);

+ 14 - 8
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -331,22 +331,28 @@ namespace CamelotFramework
 		mDevice->getImmediateContext()->RSSetViewports(1, &mViewport);
 		mDevice->getImmediateContext()->RSSetViewports(1, &mViewport);
 	}
 	}
 
 
-	void D3D11RenderSystem::setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer)
+	void D3D11RenderSystem::setVertexBuffers(UINT32 index, VertexBufferPtr* buffers, UINT32 numBuffers)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		UINT32 maxBoundVertexBuffers = mCurrentCapabilities->getMaxBoundVertexBuffers();
 		UINT32 maxBoundVertexBuffers = mCurrentCapabilities->getMaxBoundVertexBuffers();
-		if(index < 0 || index >= maxBoundVertexBuffers)
+		if(index < 0 || (index + numBuffers) >= maxBoundVertexBuffers)
 			CM_EXCEPT(InvalidParametersException, "Invalid vertex index: " + toString(index) + ". Valid range is 0 .. " + toString(maxBoundVertexBuffers - 1));
 			CM_EXCEPT(InvalidParametersException, "Invalid vertex index: " + toString(index) + ". Valid range is 0 .. " + toString(maxBoundVertexBuffers - 1));
 
 
-		ID3D11Buffer* buffers[1];
-		D3D11VertexBuffer* vertexBuffer = static_cast<D3D11VertexBuffer*>(buffer.get());
-		buffers[0] = vertexBuffer->getD3DVertexBuffer();
+		ID3D11Buffer* dx11buffers[MAX_BOUND_VERTEX_BUFFERS];
+		UINT32 strides[MAX_BOUND_VERTEX_BUFFERS];
+		UINT32 offsets[MAX_BOUND_VERTEX_BUFFERS];
 
 
-		UINT32 strides[1] = { buffer->getVertexSize() };
-		UINT32 offsets[1] = { 0 };
+		for(UINT32 i = 0; i < numBuffers; i++)
+		{
+			D3D11VertexBuffer* vertexBuffer = static_cast<D3D11VertexBuffer*>(buffers[i].get());
+			dx11buffers[i] = vertexBuffer->getD3DVertexBuffer();
+
+			strides[i] = buffers[i]->getVertexSize();
+			offsets[i] = 0;
+		}
 
 
-		mDevice->getImmediateContext()->IASetVertexBuffers(index, 1, buffers, strides, offsets);
+		mDevice->getImmediateContext()->IASetVertexBuffers(index, numBuffers, dx11buffers, strides, offsets);
 	}
 	}
 
 
 	void D3D11RenderSystem::setIndexBuffer(const IndexBufferPtr& buffer)
 	void D3D11RenderSystem::setIndexBuffer(const IndexBufferPtr& buffer)

+ 2 - 2
CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h

@@ -79,9 +79,9 @@ namespace CamelotFramework
 		void bindGpuParams(GpuProgramType gptype, BindableGpuParams& params);
 		void bindGpuParams(GpuProgramType gptype, BindableGpuParams& params);
 
 
 		/**
 		/**
-		 * @copydoc RenderSystem::setVertexBuffer()
+		 * @copydoc RenderSystem::setVertexBuffers()
 		 */
 		 */
-		void setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer);
+		void setVertexBuffers(UINT32 index, VertexBufferPtr* buffers, UINT32 numBuffers);
 
 
 		/**
 		/**
 		 * @copydoc RenderSystem::setIndexBuffer()
 		 * @copydoc RenderSystem::setIndexBuffer()

+ 21 - 17
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -1215,33 +1215,37 @@ namespace CamelotFramework
 
 
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
-	void D3D9RenderSystem::setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer)
+	void D3D9RenderSystem::setVertexBuffers(UINT32 index, VertexBufferPtr* buffers, UINT32 numBuffers)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		UINT32 maxBoundVertexBuffers = mCurrentCapabilities->getMaxBoundVertexBuffers();
 		UINT32 maxBoundVertexBuffers = mCurrentCapabilities->getMaxBoundVertexBuffers();
-		if(index < 0 || index >= maxBoundVertexBuffers)
+		if(index < 0 || (index + numBuffers) > maxBoundVertexBuffers)
 			CM_EXCEPT(InvalidParametersException, "Invalid vertex index: " + toString(index) + ". Valid range is 0 .. " + toString(maxBoundVertexBuffers - 1));
 			CM_EXCEPT(InvalidParametersException, "Invalid vertex index: " + toString(index) + ". Valid range is 0 .. " + toString(maxBoundVertexBuffers - 1));
 
 
 		HRESULT hr;
 		HRESULT hr;
-		if(buffer != nullptr)
-		{
-			D3D9VertexBuffer* d3d9buf = static_cast<D3D9VertexBuffer*>(buffer.get());
 
 
-			hr = getActiveD3D9Device()->SetStreamSource(
-				static_cast<UINT>(index),
-				d3d9buf->getD3D9VertexBuffer(),
-				0,
-				static_cast<UINT>(d3d9buf->getVertexSize()) // stride
-				);
-		}
-		else
+		for(UINT32 i = 0; i < numBuffers; i++)
 		{
 		{
-			hr = getActiveD3D9Device()->SetStreamSource(static_cast<UINT>(index), nullptr, 0, 0);
-		}
+			if(buffers[i] != nullptr)
+			{
+				D3D9VertexBuffer* d3d9buf = static_cast<D3D9VertexBuffer*>(buffers[i].get());
+
+				hr = getActiveD3D9Device()->SetStreamSource(
+					static_cast<UINT>(index + i),
+					d3d9buf->getD3D9VertexBuffer(),
+					0,
+					static_cast<UINT>(d3d9buf->getVertexSize()) // stride
+					);
+			}
+			else
+			{
+				hr = getActiveD3D9Device()->SetStreamSource(static_cast<UINT>(index + i), nullptr, 0, 0);
+			}
 
 
-		if (FAILED(hr))
-			CM_EXCEPT(RenderingAPIException, "Unable to set D3D9 stream source for buffer binding");
+			if (FAILED(hr))
+				CM_EXCEPT(RenderingAPIException, "Unable to set D3D9 stream source for buffer binding");
+		}
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	void D3D9RenderSystem::setIndexBuffer(const IndexBufferPtr& buffer)
 	void D3D9RenderSystem::setIndexBuffer(const IndexBufferPtr& buffer)

+ 2 - 2
CamelotGLRenderer/Include/CmGLRenderSystem.h

@@ -62,9 +62,9 @@ namespace CamelotFramework {
         void setRenderTarget(RenderTargetPtr target);
         void setRenderTarget(RenderTargetPtr target);
 
 
         /**
         /**
-		 * @copydoc RenderSystem::setVertexBuffer()
+		 * @copydoc RenderSystem::setVertexBuffers()
 		 */
 		 */
-		void setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer);
+		void setVertexBuffers(UINT32 index, VertexBufferPtr* buffers, UINT32 numBuffers);
 
 
 		/**
 		/**
 		 * @copydoc RenderSystem::setIndexBuffer()
 		 * @copydoc RenderSystem::setIndexBuffer()

+ 5 - 2
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -653,11 +653,14 @@ namespace CamelotFramework
 		unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
 		unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
-	void GLRenderSystem::setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer)
+	void GLRenderSystem::setVertexBuffers(UINT32 index, VertexBufferPtr* buffers, UINT32 numBuffers)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
-		mBoundVertexBuffers[index] = buffer;
+		for(UINT32 i = 0; i < numBuffers; i++)
+		{
+			mBoundVertexBuffers[index + i] = buffers[i];
+		}
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	void GLRenderSystem::setVertexDeclaration(VertexDeclarationPtr vertexDeclaration)
 	void GLRenderSystem::setVertexDeclaration(VertexDeclarationPtr vertexDeclaration)