Tomaz wrote:I've done exactly this, but outside Quake and in D3D, you ideally don't want to scale all z and use regular 3d perspective, what you want is a hybrid between 3d perspective and 2d ortho, which I in my engine call 3d ortho, its basically an orthogonal proecjtion but with real near / far clip
perspective camera usually has a nearclip of 0.01 and fraclip at 512 ( or ifinite )
2d ortho usually is -1.0 to 1.0 but everyone usually always render 2d stuff at 0.0 making the last thing you renderede end up ontop ( you can have proper z-test even in ortho so you don't need to render 2d stuff i na particular order )
anyway, the approach i call 3d ortho is an orthogonal projection with near and far clip matching my 3d perspective projection. This way i made a "live" minimap thatis generated at level load by the game, and updates while playing whenever a change happens. All using the real geometry of the level. This removed a huge step for our oartists by not having to generate a new minimap each time they redeisgned / changed a level.
Long post but I hope you got the idea.
Edit:
http://temp.snowcold.net/Perspective%20 ... 20Test.rar
Found one of my old demos showing what my 3d ortho projection is, the demo is of 2 fighters, looks like your regular 2d fighting game, but its actually 3d ortho, press '2' to turn it into a 3d perspective projection ( it interpolates between the 2 projections giving a nice transition )
pressing '1' turns it back into 3d ortho again
Thats the same approach i used when making the "load-time" minimap except i rendered to a texture instead of to the screen
(Yeah ... this isn't exactly an immediate reply but storing the info here or someone else finding it might be helpful to them)
In FitzQuake using what you advocate with the Z Scaling can be done like this (probably translates nearly exactly to GLQuake):
gl_rmain.c
Code: Select all
/*
=============
R_SetupGL
=============
*/
void R_SetupGL (void)
{
//johnfitz -- rewrote this section
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
glViewport (glx + r_refdef.vrect.x,
gly + glheight - r_refdef.vrect.y - r_refdef.vrect.height,
r_refdef.vrect.width,
r_refdef.vrect.height);
//johnfitz
GL_SetFrustum (r_fovx, r_fovy); //johnfitz -- use r_fov* vars
glCullFace(GL_BACK); //johnfitz -- glquake used CCW with backwards culling -- let's do it right
glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();
glRotatef (-90, 1, 0, 0); // put Z going up
glRotatef (90, 0, 0, 1); // put Z going up
glRotatef (-r_refdef.viewangles[2], 1, 0, 0);
glRotatef (-r_refdef.viewangles[0], 0, 1, 0);
glRotatef (-r_refdef.viewangles[1], 0, 0, 1);
glTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]);
glScalef (1,1, 0.01); // <--------------- Baker: slap Z scaling in right here
glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
//
// set drawing parms
//
if (gl_cull.value)
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
}
The "right" way to do the 2D mini-maps in a Quake engine using true 2D works kind of like this:
1. Instead of setting glFrustum ... do a glOrtho. Capture the mins and maxs of the map first using Electro's post from this thread:
http://forums.inside3d.com/viewtopic.php?t=1353
2. Eliminate all the FOV culling and surface culling. Kind of like a bit more than r_novis 1.
3. Kill the "point of view" positioning stuff that looks like this (elimating the "View" from the equation) ...
Code: Select all
glRotatef (-r_refdef.viewangles[2], 1, 0, 0);
glRotatef (-r_refdef.viewangles[0], 0, 1, 0);
glRotatef (-r_refdef.viewangles[1], 0, 0, 1);
glTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]);
because that isn't necessary since glOrtho would be used to specify the coordinates. Something like glOrtho (left, right, bottom, top, znear, zfar) where left/right = mins/maxs World X, top/bottom = mins/maxs World Y, znear and zfar should be mins/maxs World Z. Some of the GL stuff might need to be tweaked a little, you'd still want the depth buffer to be your friend but possibly some of the 3D stuff might interfere.
To localize the mini-map, the glOrtho could be adjusted to player/camera origin r_refdef.vieworg +/- some X and Y range like glOrtho (r_refdef.vieworg[0] - 200, r_refdef.vieworg[0] + 200, r_refdef.vieworg[1] - 200, r_refdef.vieworg[1] + 200, worldminz, worldmaxz). The visibility culling could still be used to prevent seeing stuff you should be able to see, but the frustum culling (frustum = what is in front of you) would have to go.
Sure the minimaps stuff in older DirectQ probably did exactly that +/- or minus, but back then I simply didn't know enough about the engine or the 3D stuff to even get the mechanics of this stuff. Not in a way that I actually understood. glOrtho more or less just tells OpenGL where a pixel gets rendered so if you say glOrtho (-32768, 32768, -16384, 16384, -999999, 999999) the pixels the top left of the viewport (or screen usually) would be (-32768 X, -16384 Y) through (32768 X, 16384 Y) and the Z range wouldn't do anything.
[I wonder how much my browser's "auto-spell check" screws up what I type by auto-correcting it stupidly?]