What about multiple objects?,
Members - Reputation: 475
Posted 26 January 2011 - 09:51 AM
Additionally, can effects be nested? to for instance, apply an effect on the results of another one?
For the inexperienced developers following this tutorial I would seriously recommend not following it by the letter, rendering primitives in game loop functions as the book is doing is an extremely bad idea. I'd encourage you to try making a Mesh class and figuring out which parts of the example code are specific for each different model to be rendered and which actually do belong in the main rendering loop.
I would also advice to create a renderer class that handles the main rendering loop, maybe a game component derivate, the game class should not do this directly, the game class is Application Specific (meaning it is not likely to work in other projects without a major refactor) and the basics of rendering should be reusable in other projects if done right.
LinkedIn profile: http://ar.linkedin.com/pub/andres-ricardo-chamarra/2a/28a/272
Members - Reputation: 100
Posted 28 January 2011 - 12:28 AM
When you say "Nested", do you mean calling Begin/End inside the Begin/End of another effect?
Effects technically cannot be nested in that way, however in certain cases you can nest effects to apply some tricks. (more later)
The Effect object is simply a nice representation (and manager) for the two shaders that you use to render, the Vertex Shader and the Pixel Shader. When you call Effect.Begin, it applies those shaders to the graphics device, and when you begin each pass, it commits the parameters you may have specified to the shader on the GPU, ready to draw the geometry.
You can make as many draw calls inside a pass as you want, however if you change the state, for example changing the Texture or another parameter, you need to call Pass.CommitChanges before drawing.
If you are outside of a pass, you do not need to call CommitChanges; only when you are inside a pass. Calling Begin on an EffectPass will automatically commit the parameters.
You probably shouldn't change effects a lot, that does has performance implications - especially if you do not need to. So as a direct answer, Begin/End can be expensive, and you're better off batching every model that uses the effect into a single Begin/End, and then changing parameters and calling CommitChanges as required.
If you nest Effects, you simply override the shader objects on the graphics device with the ones in the child effect. This can be useful when you have say, just a Pixel Shader in an effect, and want to override the pixel shader specified by SpriteBatch without touching the Vertex Shader.
One other thing, as far as I know, changing textures on the graphics device itself (GraphicsDevice.Textures[x]), rather than through the Effect interface, shouldn't require a call to CommitChanges.
XNA 4.0 doesn't actually use Begin/End for both the Effect and the Pass. Instead it uses the Apply method for each pass.