# OpenGL Using same material with different params.

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

## Recommended Posts

Hello!

I have been working a bit with DX12 the last week and I encountered a problem.

I came from an OpenGL background so let me give you an example:

In opengl I could "use" a material and then use that material to render multiple geometries,I coul also change the params of the material (uniforms) between Draw calls.

With DX12 I also have 1 material that I would like to use for multiple geometries:

void Terrain::Render(ID3D12GraphicsCommandList* cmdList)
{
m_material->Use(cmdList);
for (unsigned int i = 0; i < m_chunks.size(); i++)
{
m_material->SetModel(m_chunks[i]->GetModel());
m_chunks[i]->Render(m_material->mCbvHeap);
}
}
void Material::SetModel(XMFLOAT4X4 model)
{
m_objConstantsData.Model = model;
mObjectCB->CopyData(0, m_objConstantsData);
}

The problem is,that the geometry is being rendered with the last applyed model, and I understand that.

Because I am recording to the Command List it will keep the last applied model.

How can I solve this?

See you!

##### Share on other sites

D3D12 requires that you manage the memory manually, which basically means not overwriting memory that may be in flight. You could start by creating a ring buffer for all of your constants data, and every time you change data in a Material, suballocate the amount of memory you need from the ring buffer and patch into that - and remember to rebind the material with the appropriate offset for each draw!

edit:
I take this approach with dynamic vertex/index data too, rather than allocating lots of smaller buffers. Basically you're now responsible for a ton of the work that the GPU driver used to do for you.

Edited by Digitalfragment

##### Share on other sites

D3D12 requires that you manage the memory manually, which basically means not overwriting memory that may be in flight. You could start by creating a ring buffer for all of your constants data, and every time you change data in a Material, suballocate the amount of memory you need from the ring buffer and patch into that - and remember to rebind the material with the appropriate offset for each draw!

edit:
I take this approach with dynamic vertex/index data too, rather than allocating lots of smaller buffers. Basically you're now responsible for a ton of the work that the GPU driver used to do for you.

Hello and thanks for the reply!

What I understand, is that I should detect (by the material) when I change a param (in this case the model) during the current command recording, and if I change it, alloc more space for a new set of param(s).

Then when I use the material, I have to select the appropriate object constants?

Right now I´m doing:

m_material->Use(...)
foreach(Drawable d in m_drawables)
{
m_material->SetModel(...)
d->Draw(...)
}

So now,inside of "SetModel(...)" I should have a flag to check if I should allocate more params?

Also,how should I tell the pipeline to use the correct param?

This is the code I´m using to "Use" a material:

void Material::Use(ID3D12GraphicsCommandList* cmdList)
{
ID3D12DescriptorHeap* descriptorHeaps[] = { mCbvHeap };
cmdList->SetDescriptorHeaps(_countof(descriptorHeaps), descriptorHeaps);

cmdList->SetGraphicsRootSignature(mRootSignature);
}
Edited by piluve

1. 1
2. 2
3. 3
Rutin
18
4. 4
JoeJ
14
5. 5

• 14
• 10
• 23
• 9
• 47
• ### Forum Statistics

• Total Topics
632636
• Total Posts
3007573
• ### Who's Online (See full list)

There are no registered users currently online

×