Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to get a model rendered in monogame using a texture shader. I'm using the code from this tutorial project: http://kgiannakakis.github.io/MonoGameEffects/

I created a simple textured cube using Wings3D with it's own texture and saved it as cube.x. With no modified code, the 'BasicEffect' shows the cube with the texture as defined in the 3D model file. Switching to the 'Textured' effect, the cube is textured with the helicopter texture. Now I completely understand this is because the texture is passed to the TexturedEffect 'texture' parameter.

My question is, how to modify the shader or the code to use the texture as defined by the mesh? My goal is to have a model passed to a draw function without having to pass the textures (as I have no idea how to match the textures to the parts- also these seem to be present in the model's data anyway).

I tried two things (both without the desired result): 1: modify the shader. I expected the texture to be passed in a register:

Modified section in Textured.fx:

sampler2D textureSampler = sampler_state {
    Texture = (register(s0));
    MinFilter = Linear;
    MagFilter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

Why did I try s0? Because I assumed based on experience with 2D shader this would be the texture passed by the draw call (also based on this question: http://stackoverflow.com/questions/7617424/some-simple-xna-hlsl-questions) I am not sure this assumption is correct for 3D models (apparently not).

The other thing I tried: I noticed that the basicEffect.Texture was set on the mesh part. So in the code:

private void DrawModelWithTexturedEffect(Model model, Matrix world, Matrix view, Matrix projection)
    {
        foreach (ModelMesh mesh in model.Meshes)
        {
            foreach (ModelMeshPart part in mesh.MeshParts)
            {

                texturedEffect.Parameters["World"].SetValue(world * mesh.ParentBone.Transform);
                texturedEffect.Parameters["View"].SetValue(view);
                texturedEffect.Parameters["Projection"].SetValue(projection);
                texturedEffect.Parameters["ViewVector"].SetValue(viewVector);
                texturedEffect.Parameters["ModelTexture"].SetValue(part.Effect.Parameters["Texture"].GetValueTexture2D());

                Matrix worldInverseTransposeMatrix = Matrix.Transpose(Matrix.Invert(mesh.ParentBone.Transform * world));
                texturedEffect.Parameters["WorldInverseTranspose"].SetValue(worldInverseTransposeMatrix);

                part.Effect = texturedEffect;
            }
            mesh.Draw();
        }
    }

I tried extracting the texture from the mesh.effect, but I could not retrieve it (debugger shows it is there) as I cannot seem to cast the part.Effect to a BasicEffect? edit I found the above code to work the first call only; as the part.Effect has been replaced by the last last call of the loop. Still, the question remains, how to deal with textures and models?

So what is the best way to get this to work? The samples I found work with older XNA and older shader models that do not seem to compile with Monogame (for example Riemers or Whitakers).

share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.