了解 opengl 的 (glut) 调整大小

发布于 2024-09-29 22:18:41 字数 2849 浏览 3 评论 0原文

我正在 opengl 教程的在线版本上阅读贝塞尔曲线的示例代码。

我很好奇示例中如何处理调整大小,因为我想我可能会在我自己的程序版本中使用它,我将我的问题放在它的注释中:

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;
}

I'm reading the sample code for the bezier curve on the online version of opengl's tutorial.

I'm curious about how is resize being handled in the example cause I figure I might use it on my own version of this program , I placed my questions on its comments:

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?
}

Full code:

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鯉魚旗 2024-10-06 22:18:42

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

glMatrixMode(...);

不会重置矩阵,除非后面跟着 glLoadIdentity() 调用。相反,它将 OpenGL 矩阵运算的当前目标设置为指定的矩阵。这样,OpenGL 就知道您想要影响哪个矩阵。

我之前在 OpenGL superible 中见过这种计算(或者至少是类似的东西);你为什么不和自己谈谈,看看它会做出什么决定以及为什么? (提示(我认为):它试图保持视口正方形以避免拉伸)

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

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

如果您是 OpenGL 新手,您应该从头开始学习 - 后面的教程将假定您具备此类知识。

GLsizei is a type, not a function. Therefore, it's not being called; its being casted; it's converting an int into a GLsizei. It's basically an int, but it makes it clear that you're using it for a size (I think). (I'm a Python programmer, so this is a guess)

glMatrixMode(...);

This does not reset the matrix, unless it is followed by a glLoadIdentity() call. Instead, it sets the current target of OpenGL's matrix operations to the matrix specified. This way, OpenGL knows what matrix you're trying to affect.

I've seen that calcuation before in the OpenGL superbible (or at least something like it); why don't you talk yourself through it and see what it's deciding and why? (Hint (I think): it's trying to keep the viewport square to avoid stretching)

At the end, it sets it back to GL_MODELVIEW since that matrix handles transformations, like translation and rotation, which are used to position vertices onscreen. It should be reset every frame so that your code can assume that the coordinate plane is currently at (0,0); that simplifies calculations about where to translate to.

Also note that reshape is not called by OpenGL, but by GLUT. OpenGL is platform-independent and does not handle windowing; this is why you need GLUT.

If you're new to OpenGL, you should work through it from the beginning - later tutorials will assume this sort of knowledge.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文