Reputation: 1225
So I ended up writing my first HLSL Shader for MonoGame, and managed to somehow connect it to a Model I want to draw. So far so good. However the "somehow managed to do it code" is in my opinion ugly, and probably not the Intended way to achieve this:
internal Model(ContentManager content)
{
mModel = content.Load<Microsoft.Xna.Framework.Graphics.Model>("models/CustomModel");
// individual effect for individual models
var effect = content.Load<Effect>("effects/CustomEffect").Clone();
effect.Parameters["Texture"].SetValue(mModel.Meshes[0].MeshParts[0].Effect.Parameters["Texture"].GetValueTexture2D());
foreach (var mesh in mModel.Meshes)
{
foreach (var meshPart in mesh.MeshParts)
{
meshPart.Effect = effect;
}
}
}
As you can see I load in my Model and the effect individually and replace all the BasicEffects of the model with my newly loaded custom effect. And keep the old TextureVariable.
I'm for myself convinced that there's a more elegant solution to this, a solution that involves telling MonoGame to use CustomEffect instead of BasicEffect. I know that using the MGCB Tool I can specify a DefaultEffect for the ModelProcessor, however I haven't found out what I need to do so I can specify my effect there without the Game crashing and telling me that effects/CustomEffect isn't a valid effect.
So is there a better way to achieve the same goal my existing code does? And if so, how?
Upvotes: 0
Views: 514
Reputation:
Your solution is the primary one available, and the most flexible.
You do need to move the effect clone and parameter lines inside the foreach loop and change it to:
var effect = content.Load<Effect>("effects/CustomEffect").Clone();
effect.Parameters["Texture"].SetValue(meshPart.Effect.Parameters["Texture"].GetValueTexture2D());
Otherwise all parts of the model will use the same texture.
The lack of elegance is in the fact that this is a direct carry-over from the XNA
platform.
The other option is to make your parameters and semantics match those of BasicEffect
, at which point you should be able to set it in the Model Processor. The model processor expects the parameters exist and in that specific order.
Upvotes: 1
Reputation: 2123
Looks like every effect
has the same value, because it doesn't change in the for-loop.
So I think you can also define the effect
in the meshPart
instead. so you don't have to go through the for-loop for each individual one.
You can also create the effect in the Loadcontent
class in game1.cs, so you don't have to define it each time again.
I think that's it as far as I know.
Upvotes: 0