OpenGL just won't draw

Hi there!

I’m relatively new in OpenGL. I worked through a tutorial at
nehe.gamedev.net and it can be possible be, that I’ve done something
wrong with C here… Well, just call me newbie… :wink:

I’ve wrote a program - based on the tutorial sources - that should
just draw me two lists, a tunnel and a spaceship. (I’ll put it at the
end of this message, hope it’s not too long…) When I compile it
using

gcc -Wall -I/usr/include/ -c -o tunnels.o tunnels.c
gcc -Wall -I/usr/include/ -o tunnels -L/usr/X11R6/lib tunnels.o -lX11
-lXi -lXmu -lglut -lGL -lGLU -lm

and run it, it just displays a blue window and doesn’t react to my
Escape-keypresses for about ten seconds…

I know that I’ve done something wrong in this source, but I can’t
figure out what. I’ve copied the parts, where the tunnel and the
ship-lists are created in the tutorial source, compiled it and run it

  • and it worked…

Thanks in advance.

Bye,
Dennis

(Sorry 'bout the german comments, hope you understand it…)

–snip-- (tunnels.c)
// tunnels
// Ein einfaches Spiel zum Testen von OpenGL
// Ziel ist es, mit den Cursortasten den Flieger in der Mitte des
Bildschirms durch
// Tunnel zu steuern, ohne irgendwo anzuecken.

// Includes

#include <GL/glut.h> // GLUT
#include <GL/gl.h> // GL itself
#include <GL/glu.h> // GLU
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

// Konstanten

#define ESCAPE 27

// Variablen

int window; // Das Spielfenster

GLfloat ship_x; // Position unseres Raumschiffes
GLfloat ship_y;
GLfloat ship_z;

GLfloat speed; // Geschwindigkeit des Raumschiffes

GLint list_ship; // Display-List des Schiffes
GLint list_tunnel; // Display-List des Tunnels

int tunnel_max_change;
int max_tunnels;

struct Box {
GLfloat x_top_left;
GLfloat y_top_left;
GLfloat z_top_left;

GLfloat x_top_right;
GLfloat y_top_right;
GLfloat z_top_right;

GLfloat x_bottom_right;
GLfloat y_bottom_right;
GLfloat z_bottom_right;

GLfloat x_bottom_left;
GLfloat y_bottom_left;
GLfloat z_bottom_left;
};

typedef struct Box Box;

// Initfunktion für OpenGL

void InitGL(int Width, int Height)
{

srand( (unsigned) time (NULL));

glClearColor(0.2f, 0.2f, 0.6f, 0.0f); // Hellblauer
Hintergrund (der “Himmel” am Ende der Tunnels)
glClearDepth(1.0); // Enables Clearing Of
The Depth Buffer
glDepthFunc(GL_LEQUAL); // The Type Of Depth
Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth
Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color
Shading

glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // Reset The Projection
Matrix

gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
// Calculate The Aspect Ratio Of The Window

glMatrixMode(GL_MODELVIEW);

// Initialisieren der Variablen

ship_x=0;
ship_y=0;
ship_z=0;

speed=0;
tunnel_max_change=10;
max_tunnels=100;

}

// Funktion, wenn das Window resized wird

void ReSizeGLScene(int Width, int Height)
{
if (Height==0) // Prevent A Divide By
Zero If The Window Is Too Small
Height=1;

glViewport(0, 0, Width, Height); // Reset The Current
Viewport And Perspective Transformation

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}

// Hilfsfunktion: Erstellt einen Kasten

void createbox(Box *boxobj, GLfloat x_top_left, GLfloat y_top_left,
GLfloat z_top_left, GLfloat x_size, GLfloat y_size)
{
boxobj->x_top_left=x_top_left;
boxobj->y_top_left=y_top_left;
boxobj->z_top_left=z_top_left;

boxobj->x_top_right=x_top_left+x_size;
boxobj->y_top_right=y_top_left;
boxobj->z_top_right=z_top_left;

boxobj->x_bottom_right=x_top_left+x_size;
boxobj->y_bottom_right=y_top_left+y_size;
boxobj->z_bottom_right=z_top_left;

boxobj->x_bottom_left=x_top_left;
boxobj->y_bottom_left=y_top_left+y_size;
boxobj->z_bottom_left=z_top_left;
}

// Zeichnet per glVertex3f die Zwischenräume zwischen zwei Boxen

void drawboxes(Box *oldbox, Box *newbox)
{
GLfloat newcolor;

newcolor=(rand()/RAND_MAX);

glColor3f(newcolor,newcolor,newcolor); // In Grauabstufungen
zeichnen

// Top

glVertex3f(newbox->x_top_left,newbox->y_top_left,newbox->z_top_left);
glVertex3f(newbox->x_top_right,newbox->y_top_left,newbox->z_top_left);
glVertex3f(oldbox->x_top_right,oldbox->y_top_right,oldbox->z_top_right);
glVertex3f(oldbox->x_top_left,oldbox->y_top_left,oldbox->z_top_left);

// Right

glVertex3f(oldbox->x_top_right,oldbox->y_top_right,oldbox->z_top_right);
glVertex3f(newbox->x_top_right,newbox->y_top_right,newbox->z_top_right);
glVertex3f(newbox->x_bottom_right,newbox->y_bottom_right,newbox->z_bottom_right);
glVertex3f(oldbox->x_bottom_right,oldbox->y_bottom_right,oldbox->z_bottom_right);

// Bottom

glVertex3f(oldbox->x_bottom_left,oldbox->y_bottom_left,oldbox->z_bottom_left);
glVertex3f(newbox->x_bottom_left,newbox->y_bottom_left,newbox->z_bottom_left);
glVertex3f(newbox->x_bottom_right,newbox->y_bottom_right,newbox->z_bottom_right);
glVertex3f(oldbox->x_bottom_right,oldbox->y_bottom_right,oldbox->z_bottom_right);

// Left

glVertex3f(oldbox->x_top_left,oldbox->y_top_left,oldbox->z_top_left);
glVertex3f(newbox->x_top_left,newbox->y_top_left,newbox->z_top_left);
glVertex3f(newbox->x_bottom_left,newbox->y_bottom_left,newbox->z_bottom_left);
glVertex3f(oldbox->x_bottom_left,oldbox->y_bottom_left,oldbox->z_bottom_left);
}

// Erstellt unsere Objekte (Schiff und Tunnel) als Displaylists

void DoCreateLists(void)
{
// Schiff

list_ship=glGenLists(2);

glNewList(list_ship,GL_COMPILE);

glBegin(GL_POLYGON);

glColor3f( 0.0f, 0.0f, 1.0f);
glVertex3f(-1.0f, 0.0f, 0.0f);
glColor3f( 1.0f, 0.0f, 0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f( 0.0f, 0.0f, 1.0f);
glVertex3f( 1.0f, 0.0f, 0.0f);

glEnd();

glEndList();

// Tunnel

// Es wird ein definiert langer Tunnel zufällig generiert.

Box *oldbox;
Box *newbox;

oldbox = (Box *) malloc(sizeof(Box));
newbox = (Box *) malloc(sizeof(Box));

int i;

createbox(oldbox,-2.0f,2.0f,0.0f,2.0f,-2.0f);

list_tunnel=list_ship+1;

glNewList(list_tunnel,GL_COMPILE);

glBegin(GL_QUADS);

for (i=0; i<max_tunnels;i++)
{
// Newbox generieren

GLfloat new_x_top_left;
GLfloat new_y_top_left;
GLfloat new_z_top_left;

GLfloat new_x_size;
GLfloat new_y_size;

GLfloat old_x_size;
GLfloat old_y_size;

old_x_size=oldbox->x_top_right-oldbox->x_top_left;
old_y_size=oldbox->y_bottom_left-oldbox->y_top_left;

new_z_top_left=oldbox->z_top_left+((int) tunnel_max_change * rand()
/ (RAND_MAX+1.0)+0.1f);

if (((int) rand() / RAND_MAX)==0)
{
new_x_top_left=oldbox->x_top_left+((int) tunnel_max_change *
rand() / (RAND_MAX+1.0)+0.1f);
} else
{
new_x_top_left=oldbox->x_top_left-((int) tunnel_max_change *
rand() / (RAND_MAX+1.0)+0.1f);
}

if (((int) rand() / RAND_MAX)==0)
{
new_y_top_left=oldbox->y_top_left+((int) tunnel_max_change *
rand() / (RAND_MAX+1.0)+0.1f);
} else
{
new_y_top_left=oldbox->y_top_left-((int) tunnel_max_change *
rand() / (RAND_MAX+1.0)+0.1f);
}

if (((int) rand() / RAND_MAX)==0)
{
new_x_size=old_x_size+((int) tunnel_max_change * rand() /
(RAND_MAX+1.0)+0.1f);
} else
{
new_x_size=old_x_size-((int) tunnel_max_change * rand() /
(RAND_MAX+1.0)+0.1f);
}

if (((int) rand() / RAND_MAX)==0)
{
new_y_size=old_y_size+((int) tunnel_max_change * rand() /
(RAND_MAX+1.0)+0.1f);
} else
{
new_y_size=old_y_size-((int) tunnel_max_change * rand() /
(RAND_MAX+1.0)+0.1f);
}

createbox(newbox,new_x_top_left,new_y_top_left,new_z_top_left,new_x_size,new_y_size);

drawboxes(oldbox,newbox);

oldbox=newbox;
}

glEnd();

glEndList();
}

// Draw-Funktion

void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //
Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View

glTranslatef(0.0f,0.0f,0.0f);

// Draw ship

glCallList(list_ship);

// Draw tunnel

glTranslatef(ship_x,ship_y,ship_z);

glCallList(list_tunnel);

glutSwapBuffers();
}

void keyPressed(unsigned char key, int x, int y)
{
/* avoid thrashing this procedure */
usleep(100);

/* If escape is pressed, kill everything. */

if (key == ESCAPE)
{
    /* shut down our window */
    glutDestroyWindow(window);

    /* exit the program...normal termination. */
    exit(0);
}

}

void specialKeys(int key, int x, int y)
{
if (key == GLUT_KEY_LEFT)
{
ship_x+=0.1f;
}

if (key == GLUT_KEY_RIGHT)
{
    ship_x-=0.1f;
}

if ((key == GLUT_KEY_UP) && (glutGetModifiers()==0))
{
    ship_y-=0.1f;
}

if ((key == GLUT_KEY_DOWN) && (glutGetModifiers()==0))
{
    ship_y+=0.1f;
}

if ((key == GLUT_KEY_UP) &&

(glutGetModifiers()==GLUT_ACTIVE_SHIFT))
{
ship_z+=0.1f;
}

if ((key == GLUT_KEY_DOWN) &&

(glutGetModifiers()==GLUT_ACTIVE_SHIFT))
{
ship_z-=0.1f;
}

if (key==GLUT_KEY_HOME)
{
    ship_x=0.0f;
    ship_y=0.0f;
    ship_z=0.0f;
} 

}

int main(int argc, char *argv)
{
/
Initialize GLUT state - glut will take any command line arguments
that pertain to it or
X Windows - look at its documentation at
http://reality.sgi.com/mjk/spec3/spec3.html */
glutInit(&argc, argv);

/* Select type of Display mode:
Double buffer
RGBA color
Alpha components supported
Depth buffer */
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);

/* get a 640 x 480 window */
glutInitWindowSize(640, 480);

/* the window starts at the upper left corner of the screen */
glutInitWindowPosition(0, 0);

/* Open a window */
window = glutCreateWindow(“T U N N E L S”);

/* Register the function to do all our OpenGL drawing. */
glutDisplayFunc(&DrawGLScene);

/* Even if there are no events, redraw our gl scene. */
glutIdleFunc(&DrawGLScene);

/* Register the function called when our window is resized. */
glutReshapeFunc(&ReSizeGLScene);

/* Register the function called when the keyboard is pressed. */
glutKeyboardFunc(&keyPressed);
glutSpecialFunc(&specialKeys);

/* Initialize our window. */
InitGL(640, 480);

//DoCreateLists();

/* Start Event Processing Engine */
glutMainLoop();

return 1;
}
–/snip–

Can you get anything simpler to work? That’s a lot to look over.