Reputation: 563
I'm working with Glut and C, my purpose is to screen a 3D Lego and two Kaplas with dynamic width, height and depth. There's a few keyboard listeners that move the camera, and rotate the Kaplas.
My problem is: when I press any touch of the keyboard or the mouse (which are not dealt with in my code) my Lego get its X and Z positions greatly increased!
Here's my code and details:
int main(int argc, char **argv) {
// init GLUT and create Window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,800);
glutCreateWindow("Lighthouse3D- GLUT Tutorial");
glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
glutDisplayFunc(renderScene); //my display function
glutReshapeFunc(resize); //my reshape function
glutKeyboardFunc(key); //basic keyboard listener function
glutSpecialFunc(specialKey); //special keyboard listener function
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightiv(GL_LIGHT0, GL_POSITION, light_position);
glutMainLoop();
return 1;
}
The code below is my reshape function:
static void resize(int width, int height) {
if(height == 0)
height = 1;
const float ar = (float) width / (float) height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
gluPerspective(90, ar, 1, 10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Next functions are creating a Kapla and a Lego:
void setKapla() {
glColor3f(0.76f, 0.42f, 0.0f);
float rX = xRot; //moved by keyboard's 'x' key
float rY = yRot; //moved by keyboard's 'y' key
float rZ = zRot; //moved by keyboard's 'z' key
float pX = xPos; //not dynamic, equal to 0.0f
float pY = yPos; //not dynamic, equal to 0.0f
float pZ = zPos; //not dynamic, equal to -30.0f
glPushMatrix();
glTranslatef(pX, pY, pZ); //place origin point to static coords
glRotatef(angleRot, rX, rY, rZ); //rotate the object following
//dynamic coords
glScalef(1.0f, 3.0f, 15.0f); //multiplying the following cube by this
//proportions
glutSolidCube(2.0f); //base cube
glPopMatrix();
}
Now the Lego:
void setLego(int zHeight) {
GLUquadricObj* quadric = gluNewQuadric(); //creatin my quadric object
gluQuadricDrawStyle(quadric, GLU_FILL);
glColor3f(0.72f, 0.72f, 0.05f);
glPushMatrix();
glTranslatef(posLegoX, posLegoY, posLegoZ); //setting lego
//position to
//dynamic coords, set
//in the function in the
//next bloc of code
glRotatef(-90, 1, 0, 0); //rotation for the next cylinder
gluCylinder(quadric, 2.4, 2.4, 1.7, 10, 10); //cylinder in the top of
//the cube
gluDisk(quadric, 0.0, 2.4, 10, 10); //closing the bottom of the
//cylinder
glTranslatef(0.0f, 0.0f, 1.7f); //translated to the top of the
//cylinder
gluDisk(quadric, 0.0, 2.4, 10, 10); //closing the top of the cylinder
glTranslatef(0.0f, 0.0f, ((-3.2f * zHeight) / 2.0f) - 1.7f);
//setting Lego's basic cube position
glScalef(7.8f, 7.8f, 3.2f * zHeight); //setting Lego's basic cube
//size to the function param
glutSolidCube(1.0f); //creating the cube
glPopMatrix();
gluDeleteQuadric(quadric);
}
Instead of the Kapla, the lego is not immediately created in the display function, before that the following function is called to multiply basic Lego's to make a complete Lego (following params):
void addLego(int depth, int height, int width) {
int i = 0;
int j = 0;
for(i=0 ; i<depth ; i++) { //multiply basic Lego to get the right depth
posLegoX += 7.8f; //incrementing global variable which change the
//basic position of the current Lego in the above
//function
setLego(height); //creating the current basic Lego
}
for(j=0 ; j<width ; j++) { //multiply basic Lego to get the right depth
posLegoZ -= 7.8; //decrementing global variable which change the
//basic position of the current Lego in the above
//function
setLego(height); //creating the current basic Lego
}
}
And finally my display function:
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
printf(" xCam : %f | yCam : %f\n", xCam, yCam);
glPushMatrix();
gluLookAt(xCam, yCam, zCam,
xCenter, yCenter, zCenter,
xVec, yVec, zVec); //move the camera with keyboard's arrow
//touches
xPos = -10.0f; //x position of the first Kapla
yPos = -10.0f; //y position of the first Kapla
setKapla(); //set the first Kapla
xPos = 10.0f; //x position of the second Kapla
yPos = 10.0f; //y position of the second Kapla
setKapla(); //set the second Kapla
addLego(2, 5, 3); //creating a complete Lego with 2 basic Legos in
//depth, 5 Legos in height and 3 Legos in width
glPopMatrix();
glutSwapBuffers();
}
My basic and special keyboard functions are only using the keys : q, a, z, x, y, space, +, -, GLUT_KEY_LEFT, GLUT_KEY_RIGHT, GLUT_KEY_UP, GLUT_KEY_DOWN.
When I pressed ANY key of my mouse or my keyboard, posLegoX
and posLegoZ
are each incrementing and decrementing following the code in the addLego()
function, but there's no event in my code which controls it.
The result is my complete Lego run away from the camera when I press any key, but NOT the Kapla!
IMPORTANT!
I made a lot of tests, and the problem is located in my addLego()
function, i tried to put in it glPushMatrix()
and glPopMatrix()
in different lines, tried also to put a glFlush()
and a glLoadIdentity()
but nothing worked...
How can I stop this?
Upvotes: 0
Views: 76
Reputation: 3652
This is the solution posted by Ankomm in an edit to their question:
I found the problem with one of my teachers. The functions which are listening for Keyboard and Mouse events are listening ALL keys and buttons even they're not set in the functions, and refresh with the redisplay (which call the display function [here : renderscene()
]). The renderscene()
calls the function which increments and decrements global variables which have been set when the program was compiled. The solution is to set the variables values at the beginning of the function like this:
void addLego(int depth, int height, int width) {
posLegoX = 0.0f;
posLegoZ = -50.0f;//set the values here so when the function will be
//called, the position of the first Lego will be always
//the same
int i = 0;
int j = 0;
for(i=0 ; i<depth ; i++) { //multiply basic Lego to get the right depth
posLegoX += 7.8f; //incrementing global variable which changes the
//basic position of the current Lego in the above
//function
setLego(height); //creating the current basic Lego
}
for(j=0 ; j<width ; j++) { //multiply basic Lego to get the right depth
posLegoZ -= 7.8; //decrementing global variable which change the
//basic position of the current Lego in the above
//function
setLego(height); //creating the current basic Lego
}
}
And it works!
Upvotes: 1