How to handle entity rendering

Member
Posts: 65
Joined: 2009.03
Post: #1
Hi all

I wanted to see how other people are rendering their entities to the screen. Hmm, that may not make sense. What I mean is I may have 20 baddies which are each self contained entities that look after their own movement and AI etc.

I normally have these entities also rendering themselves as well when asked to do so. I've recently been using vertex arrays to speed things up and reduce the number of OpenGL API calls. This is fine for self contained classes I have such as bitmap fonts and tile maps as I can easily create the vertex arrays and then use something like glDrawElements. What I am not sure of is how best to do something similar when I have these multiple entities moving around.

I was thinking I could have a scene manager of some kind to which each entity provides its vertex info and once all entities which are to be rendered have done so the scene manager then renders them all with a single call to OpenGL.

Does this make sense or are there other more effective ways to manage the overall rendering.

Thanks for the help.

Mike
Quote this message in a reply
Member
Posts: 46
Joined: 2008.10
Post: #2
You can reference a single model for each of your objects when rendering, possibly using a vertex list to speed things up. The difference will be the transformations undergone before that render call is made. Here's a sort of sketch, assuming that all objects are direct children of the world frame and using the same mesh ('Bob'):

/-> Object 2 Transformation -\
World Frame ---> Object 1 Transformation --> Render Bob Mesh
\-> Object 3 Transformation -/

Transformations are made, ideally, by pushing and popping matrices. Hope that makes sense! Not the best ASCII diagram I've ever drawn.

"Who's John Galt?"
Quote this message in a reply
Member
Posts: 65
Joined: 2009.03
Post: #3
Thanks Thythos

I'm not sure I completely follow your example and I should say that I'm working in 2D with simple quads and textures. I'm not sure how that would effect your example.

Transformation each entity in isolation from the others but still only having a single OpenGL call to draw them was one of the issues I was trying to get my head around, hence getting them each to generate their own vertices which are loaded into a central array and the rendering is then done from there.

MikeD
Quote this message in a reply
Moderator
Posts: 3,573
Joined: 2003.06
Post: #4
You won't be able to draw the entire scene with only one call to glDrawArrays or glDrawElements unless you can fit all your sprites on one atlas, since you'll at least need to switch texture binds in between atlases, plus whatever other state changes you'll need for things like blending. However, if you don't need any effects changes in-between sprites and you manage things right, you can do it with only one draw per atlas, which is about as efficient as you're gonna get. Honestly though, it's not really all that big of a deal performance-wise to fight to fit everything in only a few draws; just minimizing gl calls and texture binds a bit can help greatly. That said, one place where it can really help to do a whole bunch of sprites in one draw is with particle effects.

MikeD Wrote:Transformation each entity in isolation from the others but still only having a single OpenGL call to draw them was one of the issues I was trying to get my head around, hence getting them each to generate their own vertices which are loaded into a central array and the rendering is then done from there.

It is much easier to do than you think! All you gotta do is replace glTranslate/Rotate/Scale and glPush/Pop and glLoadIdentity with your own versions, and add a function or two to multiply each vertex by the resultant matrix just before you draw the batch. My entire 2D transform library which replaces those gl functions is only about 150 lines of code, so there's no sweat to it. In addition to being able to transform your own batches of geometry before submitting it to the GL, there's a benefit to doing your own 2D transforms since you can minimize math operations greatly compared to the generic 3D transform functions provided by OpenGL.
Quote this message in a reply
Member
Posts: 65
Joined: 2009.03
Post: #5
Thanks AnotherJake

When you mention using your own transform functions, do you mean that you take the vertices from your arrays from which you will render, apply the transform to them and pop them back into the array?

If that is right the I would need to know where a particular object is inside the array so I know what I want to apply.

Also thanks for the tip on reducing the number of OpenGL calls. I think I'm getting a little too anal about reducing the number of OpenGL calls. As you say, as long as they are kept to a minimum such as one per tile map if possible then it should not be too much of a problem.

I think its because I have got frustrated in the past that I've had performance problems when rendering around 200 quads in 2D with sprites and tile maps and bitmap fonts etc. When I look at the 3D games out there they must be using WAY more and they are running ok Sad still a lot to learn me thinks.

Thanks again for the help.

MikeD
Quote this message in a reply
Moderator
Posts: 3,573
Joined: 2003.06
Post: #6
MikeD Wrote:When you mention using your own transform functions, do you mean that you take the vertices from your arrays from which you will render, apply the transform to them and pop them back into the array?

If that is right the I would need to know where a particular object is inside the array so I know what I want to apply.

Yes that's essentially right, but there are several different approaches you could use. If you transform the verts in place then you destroy the original untransformed geometry, so it might be convenient to use a blank, untransformed sprite vert array and copy it's verts into the submission array as you transform it. Or if you're just submitting one sprite at a time, which I have found to be needed at times, then you could transform the verts in place if you're initializing them every time in that sprite's drawing function. Like I said, there is more than one way to approach it.

Like I mentioned before, it's actually a lot easier to do than it seems at first. For your first run, I would suggest simply submitting one sprite's worth of pre-transformed geometry to work out your transforms. Once you can do just one sprite with your own transforms it's easy to expand past that and group things into larger arrays for efficiency.
Quote this message in a reply
Member
Posts: 65
Joined: 2009.03
Post: #7
Excellent, thanks AnotherJake. I'll give that a go and see how I get on. I've not really played with my own matrices before so there is no time like the present.

Thanks for the advice.

MikeD
Quote this message in a reply
Member
Posts: 446
Joined: 2002.09
Post: #8
MikeD Wrote:I've not really played with my own matrices before...
There may be times when using a matrix makes sense but they aren't explicitly required. For object/vertex-to-world transformations you can just take each vertex and scale, rotate, then add the position. This avoids extra conversions to matrixes, which is especially nice if you're already using quaternions for the high-level rotations.
Quote this message in a reply
Member
Posts: 65
Joined: 2009.03
Post: #9
Thanks Frank

Just to check I've understood, you would rotate a vertex as required and then just add to the x, y of that rotated vertex to then place it where you need on the screen. I'm only just starting to get my head around this side of things so I may have got the wrong end of the stick Smile

If you have any examples of what you mean that would be great.

Thanks for the help.

MikeD
Quote this message in a reply
Member
Posts: 446
Joined: 2002.09
Post: #10
MikeD Wrote:...you would rotate a vertex as required and then just add to the x, y of that rotated vertex to then place it where you need on the screen.

Yup. What I do is keep a "base frame" of 2d vertexes in object coordinates and transform those into a buffer as needed. Each entity has 2d vectors for scale and position, and a quaternion (or simply an angle) for rotation. So, in pseudo-C code:

Code:
for (i=0; i<vertexcount; i++) {
  entitymeshverts[i] = vector2Multiply(basemeshverts[i], entityscale);
  entitymeshverts[i] = vector2Rotate(entitymeshverts[i], entityangle);
  entitymeshverts[i] = vector2Add(entitymeshverts[i], entityposition);
}
Quote this message in a reply
Moderator
Posts: 3,573
Joined: 2003.06
Post: #11
Why are you using quaternions for 2D?
Quote this message in a reply
Member
Posts: 446
Joined: 2002.09
Post: #12
AnotherJake Wrote:Why are you using quaternions for 2D?
I don't always use them for 2D stuff but the current game I'm working on uses multi-quad 2D meshes morphed with primitive kinematics/bones and I was getting some bad results early on using angles so I switched to quaternions and everything just worked. I suppose I could get by without them, but I've used quaternions for so long in 3D that they just feel more natural to me at this point - even when dealing with 1 axis.
Quote this message in a reply
Moderator
Posts: 3,573
Joined: 2003.06
Post: #13
I've never heard of "multi-quad 2D meshes", but I'll take your word for it that quaternions are necessary for that. Wink I can imagine the bone rotations might be generalized as quats, but otherwise I can't imagine generalizing quaternions for 2D applications as being very efficient outside of that particular use.
Quote this message in a reply
Member
Posts: 446
Joined: 2002.09
Post: #14
AnotherJake Wrote:I've never heard of "multi-quad 2D meshes", but I'll take your word for it that quaternions are necessary for that. Wink
I just made that up Rasp. Basically instead of 1 sprite made up of 1 quad it's 1 sprite made up of a bunch of quads. Technically they're just like any old triangle-soup model format, minus the Z coords.

AnotherJake Wrote:I can imagine the bone rotations might be generalized as quats, but otherwise I can't imagine generalizing quaternions for 2D applications as being very efficient outside of that particular use.
It's more math under the hood but the implementation makes more sense (to me anyway) and I haven't run into any performance problems - there are plenty of other (bigger) bottlenecks to worry about. I just like how quaternions always seem to "know" the best route to take when interpolating/combining rotations - angles can be fragile.
Quote this message in a reply
Member
Posts: 166
Joined: 2009.04
Post: #15
Frank C. Wrote:I just made that up Rasp. Basically instead of 1 sprite made up of 1 quad it's 1 sprite made up of a bunch of quads. Technically they're just like any old triangle-soup model format, minus the Z coords.


It's more math under the hood but the implementation makes more sense (to me anyway) and I haven't run into any performance problems - there are plenty of other (bigger) bottlenecks to worry about. I just like how quaternions always seem to "know" the best route to take when interpolating/combining rotations - angles can be fragile.

If you are dealing with 2d then there is no interpolation problem whatsoever ... I mean you are dealing with a scalar - no need for quats.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  emulator can't handle multithreading captainfreedom 13 5,609 Jun 22, 2010 06:41 AM
Last Post: Skorche
  Handle input with opengl es melobrien 0 2,084 Oct 24, 2009 07:37 AM
Last Post: melobrien