Понимание изменения размера opengl (переизбытка) - PullRequest
2 голосов
/ 31 октября 2010

Я читаю пример кода для кривой Безье в онлайн-версии учебника 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;
}

1 Ответ

4 голосов
/ 31 октября 2010

GLsizei - это тип , а не функция. Следовательно, это не называется; его существо брошено ; он конвертирует int в GLsizei. Это в основном int, но это дает понять, что вы используете его для размера (я думаю). (Я программист на Python, так что это предположение)

glMatrixMode(...);

Это не сбрасывает матрицу, если за ней не следует вызов glLoadIdentity(). Вместо этого он устанавливает текущую цель матричных операций OpenGL для указанной матрицы. Таким образом, OpenGL знает, на какую матрицу вы пытаетесь повлиять.

Я видел это вычисление раньше в супербибле OpenGL (или, по крайней мере, что-то вроде этого); почему бы вам не обсудить это с самим собой и посмотреть, что он решает и почему? (Подсказка (я думаю): он пытается удерживать площадь окна просмотра, чтобы избежать растяжения)

В конце он возвращает значение GL_MODELVIEW, поскольку эта матрица обрабатывает преобразования, такие как перемещение и вращение, которые используются для позиционирования вершин на экране. Необходимо сбрасывать каждый кадр, чтобы ваш код мог предположить, что координатная плоскость в данный момент находится в (0,0); это упрощает расчеты о том, куда переводить.

Также обратите внимание, что reshape вызывается не OpenGL, а GLUT. OpenGL не зависит от платформы и не поддерживает управление окнами; Вот почему вам нужно GLUT.

Если вы новичок в OpenGL, вы должны проработать его с самого начала - в следующих уроках вы получите такие знания.

...