Sign in to follow this  
Assassin

XNA: Update & Draw or something more for custom shaders?

Recommended Posts

I've been working on a small project, and so far I've been satisfied to use the built-in game loop calling Update & Draw on my objects which are just entered into the Game.Components list. Now that I've got the gameplay working, I want to add some graphical upgrades like shadows and custom shaders, and the built-in methods are already annoying me with their simplistic definition (only passing in gametime). I'm curious how other people have addressed these issues: Do you mostly ignore the XNA game loop infrastructure and manage things yourself in a scene/level class? How do you apply custom effects to models that normally use a BasicEffect (.X files, for example), while retaining the useful data like texture references and such? Do you handle multiple rendering passes for different purposes using techniques with standardized names, or is there some other insight I could borrow? Using the FX system, do you make more use of 1 technique with multiple internal passes, or multiple techniques with 1 pass? I've written 3D engine code in the past, but didn't venture into the realm of shader management. My current plan is to introduce a SceneManager which will start life as a basic list, modify my game object class hierarchy to subclass a new SceneObject class instead of GameComponent, and use enums to define standard rendering techniques like "NoLighting", "CreateShadowMap", "UseShadowMap", etc. I'm not sure how I'd like to handle multiple shadow maps, dynamic environment maps, and other stuff requiring dynamic render-to-texture - any tips would be appreciated.

Share this post


Link to post
Share on other sites
Update() and Draw() have been how the hubs of all my game projects have worked, regardless of their complexity, C++,C#,XNA, or otherwise. I don't see why you think there is anything simplistic, or limiting about it?

All the answers to your questions are in the Education part of the Creators.XNA.com site. They have a shader management series and everything else you asked about. They come as downloadable samples.

Share this post


Link to post
Share on other sites
Yeah the Game Components list becomes very limiting (I think that is what he means by the simple Update and Draw functions?). If you don't use it, you still use the update and draw functions, but you will handle the code to render each object yourself.

Here's some suggestions, if you haven't checked these out already:

- I'd start by extending the BasicEffect and SpriteBatch shaders with your own additions. The code and sample apps are here:

- http://creators.xna.com/en-US/utilities/basiceffectshader
- http://creators.xna.com/en-US/utilities/spritebatchshader

- Full screen-shaders, which you will want eventually, are run after the scene is rendered, but before the game GUI is drawn. The bloom post-process sample is a good reference:

http://creators.xna.com/en-US/sample/bloom

- I haven't done multipass myself, but there is a sample:

http://creators.xna.com/en-US/sample/shader_series5

As Daark said, that whole shader series is very helpful.

Share this post


Link to post
Share on other sites
I've been using XNA for years now, and I never once used a GameComponent. They are optional built in functionality for those that want to use them, and they don't limit or dictate anything about your design.

All programs update their state, and then present a representation of that state to their user. Update/Draw is pretty much universal, unless your coding a GUI/Window type program.

Drawing with custom shaders is the same as anywhere else. Assign your shader, and send your vertices to be drawn. Same as you would do it in D3D.

The model class is just there as a helper for people who want to get models on the screen. It doesn't dictate or limit your design in any way.

JWalsh's tutorial site has good examples of using custom shaders too. He's got a thread somewhere in this section, look for it.

-edit- here: http://gamedevelopedia.com/

Share this post


Link to post
Share on other sites
Quote:
Original post by Daaark
I've been using XNA for years now, and I never once used a GameComponent. They are optional built in functionality for those that want to use them, and they don't limit or dictate anything about your design.

All programs update their state, and then present a representation of that state to their user. Update/Draw is pretty much universal, unless your coding a GUI/Window type program.

Drawing with custom shaders is the same as anywhere else. Assign your shader, and send your vertices to be drawn. Same as you would do it in D3D.

The model class is just there as a helper for people who want to get models on the screen. It doesn't dictate or limit your design in any way.

JWalsh's tutorial site has good examples of using custom shaders too. He's got a thread somewhere in this section, look for it.

-edit- here: http://gamedevelopedia.com/


Thanks for the tips. Of course all 3D programs update and draw, I was mainly finding myself limited by the built-in GameComponent.Update and Draw methods, which I was coerced into using when following the XNA documentation "how to get started" stuff. Clearly you don't have exposure to those as you've never used them; I'll take that as implicit advice against their use. Considering that every effect needs to consume a set of matrices including view and projection, among other values that may be environmental rather than specific to the object being rendered, what design do you use to get them - fetching from a global store, feeding them into the Draw parameters, or something different? Manipulating the view and projection matrices is essential for shadow mapping, and I want to elegantly manage them when re-drawing objects into different render-targets within the same frame draw.

The ShadowMapping sample on the XNA site has some useful examples, including a content processor that appears to replace the effect on a Model with a custom one. That sample still uses static scene management, simply calling Draw on a couple of named variables in a particular order. I suppose that can be abstracted to a collection of objects, but at that point it becomes less clear whether any object in the collection is using a specific effect or should be drawn with a certain technique name or which variables it will need to consume.

Admittedly, XNA is the only venue for writing indie games that will run on an Xbox, but I was hoping it might provide better basic functionality than raw D3D. JWalsh's tutorials currently appear to be focused on reproducing the low-level instruction of NeHe and ignoring almost all of the XNA infrastructure and helper classes, and they don't really discuss any scene management at all - they're just rendering a triangle and a box with a static view matrix. The implementation of custom shaders is a useful demonstration, though.

Share this post


Link to post
Share on other sites
Quote:
Original post by Assassin
Thanks for the tips. Of course all 3D programs update and draw, I was mainly finding myself limited by the built-in GameComponent.Update and Draw methods, which I was coerced into using when following the XNA documentation "how to get started" stuff. Clearly you don't have exposure to those as you've never used them; I'll take that as implicit advice against their use. Considering that every effect needs to consume a set of matrices including view and projection, among other values that may be environmental rather than specific to the object being rendered, what design do you use to get them - fetching from a global store, feeding them into the Draw parameters, or something different? Manipulating the view and projection matrices is essential for shadow mapping, and I want to elegantly manage them when re-drawing objects into different render-targets within the same frame draw.


There's absolutely nothing about Update/Draw that limit you here. Generally, for environmental parameters, you would pass the object that contains those into the constructor of your object. Or, since the constructor must take a Game object, you could obtain the "environment" object via the Game.Services property (and the startup code for your game would add it to the Services property).

Share this post


Link to post
Share on other sites
I never badmouthed the GameComponents classes. There is nothing wrong with them. Engines like Unity also use the scriptable Gamecomponent/GameObject design pattern. It's just that I have my own ways of organising a program, and I stick to them.

How I organize my programs? I just use Game1 as a hub. It does global level updating and Drawing (like pause menus and safe area overlays), but also hands off to a GameMode class I derive from, where each mode of the game does it's own updating and drawing.

My modes draw things in whatever way is most convenient. Sometimes it's as easy as just having the Mode itself have a long draw function that knows how to render out each type of object, sometimes not.

So Game1 does very little other than allocate GameModes, and hand off updating and drawing chores to them.

You're 100% free to use whatever design you want. I've never had to do anything different then when I was using native D3D or OpenGL.

You should probably also read Shawn Hargreaves' blog. Great source of XNA info.

And Riemer's.


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this