Jump to content
  • Advertisement
Sign in to follow this  
piluve

OpenGL Using same material with different params.

This topic is 771 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

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 this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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

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!