Glut对象在不告诉

时间:2017-07-25 14:45:41

标签: c freeglut

我正在使用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。

当我按下鼠标或键盘的任意键时,posLegoXposLegoZ都会按照addLego()功能中的代码递增和递减,但是没有在我的代码中控制它的事件。

结果是当我按任意键时,我的完整乐高离开相机,但不是Kapla !!

!重要! 我做了很多测试,问题出现在我的addLego()函数中,我试图将glPushMatrix()glPopMatrix()放在不同的行中,同时尝试放置{{1} }和glFlush()但没有任何效果......

有人可以提出任何建议吗?

非常感谢!

度过愉快的一天,

Ankomm

解决方案编辑:

我找到了我老师的问题:听取键盘和鼠标事件的功能正在监听所有键和按钮,即使它们没有在功能中设置,也可以通过重新显示进行刷新(通过调用显示器) function [here:glLoadIdentity()])。 renderscene()调用函数,它增加和减少程序编译时设置的全局变量。解决方案是在函数的开头设置变量值,如下所示:

renderscene()

它有效!

1 个答案:

答案 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
    }
}

它有效!