Site Stability Read more... ×

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.

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 on other sites

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;
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++)
{
//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 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 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.

• Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 11
• 15
• 21
• 26
• 11