Shader doesn't store context?

I’ve got a shader where I set the normal map using EffectParameterCollection:

_effectsParams["NormalTexture"].SetValue(image.NormalMap);

however when it renders the image, it always uses the current contents of _effectsParams, not the contents when Draw(…) was called. It doesn’t seem like SpriteBatch saves the contents of the EffectParameterCollection as the context of the Draw call.

The result of this is that everything is drawn correctly if I use SpriteSortMode.Immediate, unfortunately I am drawing a lot of sprites and Immediate is pretty slow. I’d like to use one of the faster sort modes like SpriteSortMode.BackToFront or Deffered, unfortunately every image in those cases is rendered using the NormalTexture map of the last image.

I’ve attached a screenshot to give an idea of what’s going on… I’ve got the base goblin, and then I want to swap out of the weapons and armor as needed. What’s going on in this image is the SpriteSortMode is set to Deferred, and the weapons & armor are being rendered incorrectly with the normal map from the goblin instead of the correct one.

Am I doing something wrong? Anyone have any ideas?

If anyone would like to see the code, it’s the Draw method in this class:
RenderBuddy.cs

and the shader itself:
AnimationBuddyShader.fx

This looks like its over my head but I might guess that the shader isn’t actually applied until End is called - so if there are other draws using the same shader with different parameter settings or normal maps, it will keep getting changed to the current one until End is called. I dunno. Maybe you could put all the normal maps on 1 sheet and go by uv-coords? (if I understand correctly)

Yup, that is exactly what is happening :slight_smile:

Yeah, putting everything in one big texture would work, but it’s not ideal… like in the goblin example, as I add different types of goblin it’s going to load one giant texture with a bunch of image I am probably not going to need. Thanks for taking a look though, that is a potential fix.

On a related note, when I try to change that shader to:
#if OPENGL #define VS_SHADERMODEL vs_3_0 #define PS_SHADERMODEL ps_3_0 #else #define VS_SHADERMODEL vs_5_0 //changed from vs_4_0_level_9_3 #define PS_SHADERMODEL ps_5_0 //changed from ps_4_0_level_9_3 #endif

I get the following error at startup:
SharpDX.SharpDXException: 'HRESULT: [0x80070057], Module: [General], ApiCode: [E_INVALIDARG/Invalid Arguments], Message: The parameter is incorrect.

I googled around and found an answer to set GraphicsProfile = GraphicsProfile.HiDef but that didn’t fix it :frowning: