0

シンプルな「キューブを描く」openGlチュートリアルに従おうとし始めたところです。OpenGL を機能させることに最終的に勝利した後でも、非常に奇妙な結果が得られます。私の問題は、オブジェクトがウィンドウのサイズに合わせてサイズを変更する傾向があることです。代わりに、ウィンドウ サイズでレンダリング領域を決定したいと思います。ウィンドウが大きいほど、より多くの画像が表示される可能性があります。

サイズ変更のスクリーンショットは次のとおりです。
通常のサイズ
サイズ変更
された画像は意図的にリンクとして保持されます。

この自動サイズ変更動作は、OpenGL で使用される座標が何であるかという疑問をもたらします。

4

2 に答える 2

2

最初に覚えておくべきこと: OpenGL は描画 API です。シーンなどを維持しません。

OpenGL が行うことは、ジオメトリ入力座標を頂点属性の形式で画面空間にマップすることです。古い固定関数には、「頂点位置」または単に短い「頂点」と呼ばれる特別な頂点属性があります (実際の頂点は単なる位置ではありません)。

位置は、通常「スクリーン」スペースと呼ばれるものに変換されます (ただし、ビューポートが配置されている場所によっては、「ウィンドウ」または「ビューポート」スペースと呼ばれることもあります)。

1. ビュー/アイ スペースへの変換: これは、頂点位置にモデルビュー マトリックスを乗算することによって行われます。

照度計算などの特定の追加計算は、ビュー空間で行われます。

2. クリップ空間への変換: ビュー空間の位置がクリップ空間に変換されます。これは通常射影と呼ばれ、適切にこの変換を記述する行列は射影行列と呼ばれます

クリップ スペースでは、いくつかの特別なことが発生し、クリッピングとしてまとめられますが、まだ心配する必要はありません。

3. 最後のステップで、クリップされたジオメトリを正規化されたデバイス座標 (NDC) に変換します。NDC スペースは、実際にはビューポートに対する 1:1 のマッピングです。つまり、NDC ボリュームの制限は、glViewport で設定されたビューポートのオフセットと寸法に直接対応します。

3 番目のステップが発生する方法を変更することはできません。1 番目のステップは、ものをビュー空間に変換するために予約されています。そのため、調整は 2 番目のステップで行う必要があります。

投影の制限は、ビューポートの範囲に正比例する必要があります。たとえば、このように

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-width/2, width/2, -height/2, height/2, -1, 1);

ああ、一般的な注意点として、描画機能でも常にビューポートと投影設定を設定する必要があります。これらのステートメントをウィンドウのサイズ変更ハンドラーに配置するチュートリアルが表示された場合は、それを無視して、とにかく描画コードで実行してください。長期的には、これは物事を本当に単純化します。

于 2013-03-31T01:06:29.250 に答える
1

興味深い部分:

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH ) / 300.0;
double h = glutGet( GLUT_WINDOW_HEIGHT ) / 300.0;
glOrtho( -1 * w, 1 * w, -1 * h, 1 * h, 10, -10);

glMatrixMode( GL_MODELVIEW );
glLoadIdentity(); 

文脈では:

#include <GL/glut.h>

void display();
void specialKeys();

double rotate_y=0; 
double rotate_x=0;

void display(){
   //  Clear screen and Z-buffer
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();
  double w = glutGet( GLUT_WINDOW_WIDTH ) / 300.0;
  double h = glutGet( GLUT_WINDOW_HEIGHT ) / 300.0;
  glOrtho( -1 * w, 1 * w, -1 * h, 1 * h, 10, -10);

  glMatrixMode( GL_MODELVIEW );
  glLoadIdentity(); 

  // Rotate when user changes rotate_x and rotate_y
  glRotatef( rotate_x, 1.0, 0.0, 0.0 );
  glRotatef( rotate_y, 0.0, 1.0, 0.0 );

  //Multi-colored side - FRONT
  glBegin(GL_POLYGON);

  glColor3f( 1.0, 0.0, 0.0 );     glVertex3f(  0.5, -0.5, -0.5 );      // P1 is red
  glColor3f( 0.0, 1.0, 0.0 );     glVertex3f(  0.5,  0.5, -0.5 );      // P2 is green
  glColor3f( 0.0, 0.0, 1.0 );     glVertex3f( -0.5,  0.5, -0.5 );      // P3 is blue
  glColor3f( 1.0, 0.0, 1.0 );     glVertex3f( -0.5, -0.5, -0.5 );      // P4 is purple

  glEnd();

  // White side - BACK
  glBegin(GL_POLYGON);
  glColor3f(   1.0,  1.0, 1.0 );
  glVertex3f(  0.5, -0.5, 0.5 );
  glVertex3f(  0.5,  0.5, 0.5 );
  glVertex3f( -0.5,  0.5, 0.5 );
  glVertex3f( -0.5, -0.5, 0.5 );
  glEnd();

  // Purple side - RIGHT
  glBegin(GL_POLYGON);
  glColor3f(  1.0,  0.0,  1.0 );
  glVertex3f( 0.5, -0.5, -0.5 );
  glVertex3f( 0.5,  0.5, -0.5 );
  glVertex3f( 0.5,  0.5,  0.5 );
  glVertex3f( 0.5, -0.5,  0.5 );
  glEnd();

  // Green side - LEFT
  glBegin(GL_POLYGON);
  glColor3f(   0.0,  1.0,  0.0 );
  glVertex3f( -0.5, -0.5,  0.5 );
  glVertex3f( -0.5,  0.5,  0.5 );
  glVertex3f( -0.5,  0.5, -0.5 );
  glVertex3f( -0.5, -0.5, -0.5 );
  glEnd();

  // Blue side - TOP
  glBegin(GL_POLYGON);
  glColor3f(   0.0,  0.0,  1.0 );
  glVertex3f(  0.5,  0.5,  0.5 );
  glVertex3f(  0.5,  0.5, -0.5 );
  glVertex3f( -0.5,  0.5, -0.5 );
  glVertex3f( -0.5,  0.5,  0.5 );
  glEnd();

  // Red side - BOTTOM
  glBegin(GL_POLYGON);
  glColor3f(   1.0,  0.0,  0.0 );
  glVertex3f(  0.5, -0.5, -0.5 );
  glVertex3f(  0.5, -0.5,  0.5 );
  glVertex3f( -0.5, -0.5,  0.5 );
  glVertex3f( -0.5, -0.5, -0.5 );
  glEnd();

  glFlush();
  glutSwapBuffers();
}

void specialKeys( int key, int x, int y ) {
   //  Right arrow - increase rotation by 5 degree
  if (key == GLUT_KEY_RIGHT)
    rotate_y += 5;

  //  Left arrow - decrease rotation by 5 degree
  else if (key == GLUT_KEY_LEFT)
    rotate_y -= 5;

  else if (key == GLUT_KEY_UP)
    rotate_x += 5;

  else if (key == GLUT_KEY_DOWN)
    rotate_x -= 5;

  //  Request display update
  glutPostRedisplay();
}

int main(int argc, char* argv[]){
  //  Initialize GLUT and process user parameters
  glutInit(&argc,argv);

  //  Request double buffered true color window with Z-buffer
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

  // Create window
  glutCreateWindow("Awesome Cube");

  //  Enable Z-buffer depth test
  glEnable(GL_DEPTH_TEST);

  // Callback functions
  glutDisplayFunc(display);
  glutSpecialFunc(specialKeys);

  //  Pass control to GLUT for events
  glutMainLoop();

  //  Return to OS
  return 0;
}
于 2013-03-31T01:11:24.453 に答える