• Advertisement
Sign in to follow this  

C#/XNA Render Object Transforms Problem

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

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.

Share this post


Link to post
Share on other sites
Advertisement
I've literally spent a large chunk of the last four days banging my head against the wall with this and then I figure it out 20 minutes after posting on here for help.

Thanks to anyone who read this anyway.

The problem was solved by using the Effect.CommitChanges() function after setting the effect parameters in the render loop. I'm not sure if this is the preferred way of doing things it works for me at the moment.

Share this post


Link to post
Share on other sites
Quote:
Original post by Boonio
The problem was solved by using the Effect.CommitChanges() function after setting the effect parameters in the render loop. I'm not sure if this is the preferred way of doing things it works for me at the moment.


Nah that's fine, since you don't want to have to call Effect.Begin and Effect.End multiple times.

Share this post


Link to post
Share on other sites
So, are you saying that I wouldn't be required to BEGIN and END my effect if I'm using the same one on a different model - Only COMMITCHANGES?

Just a question...
Xy

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement