Hi,
I’m new to opengl, and trying to create a small project with it. I have created some kind of a floor on the x-y plane, and I want to be able to turn the camera with the arrows to look around.
I created an array for the camera position ([x,y,z] values) and an array for the direction of viewing which is added to the camera location to get the look at point. Both these parameters - the camera location and the look at should be able to receive any value (within the perspective), I want to be able to change them later as I want while the program is running.
At first I calculate the degree of the viewing direction with the x axis, and for every arrow key press I increase this degree by 0.01.
What I don’t understand, is why when creating the rotation, I need to add 90 degrees to the starting angle. If I don’t add the 90 degrees, the viewing direction is as expected, but when I press the arrow keys (which add the right values as seems), the rotation jumps 90 degrees back (clockwise) and then continues smoothly.
Can anyone help me with this?
My code:
#include <GL\glut.h>
#include <cmath>
#include <math.h>
double rotationAngle;
bool isPerspective;
double winSizeX;
double winSizeY;
bool rightMouseDown;
int mouseX;
int mouseY;
int deltaX;
int deltaY;
float currentViewDirection[3] = { 1, 1, 0 };
float currentCameraLocation[3] = { 0, 5, 5 };
const double PI = 3.141592653589793238463;
float xViewAngle;
void drawFloor(void) {
for (int row = -50; row <= 50; row++)
{
for (int col = -50; col <= 50; col++)
{
int colorNum = (abs(row) % 3) + (abs(col) % 3) - 1;
switch (colorNum)
{
case 0:
{
glColor3ub(254, 232, 178);
break;
}
case 1:
{
glColor3ub(79, 39, 0);
break;
}
case 2:
{
glColor3ub(168, 67, 0);
break;
}
}
glBegin(GL_POLYGON);
glVertex3d(row, col, 0);
glVertex3d(row + 1, col, 0);
glVertex3d(row + 1, col + 1, 0);
glVertex3d(row, col + 1, 0);
glEnd();
}
}
}
void display(void)
{
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(currentCameraLocation[0], currentCameraLocation[1], currentCameraLocation[2],
currentCameraLocation[0] + currentViewDirection[0], currentCameraLocation[1] + currentViewDirection[1], currentCameraLocation[2] + currentViewDirection[2],
0, 0, 1);
drawFloor();
glutSwapBuffers();
}
void reshape(int x, int y) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLdouble)1200 / (GLdouble)900, 0.1f, 1000);
glViewport(0, 0, 1200, 900);
}
void specialInput(int key, int x, int y)
{
float vectorLength = sqrt(currentViewDirection[0] * currentViewDirection[0] + currentViewDirection[1] * currentViewDirection[1] + currentViewDirection[2] * currentViewDirection[2]);
switch (key)
{
case GLUT_KEY_LEFT:
{
xViewAngle -= 0.01f;
currentViewDirection[0] = -cos(xViewAngle) * vectorLength;
currentViewDirection[1] = sin(xViewAngle) * vectorLength;
break;
}
case GLUT_KEY_RIGHT:
{
xViewAngle += 0.01f;
currentViewDirection[0] = -cos(xViewAngle) * vectorLength;
currentViewDirection[1] = sin(xViewAngle) * vectorLength;
break;
}
}
}
int main(int argc, char **argv)
{
if (currentViewDirection[0] != 0) {
xViewAngle = atan(currentViewDirection[1] / currentViewDirection[0]);
}
else {
if (currentViewDirection[1] > 0) {
xViewAngle = PI/2;
}
else
{
xViewAngle = -PI/2;
}
}
// if this is removed, the rotation will jump at the beginning
xViewAngle += PI / 2;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 50);
glutInitWindowSize(1200, 900);
glutCreateWindow("A");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
glutSpecialFunc(specialInput);
glutMainLoop();
return 0;
}