Thread: C / OpenGL help REALLY needed for simple but annoying problem!

  1. #1
    Registered User
    Join Date
    Dec 2003
    Posts
    4

    C / OpenGL help REALLY needed for simple but annoying problem!

    Hi!

    I'm learning openGL over the holidays (and loving it), but I've come across a very simple problem (I think it's just a syntax problem, but anyway. ...)

    Below you'll find my code. If you go down to the renderScene(void) function, and about 2 thirds down the contents of this function I've placed 3 lines of asterixes above the problem code and 3 lines of asterixes below the problem code. There's also a description of the problem!

    To execute the problem code, just press the "s" key on ya keyboard, and watch the command prompt running in the background. After a couple of seconds the problem code will execute.

    I use Microsoft Visual Studio if that helps.


    Code:
    #include <math.h> 
    #include <gl\glut.h> 
    #include <gl\gl.h> 
    #include <gl\glu.h> 
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <conio.h> 
    #include <string.h> 
    #include <dos.h> 
    
    static float angle=0.0,ratio; 
    
    float x=0.0f,y=1.75f,z=5.0f; 
    //Variables for the position of the camera in 3D space 
    
    float lx=0.0f,ly=0.0f,lz=-1.0f; 
    
    
    static GLint snowman_display_list; 
    
    int CameraUp = 0, CameraDown = 0; 
    //Integer values used for moving the camera POSITION in amounts along the Y axis 
    
    int LookAngleDown = 0, LookAngleUp = 0; 
    //Integer values used for moving the camera VIEW ANGLE - Y AXIS 
    
    
    
    
    
    void changeSize(int w, int h) 
    { 
    
    // Prevent a divide by zero, when window is too short 
    // (you cant make a window of zero width). 
    if(h == 0) 
    h = 1; 
    
    ratio = 1.0f * w / h; 
    // Reset the coordinate system before modifying 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    
    // Set the viewport to be the entire window 
    glViewport(0, 0, w, h); 
    
    // Set the clipping volume 
    gluPerspective(45,ratio,1,1000); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    gluLookAt(x, y, z, 
    x + lx,y + ly,z + lz, 
    0.0f,1.0f,0.0f); 
    } 
    
    
    
    
    
    void drawSnowMan() { 
    
    glColor3f(1.0f, 1.0f, 1.0f); 
    
    // Draw Body 
    glTranslatef(0.0f ,0.75f, 0.0f); 
    glutSolidSphere(0.75f,20,20); 
    
    
    // Draw Head 
    glTranslatef(0.0f, 1.0f, 0.0f); 
    glutSolidSphere(0.25f,20,20); 
    
    // Draw Eyes 
    glPushMatrix(); 
    glColor3f(0.0f,0.0f,0.0f); 
    glTranslatef(0.05f, 0.10f, 0.18f); 
    glutSolidSphere(0.05f,10,10); 
    glTranslatef(-0.1f, 0.0f, 0.0f); 
    glutSolidSphere(0.05f,10,10); 
    glPopMatrix(); 
    
    // Draw Nose 
    glColor3f(1.0f, 0.5f , 0.5f); 
    glRotatef(0.0f,1.0f, 0.0f, 0.0f); 
    glutSolidCone(0.08f,0.5f,10,2); 
    } 
    
    
    
    
    
    GLuint createDL() { 
    GLuint snowManDL; 
    
    // Create the id for the list 
    snowManDL = glGenLists(1); 
    
    // start list 
    glNewList(snowManDL,GL_COMPILE); 
    
    // call the function that contains 
    // the rendering commands 
    drawSnowMan(); 
    
    // endList 
    glEndList(); 
    
    return(snowManDL); 
    } 
    
    
    
    
    
    void initScene() { 
    
    glEnable(GL_DEPTH_TEST); 
    snowman_display_list = createDL(); 
    } 
    
    
    
    
    
    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 direction) { 
    x = x + direction*(lx)*0.1; 
    z = z + direction*(lz)*0.1; 
    glLoadIdentity(); 
    gluLookAt(x, y, z, 
    x + lx,y + ly,z + lz, 
    0.0f,1.0f,0.0f); 
    } 
    
    
    
    
    
    
    
    
    void renderScene(void) { 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    
    
    
    //***********************************************// 
    // Code for the camera moving DOWN the Y axis 
    //***********************************************// 
    if (CameraDown > 0) 
    //If the camera should be moving down... 
    { 
    if (y > 0) 
    //if the y loc angle is greater than the middle of the screen(0) then... 
    y = y - 0.1; 
    //Move camera down (Y-Axis) 
    orientMe(angle); 
    //Re-view the world with the changes 
    CameraDown = CameraDown - 1; 
    //de-crement the camera down counter value 
    if (y <= 0) 
    // if the loc y has finally reached the middle of the screen 
    { 
    CameraUp = CameraDown; 
    CameraDown = 0; 
    } 
    } 
    //************************************************** 
    
    
    
    
    //***********************************************// 
    // Code for the camera moving UP the Y axis 
    //***********************************************// 
    if (CameraUp > 0) 
    { 
    y = y + 0.1; 
    //Move the camera up (Y-axis) 
    orientMe(angle); 
    //Re-view the world with the changes 
    CameraUp = CameraUp - 1; 
    //Decrement the camera up counter value 
    } 
    //************************************************* 
    
    
    
    
    
    
    
    
    //***********************************************// 
    // Code for the camera ANGLE moving UP the Y axis 
    //***********************************************// 
    //S has been pressed 
    if (LookAngleUp >= 1) 
    { 
    
    ly = ly + 0.005; 
    orientMe(angle); 
    
    LookAngleUp = LookAngleUp - 1; 
    
    
    if ((LookAngleUp == 0) && (ly != 0.0f)) 
    { 
    LookAngleDown = 50; 
    orientMe(angle); 
    } 
    } 
    //********************************************** 
    
    
    
    
    
    //***********************************************// 
    // Code for the camera ANGLE moving down the Y axis 
    //***********************************************// 
    //X has been pressed 
    if (LookAngleDown >= 1) 
    //Camera view angle on the Y axis is movin downward 
    { 
    ly = ly - 0.005; 
    orientMe(angle); 
    
    LookAngleDown = LookAngleDown - 1; 
    
    /******************************************************/ 
    /******************************************************/ 
    /******************************************************/ 
    //THIS IS WHAT I CAN'T WORK OUT! The first IF condition below executes, stating 
    //that the value of ly is 0.000000, yet the second IF statement which should 
    //execute because ly equals 0.000000 WON'T EXECUTE! ANY help wouLd be 
    //GREATLY appreciated! 
    //* NOTE! To activate the code below, Press the "s" button on your keyboard, 
    //wait for the view of the 3D world to return to it's centre postion 
    //(it only takes a few seconds)then watch the command prompt. 
    
    
    if (LookAngleDown == 0) 
    { 
    printf("ly should equal 0.000000\n"); 
    printf("ly actually equals %f\n\n\n\n", ly); 
    } 
    
    
    
    if (ly == 0.000000) 
    { 
    printf("IF YOU CAN READ THIS CODE THEN YOU HAVE FIXED MY PROBLEM!\n\n\n\n"); 
    } 
    
    //*********************************************************** 
    /******************************************************/ 
    /******************************************************/ 
    
    
    if ((LookAngleDown == 0) && (ly == 0.00)) 
    //Camera ANGLE has been moving down and has reached the middle of the screen 
    { 
    printf("HEY!!!!\n\n"); 
    LookAngleDown = 0; 
    LookAngleUp = 0; 
    orientMe(angle); 
    } 
    
    
    
    else if ((LookAngleDown == 0) && (ly < 0.0f)) 
    { 
    LookAngleUp = 50; 
    orientMe(angle); 
    } 
    
    
    } 
    //************************************************** 
    
    
    
    
    
    
    
    
    
    // Draw ground 
    glColor3f(0.9f, 0.9f, 0.9f); 
    glBegin(GL_QUADS); 
    glVertex3f(-100.0f, 0.0f, -100.0f); 
    glVertex3f(-100.0f, 0.0f, 100.0f); 
    glVertex3f( 100.0f, 0.0f, 100.0f); 
    glVertex3f( 100.0f, 0.0f, -100.0f); 
    glEnd(); 
    
    // Draw 36 SnowMen 
    
    for(int i = -3; i < 3; i++) 
    for(int j=-3; j < 3; j++) { 
    glPushMatrix(); 
    glTranslatef(i*10.0,0,j * 10.0); 
    glCallList(snowman_display_list);; 
    glPopMatrix(); 
    } 
    
    
    glutSwapBuffers(); 
    } 
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    void inputKey(int key, int x, int y) { 
    
    switch (key) { 
    case GLUT_KEY_LEFT : 
    angle -= 0.01f; 
    orientMe(angle);break; 
    case GLUT_KEY_RIGHT : 
    angle +=0.01f; 
    orientMe(angle);break; 
    case GLUT_KEY_UP : 
    moveMeFlat(2);break; 
    case GLUT_KEY_DOWN : 
    moveMeFlat(-2);break; 
    } 
    } 
    
    
    
    
    
    void processNormalKeys(unsigned char key, int MouseLocX, int MouseLocY) { 
    
    if (key == 27) 
    { 
    exit(0); 
    } 
    
    
    if (key == 'a') 
    { 
    CameraDown = 0; 
    CameraUp = 20; 
    } 
    
    
    
    if (key == 'z') 
    { 
    CameraUp = 0; 
    CameraDown = 20; 
    } 
    
    
    
    
    if (key == 's') 
    { 
    LookAngleUp = 50; 
    } 
    
    
    if (key == 'x') 
    { 
    LookAngleDown = 50; 
    } 
    
    
    
    } 
    
    
    
    
    
    
    
    
    
    int main(int argc, char **argv) 
    { 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); 
    glutInitWindowPosition(100,100); 
    glutInitWindowSize(640,360); 
    glutCreateWindow("SnowMen from 3D-Tech"); 
    
    initScene(); 
    
    
    
    glutSpecialFunc(inputKey); 
    glutKeyboardFunc(processNormalKeys); 
    
    glutDisplayFunc(renderScene); 
    glutIdleFunc(renderScene); 
    
    glutReshapeFunc(changeSize); 
    
    glutMainLoop(); 
    
    fflush(0); 
    
    return(0); 
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    You can't reliably compare floating point numbers for equality. Floats are approximations, so whilst
    ( 1 / 3 ) * 3 - 1 is mathematically 0, it might not be computationally 0.

    Short story, try
    if (ly == 0.000000)
    as
    if ( fabs(ly) <= 0.000001 )

    Go find the article titled "What every computer scientist should know about floating-point" by David Goldberg.

    Oh and next time you decide to dump several hundred lines of code on a message board, stop!
    Then try and write an equivalent 10 line program which demonstrates the same problem.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    .
    Join Date
    Nov 2003
    Posts
    307
    Some compilers define EPSILON in math.h as the floating point fuzz factor that Salem mentions - it's used for making comparisons.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Some compilers define EPSILON in math.h as the floating point fuzz factor that Salem mentions
    All compilers define FLT_EPSILON and DBL_EPSILON in float.h, use one of those instead as they are more portable than some arbitrary compiler extension.
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Dec 2003
    Posts
    4
    Originally posted by Salem
    You can't reliably compare floating point numbers for equality. Floats are approximations, so whilst
    ( 1 / 3 ) * 3 - 1 is mathematically 0, it might not be computationally 0.

    Short story, try
    if (ly == 0.000000)
    as
    if ( fabs(ly) <= 0.000001 )

    THANK-YOU SO MUCH SALEM!!!!!!! You have no idea how much frustration that has been causing me!!!!! Why floats have to be such a pain in the ass I don't know....... but anyway, thanx so much!!!!!

    Also, I really didn't want to post a few hundred lines of code (sorry!), but for some reason, the "problem" doesn't show itself in the main function - the "if" comparison code test works fine in the main function, yet in the renderScene function it doesn't (weird huh - if ya don't believe me try it). Never-the-less, in the future I will try to tone the amount of code I post - again, I'm sorry!

    Thanx!

  6. #6
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Originally posted by Oz_joker You have no idea how much frustration that has been causing me!!!!!
    Oh, we know, we know!!!! At the beginning they make no sense at all. Then the understanding dawns....

    It's the problem with converting analog to digital...
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. OpenGL Window
    By Morgul in forum Game Programming
    Replies: 1
    Last Post: 05-15-2005, 12:34 PM
  2. opengl color problem
    By Zeeshan in forum Game Programming
    Replies: 2
    Last Post: 06-16-2002, 01:56 PM
  3. OpenGL Problem
    By slx47 in forum C++ Programming
    Replies: 0
    Last Post: 05-07-2002, 08:00 PM
  4. OpenGL Tut problem
    By valar_king in forum Game Programming
    Replies: 3
    Last Post: 01-15-2002, 09:08 AM
  5. problem with output
    By Garfield in forum C Programming
    Replies: 2
    Last Post: 11-18-2001, 08:34 PM