6

関数はreshape()このコードでどのように機能し、どのようにパラメーターをglutReshapeFunc(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()へのポインターも受け取ります。関数呼び出しの括弧を付けずに名前で関数を指定すると、関数は「関数へのポインター」になります (または、そのままの配列名がポインターであるのと同様に、そのままの関数名を関数本体へのポインターと考えることができます)。配列の先頭まで)。

x関数のおよびyパラメータの目的を理解するには、マニュアルを読む必要があり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 コールバックで行われることについて説明します。初心者向けチュートリアルに配置されているすべてのものは、実際には表示関数で行う方がはるかに優れています。ビューポートの設定、つまり投影の設定。後で、HUD、テキスト、ミニマップ、または分割ビューを描画したくなるでしょう。そして、そのポイントに到達すると、ビューポートと投影の設定を行う reshape 関数が負担になります。だから今すぐそれを取り除きます。

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 に答える