6

reshape()这段代码中的函数是如何工作的,它是如何在glutReshapeFunc(reshape)没有任何 reshape 参数的情况下获取其参数的glutReshapeFunc(reshape)int x,int yvoid keyboard (unsigned char key, int x, int y)函数中的值是多少?

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

static int year = 0, day = 0;

void init(void) 
{
   glClearColor (0.0, 0.0, 0.0, 0.0);
   glShadeModel (GL_FLAT);
}

void display(void)
{
   glClear (GL_COLOR_BUFFER_BIT);
   glColor3f (1.0, 1.0, 1.0);

   glPushMatrix();
   glutWireSphere(1.0, 20, 16);   /* draw sun */
   glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);
   glTranslatef (2.0, 0.0, 0.0);
   glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);
   glutWireSphere(0.2, 10, 8);    /* draw smaller planet */
   glPopMatrix();
   glutSwapBuffers();
}

void reshape (int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}

void keyboard (unsigned char key, int x, int y)
{
   switch (key) {
      case `d':
         day = (day + 10) % 360;
         glutPostRedisplay();
         break;
      case `D':
         day = (day - 10) % 360;
         glutPostRedisplay();
         break;
      case `y':
         year = (year + 5) % 360;
         glutPostRedisplay();
         break;
      case `Y':
         year = (year - 5) % 360;
         glutPostRedisplay();
         break;
      default:
         break;
   }
}

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
   glutInitWindowSize (500, 500); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   init ();
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutMainLoop();
   return 0;
}
4

3 回答 3

7

看来该glutReshapeFunc()函数需要一个指向函数的指针;据推测,事实上,它被声明为有点类似于:

void glutReshapeFunc(void (*function)(int x, int y));

类似地,glutDisplayFunc()接受另一个指向函数的指针,glutKeyboardFunc()也接受一个指向函数的指针。当一个函数由名称指定而其后没有函数调用括号时,它会简化为“指向函数的指针”(或者您可以将裸函数名称视为指向函数体的指针,就像裸数组名称是指针一样到数组的开头)。

您必须阅读手册才能发现函数的用途xy参数keyboard()。显示的代码不使用它们。它们可能是某物的位置,但不阅读手册就不太清楚。

于 2013-07-09T02:59:35.283 回答
6

reshapekeyboard函数被用作所谓的回调。您正在为这些函数提供 GLUT 指针,GLUT 保留这些指针并在 GLUT 文档中指定的时间使用参数调用这些函数。

大约是这样的:

void (*display_callback)(void);
void (*reshape_callback)(int, int);
void (*keyboard_callback(unsigned char, int, int);
/* ... */

void eventloop(...)
{
    while(...) {
        if( keyboard_event )
              keyboard_callback(keyboard_event->key, mouse_x, mouse_y);

        if( window_reshaped )
              reshape_callback(window->width, window->height);

        if( needs_redraw )
              display_callback();
    }
}

现在关于 reshape 回调中所做的事情:初学者教程中放置的所有内容实际上在 display 函数中做得更好。设置视口,设置投影我的意思。稍后您可能想要绘制 HUD、一些文本或小地图或拆分视图。一旦你达到了这一点,进行视口和投影设置的重塑功能就成为一种负担。所以现在摆脱它。

void display(void)
{
   int const w = glutGet(GLUT_WINDOW_WIDTH);
   int const h = glutGet(GLUT_WINDOW_HEIGHT);

   glClear (GL_COLOR_BUFFER_BIT);
   glColor3f (1.0, 1.0, 1.0);

   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

   glPushMatrix();
   glutWireSphere(1.0, 20, 16);   /* draw sun */
   glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);
   glTranslatef (2.0, 0.0, 0.0);
   glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);
   glutWireSphere(0.2, 10, 8);    /* draw smaller planet */
   glPopMatrix();

   glutSwapBuffers();
}
于 2013-07-09T08:02:00.510 回答
0

我希望这将是这个问题的直接答案。reshape函数是一个回调函数,每当应用程序窗口的大小或形状发生变化时都会调用该函数。整形函数有 2 个参数,它们是整形窗口的宽度高度。这些参数主要用于设置新的视口

于 2013-07-09T19:09:50.073 回答