views:

570

answers:

2

I have been following this tutorial series for OpenGL: GLUT:

http://www.lighthouse3d.com/opengl/glut/

I have reached the stage of implementing camera controls using the keyboard:

http://www.lighthouse3d.com/opengl/glut/index.php?8

When doing the advanced tutorial it stops working. I've pretty much just copied and pasted it. When I run its version of the code it works. Mine just doesn't seem to work. It should rotate the camera view when moving left and right and move forward and backwards when using up and down keys.

My code is here broken down:

This part of my code renders components in the scene with init() which initilizes values etc.:

void display(void)
{
 if (deltaMove)
  moveMeFlat(deltaMove);
 if (deltaAngle) {
  angle += deltaAngle;
  orientMe(angle);
 }

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glBindTexture(GL_TEXTURE_2D, texture[0]);
 RenderSkyDome();
 glBindTexture(GL_TEXTURE_2D, NULL);

 glutSwapBuffers();

}

void init(void)
{
 glClearColor(0.0, 0.0, 0.0, 0.0);
 glClearDepth(1.0f);
 glColor3f(0.0, 0.0, 1.0);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 glEnable(GL_TEXTURE_2D);
 glEnable(GL_DEPTH_TEST);
 glDepthFunc(GL_LEQUAL);
 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

 LoadTextures("clouds2.bmp", 0);
 GenerateDome(600.0f, 5.0f, 5.0f, 1.0f, 1.0f);

 snowman_display_list = createDL();
}

This is my main loop function:

int main ()
{
 glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
 glutInitWindowSize(800, 600);
 glutInitWindowPosition(0, 0);
 glutCreateWindow("Captain Ed's Adventures: Great Wall of China");
 init();

 //Glut Input Commands
 glutIgnoreKeyRepeat(1);
 glutSpecialFunc(pressKey);
 glutSpecialUpFunc(releaseKey);
 glutKeyboardFunc(processNormalKeys);

 glutDisplayFunc(display);
 glutIdleFunc(display);
 glutReshapeFunc(reshape);  // This redraws everything on screen when window size is changed.               
 glutMainLoop();
 return 0;
}

Here are my input functions which are called:

void pressKey(int key, int x, int y) {

 switch (key) {
  case GLUT_KEY_LEFT : deltaAngle = -0.10f;break;
  case GLUT_KEY_RIGHT : deltaAngle = 0.10f;break;
  case GLUT_KEY_UP : deltaMove = 50;break;
  case GLUT_KEY_DOWN : deltaMove = -50;break;
 }
}

void releaseKey(int key, int x, int y) {

 switch (key) {
  case GLUT_KEY_LEFT : if (deltaAngle < 0.0f) 
         deltaAngle = 0.0f;
        break;
  case GLUT_KEY_RIGHT : if (deltaAngle > 0.0f) 
         deltaAngle = 0.0f;
        break;
  case GLUT_KEY_UP :  if (deltaMove > 0) 
         deltaMove = 0;
        break;
  case GLUT_KEY_DOWN : if (deltaMove < 0) 
         deltaMove = 0;
        break;
 }
}

void processNormalKeys(unsigned char key, int x, int y) {

 if (key == 27) 
  exit(0);
}

Variables that get used by the camera and the functions that should change it:

static float angle=0.0,deltaAngle = 0.0,ratio;
static float x=0.0f,y=1.75f,z=5.0f;
static float lx=0.0f,ly=0.0f,lz=-1.0f;
static int deltaMove=0;

void orientMe(float ang) {

 lx = sin(ang);
 lz = -cos(ang);
 glLoadIdentity();
 gluLookAt(x, y, z, 
        x + lx,y + ly,z + lz,
     0.0f,1.0f,0.0f);
} 

void moveMeFlat(int i) {
 x = x + i*(lx)*0.1;
 z = z + i*(lz)*0.1;
 glLoadIdentity();
 gluLookAt(x, y, z, 
        x + lx,y + ly,z + lz,
     0.0f,1.0f,0.0f);
}

I believe that's pretty much everything I am working with so basically what should happen is that when I press UP key deltaMove should = 50 and when this happens the if statement in void display(void) should do moveMeFlat(deltaMove); I don't know if I am doing this wrong or if there is a better result....

I can move "moveMeFlat(deltaMove)" within the relevant switch cases but this does not allow me to have the movement that I want. It seems to work using the source code from the tutorials above with the right functionality but not in my case so my assumption is that it's to do with the if statement in display.

The end result I am looking for is to be able to have forwards and backwards working with left and right rotating the camera. I would like to be able to press forward and left key and see the camera swerve left like in a racing game...

A: 

Is GLUT idle when a key press is occurring? I think it is not idle. Your display() function is only called when the window is created and when GLUT is idle, which doesn't allow your position to be changed.

I suggest adding:

glutTimerFunc(40, display, 1);

to the end of your display function. This will cause display to be called every 40 milliseconds.

Also, don't register display as the idle function, or you'll have the idle function starting lots of series of timer functions.

P.S. I would call glFlush(); just before swapping the buffers in your display function.

Mr. Berna
http://www.gamedev.net/community/forums/topic.asp?topic_id=553415 thanks for the glFlush tip the solution can be found on this forum post
Anicho
+1  A: 

Try getting rid of static in front of all of your global variable declarations.

The last use of static is as a global variable inside a file of code. In this case, the use of static indicates that source code in other files that are part of the project cannot access the variable. Only code inside the single file can see the variable. (It's scope -- or visibility -- is limited to the file.) This technique can be used to simulate object oriented code because it limits visibility of a variable and thus helps avoid naming conflicts. This use of static is a holdover from C.

-http://www.cprogramming.com/tutorial/statickeyword.html

Also, instead of this:

if (deltaMove)
  moveMeFlat(deltaMove);
 if (deltaAngle) {
  angle += deltaAngle;
  orientMe(angle);
 }

try this:

if (deltaMove != 0)
  moveMeFlat(deltaMove);
 if (deltaAngle != 0.0) {
  angle += deltaAngle;
  orientMe(angle);
 }
Ned
http://www.gamedev.net/community/forums/topic.asp?topic_id=553415 solution can be found here
Anicho