PDA

View Full Version : gluLookAt, can you work out how much it sees?



Andrew Davey
04-27-2004, 05:31 AM
I am using cameras but i dont know how much the camera angle sees. i.e. the x range from far left to far right.

This would be useful so i can create a function to automatically optimise the camera so it can see everything in my "world"

Can someone help me out please.

dvm
04-27-2004, 05:54 AM
If I'm not mistaken, gluLookAt only positions the camera.
You can create all your objects without thinking about the camera or the world (ofcourse you need to know the coordinates of your objects).
Then you set how much can be seen by setting the clipping volume or view frustum.
The functions are
glOrtho or gluOrtho2D for an orthographic projection
glFrustum or gluPerspective for a perspective projection. If anything is outside this volume it will not get drawn.
How you position the camera is another thing, but one you set you volume at say
gluPerpsective(60.0, 1.0, 1.0, 100.0);
I think you can see everything if you pull the camera with
gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0); You can start growing the z-value (where the 5 is) and see when you are back enough.

Andrew Davey
04-27-2004, 06:00 AM
yeah i have that far, but the way my object generation works is they are randomly created around the world. I would like to have my camera so that it can rotate untill all the objects are in its "viewing area".

Catch my drift?? As i would not like a static camera pointing one way if the object is just behind it. Ideally the camera would rotate untill it finds it. One way i guess would be to compare the origX of the object with the viewX and if its the same then you know you are looking at the object. But would like to say if all objects are within the camera range then stop rotating

04-27-2004, 11:39 PM
Hey,
I think u need to change ur mind set about camera.There is nothing like camera rotating , Consider tht camera is not there and the anlogy of camera is check our self wht we were viewing.All the walkthr's in the graphics world is achived by placing the camera at a point and manipulating ur modelview matrix.Rotate the scene and translate the scene in a negative direction which makes u feel as if the camera is moving around.

Kumar K
04-27-2004, 11:43 PM
Hey,
I think u need to change ur mind set about camera.There is nothing like camera rotating , Consider tht camera is not there and the anlogy of camera is check our self wht we were viewing.All the walkthr's in the graphics world is achived by placing the camera at a point and manipulating ur modelview matrix.Rotate the scene and translate the scene in a negative direction which makes u feel as if the camera is moving around.


Originally posted by Andrew Davey:
I am using cameras but i dont know how much the camera angle sees. i.e. the x range from far left to far right.

This would be useful so i can create a function to automatically optimise the camera so it can see everything in my "world"

Can someone help me out please.

BeginOpenGL
04-28-2004, 08:00 AM
Donīt pay too much attention to me, because I just started this stuff. But, hereīs some food for thought.

Just because you canīt "move" the statue of liberty doesīnt mean itīs not there.

OpenGL comes with a very rudimentary camera for the user to see inside virtual 3d space without having to set projection parameters like frustum or perspective(setting of 6 clipping planes) or viewport or matrices or gluLookAt in order to move a 3d scene back towards us at point origin(0,0,0), so that we donīt loose sight of it.

Itīs a myopic camera to say the least, but, itīs there. If you place 3d object in 3d space, preferably smaller than 1.0, between +1.. -1 Z axis, +1...-1 X axis and +1...-1 Y axis. The user should be able to see it, as long as itīs(the 3d object) not translated away from this "very tiny" viewing area. Place your finger right on the center of the monitor screen. That, in a way can be though of as point origin or (X 0,Y 0,Z 0), where the cmaera is. Thatīs where our real 3d space meets 3d "virtual space".

But, since we are "not" inside this virtual 3d space but,rather outside of it, in our own "real" 3d space then, we must bring this virtual world towards us at (0,0,0). Otherwise, 3d objects(gun, ect.) attached to our first person or the third person object, will just go off into the distance as we translate(move) them inside virtual 3d space.

Thus we move the 3d virtual scene sort of in an inverse way to the way these 3d objects move, in order to keep a focus on them.

The example below might prove once and for all that there is a default camera at (0,0,0) origin that can see, in a very myopic way, inside 3d virtual space. Notice that there is no projection setup or viewport or matrices or gluLookAt to refine the viewing parameters. But, the pyramid can clearly be seen. Translate ir or rotate it, and it will start to be clipped out of view.

We can see it because thereīs a rudimmentary viewing defaul set up. Call it a camera or not.

I think the pyramid example will complie with any C++ compiler, given the right linkers, ect.

Live long and prosper.

BeginOpenGL

/***************************************
* PYRAMID
*
***************************************/
/*Includes*/
#include <windows.h>
#include <gl/gl.h>

/**************************
* Function Declarations
*
**************************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);

/**************************
* WinMain
*
**************************/

int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int iCmdShow)
{
WNDCLASS wc;
HWND hWnd;
HDC hDC;
HGLRC hRC;
MSG msg;
BOOL bQuit = FALSE;
/*īdeclare the var theta, to be used as an angle in rotations*/
float theta = 0.0;

/* register window class */
wc.style = CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "GLSample";
RegisterClass (&wc);

/* create main window */
hWnd = CreateWindow (
"GLSample", "DEV C++ 4.9.8.0 3D Engine",
WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
0, 0, 1024, 768,
NULL, NULL, hInstance, NULL);

/* enable OpenGL for the window */
EnableOpenGL (hWnd, &hDC, &hRC);

/* program main loop */
while (!bQuit)
{
/* check for messages */
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
/* handle or dispatch messages */
if (msg.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
else
{
/* OPEN GL ANIMATION CODE FOR PRIMITIVES GOES BELOW */

/*Set the Background color to black*/
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
/*Clear previous frame color buffer to enable drawing of next frame*/
/*Clear previous frame depth buffer to enable drawing of next frame*/
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*Clear existing internal tansformations by loading identity matrix*/
glLoadIdentity ();
/*move all vertices(the pyramid) 1 unit forward on z axis*/
glTranslatef (0, 0, -1);
/*rotate(spin) pyramid around itīs vertical Y axis*/
glRotatef (theta, 0, 1, 0);
/*access OpenGlīs matrix stack to save transformations*/
glPushMatrix ();
/*Join vertex 1,2,3..1,3,4 and 1,4,5(vertice 1 is common to the rest)*/
glBegin (GL_TRIANGLE_FAN);
/*assign color and position in 3d space to each vertex thru its 3 coords*/
glColor3f (0,.5, 1); glVertex3f ( 0, 1, 0);
glColor3f (1, .5, 0); glVertex3f (-1,-1, 1);
glColor3f (1, .3, 1); glVertex3f ( 1,-1, 1);
glColor3f (.2, 0, 1); glVertex3f ( 1,-1,-1);
glColor3f (0, 1, 0); glVertex3f (-1,-1,-1);
glColor3f (1, .7, 0); glVertex3f (-1,-1, 1);
glEnd ();
/*restore OpenGlīs matrix stack transformations to continue to translatef*/
glPopMatrix ();
/*Make the pyramid visible*/
SwapBuffers (hDC);

theta += .5;
Sleep (1);
}
}

/* shutdown OpenGL */
DisableOpenGL (hWnd, hDC, hRC);

/* destroy the window explicitly */
DestroyWindow (hWnd);

return msg.wParam;
}

/********************
* Window Procedure
*
********************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{

switch (message)
{
case WM_CREATE:
return 0;
case WM_CLOSE:
PostQuitMessage (0);
return 0;

case WM_DESTROY:
return 0;

case WM_KEYDOWN:
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;

default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
}

/*******************
* Enable OpenGL
*
*******************/

void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;

/* get the device context (DC) */
*hDC = GetDC (hWnd);

/* set the pixel format for the DC */
ZeroMemory (&pfd, sizeof (pfd));
pfd.nSize = sizeof (pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat (*hDC, &pfd);
SetPixelFormat (*hDC, iFormat, &pfd);

/* create and enable the render context (RC) */
*hRC = wglCreateContext( *hDC );
wglMakeCurrent( *hDC, *hRC );

}

/******************
* Disable OpenGL
*
******************/

void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent (NULL, NULL);
wglDeleteContext (hRC);
ReleaseDC (hWnd, hDC);
}

mikeman
04-28-2004, 09:08 AM
BeginOpenGL,I would advise you to just read and learn well about matrix operations,it's one of the fundamentals of OpenGL.I can't honestly say that i understood what you're trying to say or prove there,but you seem to have misunderstood some things.I mean,you push the matrix,have no operations on it,and then you pop the matrix again!And you certainly have to define a viewport,that's where your world is rendered!
To be short,OpenGL does not have a camera of any kind,default,myopic or whatever.There are only modelview&projection matrices.You pass the vertex data in worldspace,modelview transforms them into eyespace,projection transforms them to clip coordinates,and eventually they are converted to window coordinates.The "camera" is an abstract idea,we use the modelview matrix to define its position and orientation but OpenGL has no knowledge of that,OpenGL knows only the modelview matrix.

BeginOpenGL
04-28-2004, 09:32 AM
"I mean,you push the matrix,have no operations on it,and then you pop the matrix again!"

Yeah, I took all that stuff out which I had originally added to the example, to simplify it. Except, push/pop matrix, which I forgot. . But, you can still "see" the pyramid. Clearly....and itīs "inside" 3d space, not just a 2d pasted image with no Z axis(Depth).

Compile it.

BeginOpenGL

Andrew Davey
04-28-2004, 11:13 AM
hmmm, right i am not sure i explained myself very well, so i will try with some ascii art. Lets say i have a camera looking at a point i would just like to work out how much it can see, periferal vision so to speak. So here is my area that i am looking at:


|-------------------------|
| ^ |
| <---------|----------> |
| | |
| | |
| V |
|-------------------------|So the two arrows show the periferal vision i was talking about. So obviously the amount i can see is dependant on the z axis, for instance if i am at 300 then i might see in between the following x ranges -400 +400 but if the Z was at 20 then my viewing of x might onbly be -100 +100.

Does this maybe explain myself better?? i would just basically try and work this out so my camera can then realign itself automatically so it can see all objects in its periferal vision.

Better???

Aeluned
04-28-2004, 11:51 AM
What do you mean 'realign itself'?

Are you trying to keep all objects in the scene visible (that is, not be outside the field of view, peripheral vision, whatever you want to call it) as the camera moves into the screen?

naturally, as you're walking into a scene objects in your peripheral vision will eventually end up outside of your field of view.

If what you want to do is keep all objects visible as the camera moves forward then you need to adjust your field of view as a function of the camera movement. The field of view is set in your gluPerspective call.

I'm not sure if this is what you mean or are trying to achieve - this sort of thing is very unnatural.

Andrew Davey
04-28-2004, 12:10 PM
just about.

Ok here is what my program/simulation does.

I create a tree using lines and random numbers, the program also creates more than one tree. But the starting point is completely random, well it has constraints like ranges. Buts ome times the ranges fall behind or out of the cameras default view. So basically the ealign itself is just so the camera can find the best position in order to see all the trees.

Thats what happens and that is why o would like to do it. It would be unnatural if my trees all grew in the field of view everytime, as eventually the trees will drop seeds and wind might move these seeds all over the shop, to coin a phrase. And if i limitewd it to just in the default camera view then it would not make the simulation as natural as it could be.

Catch my drift?

Andrew Davey
04-28-2004, 12:13 PM
Also this is only to work out the default position, i understand that as soon as i move it will make the trees go out of my field of vision. Thats ok.

I just need to find a default which in its fiedl of view all the trees are present, and i wondered if anyone knew of a way to do this our could help by guessing or what not.

BeginOpenGL
04-28-2004, 01:41 PM
Andrew Davey

Take a look at this example. It might be what youīre looking for. It uses various resize functions which probably help in finding a centered default location for the object thru the use of gluPerspective, ect..

gluPerspective( 45.0, aspect, 3.0, 7.0 );

Example no. 6 at Nehe is also a good example since it has player movement. But, that makeshift house or whatever it is, is always centered. As long as itīs within the use`īs field of view.

BeginOpenGL

Cylinder (http://www.opengl.org/discussion_boards/cgi_directory/ultimatebb.cgi?ubb=get_topic;f=2;t=016229)

04-29-2004, 05:19 PM
Cameras or no cameras, he's using gluLookAt apparently so for the sake of arguments lets pretend there are cameras ok? basically what i would do is:

1) generate all the trees for that frame
2) average all their centers to find the center of the scene
3) set that as the "look at" point
4) place the camera at an arbitrary position
5) loop thourgh all the trees and use gluProject to find the window coordinates of the center of each tree.
6) if any are outside or very close to the edge of the viewport then move the camera back a small amount along the vector from the focal point to the camera position to zoom out.
7) repeat #6 and #7 until no trees are outside the window.

You can render each step for a smooth transition if you like, and in a similar way you could also zoom in if trees are deleted by finding the minimum distance of a tree from the edge of the window and if its too big then zoom in.

I hope that helps