PDA

View Full Version : Need help understanding coordinates in OpenGL



pjyelton
05-20-2009, 10:10 PM
Ok, this may be a silly question but its driving me nuts. I have a terrain editor that basically draws land within a box. The size of the box is determined by the map scale and the number of points in the terrain grid, for example map scale of 100 and a grid of 512x512 would create a square from coordinates (0,0) to (51200,-51200) in the XZ plane. I then set the camera at one end of the square overlooking the terrain.

This works fine, but when I change the number of points in the grid or the map scale the image doesn't get any bigger in my viewport. I can set the scale to 1 or 1000000 but the square never appears any bigger. I know that the coordinate scale on the screen is changing because hills of the same height are mountains at scale 1 but flat at 1000000, plus the camera which moves a fixed number of units per second goes twice as slow when doubling the scale and twice as fast when halving the scale. So basically the program is resizing the coordinate system so that this box always fits on the screen no matter what the X and Z coordinates are.

What part of the code determines the coordinate scale as it is drawn on the screen? I'm not talking about using scaling transformations while the program is running. Basically I just want the terrain to appear twice as large on the screen if I double the scale pre-compile. Here are snippets of my code, I've taken out the parts that I don't think are relavent. Thanks for any help!


void Initialize() {
glClearColor(0.0f,0.0f,0.0f,0.0f); // clear to black
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);

glEnable(GL_TEXTURE_2D);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

// initialize the terrain data and load the texture
InitializeTerrain();
LoadTextures();
}


case WM_CREATE:

hDC = GetDC(hwnd); // get device context for window
g_HDC = hDC;
SetupPixelFormat(hDC); // call your pixel format setup

hRC = wglCreateContext(hDC); // create rendering context
wglMakeCurrent(hDC, hRC); // make rendering context current

return 0;
break;

case WM_SIZE:

height = HIWORD(lParam);
width = LOWORD(lParam);

if (height == 0) { // to avoid division by zero errors
height = 1;
}

// reset viewport to new dimensions

glViewport(0,0,width, height);
glMatrixMode(GL_PROJECTION); // set projection matrix
glLoadIdentity(); // reset projection matrix

// calculate aspect ratio of window

gluPerspective(54.0,(GLfloat)width/(GLfloat)height,1.0f,10000000.0f);
gluLookAt(cameraX, cameraY, cameraZ, lookX, lookY, lookZ,0.0, 1.0, 0.0);

glMatrixMode(GL_MODELVIEW); // set modelview matrix
glLoadIdentity(); // reset modelview matrix

return 0;
break;


void Render() {

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glShadeModel(GL_SMOOTH);

// set the current texture to the land texture
glBindTexture(GL_TEXTURE_2D,land);

for (int index = 0; index<VERTEX_COUNT; index+=10) {
glDrawElements(GL_TRIANGLE_FAN,10,GL_UNSIGNED_INT, &amp;g_indexArray[index]);
}

// enable blending
glEnable(GL_BLEND);

// enable read only depth buffer
glDepthMask(GL_FALSE);

// set the blend function to transparency

glBlendFunc(GL_SRC_ALPHA,GL_ONE);

// DRAW WATER HERE

// set back to normal depth buffer mode
glDepthMask(GL_TRUE);

// disable blending
glDisable(GL_BLEND);

glFlush();
SwapBuffers(g_HDC);
}

scratt
05-21-2009, 12:04 AM
If you are always putting the camera on the corner of the landscape, it's going to be the same proportional distance from the center of the landscape each time.

So in theory the overall view dimensions will look the same size every time, regardless of the size of the landscape.

I am not quite sure what effect you want to achieve, but moving the camera view closer in with finer and finer movements will fly you "into" the landscape and you should sense the change in scale / resolution that way.

Another method which can very effectively make an environment seem bigger or smaller is to play with the first value in gluPerspective, which is your field of view. Setting that to a lower number will seem to make the scene bigger. Conversely a larger number will make it seem smaller.... It's simply a cosmetic effect, but working with that and your landscape size might help.

Other than that what you are seeing is what I would expect to see based on what you describe you are doing.

ZbuffeR
05-21-2009, 12:53 AM
I think the crucial part is this :

gluLookAt(cameraX, cameraY, cameraZ, lookX, lookY, lookZ,0.0, 1.0, 0.0);

You should use fixed values for all 3 variables, independant of terrain scale.
ie, if you have z axis for altitude :
cameraX=0
cameraY=0
cameraZ=5000
lookX=25000
lookY=25000
lookZ=0
That would roughly center your example terrain on screen.
Increasing the terrain scale without touching these values will give the effect of a larger terrain.

pjyelton
05-21-2009, 11:49 AM
Thanks, after I went to bed last night I started to think about it a bit and I can see how if the camera is always proportional to the scene then it can appear to always be the same size. Don't understand why the mountains flatten out at higher scales, even when I'm right up against the ground, but that might be a bug somewhere. I'll experiment tonight and see what I can find out. Thanks for the help!

pjyelton
05-23-2009, 01:28 PM
Yep, that was the issue. The problem was the horizon walls also grew by the same size as the land so even though the terrain was technically larger it always just appeared the same.