了解opengl(过剩)调整大小

时间:2010-10-30 22:19:31

标签: c opengl glut

我正在阅读在线版本的opengl教程中bezier曲线的示例代码。

我很好奇如何在示例中处理resize,因为我想我可能会在我自己的程序版本中使用它,我在评论中提出了问题:

void reshape(int w, int h)

{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h); // what's GLsizei? Why is it called inside glViewPort?
   glMatrixMode(GL_PROJECTION); // is it necessary to reset the projection matrix?
   glLoadIdentity();
   if (w <= h)  // is this calculation universal, could I use it on another program? 
      glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w, 
               5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);

   else
      glOrtho(-5.0*(GLfloat)w/(GLfloat)h, 
               5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
   glMatrixMode(GL_MODELVIEW); // why do I set to GL_MODELVIEW at the end?
   glLoadIdentity(); // why does it get a reset?
}

完整代码:

#include <stdlib.h>
#include <GL/glut.h>

GLfloat ctrlpoints[4][3] = {
    { -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0}, 
    {2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};


void init(void)
{
   glClearColor(0.0, 0.0, 0.0, 0.0);
   glShadeModel(GL_FLAT);
   glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
   glEnable(GL_MAP1_VERTEX_3);
}

void display(void)

{
   int i;

   glClear(GL_COLOR_BUFFER_BIT);
   glColor3f(1.0, 1.0, 1.0);
   glBegin(GL_LINE_STRIP);
      for (i = 0; i <= 30; i++) 
         glEvalCoord1f((GLfloat) i/30.0);
   glEnd();
   /* The following code displays the control points as dots. */

   glPointSize(5.0);
   glColor3f(1.0, 1.0, 0.0);
   glBegin(GL_POINTS);
      for (i = 0; i < 4; i++) 
         glVertex3fv(&ctrlpoints[i][0]);
   glEnd();
   glFlush();

}

void reshape(int w, int h)

{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h); // what's GLsizei? Why is it called inside glViewPort?
   glMatrixMode(GL_PROJECTION); // is it necessary to reset the projection matrix?
   glLoadIdentity();
   if (w <= h)  // is this calculation universal, could I use it on another program? 
      glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w, 
               5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);

   else
      glOrtho(-5.0*(GLfloat)w/(GLfloat)h, 
               5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
   glMatrixMode(GL_MODELVIEW); // why do I set to GL_MODELVIEW at the end?
   glLoadIdentity(); // why does it get a reset?
}

void keyboard(unsigned char key, int x, int y)

{
   switch (key) {
      case 27:
         exit(0);
         break;
   }
}

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);

   glutInitWindowSize (500, 500);
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   init ();
   glutDisplayFunc(display);
   glutReshapeFunc(reshape); // el reshape funciona correctamente 
   glutKeyboardFunc (keyboard);

   glutMainLoop();
   return 0;
}

1 个答案:

答案 0 :(得分:4)

GLsizei类型,而不是函数。因此,它没有被召唤;它被铸造;它正在将int转换为GLsizei。它基本上是一个int,但它清楚地表明你正在使用它(我认为)。 (我是一名Python程序员,所以这是猜测)

glMatrixMode(...);

除非后跟glLoadIdentity()来电,否则重置矩阵。相反,它将OpenGL矩阵运算的当前目标设置为指定的矩阵。这样,OpenGL知道你想要影响的矩阵。

我之前在OpenGL中看到过这种计算方法(或至少类似的东西);为什么不通过它自言自语,看看它的决定是什么?为什么? (提示(我认为):它试图保持视口方块以避免拉伸)

最后,它将其设置回GL_MODELVIEW,因为该矩阵处理转换,如平移和旋转,用于在屏幕上定位顶点。它应该每帧重置,以便你的代码可以假设坐标平面当前为(0,0);这简化了有关转换到的位置的计算。

另请注意,reshape不是由OpenGL调用,而是由GLUT调用。 OpenGL与平台无关,不处理窗口化;这就是你需要GLUT的原因。

如果您是OpenGL的新手,您应该从头开始学习它 - 以后的教程将假设这种知识。