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 make a test with Effect class in XNA and I want to set multiple times the same parameters (MyParameter in below code).

My code is :

[...]
//In Engine class
Effect ShaderEffect = GameEngine.Instance.Content.Load<Effect>(@"shaders\test");

spriteBatch.Begin(
    SpriteSortMode.Deferred,
    BlendState.AlphaBlend,
    SamplerState.PointWrap,
    DepthStencilState.Default,
    RasterizerState.CullNone,
    ShaderEffect);

[...]

//in drawable class
foreach(//big loop) {
     ShaderEffect.Parameters["MyParameter"].SetValue(//random vector4);
     spriteBatch.Draw(
            SpriteSheet,
            ScreenRect,
            sprite_to_draw.Rectangle,
            color,
            rotation,
            Scene.getInstance().Camera.Position,
            sprite_to_draw.SpriteEffect,
            layer
     );
}

[...]

//In Engine class
spriteBatch.End();
[...]

But on my screen it look like the Parameter "MyParameter" is not overwrite.

So can I overwrite it and If yes do you know how ?

Thanks

share|improve this question
    
I try Scene.getInstance().ShaderEffect.Parameters["MyParameter"].GetValueVector4Array‌​(1).SetValue(/*new random vector4*/,0); without success. –  Cyril ALFARO Mar 4 '13 at 0:45
    
I try bind only one time on a variable in my code, same probleme, no change when I change C# variable. –  Cyril ALFARO Mar 4 '13 at 0:57
    
If end()/begin() my SpriteBatch it works but perf are lower of course. I'm sure there is an other way to do that... –  Cyril ALFARO Mar 4 '13 at 1:18

2 Answers 2

up vote 1 down vote accepted

I'm afraid there is not an easy solution to this problem, because you can not add extra information to the vertices generated by SpriteBatch.

Like Blau said, you can change the SpriteBatch to Immediate mode, or call Begin() and End() every time you change the parameter, but you will get a ton of draw calls and won't be batching anything anymore. I can think of two additional solutions:

1) SpriteBatch.Draw takes a color parameter and stores it inside each vertex of the quads it generates. You can then get this value back in your custom shaders. If you do not need to use the default color tinting, and your only parameter is a float4 like in your example, you could hijack the color parameter for your needs, and override the default pixel shader so that it does not tint the sprite.

float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
    // Do whatever you want with the color parameter
    // Sample texture but ignore color because it's not really a color
    return tex2D(TextureSampler, texCoord);
}

2) Implement your own SpriteBatch with a custom vertex struture that stores the additional information that you need for the shader, so that you do not need to change parameters between drawing each sprite. You can check the following question for some ideas on how to implement it yourself.

How exactly does XNA's SpriteBatch work?

share|improve this answer
    
Thnaks a lot for your answer, I will check it this evening. –  Cyril ALFARO Mar 4 '13 at 13:13
    
After our exchange by mail It works ! –  Cyril ALFARO Mar 5 '13 at 2:00

if you set SpriteSortMode.Deferred the batch will be executed when Batch.End() is called...

You could use SpriteSortMode.Inmediate but it can hurts the perfomance...

The other options are building your own QuadRenderer or using deferred sort mode and call Begin/End for each parameter you need to pass.

share|improve this answer
    
Thank for the answer, It works in immediate render but performance are horrible... I don't know yet how QuadRenderer can help me, where is it and how to build it. There is really no other method to pass a var in shader depending on object ? It looks like a big limitation so I think I didnt get it... –  Cyril ALFARO Mar 4 '13 at 9:10
    
A quad renderer is an own implementation of spritebatch... ;) –  Blau Mar 4 '13 at 9:33
    
I did a kind of in OpengGL with LWJGL, code my own renderer to have only one pass to draw all sprite. But spriteBatch have deferred renderer which make this already. I don't know if it can help me to make my own one. But an other param of draw function on spritebatch is Color params, I know that I can change this filter but how it works ? It's a shader ? If yes do you know how they change this to the pipeline renderer ? –  Cyril ALFARO Mar 4 '13 at 9:48

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.