Jump to content
  • Advertisement
Sign in to follow this  
Guinnie

Musings over "Y" axis movement...

This topic is 3259 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Something I was thinking about in the kitchen yesterday... I'm planning in my game to use a sort of "height map" divided into zones, with each zone having 0-4 heights depending on its complexity (i.e. a flat tile only needs 1 height, but a sloped tile may need 4). The idea is that when the player moves into a new zone, it will be set to the height of that zone. So if the zone is a slope with a (mid-way) height of -0.5, the player drops 0.5. But I'm wondering... would it be faster to do this using a translation in OpenGL - or using SIMD (e.g. SSE2) to drop the height of each vertex in the model by 0.5 or whatever? I have no idea how OpenGL's translation actually works. It may be something much simpler than recalculating each vertex. But also, the player's height won't always be changing; if they're stood still or moving across simple flat zones with only one height, they could navigate most of the map without ever really needing to move up or down, whereas a translation would have to be done every time the model is drawn. All input on this would be appreciated. Also perhaps some material on how OpenGL "works" on the translate/scale/rotate level... and maybe suggest some better alternatives to my height mapping idea (though I think collision detection against the floor might be overkill). Thanks.

Share this post


Link to post
Share on other sites
Advertisement
OpenGL is a translation API implemented in your graphics card driver that takes your crap and does with it whatever is bestest for that specific card. Basically it feeds things to the card which is responsible for executing them. In the hardware it's a massively parallel set up which can process many vertices in parallel. That's the whole idea of graphics card: special hardware that is way faster than anything else at doing matrix math, pushing vertices and textures and shaders around. Therefore, the "fastest" thing to do will always be to have the graphics card do it because you can't achieve the same parallelity on your CPU. So just do a simple:


glPushMatrix();
glTranslatef( offset );

// your tile render code

glPopMatrix()




That has the extra advantage of being super readible which is more important than anything else in 99% of situations.

-me

Share this post


Link to post
Share on other sites
Thanks for the input.

Having said that the G-card will be faster in terms of calculations as they happen, would the frequency of those calculations make any difference?

In other words... you may have two scenarios: one where you're translating every time the scene is drawn and one where you're "manually" repositioning your vertices every time it's required... which may be every few seconds assuming the player is on varied terrain. If they were walking on a flat surface and the "engine" knew to only recalculate the height if the new height was different to the old height, it may not have to ever reposition the model.

Or made shorter still: player is at 0, moves to a new height of -1 and stays on the -1 platform for a while. OpenGL has to apply this -1 change every frame, whereas the recalculation to drop to -1 only has to be done once.

Given the way I'm imagining my levels, I can see the vast majority being flat, but I'd want variations in terrain height to add certain features and a feel to the game.

I hope all of that makes sense.

Share this post


Link to post
Share on other sites
If you don't have the book "OpenGL Programming Guide," the "Red Book," then:

step 1. Buy it.

It'll run about 60USD or so, but it is the official guide to learning OGL, authored and edited by the OpenGL Architecture Review Board - ~700 pages of tutorials and examples, descriptions of matrix manipulations, detailed descriptions of functions, tables, appendices describing all aspects of the language, description of texture manipulations, etc., etc.

To actually answer one of your questions very simply - OGL primarily uses two matrices - a projection matrix (to give you perspective or orthographic projections) and a modelview matrix. The modelview matrix is your SRT (scale-rotation-translation) to be applied to the vertices of a particular object prior to rendering. Set the projection, set a model matrix, render, set another model matrix, render, etc. Then present the scene.

So, applying a single translation each frame is already part of the process.

Share this post


Link to post
Share on other sites
'lo, Buckeye.

I already have bookmarked the "Official OpenGL Programming Guide" which does explain the matrices and such; I just didn't know how exactly they were used internally to reach the end result (whether each vertex was recalculated or whether OpenGL's "point of focus" just shifted or whatever).

The translation per frame is my point; if the model is only moving up or down once every so often, would it be faster to recalculate the model's position (just simple addition and subtraction) using SSE once, rather than the graphics card/OpenGL having to do it 60 times per second.

Share this post


Link to post
Share on other sites
You still seem to be confused about matrices. OpenGL doesn't care about "frames" and doesn't have a memory of what you did or sent the last time around. It doesn't store some weird internal 3D scene where you can move stuff around.

Every vertex will always be transformed by those matrices every single time you render it. Every time you render a polygon, it will be rasterized and is _fixed_ in the frame buffer. If your scene doesn't change from one frame to another, then the only way to save time is by _not having_ another frame and not render anything.

glTranslate doesn't do squat to your vertices. It modifies the matrix that every vertex will be multiplied with anyway (unless you a) want a completely static scene with no "camera movement", b) use an identity matrix for projection and c) the driver actually considers this highly unlikely case to optimize away the multiplication).

Side not: of course you _could_ do fancy stuff with dirty regions, figure out which parts of the frame actually change and only render that part of the viewport with an adjusted frustum. But I've never actually heard about anyone using that kind of approach. Mostly because it's useless fiddling for some special case that would only work for very special kinds of game.

Share this post


Link to post
Share on other sites
There's no confusion; I think you just misunderstood me.

I'll try to make what I'm imagining clearer. Let's assume I have a model which we know is a load of vertices in memory somewhere. Every time I want to draw the scene (approx 60 times per second), I send those vertices to OpenGL and it then draws my model.

Now... my model has just moved to a new region so it needs a new height. Using OpenGL, during the scene drawing, I'd translate the model say -1 or whatever. This is being done every time I draw the scene - the aforementioned 60 times per second. I'd also probably have to translate back afterwards so other models (which will also likely be of varied height) can be moved to their positions.

Instead, I'm wondering if it'd be faster to have no translations per second and instead do one "manual" translation on the model/s using SIMD. Then whenever the height needs to change again, do another with SIMD. The question really is whether one SIMD translation would be faster than the estimated 60 done on the graphics card or whatever.

So when the guy is walking along, instead of having to constantly call the translate function to keep it where it needs to be, I just draw the vertices as normal - vertices which have been previously modified to reflect the new height. Same applies to all other moving models in the world. When they come to a zone of new height, their vertices are increased/decreased by x.

As I said before, there will be large areas of the map with no height difference. If their height would constantly be changing then I realise it'd be senseless recalculating their position in software every frame.

Share this post


Link to post
Share on other sites
It still sounds to me like you don't understand how the rendering pipeline works and extremely overestimate the cost of translation.

Every vertex you send to OpenGL is going to be transformed and it absolutely doesn't make a difference if the matrix value at index 5 is 0 or -1 (which is the only thing that glTranslate will eventually do in your case).

You seem to believe that not calling glTranslate is somehow going to spare you a lot of calculations, but that simply isn't the case. You are saving one lousy matrix multiplication per frame.

Also, since you're saying you send all the vertices to OpenGL everytime you draw your stuff, you must be using immediate mode (ie. glBegin/glEnd). That's the worst possible way to use OpenGL if you're worried about performance. Look into vertex buffers.

Unless your model is animated and hardware skinning isn't an option, it simply isn't a good idea to even think about touching any vertices yourself if you can achieve the same result with simple transformations.

Or simplified, using immediate mode (and making some assumptions about driver behavior):

glTranslate:
-modelview = modelview * translation

glBegin:
-ModelViewProjection = projection * modelview
-some more setup

Every time you call glVertex, this happens:
-ModelViewProjection * vertex
-clipping
-transforming to viewport
-rasterizing triangle after 3 vertices
-per pixel: z-test, shading, writing to buffer

Share this post


Link to post
Share on other sites
I do plan to use the vertex/texture buffers for the map itself and display lists for models... in the future. I've not yet put much thought into how I'm going about that other than what came to me while reading the programming guide.

Having established that the translation is going to happen anyway, the only thing left would be the question of whether the one-off software translation would be better than the actual function calls (and whatever happens inside the function)... considering branch elimination and such. I'm guessing not, having crunched the numbers for a 600 triangle model. I might do some benchmark test in the future, if I ever get that far.

Share this post


Link to post
Share on other sites
Morning, Guinnie.

Quote:
the one-off software translation would be better than the actual function calls (and whatever happens inside the function)

Yeah, it would be.

What you'll probably end up doing is setting up a model matrix for each object. Each frame, you'll set the matrix for the object and send the vertices into the pipeline. If there's no change needed (no change in elevation), same thing happens next frame.

If there's a change in elev, change the matrix for the object (could be as simple as m[2,4] += 1) and continue the loop.

Another reason you'll use transforms (matrices) to manipulate your scene, rather than changing the vertices themselves, is that you may want to compile a list of the calls necessary to render the object. Using a list will get the geometry into the pipeline faster. The list (which contains all the vertex data, tex coords, etc., all formatted for pipeline input) need not be recompiled for the lifetime of the object. Then the process is: set the matrix, execute the list, set a matrix,... That also allows you to use the same geometry for different objects in different positions, perhaps changing the color or the texture, etc.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!