C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 12-02-2003, 09:25 PM   #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); 
}
Oz_joker is offline   Reply With Quote
Old 12-03-2003, 03:58 AM   #2
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
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.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Old 12-03-2003, 06:30 AM   #3
.
 
Join Date: Nov 2003
Posts: 293
Some compilers define EPSILON in math.h as the floating point fuzz factor that Salem mentions - it's used for making comparisons.
jim mcnamara is offline   Reply With Quote
Old 12-03-2003, 08:45 AM   #4
Code Goddess
 
Prelude's Avatar
 
Join Date: Sep 2001
Posts: 9,661
>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.
Prelude is offline   Reply With Quote
Old 12-03-2003, 04:07 PM   #5
Registered User
 
Join Date: Dec 2003
Posts: 4
Quote:
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!
Oz_joker is offline   Reply With Quote
Old 12-03-2003, 05:47 PM   #6
Been here, done that.
 
Join Date: May 2003
Posts: 1,036
Quote:
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...
__________________
There are only 10 types of people in the world -- those that use binary, and those that don't
WaltP is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
OpenGL Window Morgul Game Programming 1 05-15-2005 12:34 PM
opengl color problem Zeeshan Game Programming 2 06-16-2002 01:56 PM
OpenGL Problem slx47 C++ Programming 0 05-07-2002 08:00 PM
OpenGL Tut problem valar_king Game Programming 3 01-15-2002 09:08 AM
problem with output Garfield C Programming 2 11-18-2001 08:34 PM


All times are GMT -6. The time now is 02:35 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22