Jump to content
Site Stability Read more... ×
  • Advertisement
Sign in to follow this  
Hawkblood

Rendering a subset in DX11

This topic is 2018 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

How do I render only a select subset of a mesh in DX11?

I'm setting up the render like this:

void EFFECTMESH::Render(void){
	unsigned int stride;
	unsigned int offset;


	// Set vertex buffer stride and offset.
	stride = sizeof(NMVertex); 
	offset = 0;
    
	// Set the vertex buffer to active in the input assembler so it can be rendered.
	GE->devcon->IASetVertexBuffers(0, 1, &VB, &stride, &offset);

	// Set the index buffer to active in the input assembler so it can be rendered.
	GE->devcon->IASetIndexBuffer(IB, DXGI_FORMAT_R32_UINT, 0);

	// Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
	GE->devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}

and then I'm calling the shader. The entire mesh renders fine, but I want to render different parts with different shaders......

Share this post


Link to post
Share on other sites
Advertisement

You just have to call DrawIndexed with the correct IndexCount (the numbers of indices in the index buffer of the subset you want to draw) and StartIndexLocation (the position of the first index in the index buffer of the subset you want to draw). The other draw calls have similar arguments.

struct Subset
{
    uint index_count;
    uint start_index;
    Shader* shaders;
    Texture* textures;
    CBuffer* cbuffers;
};

void EFFECTMESH::Render(uint num_subsets, Subset* subsets){
	unsigned int stride;
	unsigned int offset;


	// Set vertex buffer stride and offset.
	stride = sizeof(NMVertex); 
	offset = 0;
    
	// Set the vertex buffer to active in the input assembler so it can be rendered.
	GE->devcon->IASetVertexBuffers(0, 1, &VB, &stride, &offset);

	// Set the index buffer to active in the input assembler so it can be rendered.
	GE->devcon->IASetIndexBuffer(IB, DXGI_FORMAT_R32_UINT, 0);

	// Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
	GE->devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

        for(uint i = 0; i < num_subsets; i++)
        {
            //Set correct shaders (subsets[i].shaders)
            //Bind correct textures (subsets[i].textures)
            //Bind correct cbuffers (subsets[i].cbuffers)

            //Draw current subset
            GE->devcon->DrawIndexed(subsets[i].index_count, subsets[i].start_index, 0);
        }
}
Edited by TiagoCosta

Share this post


Link to post
Share on other sites

Thanks, I was thinking I might have to create a separate index and vertex buffer for each subset. It's not exactly how you showed, but I got it to work for me. I'll post my finished code when I can make it look better (right now it's a mess).

Share this post


Link to post
Share on other sites

Ok. It looks a little more intelligent now:

void EFFECTMESH::PrimeRenderVB(void){
	unsigned int stride;
	unsigned int offset;
	// Set vertex buffer stride and offset.
	stride = sizeof(NMVertex); 
	offset = 0;
  	// Set the vertex buffer to active in the input assembler so it can be rendered.
	GE->devcon->IASetVertexBuffers(0, 1, &VB, &stride, &offset);
	// Set the index buffer to active in the input assembler so it can be rendered.
//	GE->devcon->IASetIndexBuffer(IB, DXGI_FORMAT_R32_UINT, 0);//this will be done in PrimeRenderIB(..)
	// Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
	GE->devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
void EFFECTMESH::PrimeRenderIB(int index){
	if (index>=NumSubsets) return;
	GE->devcon->IASetIndexBuffer(IB, DXGI_FORMAT_R32_UINT, indexInfo[index].iStart*sizeof(UINT));
	GE->devcon->DrawIndexed(indexInfo[index].iCount,indexInfo[index].iStart,0);
}

and to render the two subsets:

	EffectMesh[testMesh].PrimeRenderVB();

	EffectMesh[testMesh].PrimeRenderIB(0);
	worldMatrix=EffectMesh[testMesh].indexInfo[0].KeyframeMatrix[int(float((GE->Timer.TotalTime/1000)%500)/100.0f)];
	worldMatrix(3,2)+=190-camloc.z;
	worldMatrix(3,1)+=-40-camloc.y;
	worldMatrix(3,0)+=-camloc.x;
	if (!NMShader.Render(GE->devcon,EffectMesh[testMesh].indexInfo[0].iCount, worldMatrix, m_Camera->m_viewMatrix, projectionMatrix,TA)) tp1++;

	EffectMesh[testMesh].PrimeRenderIB(1);
	worldMatrix=EffectMesh[testMesh].indexInfo[1].KeyframeMatrix[int(float((GE->Timer.TotalTime/1000)%500)/100.0f)];
	worldMatrix(3,2)+=190-camloc.z;
	worldMatrix(3,1)+=-40-camloc.y;
	worldMatrix(3,0)+=-camloc.x;
	if (!NMShader.Render(GE->devcon,EffectMesh[testMesh].indexInfo[1].iCount, worldMatrix, m_Camera->m_viewMatrix, projectionMatrix,TA)) tp1++;

This works nicely for my purposes. I only "setup" the common stuff once with PrimeRenderVB() and then I render each subset with PrimeRenderIB() and the appropriate shader.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!