Jump to content

  • Log In with Google      Sign In   
  • Create Account


Whats the shader data a Material class holds?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
22 replies to this topic

#21 Icebone1000   Members   -  Reputation: 1050

Like
0Likes
Like

Posted 27 March 2013 - 09:04 AM

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);
	}
};

Edited by Icebone1000, 27 March 2013 - 09:14 AM.


Sponsor:

#22 JohnnyCode   Members   -  Reputation: 227

Like
0Likes
Like

Posted 28 March 2013 - 03:33 AM

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.



#23 Weton   Members   -  Reputation: 255

Like
0Likes
Like

Posted 30 March 2013 - 04:40 AM

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






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS