Hi,
I'm having a bit of a weird rendering problem and I really can't figure out what is going on.
I've made a Model class with a Render() function which takes as parameters a Matrix (for world transforms) a Material and an Effect. It works fine on a single model, but when I come to draw a list of objects it doesn't quite work right. For instance, Object 1 will sometimes end up using the transform Matrix that was passed to the Render function of Object 2 (i.e. be rotated the way object 1 should be) and vice versa. I'm obviously not resetting something or setting something I shouldn't be but I can't figure out what.
This is my Render function for the Model:
public void Render(Matrix _RenderMatrix, CoinMaterial _Material, CoinEffect _Effect)
{
// Check the model is valid
if (this.isValid == false)
return;
// Apply the object matrix
_RenderMatrix = ObjectMatrix * _RenderMatrix;
// TODO: Set the vertex decleration elsewhere
// VertexPositionNormalTexture vertex format used in temp shader
BaseGame.GraphicsManager.GraphicsDevice.VertexDeclaration = new VertexDeclaration(BaseGame.GraphicsManager.GraphicsDevice,
VertexPositionNormalTexture.VertexElements);
_Effect.SetMaterialParameters(_Material);
_Effect.GetXNAEffect.Begin();
// Loop through each effect pass
foreach (EffectPass pass in _Effect.GetXNAEffect.CurrentTechnique.Passes)
{
// Begin this pass
pass.Begin();
// Render all meshes
foreach (ModelMesh mesh in InternalXNAModel.Meshes)
{
// Setup the world matrix for each mesh
BaseGame.WorldMatrix = Transforms[mesh.ParentBone.Index] * _RenderMatrix;
_Effect.SetMatrixParameters();
// Render all mesh parts
foreach (ModelMeshPart part in mesh.MeshParts)
{
// Set the stream source
BaseGame.GraphicsManager.GraphicsDevice.Vertices[0].SetSource(mesh.VertexBuffer, part.StreamOffset, part.VertexStride);
BaseGame.GraphicsManager.GraphicsDevice.Indices = mesh.IndexBuffer;
// And render
BaseGame.GraphicsManager.GraphicsDevice.DrawIndexedPrimitives( PrimitiveType.TriangleList,
part.BaseVertex, 0, part.NumVertices,
part.StartIndex, part.PrimitiveCount);
}
}
pass.End();
}
_Effect.GetXNAEffect.End();
}
I'll paste the effect Effect.SetMaterialParameters() and Effect.SetMatrixParameters() functions too as I'm thinking it's something to do with them.
// Set the material parameters for the effect
public virtual void SetMaterialParameters(CoinMaterial _mat)
{
// Set all material properties
if (_mat != null)
{
ambientColor.SetValue(_mat.AmbientColour.ToVector4());
diffuseColor.SetValue(_mat.DiffuseColour.ToVector4());
specularColor.SetValue(_mat.SpecularColour.ToVector4());
specularPower.SetValue(_mat.SpecularPower); // TODO <<< Add specular power to materials
diffuseTexture.SetValue(_mat.DiffuseTexture);
//normalTexture = _mat.normalTexture;
}
}
// Set the Matrix parameters for the shader
public virtual void SetMatrixParameters()
{
if (worldViewProj != null)
worldViewProj.SetValue(BaseGame.WorldMatrix * BaseGame.ViewMatrix * BaseGame.ProjectionMatrix);
if (viewProj != null)
viewProj.SetValue(BaseGame.ViewMatrix * BaseGame.ProjectionMatrix);
if (world != null)
world.SetValue(BaseGame.WorldMatrix);
if (viewInverse != null)
viewInverse.SetValue(Matrix.Invert(BaseGame.ViewMatrix));
if (lightDir != null)
lightDir.SetValue(BaseGame.LightDirection);
// TODO ^^^^ Add proper lighting
}
A call example
TestModel.Render( Matrix.CreateScale(2.0f) * Matrix.CreateTranslation(new Vector3(0.0f, 0.0f, 0.0f)),
TestMaterial,
CoinShaders.SimpleShader);
Sorry for the code dump but I didn't really think it would make much sense without most of it.
Any help is much appreciated.
Thanks.