views:

105

answers:

3

I'm new to OpenGL and graphics programming in general, though I've always been interested in the topic so have a grounding in the theory.

What I'd like to do is create a scene in which a set of objects move about. Specifically, they're robotic soccer players on a field. The objects are:

  • The lighting, field and goals, which don't change
  • The ball, which is a single mesh which will undergo translation and rotation but not scaling
  • The players, which are each composed of body parts, each of which are translated and rotated to give the illusion of a connected body

So to my GL novice mind, I'd like to load these objects into the scene and then just move them about. No properties of the vertices will change, either their positioning nor texture/normals/etc. Just the transformation of their 'parent' object as a whole.

Furthermore, the players all have identical bodies. Can I optimise somehow by loading the model into memory once, then painting it multiple times with a different transformation matrix each time?

I'm currently playing with OpenTK which is a lightweight wrapper on top of OpenGL libraries.

So a helpful answer to this question would either be:

  • What parts of OpenGL give me what I need? Do I have to redraw all the faces every frame? Just those that move? Can I just update some transformation matrices? How simple can I make this using OpenTK? What would psuedocode look like? Or,
  • Is there a better framework that's free (ideally open source) and provides this level of abstraction?

Note that I require any solution to run in .NET across multiple platforms.

+4  A: 

Using so called vertex arrays is probably the surest way to optimize such a scene. Here's a good tutorial:

http://www.songho.ca/opengl/gl_vertexarray.html

A vertex array or more generally, a gl data array holds data like vertex positions, normals, colors. You can also have an array that hold indexes to these buffers to indicate in which order to draw them.
Then you have a few closely related functions which manage these arrays, allocate them, set data to them and paint them. You can perform a rendering of a complex mesh with just a single OpenGL command like glDrawElements()

These arrays generally reside on the host memory, A further optimization is to use vertex buffer objects which are the same concept as regular arrays but reside on the GPU memory and can be somewhat faster. Here's abit about that:

http://www.songho.ca/opengl/gl_vbo.html

Working with buffers as opposed to good old glBegin() .. glEnd() has the advantage of being compatible with OpenGL ES. in OpenGL ES, arrays and buffers are the only way to draw stuff.

--- EDIT

Moving things, rotating them and transforming them in the scene is done using the Model View matrix and does not require any changes to the mesh data. To illustrate:

you have your initialization:

void initGL() {
  // create set of arrays to draw a player
  // set data in them
  // create set of arrays for ball
  // set data in them
}

void drawScene {
  glMatrixMode(GL_MODEL_VIEW);
  glLoadIdentity();
  // set up view transformation
  gluLookAt(...);
  drawPlayingField();

  glPushMatrix();
  glTranslate( player 1 position );
  drawPlayer();
  glPopMatrix();

  glPushMatrix();
  glTranslate( player 2 position );
  drawPlayer();
  glPopMatrix();

  glPushMatix();
  glTranslate( ball position );
  glRotate( ball rotation );
  drawBall();
  glPopMatrix();
}
shoosh
That explains the basic mechanics of drawing a mesh, but what about moving them around (as in the title of the question)? Can I reuse the same mesh multiple times in the one frame with different transformations applied? And which should I use, VBO or VA?
Drew Noakes
see new edited text
shoosh
@shoosh: thanks for the update. This looks good and I have a preliminary version running drawing a single VBO multiple times per frame. Very exciting to see it coming together, though now I need to sort out lighting. Thanks for your help.
Drew Noakes
+3  A: 

Since you are beginning, I suggest sticking to immediate mode rendering and getting that to work first. If you get more comfortable, you can improve to vertex arrays. If you get even more comfortable, VBOs. And finally, if you get super comfortable, instancing which is the fastest possible solution for your case (no deformations, only whole object transformations).

Unless you're trying to implement something like Fifa 2009, it's best to stick to the simple methods until you have a demonstrable efficiency problem. No need to give yourself headaches prematurely.

For whole object transformations, you typically transform the model view matrix.

glPushMatrix();
// do gl transforms here and render your object
glPopMatrix();

For loading objects, you'll even need to come up with some format or implement something that can load mesh formats (obj is one of the easiest formats to support). There are high-level libraries to simplify this but I recommend going with OpenGL for the experience and control that you'll have.

+1  A: 

I'd hoped the OpenGL API might be easy to navigate via the IDE support (intellisense and such). After a few hours it became apparent that some ground rules need to be established. So I stopped typing and RTFM.

http://www.glprogramming.com/red/

Best advice I could give to anyone else who finds this question when finding their OpenGL footing. A long read, but empowering.

Drew Noakes