我正在使用Glut和C,我的目的是屏幕3D乐高和两个动态宽度,高度和深度的Kaplas。有一些键盘监听器可以移动相机并旋转Kaplas。
我的问题是:当我按下键盘或鼠标的任何触摸时(我的代码中没有处理)我的乐高会让他的X和Z位置大大增加!
这是我的代码和详细信息:
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;
}
以下代码是我的重塑功能:
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();
}
接下来的功能是创建一个Kapla和一个乐高:
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();
}
现在乐高:
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, setted
//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);
}
而不是Kapla,lego不是立即在显示功能中创建的,在此之前调用以下函数来乘以基本Lego以制作完整的乐高(以下参数):
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 wich 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 wich change the
//basic position of the current Lego in the above
//function
setLego(height); //creating the current basic Lego
}
}
最后我的显示功能:
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();
}
我的基本和特殊键盘功能仅使用键:q,a,z,x,y,空格,+, - ,GLUT_KEY_LEFT,GLUT_KEY_RIGHT,GLUT_KEY_UP,GLUT_KEY_DOWN。
当我按下鼠标或键盘的任意键时,posLegoX
和posLegoZ
都会按照addLego()
功能中的代码递增和递减,但是没有在我的代码中控制它的事件。
结果是当我按任意键时,我的完整乐高离开相机,但不是Kapla !!
!重要!
我做了很多测试,问题出现在我的addLego()
函数中,我试图将glPushMatrix()
和glPopMatrix()
放在不同的行中,同时尝试放置{{1} }和glFlush()
但没有任何效果......
有人可以提出任何建议吗?
非常感谢!
度过愉快的一天,
Ankomm
解决方案编辑:
我找到了我老师的问题:听取键盘和鼠标事件的功能正在监听所有键和按钮,即使它们没有在功能中设置,也可以通过重新显示进行刷新(通过调用显示器) function [here:glLoadIdentity()
])。 renderscene()
调用函数,它增加和减少程序编译时设置的全局变量。解决方案是在函数的开头设置变量值,如下所示:
renderscene()
它有效!
答案 0 :(得分:0)
这是Ankomm在对其问题的编辑中发布的解决方案:
我发现我的一位老师有问题。正在监听键盘和鼠标事件的函数正在监听所有键和按钮(即使它们未在函数中设置),并通过重新显示(调用显示功能[此处:renderscene()
])刷新。 renderscene()
调用该函数,该函数递增和递减在编译程序时设置的全局变量。解决方案是在函数的开头设置变量值,如下所示:
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
}
}
它有效!