Whats the shader data a Material class holds?

Started by
21 comments, last by Weton 11 years ago

high lvl object data -> cbuffer data -> update subresource (data being copied)

This also annoys me, on a higer lvl I end up working with more readable/manageable data, instead of using cbuffer raw data, so I end up having a update that copies data to cbuffer and then copies data to ID3D11Buffer..Is it viable to work straight on a cbuffer data so that you dont need to copy data to it?[edit] answered on previous post[/edit]

Im doing this way (my system is "working", but its barely tested (got things rendering yesterday), so it might be really lame and full of yet to detect bugs):

my cbuffer class:


#pragma once

// system/standard headers

#include <D3D11.h>
#include <boost/smart_ptr.hpp>

namespace render{

	//========================================================================
	// holds CBs actual data(values)
	//========================================================================
	class ConstantBuffer{

		typedef UINT byteoffset;

		UINT m_nBytes;
		UINT m_nVariables;

		boost::scoped_array<BYTE> m_variablesBuffer;
		boost::scoped_array<byteoffset> m_variablesOffsets;
		boost::scoped_array<UINT> m_variablesSizes;

		bool m_bNeedUpdate;	// used to check if it needs update to the pipeline

	public:

		//------------------------------------------------------------------------
		// ctor
		//------------------------------------------------------------------------
		ConstantBuffer( const UINT size_p, const UINT nVariables_p, const UINT * pVariablesSizes_p )
			:	m_variablesBuffer(new BYTE[size_p]()),
				m_variablesOffsets(new byteoffset[nVariables_p]),
				m_variablesSizes(new UINT[nVariables_p]){

			m_nBytes = size_p;
			m_nVariables = nVariables_p;
			m_bNeedUpdate = false;

			UINT iOffsetCache = 0;
			for( UINT it = 0; it < m_nVariables; ++it ){

				m_variablesOffsets[it] = iOffsetCache;
				m_variablesSizes[it] = pVariablesSizes_p[it];

				iOffsetCache += m_variablesSizes[it];
			}
		}
		
		UINT GetSize() const{
			return m_nBytes;
		}

		//------------------------------------------------------------------------
		// Set variable by index
		//------------------------------------------------------------------------
		void SetVariable( UINT index_p, const BYTE* data_p ){

			memcpy( &m_variablesBuffer[ m_variablesOffsets[index_p] ], data_p, m_variablesSizes[index_p] );
			m_bNeedUpdate = true;
		}

		//------------------------------------------------------------------------
		// Set the entire buffer at once
		//------------------------------------------------------------------------
		void Set( const BYTE * data_p ){

			memcpy( m_variablesBuffer.get(), data_p, m_nBytes );
			m_bNeedUpdate = true;
		}

		//------------------------------------------------------------------------
		// Test if buffer data was modified since last update call, than updates it,
		// or not.
		//------------------------------------------------------------------------
		void Update( ID3D11DeviceContext * pContext_p, ID3D11Buffer *& pConstantBuffer_p ){

			if( m_bNeedUpdate ){

				pContext_p->UpdateSubresource( pConstantBuffer_p, 0, NULL, m_variablesBuffer.get(), 0, 0 );
				m_bNeedUpdate = false;
			}
		}
	};

	typedef boost::shared_ptr<ConstantBuffer> shared_CBuffer_ptr;
}

Then my binder cbuff command :


class BindVSConstantBuffer : public Binder{

	UINT m_iStartSlot;
	ID3D11Buffer *m_pConstantBuffer;
	boost::shared_ptr<render::ConstantBuffer> m_pConstantBufferData;

public:

	BindVSConstantBuffer( UINT iSlot_p, ID3D11Buffer *pConstantBuffers_p,  const boost::shared_ptr<render::ConstantBuffer> & pConstBufferData_p )
		:
	  Binder( 1LL << (E_VS_CBuffer0 + iSlot_p), E_BIND(E_VS_CBuffer0 + iSlot_p) ),
	  m_iStartSlot( iSlot_p ), m_pConstantBuffer( pConstantBuffers_p ),
	  m_pConstantBufferData(pConstBufferData_p){

		  assert( iSlot_p < 4);	// handling up to 4 cbuffers slot
	  }
	 
	//------------------------------------------------------------------------
	// Updates data to the buffer before binding it.
	//------------------------------------------------------------------------
	virtual void Execute( ID3D11DeviceContext * pDeviceContext_p ){

		m_pConstantBufferData->Update( pDeviceContext_p, m_pConstantBuffer );

		pDeviceContext_p->VSSetConstantBuffers( m_iStartSlot, 1, &m_pConstantBuffer);
	}
};
Advertisement

I was very messed on this issue in my renderer and still could not come up with tidy solution.

Material is somehow much connected to the geometry.

I have a CShader class, it contains informations:

1- vertex declaration

2- compiled shader

then CMesh class that contains:

1-Vertex/Index Buffers

2- texture information

3- Cshader to use with the mesh (precisely 1)

Then in rendering, draw method of the CMesh looks up the vertex declaration of CShader instance and bounds vertex buffers streams accordingly, you have to assure CMesh has all of the streams vertex declaration asks though. Then textures are bound according to material ids. Then Scene Node info is passed to uniform data... and I draw. I also wrote more Render methods for CMesh if I needed to display it with another material, like RenderShadowVolume, or RenderDefferedLight(CLight) - this one is used only on screen aligned quad to render lightning after front passes.... and so on. I think that rendering instructions are so volatile that any "think for me" leads to no help.

class ConstantBuffer

I did it almost exacly the same, but I'm not completly happy with it:

I pack all the data for one object together and build a reflection of the object (name->offset array) and a buffer reflection (name->offset&size), from which I create something like a copy-instruction (arrays of sourcOffset, destinationOffset, dataSize) which copys all the data from the source offset to the buffer offset.

But it is all a bit messy right now...sad.png

This topic is closed to new replies.

Advertisement