This first part would go in the docs:
Because of the changed syntax for
declaring and using samplers since Direct3D10 the MonoGame Team
recommends handling samplers and textures in one of the following
three ways. This ensures that your shaders will work the same as in XNA
and that they'll work when they are
automatically translated to GLSL. With the first two options you
have explicit textures and should set them via the EffectParameters of
your effect. E.g. myEffect.Parameters["MyTexture"].SetValue(myTexture)
.
With the third option you can only set textures on the GraphicsDevice
by their texture slot i.e. graphicsDevice.Textures[myTextureSlot] = myTexture
.
Bind the Texture to a sampler using the sampler_state
syntax.
This guarantees you'll have an EffectParameter in your Effect
for your Texture with the name of the texture. If you do not
specify the texture name in a sampler_state
declaration explicitly
but rely on the texture register matching the sampler register, we
cannot identify the name of the texture due to effect compiler limitations
and no EffectParameter will be available. Therefore this is not recommended.
Example: In HLSL
Texture2D MyTexture;
sampler MySampler = sampler_state
{
Texture = (MyTexture);
... // optional other sampler state
};
In C# game code
myEffect.Parameters["MyTexture"].SetValue(myTexture);
Since D3D10 the bound Texture is no longer part of the sampler state. It allows to use one sampler to sample different textures in a shader. There are no restrictions when using this syntax. It is recommended however to not mix the new and old syntax for samplers.
Example: In HLSL
Texture2D MyTexture;
sampler MySampler = sampler_state // sampler_state is optional
{
... // sampler state here
}
In C# game code
myEffect.Parameters["MyTexture"].SetValue(myTexture);
You do not have to declare textures. If you bind your sampler to a register, you can set the corresponding texture through the API by specifying the texture slot instead of a name.
Example: In HLSL
sampler MySampler : register(s3);
In C# game code
graphicsDevice.Textures[3] = myTexture;
[NOT IN THE DOCS]
How we can actually achieve this: only generate a texture parameter if the sampler state has a texture bound!
if (sampler state has texture bound)
[generate texture parameter with the texture name]
else if (sampler register is not explicitly set)
[Optionally, we can generate texture parameter with sampler name so the user can reliably set the sampler texture] // I think it's better if we don't do this, users shouldn't only declare a sampler and not explicitly set its register...
// Also this will probably cause issues when users use the new sampler syntax option above without setting a register.// EDIT: We definitely shouldn't do this! // If we do this we'll also have to generate EffectParameters with the sampler name when people use the // new syntax because we cannot differentiate between the samplers in the two cases!
else
[Don't generate a texture parameter, if users only declare a sampler and explicitly set the register they intend to bind textures to the corresponding registers, not use EffectParameter syntax!]
Notes:
- Textures used with the new syntax will get a parameter because we can find their name and slot through reflection
- EffectParameters will behave like in XNA except in the following case
Texture2D MyTexture : register(t0);
sampler MySampler : register(s0);
which is why it is explicitly advised against.