Sign in to follow this  
lukesmith123

Loading Shaders for multiple models

Recommended Posts

When using a shader .fx file for multiple models do I need to load it each time for each models. For instance in my custom model class load the shader and render the model with that shader rather than loading the shader once in my main class and then render each model with the one effect? I tried doing the latter and I had a problem because the world matrix for each model is different.

Also how does all of this relate to the ppEffectInstances argument of the D3DXLoadMeshFromX function?

Share this post


Link to post
Share on other sites
You don't need to load an effect for each model if you don't want to. However you [i]will[/i] need to set all per-mesh parameters (like textures, material colors, etc.) each time you use that effect to render a model. If you create multiple effects (or clone an effect for each mesh) then you can set those per-mesh and per-material parameters once at load time.

As far as the EffectInstances stuff, an X file has the capability to store data indicating a .fx file to use for a material as well as a bunch of properties to set onto that effect. So for instance if you had a diffuse color property, it will have a D3DXEFFECTDEFAULT containing the name "DiffuseColor" and 3 or 4 floats representing the actual value. Then when you load the effect, you can set the value of those parameters to the value in the .X file. However most .X files don't have this information and will just have the "standard" material data instead (the stuff you get in the D3DXMATERIAL buffer).

Share this post


Link to post
Share on other sites
The thing is when I just load one effect and try to use it for all my models, each model is rendered at the world position of the last model in the list.

What I'm doing is making a function in my model class for SetShader(Shader shader); so I can make create the shader in my main class and pass in the shader to each of my models.

So in the model update function I pass in the view and projection and set the world view and projection parameters.

Then in the models draw function, before and after the drawsubset function is called I call Begin and end functions of my shader which has the effects Begin() and BeginPass() and End() / EndPass() functions.

Any Idea what I'm doing wrong here?



Share this post


Link to post
Share on other sites
[quote name='lukesmith123' timestamp='1312820993' post='4846234']
The thing is when I just load one effect and try to use it for all my models, each model is rendered at the world position of the last model in the list.
[/quote]

then for each model set the model dependant data IE
set the texture
set the world matrix
set light
etc

problem gone.
:) :) :)

Share this post


Link to post
Share on other sites
EDIT:

Yeah I was doing that, It seems my problem was because I was trying to set things like position of my models before adding them to a std::list but I need to go through the list and set the the positions and stuff afterwards.

Share this post


Link to post
Share on other sites
Sorry I thought I had figured this out but I hadnt.

All the models are using the last model in the lists world matrix.

Im passing the the shader to each of my models in a setShader function.

Then in the relevant functions in the model class the parameters are set.

and in my game class I loop through the list of models and call the functions.

Ive tried putting the models in an array as well and I have the same problem.

I presume it would be a huge waste of memory to create a new shader instance for each model if say I had 100 models.

note also that I'm using directX 9

Please help! thanks.

Share this post


Link to post
Share on other sites
Ok so I guess I need to post some code. Ive taken out some bits that arent relevant to try to keep the size down.

This is from Model class,

[code]void Model::Update(D3DXMATRIX mView, D3DXMATRIX mProjection, Shader s)
{
D3DXMATRIX matScale;
D3DXMATRIX matRotateX;
D3DXMATRIX matRotateY;
D3DXMATRIX matRotateZ;
D3DXMATRIX matTranslate;

D3DXMatrixScaling(&matScale,scale.x,scale.y,scale.z);
D3DXMatrixRotationX(&matRotateX,D3DXToRadian(rotation.x));
D3DXMatrixRotationY(&matRotateY,D3DXToRadian(rotation.y));
D3DXMatrixRotationZ(&matRotateZ,D3DXToRadian(rotation.z));
D3DXMatrixTranslation(&matTranslate, position.x, position.y, position.z);

matWorld = matRotateX * matRotateY * matRotateZ * matScale * matTranslate;


s.SetMatrix("World", matWorld);
s.SetMatrix("View", mView);
s.SetMatrix("Projection", mProjection);
}

void Model::Render(Shader s)
{

for (DWORD i=0; i<numMaterials; i++)
{

s.SetTexture("ModelTexture", meshTextures[i]);

s.Begin();
mesh->DrawSubset( i );
s.End();
}
}
[/code]

And this is from the Game clas I suspect the problem is in here with putting the models in a std::list

[code]void Game::LoadObjects()
{
Model floors;
floors.SetDevice(device);
floors.Initialize();
floors.SetPosition(0,-10,0);
floors.SetScale(5,5,5);
floors.LoadContent("Content//Models//floor.x");

Model walls;
walls.SetDevice(device);
walls.Initialize();
walls.SetPosition(0,-10,0);
walls.SetScale(5,5,5);
walls.LoadContent("Content//Models//walls.x");



modelList.push_back(floors);
modelList.push_back(walls);


}


void Game::Update(float dt)
{

list<Model>::const_iterator it;
for(it=modelList.begin(); it!=modelList.end(); ++it)
{
it._Mynode()->_Myval.Update(camera.matView, camera.matProjection, ModelEffect);
}

}

void Game::Draw(float dt)
{
list<Model>::const_iterator it;
for(it=modelList.begin(); it!=modelList.end(); ++it)
{
it._Mynode()->_Myval.Render(ModelEffect);
}
}
[/code]

Does anything look wrong there? If not I'll edit it and post the entire classes. Thanks so much.

Share this post


Link to post
Share on other sites
As far as I can see, you are setting the shading parameters for all the models one after another without rendering anything, effectively overwriting the previous parameters. Than you start rendering, but of course now the parameters for the last model are set. Do the SetMatrix() stuff just before you render the model.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this