PDA

View Full Version : Camera Rotation Using gluLookAt



Reaperc89
10-18-2011, 06:31 PM
First openGL project, and i'm having some troubles implementing the gluLookAt routine with the purpose of orbiting the "camera" around the origin. The program runs properly, and it orbits properly, but the issue is that it also seems to move further away/closer from the origin as I orbit. I'm sure it's a simple oversight on my part, but I can't seem to figure out what the problem is.

Any feedback would be greatly appreciated.

#include <GL/freeglut.h>
#include <GL/glui.h>

void init(void);
void main_menu(int item);
void sub_menu(int item);
void display(void);
void reshape(void);
void button_handler(int x);
void radio_handler(int x);
void draw_interface(void);
void mouse_handler(int x, int y);
void motion_handler(int x, int y);
void camera_movement(float x, float y);

static int display_selection = 2;
static int model_selection = 0;
static int button_pressed;
static int mouse_x;
static int mouse_y;
static float rotate_x;
static float rotate_y;


enum
{
Load, Exit,
DisplayRadio, ModelRadio,
Pressed,
};

void init(void)
{
glClearColor(0.0,0.0,0.0,0.0);

}

void main_menu(int menu_item)
{
glutPostRedisplay();
return;
}

void sub_menu(int menu_item)
{
glutPostRedisplay();
return;
}

void button_handler(int button_handle)
{
}

void radio_handler(int radio_handle)
{
display();
}

void mouse_handler(int button, int state, int x, int y)
{

if(state == GLUT_DOWN)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
button_pressed = Pressed;
break;
case GLUT_RIGHT_BUTTON:
button_pressed = Pressed;
break;
default:
break;
}

mouse_x = x;
mouse_y = y;

}
else if (state == GLUT_UP)
{
}
}

void motion_handler(int x, int y)
{
switch(button_pressed)
{
case Pressed:
rotate_x += ((x - mouse_x)*0.25);
rotate_y -= ((y - mouse_y)*0.25);
break;
}

mouse_x = x;
mouse_y = y;

glutPostRedisplay();
}

void camera_movement(float x, float y)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(-x ,-y ,5.0,
0.0,0.0,0.0,
0.0,1.0,0.0);
}

void draw_interface(void)
{
GLint mainMenu, subMenu;

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(700,500);
glutInitWindowPosition(100,100);

int window_id = glutCreateWindow("Model Viewer");

subMenu = glutCreateMenu(sub_menu);
glutAddMenuEntry("WireFrame",1);
glutAddMenuEntry("Vertex",2);
glutAddMenuEntry("Shaded",3);

mainMenu = glutCreateMenu(main_menu);
glutAddMenuEntry("Load", 1);
glutAddMenuEntry("Exit", 2);
glutAddSubMenu("DisplayMode", subMenu);
glutAttachMenu(GLUT_RIGHT_BUTTON);

GLUI *glui_subwin = GLUI_Master.create_glui_subwindow(window_id, GLUI_SUBWINDOW_LEFT);
glui_subwin->set_main_gfx_window(window_id);
glui_subwin->add_button("Load",Load,button_handler);
glui_subwin->add_button("Exit",Exit,button_handler);
glui_subwin->add_separator();

GLUI_Panel *display_panel = glui_subwin->add_panel("Display Mode",1);
GLUI_RadioGroup *display_group = glui_subwin->add_radiogroup_to_panel(display_panel,&amp;display_sel ection,DisplayRadio);
glui_subwin->add_radiobutton_to_group(display_group,"Vertex");
glui_subwin->add_radiobutton_to_group(display_group,"Wireframe");
glui_subwin->add_radiobutton_to_group(display_group,"Shaded");

GLUI_Panel *model_panel = glui_subwin->add_panel("Demo Models",1);
GLUI_RadioGroup *model_group = glui_subwin->add_radiogroup_to_panel(model_panel,&amp;model_selecti on,ModelRadio);
glui_subwin->add_radiobutton_to_group(model_group,"Cube");
glui_subwin->add_radiobutton_to_group(model_group,"Sphere");
glui_subwin->add_radiobutton_to_group(model_group,"Teapot");

}


void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);

camera_movement(rotate_x, rotate_y);


//Change display mode vertex/wireframe/shaded polygon
switch(display_selection)
{
glTranslatef(0.0,0.0,0.0);

case 0:
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
break;
case 1:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
break;
case 2:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
break;
default:
break;
}

//Preloaded mesh selection
switch(model_selection)
{
case 0:
glutSolidCube(1.0);
break;
case 1:
glutSolidSphere(0.65,90,90);
break;
case 2:
glutSolidTeapot(0.50);
break;
default:
break;
}

glFlush();
}

void reshape(int w, int h)
{
GLUI_Master.auto_set_viewport();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.0, 1.0, 3.0, 15.0);
glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char *argv[]){

glutInit(&amp;argc, argv);
GLUI_Master.set_glutIdleFunc(NULL);
draw_interface();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse_handler);
glutMotionFunc(motion_handler);
glutMainLoop();

return 0;
}

Reaperc89
10-19-2011, 04:00 PM
Bump bump. Still messing around with this, no clue what the issue is.

carsten neumann
10-19-2011, 04:26 PM
Please use [ code]/[ /code] (without space after '[') around code snippets to make them more readable.

I haven't read all the code, you posted a lot that seems irrelevant to your problem, but I did not see any use of trigonometric functions to calculate the eye position, so I'm not sure that orbiting works correctly - almost certainly you are not moving on a circular path ;)

The basic setup to orbit around a given point is to calculate the eye position on a circle around that point and set the centre position to the center of the circle, and the up vector to the normal of the plane the circle is in.

Reaperc89
10-19-2011, 05:43 PM
My mistake. I have made some revisions, and here is a snippet of the camera code. I am assuming my lack of understanding in the trig department is what is leaving me dumb founded. I have attempted to interpret other examples, but I continue to achieve the same results with no idea why.



void mouse_handler(int button, int state, int x, int y)
{

if(state == GLUT_DOWN)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
button_pressed = Pressed;
mouse_xOrigin = x;
break;
}
}
else if (state == GLUT_UP)
{
}
}

void motion_handler(int x, int y)
{
switch(button_pressed)
{
case Pressed:
mouse_changeAngle = (x - mouse_xOrigin) * 0.25;
rotate_x += (5*(cos(mouse_changeAngle)));
rotate_z = (5*(sin(mouse_changeAngle)));
break;
}

glutPostRedisplay();
}

void camera_movement(float x, float y, float z)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(-x ,0.0,-z,
0.0,0.0,0.0,
0.0,1.0,0.0);
}

void camera_movement(float x, float y, float z)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(-x ,0.0,-z,
0.0,0.0,0.0,
0.0,1.0,0.0);
}

Reaperc89
10-19-2011, 08:15 PM
Problem Solved. The joys of cameras.