Perspective in OpenGL - opengl

I'm trying to draw a chess board in OpenGL. When I draw it in GL_MODELVIEW mode using glOrtho, it displays just fine. However, when I try to display it in GL_PROJECTION using gluPerspective, all I get is a black empty screen. I must have my projection matrix pointing at nothing, but I can't figure out where I am going wrong. Here is the relevant code:
double dim=2.0;
float fov=50;
double asp=1;
void chessboard() {
// define the board
float square_edge = 1;
float border = 0.5;
float board_thickness = 0.25;
float board_corner = 4*square_edge+border;
float board_width = 2*board_corner;
glPushMatrix();
glScalef(1/board_corner, 1/board_corner, 1/board_corner);
GLfloat board_vertices[8][3] = {
{-board_corner, board_corner, 0.0},
{-board_corner, -board_corner, 0.0},
{ board_corner, -board_corner, 0.0},
{ board_corner, board_corner, 0.0},
{-board_corner, board_corner, board_thickness},
{-board_corner, -board_corner, board_thickness},
{ board_corner, -board_corner, board_thickness},
{ board_corner, board_corner, board_thickness}
};
float darkSquare[3] = {0,0,1};
float lightSquare[3] = {1,1,1};
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, board_vertices);
// this defines each of the six faces in counter clockwise vertex order
GLubyte boardIndices[] = {0,3,2,1,2,3,7,6,0,4,7,3,1,2,6,5,4,5,6,7,0,1,5,4};
glColor3f(0.3,0.3,0.3); //upper left square is always light
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0, 1.0);
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, boardIndices);
glPolygonOffset(0.0, 0.0);
glBegin(GL_QUADS);
// draw the individual squares on top of the board
for(int x = -4; x < 4; x++) {
for(int y = -4; y < 4; y++) {
//set the color of the square
if ( (x+y)%2 ) glColor3fv(darkSquare);
else glColor3fv(lightSquare);
glVertex3i(x*square_edge, y*square_edge, 0);
glVertex3i(x*square_edge+square_edge, y*square_edge, 0);
glVertex3i(x*square_edge+square_edge, y*square_edge+square_edge, 0);
glVertex3i(x*square_edge, y*square_edge+square_edge, 0);
}
}
glEnd();
glDisable(GL_POLYGON_OFFSET_FILL);
glPopMatrix();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
// glMatrixMode(GL_MODELVIEW);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set the view angle
glRotated(ph,1,0,0);
glRotated(th,0,1,0);
// Set the viewing matrix
// glOrtho(-dim, dim, dim, -dim, -dim, dim);
gluLookAt(0,-0.6,0.6,0,0,0,0,0,1);
gluPerspective(fov, asp, dim/4, dim);
draw_board();
glMatrixMode(GL_MODELVIEW);
glFlush();
glutSwapBuffers();
}

You should set projection matrix first, then use only modelview:
// code in display()
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// use ortho or perspective
// switch to modelview
glMatrixMode(GL_MODELVIEW);
drawScene();
do not use glRotate/glScale when in projection mode... it can only hurt you.
see here a good tutorial about this
another tutorial: lighthouse - glut - reshape. Usually Projection matrix is setup in reshape function only, then in RedenrScene() function only Modelview matrix is used.
Note that you are using old opengl and try to look for "modern" opengl tutorials.

Related

Draw 3D Cursor in screen coordinates from world coordinates of haptic device

So im rendering a curve with openGL. The curve is completely streched for a 1920 x 1080 Pixel Window. With this given relation i now want to analyse the proxy position in world coordinates of my haptic device and draw a 3D/2D Cursor for my window coordinates. How exactly do i have to transform my GL_MODELVIEW_MATRIX, GL_PROJECTION and GL_VIEWPORT to fit my proxy world coordinates (haptic device position) into screen coordinates? Or do i even have to do transformation. Even after researching i dont really understand the transformation of those matrix. So it would be very nice if you could help me here.
display func:
void renderDisplay() {
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
for (int i = 0; i < vertices.size(); i += 3) {
glVertex2f(vertices[i], vertices[i+2]);
}
glEnd();
glFlush();
hlBeginFrame();
hlCheckEvents();
drawCursor();
hlEndFrame();
}
Draw Cursor Func:
void drawCursor()
{
static const double kCursorRadius = 0.5;
static const double kCursorHeight = 1.5;
static const int kCursorTess = 15;
HLdouble proxyxform[16];
GLUquadricObj *qobj = 0;
glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT);
glPushMatrix();
if (!gCursorDisplayList)
{
gCursorDisplayList = glGenLists(1);
glNewList(gCursorDisplayList, GL_COMPILE);
qobj = gluNewQuadric();
gluCylinder(qobj, 0.0, kCursorRadius, kCursorHeight,
kCursorTess, kCursorTess);
glTranslated(0.0, 0.0, kCursorHeight);
gluCylinder(qobj, kCursorRadius, 0.0, kCursorHeight / 5.0,
kCursorTess, kCursorTess);
gluDeleteQuadric(qobj);
glEndList();
}
// Get the proxy transform in world coordinates.
hlGetDoublev(HL_PROXY_TRANSFORM, proxyxform);
glMultMatrixd(proxyxform);
// Apply the local cursor scale factor.
glScaled(gCursorScale, gCursorScale, gCursorScale);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glColor3f(0.0, 0.5, 1.0);
glCallList(gCursorDisplayList);
glPopMatrix();
glPopAttrib();
}
setup3DCursor Func:
void setup3DCursor(int width, int height)
{
GLdouble modelview[16];
GLdouble projection[16];
GLint viewport[4];
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewport);
hlMatrixMode(HL_TOUCHWORKSPACE);
hlLoadIdentity();
// Fit haptic workspace to view volume.
hluFitWorkspace(projection);
// Compute cursor scale.
gCursorScale = hluScreenToModelScale(modelview, projection, (HLint*)viewport);
gCursorScale *= CURSOR_SIZE_PIXELS;
}
main func:
findExtrema(); // Find limits for projection
gluOrtho2D(minX, maxX, minY, maxY) // Params: Left, right, bottom, top
glutDisplayFunc(renderDisplay);
glutReshapefunc(setup3DCursor);
So what exactly am i doing wrong here?

OpenGL Project - objects not keeping filling color on movement

When I execute the code I get a hot air balloon formed of three elements. My issue is that when I move the objects from the keyboard, the objects loose color, and become more like wire than solid.
From what I discovered until now, my trouble comes from this function call:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
But I need it to make the ropes...
/*
This program shows a hot air balloon rotating around its own axe to the left and to the right
*/
#include "glos.h"
#include<math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
void myinit(void);
void CALLBACK display(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
void CALLBACK rotateRight(void);
void CALLBACK rotateLeft(void);
static GLfloat x = 0;
static GLfloat y = 0;
static GLfloat z = 0;
static GLfloat alfa = 0;
double PI = 3.14159265;
void myinit (void) {
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
}
void CALLBACK rotateLeft(void) { y -= 5; }
void CALLBACK rotateRight(void) { y += 5; }
void CALLBACK display (void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(x, 1, 0, 0);
glRotatef(y, 0, 1, 0);
glTranslatef(0, -80, 0);
//cube = basket
glColor3f(1, 1, 0);
auxSolidCube(50);
//full sphere = baloon
glPushMatrix();
glColor3f(1.0, 0.0, 0.0);
glTranslatef(0,200,0);
glRotatef(-90, 1, 0, 0);
auxSolidSphere(130.0);
glPopMatrix();
//polygon cylinder = ropes
glPushMatrix();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUAD_STRIP);
glColor3f(0.0, 1.0, 1.0);
for (alfa = 0; alfa <= 360; alfa+=30) {
glVertex3f(65 * sin((PI * alfa) / 180), 100, 65 * cos((PI * alfa) / 180));//top of the cylinder
glVertex3f(15 * sin((PI * alfa) / 180),0, 15 * cos((PI * alfa) / 180));//base of the cylinder
}
glEnd();
glPopMatrix();
glPopMatrix();
glFlush();
}
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
if (!h) return;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho (-400,400, -400 *(GLfloat)h / (GLfloat)w, +400.0*(GLfloat)h/(GLfloat)w, -1000.0, 1000.0);
else
glOrtho (-400*(GLfloat)w / (GLfloat)h, 400.0*(GLfloat)w/(GLfloat)h, -400, 400.0, -1000.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGB | AUX_DEPTH);
auxInitPosition (100, 0, 600, 400);
auxInitWindow ("Hot air balloon");
myinit ();
auxKeyFunc(AUX_RIGHT, rotateRight);
auxKeyFunc(AUX_LEFT, rotateLeft);
auxReshapeFunc (myReshape);
auxMainLoop(display);
return(0);
}
OpenGL is a state engine. Once a state has been set, it is retained until it is changed again, even beyond frames. Therefore, you need to set the polygon mode GL_FILL before rendering the solid geometry:
void CALLBACK display (void)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// render solid geometry
// [...]
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// render wireframe geometry
// [...]
}

How to glutDisplayFunc, glutMainLoop in glfw?

I have a small program using glut and i need for many reasons to use glfw now. Since I have never used glfw I have a lot of problems.
The main ones are the functions : glutDisplayFunc, glutReshapeFunc, glutIdleFunc and glutMainLoop. I have just found out that there are no equivalent functions in glfw. How should I modify my program ?
My program is about a cone rotating in 3 dimensions
I have a function displaycone:
void displayCone(void){
// clear the drawing buffer.
glClear(GL_COLOR_BUFFER_BIT); //
// set matrix mode
glMatrixMode(GL_MODELVIEW);
// clear model view matrix
glLoadIdentity();
// multiply view matrix to current matrix
gluLookAt(3.0, 3.0, 3.0-4.5, 0.0, 0.0,-4.5,0,1,0);
// ******
glPushMatrix();
glTranslatef(0.0, 0.0, -4.5);
glBegin(GL_LINES);
glColor3f (1.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(2.0, 0.0, 0.0);
glColor3f (1.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 2.0, 0.0);
glColor3f (1.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 2.0);
glEnd();
glPopMatrix();
// clear the drawing buffer.
// traslate the draw by z = -4.0
// Note this when you decrease z like -8.0 the drawing will looks far , or smaller.
glTranslatef(0.0,0.0,-4.5);
// Red color used to draw.
glColor3f(0.8, 0.2, 0.1);
// changing in transformation matrix.
// rotation about X axis
glRotatef(xRotated,1.0,0.0,0.0);
// rotation about Y axis
glRotatef(yRotated,0.0,1.0,0.0);
// rotation about Z axis
glRotatef(zRotated,0.0,0.0,1.0);
// scaling transfomation
glScalef(1.0,1.0,1.0);
// built-in (glut library) function , draw you a Cone.
// move the peak of the cone to the origin
glTranslatef(0.0, 0.0, -height);
glutSolidCone(base,height,slices,stacks);
// Flush buffers to screen
// gluLookAt(3,3,3,0,0,-4.5,0,1,0); <----------------------- delete
glFlush();
// sawp buffers called because we are using double buffering
// glutSwapBuffers();
}
a function reshapecone:
void reshapeCone(int x, int y)
{
if (y == 0 || x == 0) return; //Nothing is visible then, so return
//Set a new projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//Angle of view:40 degrees
//Near clipping plane distance: 0.5
//Far clipping plane distance: 20.0
gluPerspective(35.0,(GLdouble)x/(GLdouble)y,0.5,20.0);
glViewport(0,0,x,y); //Use the whole window for rendering
}
and a function idleCone:
void idleCone(void)
{
for(int j = 1; j<10000 ; j++){
double i = dati[j+1][0];
int win = glfwGetWindow();
if(i == 0.) break;
xRotated = 180/M_PI*(dati[j][0]);
yRotated = 180/M_PI*(dati[j][1]);
zRotated = 180/M_PI*(dati[j][2]);
displayCone();
xRotated += 0.;
yRotated += 0.;
zRotated += 0.;
displayCone();
}
}
In my previous program i had in main:
glfwInit(&argc, argv);
//double buffering used to avoid flickering problem in animation
glutInitDisplayMode(GLUT_SINGLE | GL_RGB);
//glfwInitWindowSize(800,700);
glfwCreateWindow(800,700,"Rotation of the top",NULL,NULL);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
xRotated = yRotated = zRotated = 0.0;
xRotated=0.0;
yRotated=0.0;
glClearColor(0.0,0.0,0.0,0.0);
glutDisplayFunc(displayCone);
glutReshapeFunc(reshapeCone);
glutIdleFunc(idleCone);
glutMainLoop();
When using glfw, then you've to create your own application loop. Note, it is important to to make the OpenGL context current, before calling any OpenGL instruction, by glfwMakeContextCurrent. e.g.:
GLFWwindow *wnd = glfwCreateWindow(800,700,"Rotation of the top",NULL,NULL);
glfwMakeContextCurrent(wnd);
// do the OpenGL initialization
// [...]
while (!glfwWindowShouldClose(wnd))
{
// do the drawing
displayCone();
glfwSwapBuffers(wnd);
glfwPollEvents();
}
Instead of glutReshapeFunc you can set the size callback by glfwSetWindowSizeCallback: e.g.:
glfwSetWindowSizeCallback(wnd, reshapeCone);
void reshapeCone(GLFWwindow* window, int x, int y)
{
// [...]
}

Why doesn't the teapot display? OpenGL

Here is my code that set a perspective view volume. The rectangle is displayed correctly.
I want to add a teapot to my scene now, so I add a line drawing a teapot after drawing the rectangle. But no teapot was displayed.
What params did I set wrong? What's the problem with my view and teapot?
GLint winWidth = 600, winHeight = 600; // Initial display-window size.
GLfloat x0 = 50.0, y0 = 50.0, z0 = 50.0; // Viewing-coordinate origin.
GLfloat xref = 50.0, yref = 50.0, zref = 0.0; // Look-at point.
GLfloat Vx = 0.0, Vy = 1.0, Vz = 0.0; // View-up vector.
/* Set coordinate limits for the clipping window: */
//GLfloat xwMin = -40.0, ywMin = -60.0, xwMax = 40.0, ywMax = 60.0;
GLfloat xwMin = -100.0, ywMin = -100.0, xwMax = 100.0, ywMax = 100.0;
/* Set positions for near and far clipping planes: */
GLfloat dnear = 25.0, dfar = 125.0;
void init (void)
{
glClearColor (1.0, 1.0, 1.0, 0.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
gluLookAt (x0, y0, z0, xref, yref, zref, Vx, Vy, Vz);
printf("look at orign:%.0f %.0f %.0f, pref: %.0f %.0f %.0f\n",x0, y0, z0, xref, yref, zref );
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glFrustum (xwMin, xwMax, ywMin, ywMax, dnear, dfar);
}
void displayFcn (void)
{
init ( );
glClear (GL_COLOR_BUFFER_BIT);
/* Set parameters for a square fill area. */
glColor3f (0.0, 1.0, 0.0); // Set fill color to green.
//glPolygonMode (GL_FRONT, GL_FILL);
glPolygonMode(GL_FRONT, GL_LINE);
glPolygonMode (GL_BACK, GL_LINE); // Wire-frame back face.
glBegin (GL_QUADS);
glVertex3f (0.0, 0.0, 0.0);
glVertex3f (100.0, 0.0, 0.0);
glVertex3f (100.0, 100.0, 0.0);
glVertex3f (0.0, 100.0, 0.0);
glEnd ( );
glutSolidTeapot(50.9);
glFlush ( );
}
void reshapeFcn (GLint newWidth, GLint newHeight)
{
glViewport (0, 0, newWidth, newHeight);
winWidth = newWidth;
winHeight = newHeight;
}
void keyboard(unsigned char key, int x, int y);
int main (int argc, char** argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition (50, 50);
glutInitWindowSize (winWidth, winHeight);
glutCreateWindow ("Perspective View of A Square");
glutKeyboardFunc(keyboard);
glutDisplayFunc (displayFcn);
glutReshapeFunc (reshapeFcn);
glutMainLoop ( );
}
Your teapot is just totally off view.
You could place it inside the viewing volume like this:
glMatrixMode(GL_MODELVIEW);
glTranslatef(50.f, 50.f, 0.f);
glutSolidTeapot(50.9);
Also note that the field of view angle is insanely high for any normal viewing condition. Consider using the function gluPerspective instead of glFrustum to easily specify the angle, instead of manually having to specify the tangens of that angle scaled by the near plane distance as with glFrustum.
Also note that all of that is deprecated GL. Most of the functions you are using are removed from modern core profile contexts. If you start learning GL now, my advise is learning the new (well, 10 year old) way of using the programmable pipeline instead of the old (20 years) fixed-function pipeline with the builtin matrix stack.

opengl rotate an object around fixed axes

Hi I'm trying to implement a opengl program with rotation&translation. But I got this problem that, the world axes will rotating along with my object(a cube). It's like, first I rotate cube along Z-axis, it works fine, then I middle-click the mouse and want to rotate the cube along the original Y-axis. At the moment I click, the cube will stop rotating along Z and start to rotate along Y. But it turns out it will rotate along a "new and invisible" Y-axis. I figure out that's because when I rotate the cube along Z with glRotatef(), the other two axis:X,Y also rotate. How can I fix the axes when I'm rotating the cube. I know the glRotatef() will multiply all matrix in screen with a rotation axis, so I tried added a glLoadIdentity() in each rotation but it still not work. can anyone give me the solution?
the code is here for reference:
#include <stdlib.h>
#include <GL/glut.h>
#include <iostream>
GLfloat vertices[8][3] =
{ { -1.0, -1.0, -1.0 }, { 1.0, -1.0, -1.0 },
{ 1.0, 1.0, -1.0 }, { -1.0, 1.0, -1.0 }, { -1.0, -1.0, 1.0 },
{ 1.0, -1.0, 1.0 }, { 1.0, 1.0, 1.0 }, { -1.0, 1.0, 1.0 } };
GLuint listName;
GLfloat theta[3] = { 0.0, 0.0, 0.0 };
GLint axis = 2;
GLfloat delta = 0.02;
GLint stop = 0;
GLfloat distance = 0;
void face(int a, int b, int c, int d)
{
glBegin(GL_POLYGON);
//glColor3fv(colors[a]);
glVertex3fv(vertices[a]);
//glColor3fv(colors[b]);
glVertex3fv(vertices[b]);
//glColor3fv(colors[c]);
glVertex3fv(vertices[c]);
//glColor3fv(colors[d]);
glVertex3fv(vertices[d]);
glEnd();
}
void cube(void)
{
glColor3f(1.0f,1.0f,1.0f);
face(0, 3, 2, 1);
face(2, 3, 7, 6);
face(0, 4, 7, 3);
face(1, 2, 6, 5);
face(4, 5, 6, 7);
face(0, 1, 5, 4);
glutWireCube(2.5f);
glutPostRedisplay();
}
void drawAxis(void){
// save previous matrix
glPushMatrix();
// clear matrix
glLoadIdentity();
// draw our axes
glRotatef(45.0, 1.0, 0.0, 0.0);
glRotatef(45.0, 0.0, -1.0, 0.0);
glBegin(GL_LINES);
// draw line for x axis
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(10.0, 0.0, 0.0);
// draw line for y axis
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 10.0, 0.0);
// draw line for Z axis
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 10.0);
glEnd();
// load the previous matrix
glPopMatrix();
glutPostRedisplay();
}
void spinCube()
{
theta[axis] += delta;
if (theta[axis] > 360.0) theta[axis] -= 360.0;
glutPostRedisplay();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(45.0, 1.0, 0.0, 0.0);
glRotatef(45.0, 0.0, -1.0, 0.0);
drawAxis();
glPushMatrix();
glRotatef(theta[0], 1.0, 0.0, 0.0);
glRotatef(theta[1], 0.0, 1.0, 0.0);
glRotatef(theta[2], 0.0, 0.0, 1.0);
glTranslatef(0.0, 0.0, distance + 2.0);
glCallList(listName);
glPopMatrix();
glutSwapBuffers();
}
void myReshape(int w, int h)
{
GLfloat aspect = (GLfloat) w / (GLfloat) h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-10.0, 10.0, -10.0 / aspect, 10.0 / aspect, -50.0, 50.0);
else
glOrtho(-10.0*aspect, 10.0*aspect, -10.0, 10.0, -50.0, 50.0);
glMatrixMode(GL_MODELVIEW);
}
void mouse(int btn, int state, int x, int y)
{
if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { axis = 0;
}
if (btn == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) { axis = 1;
}
if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { axis = 2;
}
}
void keyboard(unsigned char key, int x, int y)
{
if (key == 'q' || key == 'Q') exit(0);
if (key == ' ') { stop = !stop; }
if (stop)
glutIdleFunc(NULL);
else
glutIdleFunc(spinCube);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
glutInitWindowSize(600, 600);
glutCreateWindow("cube");
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glutIdleFunc(spinCube);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
//creating a display list:
listName = glGenLists(1);
glNewList(listName, GL_COMPILE);
cube();
glEndList();
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return 0;
}
What you're after might be accumulating arbitrary rotations. This can't be done with euler angles, which gimbal lock. It's pretty common to have euler angle rotations and in most cases the issue is simply to do with the order they're applied in. The first thing I'd suggest is to reverse the order of your x/y/z rotations.
Next, if you want to accumulate rotations you'll really want to get into quaternions. This can be done with matrices but can easily become numerically unstable. Quaternions can be normalized which solves this issue.
If you rotate around X, the first call is of course, glRotatef(a, 1, 0, 0); draw(). Then you want to rotate the object and its current rotation around y. Note that the object and current rotation are grouped in this line of thinking. So you glRotatef(b, 0, 1, 0); glRotatef(a, 1, 0, 0); draw();. Each time you rotate, you add the rotation behind the existing list of transforms. If you added in front, it'd transform the object in its local space and not global. What you could do is this (near-pseudo-code with an imaginary matrix implementation):
Keep a current object transform matrix M
In spinCube, M = rotationMatrix(delta, axis==0?1:0, axis==1?1:0, axis==2?1:0) * M (note it's rotation * M and not M * rotation.
Before you draw the cube, glMultMatrixf(M.data)
The problem is floating point error will build up over time and the matrix will start to skew/scale your object in weird ways. Instead, you'll want a quaternion implementation (again near-pseudo-code):
Q = rotationQuaternion(delta, axis==0?1:0, axis==1?1:0, axis==2?1:0) * Q
Q.normalize()
...
glMultMatrixf(Q.toMatrix().data)