[QUOTE=Carmine;1280900]It sounds like you’re making this harder than it should be.
If you post a complete, simplified, version of your code, I’ll look at it and make some suggestions.
Make it as simple as possible, removing all routines, objects, that aren’t pertinent to the issue.
I have to be able to compile, link, and run it.
Include a statement saying what the code does wrong and/or what you want it to do.
Also, you’ll get more responses if you put your code in [ code] and [ /code] tags (without the spaces).[/QUOTE]
Fair enough. I simplified it as best as I could and I used a lot of commenting in my code so that it would be quicker to grasp what I’m trying to do. Other than the rotation and positioning of my sphere/spaceship not matching the world camera view despite using the inverted matrix for its position, the following are some caveats so that anyone looking at the code doesn’t misunderstand anything:
-
I’m assuming that for multiplying the rotation matrices, I was supposed to go X * Y = XY, and then XY * Z = final rotation. If the order is wrong, I would appreciate a correction so that I can change it. They are “not perfect” axis-angle rotations that gimbal lock after flying around on all axes for a couple of minutes. I would suggest just yawing around on the XZ plane for now to test out the problem with the sphere/spaceship not matching the world camera view. I eventually want to make this bulletproof by using Quaternions which I’m in the process of learning more about. If there is a “gimbal-lock-proof” axis-angle rotation that I could use in place of what I used in my code, I would appreciate any help in this regard.
-
I’m assuming that for setting up the world view of the camera, I had to do the rotations first for the world view and then the translation for the world view. If I did them backwards, then please let me know.
-
I compiled this using Mac OS X and can be compiled from the console without setting up a project file in Xcode. The comments at the beginning include instructions for which header files to include for Mac OS X and for Linux as well as the console compiling instructions for each. They were not tested on Windows at all. I’m assuming that anyone reading this forum who may not be as savvy as you fine gentlemen may want to try out the code as well so that’s why I commented like crazy and included details for compiling instructions for Mac OS X and Linux. I figure that both you and GClements know what you’re doing.
With all that out of the way, here is the code:
//
// SpaceTrip.cpp
//
#include <OpenGL/gl.h> // For Mac OS X.
#include <GLUT/glut.h> // For Mac OS X.
//
// For Mac OS X, compile using: g++ -o SpaceTrip SpaceTrip.cpp -framework OpenGL - framework GLUT
//
//
// For Linux: #include <GL/gl.h>
// " #include <GL/glu.h>
// " #include <GL/glut.h>
//
// Compile using: g++ -o SpaceTrip SpaceTrip.cpp -lglut -lGLU -lGL
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <iostream>
using namespace std;
// update rate (60 fps)
int interval = 1000 / 60;
GLfloat DegreesToRadians(GLfloat angle_in_degrees);
void MultiplyTheMatrices();
bool InvertTheMatrix();
GLfloat move_dist_x = 0.0; GLfloat move_dist_y = 0.0; GLfloat move_dist_z = 0.0;
// spaceship (user's view) coordinates
GLfloat spaceship_x = 0.0; GLfloat spaceship_y = 0.0; GLfloat spaceship_z = 0.0;
// rotation of user's view
GLfloat yaw_angle = 0.0; GLfloat pitch_angle = 0.0; GLfloat roll_angle = 0.0;
GLfloat user_speed = 0.0;
GLfloat cam_right_vector_x = 0.0; GLfloat cam_right_vector_y = 0.0; GLfloat cam_right_vector_z = 0.0;
GLfloat cam_up_vector_x = 0.0; GLfloat cam_up_vector_y = 0.0; GLfloat cam_up_vector_z = 0.0;
GLfloat cam_look_vector_x = 0.0; GLfloat cam_look_vector_y = 0.0; GLfloat cam_look_vector_z = 0.0;
GLfloat rot_x_mat[16]; // rotation x matrix with values set in MultiplyTheMatrices() function
GLfloat rot_y_mat[16]; // rotation y matrix with values set in MultiplyTheMatrices() function
GLfloat rot_z_mat[16]; // rotation z matrix with values set in MultiplyTheMatrices() function
GLfloat temp_mat[16]; // first step in rotation matrix calculation by multiplying (rot_x_mat * rot_y_mat)
GLfloat rot[16]; // final rotation matrix created by multiplying (temp_mat * rot_z_mat)
GLfloat view_mat[16]; // array used to grab matrix values from GL_MODELVIEW_MATRIX after rotations for the world view are performed but before the translation of the world view is performed
GLfloat m[16]; // array used to grab matrix values from GL_MODELVIEW_MATRIX after both the rotations for the world view and the translation of the world view are performed
GLfloat inv[16]; // array used by the InvertTheMatrix() function
GLfloat inv_mat[16]; // array used to store the inverted form of the world view matrix stored in m[16] so that the spaceship/wiresphere can be positioned at the world camera coordinate facing in the same direction as the camera view
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
}
void display()
{
// clear (has to be done at the beginning)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3ub(255, 255, 255);
// save the matrix before updating the position of the entire universe
glPushMatrix();
MultiplyTheMatrices(); // take my pitch, yaw, and roll angles and create a rotation matrix: rot
glMultMatrixf(rot); // take my rotation matrix and multiply it against the MODELVIEW matrix
// copy the current values located in the MODELVIEW_MATRIX which includes the rotations
glGetFloatv(GL_MODELVIEW_MATRIX, view_mat);
cam_right_vector_x = view_mat[0];
cam_right_vector_y = view_mat[4];
cam_right_vector_z = view_mat[8];
cam_up_vector_x = view_mat[1];
cam_up_vector_y = view_mat[5];
cam_up_vector_z = view_mat[9];
cam_look_vector_x = view_mat[2];
cam_look_vector_y = view_mat[6];
cam_look_vector_z = view_mat[10];
// view coordinate update
move_dist_x = user_speed * (-cam_look_vector_x);
move_dist_y = user_speed * (-cam_look_vector_y);
move_dist_z = user_speed * (-cam_look_vector_z);
spaceship_x = spaceship_x + move_dist_x;
spaceship_y = spaceship_y + move_dist_y;
spaceship_z = spaceship_z + move_dist_z;
glTranslatef(-spaceship_x, -spaceship_y, -spaceship_z); // place the view at the coordinates I want by "moving the universe"
glGetFloatv(GL_MODELVIEW_MATRIX, m);
InvertTheMatrix(); // make an inverted matrix of the current MODELVIEW_MATRIX and store it in inv_mat.
// place the spaceship that I'm sitting in at the exact center of my view
glPushMatrix();
glLoadMatrixf(inv_mat); // apply the inverted matrix in order to position my spaceship/sphere at the correct view position and rotation as the world view - NOT WORKING PROPERLY, NEED HELP WITH THIS.
glColor3ub(220, 220, 220);
glutWireSphere(20.0f, 20, 20);
glPopMatrix();
// place some extra wire spheres around so that flying through space doesn't look completely empty
glPushMatrix();
glTranslatef(0.0, 0.0, -7500.0);
glColor3ub(80, 150, 255);
glutWireSphere(500.0f, 20, 20); // big blue sphere positioned starting 7500 units in front of you
glPopMatrix();
glPushMatrix();
glTranslatef(0.0, 0.0, 300.0);
glColor3ub(255, 0, 0);
glutWireSphere(200.0f, 20, 20); // small red sphere positioned starting 300 units behind you
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'l':
// increase speed
if(user_speed < 20.0)
user_speed = user_speed + 1.0;
break;
case 'k':
// decrease speed
if(user_speed >= 1.0)
user_speed = user_speed - 1.0;
break;
case '2':
// pitch up
pitch_angle = pitch_angle - 4.5;
if (pitch_angle <= -360.0)
pitch_angle = pitch_angle + 360.0;
break;
case '8':
// pitch down
pitch_angle = pitch_angle + 4.5;
if (pitch_angle >= 360.0)
pitch_angle = pitch_angle - 360.0;
break;
case '4':
// yaw to the left
yaw_angle = yaw_angle - 4.5;
if (yaw_angle <= -360.0)
yaw_angle = yaw_angle + 360.0;
break;
case '6':
// yaw to the right
yaw_angle = yaw_angle + 4.5;
if (yaw_angle >= 360.0)
yaw_angle = yaw_angle - 360.0;
break;
case '1':
// pitch up and yaw to the left
pitch_angle = pitch_angle - 4.5;
if (pitch_angle <= -360.0)
pitch_angle = pitch_angle + 360.0;
yaw_angle = yaw_angle - 4.5;
if (yaw_angle <= -360.0)
yaw_angle = yaw_angle + 360.0;
break;
case '3':
// pitch up and yaw to the right
pitch_angle = pitch_angle - 4.5;
if (pitch_angle <= -360.0)
pitch_angle = pitch_angle + 360.0;
yaw_angle = yaw_angle + 4.5;
if (yaw_angle >= 360.0)
yaw_angle = yaw_angle - 360.0;
break;
case '7':
// pitch down and yaw to the left
pitch_angle = pitch_angle + 4.5;
if (pitch_angle >= 360.0)
pitch_angle = pitch_angle - 360.0;
yaw_angle = yaw_angle - 4.5;
if (yaw_angle <= -360.0)
yaw_angle = yaw_angle + 360.0;
break;
case '9':
// pitch down and yaw to the right
pitch_angle = pitch_angle + 4.5;
if (pitch_angle >= 360.0)
pitch_angle = pitch_angle - 360.0;
yaw_angle = yaw_angle + 4.5;
if (yaw_angle >= 360.0)
yaw_angle = yaw_angle - 360.0;
break;
case ',':
// roll to the left
roll_angle = roll_angle - 4.5;
if (roll_angle <= -360.0)
roll_angle = roll_angle + 360.0;
break;
case '.':
// roll to the right
roll_angle = roll_angle + 4.5;
if (roll_angle >= 360.0)
roll_angle = roll_angle - 360.0;
break;
case 'b':
exit(0);
break;
default:
break;
}
}
void update(int value)
{
glutTimerFunc(interval, update, 0);
glutPostRedisplay();
}
void reshape(int width, int height)
{
glViewport(0, 0, (GLsizei) width, (GLsizei) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, (GLfloat) width/(GLfloat) height, 1.0f, 1000000.0f);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
}
GLfloat DegreesToRadians(GLfloat angle_in_degrees)
{
GLfloat radians = 0.0;
radians = ((angle_in_degrees * 3.141592653589793238462643383279) / 180.0);
return radians;
}
void MultiplyTheMatrices()
{
rot_x_mat[0] = 1.0;
rot_x_mat[1] = 0.0;
rot_x_mat[2] = 0.0;
rot_x_mat[3] = 0.0;
rot_x_mat[4] = 0.0;
rot_x_mat[5] = cosf(DegreesToRadians(pitch_angle));
rot_x_mat[6] = sinf(DegreesToRadians(pitch_angle));
rot_x_mat[7] = 0.0;
rot_x_mat[8] = 0.0;
rot_x_mat[9] = -(sinf(DegreesToRadians(pitch_angle)));
rot_x_mat[10] = cosf(DegreesToRadians(pitch_angle));
rot_x_mat[11] = 0.0;
rot_x_mat[12] = 0.0;
rot_x_mat[13] = 0.0;
rot_x_mat[14] = 0.0;
rot_x_mat[15] = 1.0;
rot_y_mat[0] = cosf(DegreesToRadians(yaw_angle));
rot_y_mat[1] = 0.0;
rot_y_mat[2] = -(sinf(DegreesToRadians(yaw_angle)));
rot_y_mat[3] = 0.0;
rot_y_mat[4] = 0.0;
rot_y_mat[5] = 1.0;
rot_y_mat[6] = 0.0;
rot_y_mat[7] = 0.0;
rot_y_mat[8] = sinf(DegreesToRadians(yaw_angle));
rot_y_mat[9] = 0.0;
rot_y_mat[10] = cosf(DegreesToRadians(yaw_angle));
rot_y_mat[11] = 0.0;
rot_y_mat[12] = 0.0;
rot_y_mat[13] = 0.0;
rot_y_mat[14] = 0.0;
rot_y_mat[15] = 1.0;
rot_z_mat[0] = cosf(DegreesToRadians(roll_angle));
rot_z_mat[1] = -(sinf(DegreesToRadians(roll_angle)));
rot_z_mat[2] = 0.0;
rot_z_mat[3] = 0.0;
rot_z_mat[4] = sinf(DegreesToRadians(roll_angle));
rot_z_mat[5] = cosf(DegreesToRadians(roll_angle));
rot_z_mat[6] = 0.0;
rot_z_mat[7] = 0.0;
rot_z_mat[8] = 0.0;
rot_z_mat[9] = 0.0;
rot_z_mat[10] = 1.0;
rot_z_mat[11] = 0.0;
rot_z_mat[12] = 0.0;
rot_z_mat[13] = 0.0;
rot_z_mat[14] = 0.0;
rot_z_mat[15] = 1.0;
temp_mat[0] = (rot_x_mat[0] * rot_y_mat[0]) + (rot_x_mat[4] * rot_y_mat[1]) + (rot_x_mat[8] * rot_y_mat[2]) + (rot_x_mat[12] * rot_y_mat[3]);
temp_mat[1] = (rot_x_mat[0] * rot_y_mat[4]) + (rot_x_mat[4] * rot_y_mat[5]) + (rot_x_mat[8] * rot_y_mat[6]) + (rot_x_mat[12] * rot_y_mat[7]);
temp_mat[2] = (rot_x_mat[0] * rot_y_mat[8]) + (rot_x_mat[4] * rot_y_mat[9]) + (rot_x_mat[8] * rot_y_mat[10]) + (rot_x_mat[12] * rot_y_mat[11]);
temp_mat[3] = (rot_x_mat[0] * rot_y_mat[12]) + (rot_x_mat[4] * rot_y_mat[13]) + (rot_x_mat[8] * rot_y_mat[14]) + (rot_x_mat[12] * rot_y_mat[15]);
temp_mat[4] = (rot_x_mat[1] * rot_y_mat[0]) + (rot_x_mat[5] * rot_y_mat[1]) + (rot_x_mat[9] * rot_y_mat[2]) + (rot_x_mat[13] * rot_y_mat[3]);
temp_mat[5] = (rot_x_mat[1] * rot_y_mat[4]) + (rot_x_mat[5] * rot_y_mat[5]) + (rot_x_mat[9] * rot_y_mat[6]) + (rot_x_mat[13] * rot_y_mat[7]);
temp_mat[6] = (rot_x_mat[1] * rot_y_mat[8]) + (rot_x_mat[5] * rot_y_mat[9]) + (rot_x_mat[9] * rot_y_mat[10]) + (rot_x_mat[13] * rot_y_mat[11]);
temp_mat[7] = (rot_x_mat[1] * rot_y_mat[12]) + (rot_x_mat[5] * rot_y_mat[13]) + (rot_x_mat[9] * rot_y_mat[14]) + (rot_x_mat[13] * rot_y_mat[15]);
temp_mat[8] = (rot_x_mat[2] * rot_y_mat[0]) + (rot_x_mat[6] * rot_y_mat[1]) + (rot_x_mat[10] * rot_y_mat[2]) + (rot_x_mat[14] * rot_y_mat[3]);
temp_mat[9] = (rot_x_mat[2] * rot_y_mat[4]) + (rot_x_mat[6] * rot_y_mat[5]) + (rot_x_mat[10] * rot_y_mat[6]) + (rot_x_mat[14] * rot_y_mat[7]);
temp_mat[10] = (rot_x_mat[2] * rot_y_mat[8]) + (rot_x_mat[6] * rot_y_mat[9]) + (rot_x_mat[10] * rot_y_mat[10]) + (rot_x_mat[14] * rot_y_mat[11]);
temp_mat[11] = (rot_x_mat[2] * rot_y_mat[12]) + (rot_x_mat[6] * rot_y_mat[13]) + (rot_x_mat[10] * rot_y_mat[14]) + (rot_x_mat[14] * rot_y_mat[15]);
temp_mat[12] = (rot_x_mat[3] * rot_y_mat[0]) + (rot_x_mat[7] * rot_y_mat[1]) + (rot_x_mat[11] * rot_y_mat[2]) + (rot_x_mat[15] * rot_y_mat[3]);
temp_mat[13] = (rot_x_mat[3] * rot_y_mat[4]) + (rot_x_mat[7] * rot_y_mat[5]) + (rot_x_mat[11] * rot_y_mat[6]) + (rot_x_mat[15] * rot_y_mat[7]);
temp_mat[14] = (rot_x_mat[3] * rot_y_mat[8]) + (rot_x_mat[7] * rot_y_mat[9]) + (rot_x_mat[11] * rot_y_mat[10]) + (rot_x_mat[15] * rot_y_mat[11]);
temp_mat[15] = (rot_x_mat[3] * rot_y_mat[12]) + (rot_x_mat[7] * rot_y_mat[13]) + (rot_x_mat[11] * rot_y_mat[14]) + (rot_x_mat[15] * rot_y_mat[15]);
rot[0] = (temp_mat[0] * rot_z_mat[0]) + (temp_mat[4] * rot_z_mat[1]) + (temp_mat[8] * rot_z_mat[2]) + (temp_mat[12] * rot_z_mat[3]);
rot[1] = (temp_mat[0] * rot_z_mat[4]) + (temp_mat[4] * rot_z_mat[5]) + (temp_mat[8] * rot_z_mat[6]) + (temp_mat[12] * rot_z_mat[7]);
rot[2] = (temp_mat[0] * rot_z_mat[8]) + (temp_mat[4] * rot_z_mat[9]) + (temp_mat[8] * rot_z_mat[10]) + (temp_mat[12] * rot_z_mat[11]);
rot[3] = (temp_mat[0] * rot_z_mat[12]) + (temp_mat[4] * rot_z_mat[13]) + (temp_mat[8] * rot_z_mat[14]) + (temp_mat[12] * rot_z_mat[15]);
rot[4] = (temp_mat[1] * rot_z_mat[0]) + (temp_mat[5] * rot_z_mat[1]) + (temp_mat[9] * rot_z_mat[2]) + (temp_mat[13] * rot_z_mat[3]);
rot[5] = (temp_mat[1] * rot_z_mat[4]) + (temp_mat[5] * rot_z_mat[5]) + (temp_mat[9] * rot_z_mat[6]) + (temp_mat[13] * rot_z_mat[7]);
rot[6] = (temp_mat[1] * rot_z_mat[8]) + (temp_mat[5] * rot_z_mat[9]) + (temp_mat[9] * rot_z_mat[10]) + (temp_mat[13] * rot_z_mat[11]);
rot[7] = (temp_mat[1] * rot_z_mat[12]) + (temp_mat[5] * rot_z_mat[13]) + (temp_mat[9] * rot_z_mat[14]) + (temp_mat[13] * rot_z_mat[15]);
rot[8] = (temp_mat[2] * rot_z_mat[0]) + (temp_mat[6] * rot_z_mat[1]) + (temp_mat[10] * rot_z_mat[2]) + (temp_mat[14] * rot_z_mat[3]);
rot[9] = (temp_mat[2] * rot_z_mat[4]) + (temp_mat[6] * rot_z_mat[5]) + (temp_mat[10] * rot_z_mat[6]) + (temp_mat[14] * rot_z_mat[7]);
rot[10] = (temp_mat[2] * rot_z_mat[8]) + (temp_mat[6] * rot_z_mat[9]) + (temp_mat[10] * rot_z_mat[10]) + (temp_mat[14] * rot_z_mat[11]);
rot[11] = (temp_mat[2] * rot_z_mat[12]) + (temp_mat[6] * rot_z_mat[13]) + (temp_mat[10] * rot_z_mat[14]) + (temp_mat[14] * rot_z_mat[15]);
rot[12] = (temp_mat[3] * rot_z_mat[0]) + (temp_mat[7] * rot_z_mat[1]) + (temp_mat[11] * rot_z_mat[2]) + (temp_mat[15] * rot_z_mat[3]);
rot[13] = (temp_mat[3] * rot_z_mat[4]) + (temp_mat[7] * rot_z_mat[5]) + (temp_mat[11] * rot_z_mat[6]) + (temp_mat[15] * rot_z_mat[7]);
rot[14] = (temp_mat[3] * rot_z_mat[8]) + (temp_mat[7] * rot_z_mat[9]) + (temp_mat[11] * rot_z_mat[10]) + (temp_mat[15] * rot_z_mat[11]);
rot[15] = (temp_mat[3] * rot_z_mat[12]) + (temp_mat[7] * rot_z_mat[13]) + (temp_mat[11] * rot_z_mat[14]) + (temp_mat[15] * rot_z_mat[15]);
}
bool InvertTheMatrix()
{
GLfloat det; int i;
inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] + m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] - m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10];
inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] + m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9];
inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] - m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9];
inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] - m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10];
inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] + m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10];
inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] - m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9];
inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] + m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9];
inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] + m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6];
inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] - m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6];
inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] + m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5];
inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] - m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5];
inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] - m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6];
inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] + m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6];
inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] - m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5];
inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] + m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5];
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
if (det == 0)
return false;
det = 1.0 / det;
for (i = 0; i < 16; i++)
inv_mat[i] = inv[i] * det;
return true;
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1024, 768);
glutInitWindowPosition(0, 0);
glutCreateWindow("Space Trip");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(interval, update, 0);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}