0

glOrtho を使用して 2-D ポリゴンをクリッピングし、gluPerspective で glutWireSpheres を作成するプログラムをテキストブックから実験してきました。私の目標は、平面で球の半分を切り取ることですが、3D オブジェクトの切り取りに問題があります。球体のクリッピングとクリッピング解除を表示するトグル ボタンを作成しましたが、ボタンは代わりに球体が楕円の動きをしていると思います。

これが球を作成するための私の描画シーンです

   double eqn0[4] = {1, 0, 0.0, -60}; // Data for clipping plane 0.

   // Choose window.
   glutSetWindow(id2);
   gluLookAt(0.0, 3.0, 12.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 

   glClear(GL_COLOR_BUFFER_BIT);

    glClipPlane(GL_CLIP_PLANE0, eqn0); // Specify clipping plane 0.


   if (isClip0) glEnable(GL_CLIP_PLANE0); // Clip points s.t. z > 0.25.
   else glDisable(GL_CLIP_PLANE0);

   glPushMatrix();
   glColor3f(1.0, 0.0, 0.0);
   glutWireSphere(1.0, 10, 10);
   glPopMatrix();

   glFlush();

そして、これが私のトグルです

case '0':
         if (isClip0 == 0) isClip0 = 1;
         else isClip0 = 0;
         glutPostRedisplay();
         break;

誰かが 3D オブジェクトをクリッピングするための正しい方向に進むのを手伝ってくれますか? これは 2D ポリゴンで機能するため、球体に適用しようとすると、トグル ボタンがトグルのように機能しません。


編集:完全なコード:

#include <cmath>
#include <iostream>

#ifdef __APPLE__
#  include <GLUT/glut.h>
#else
#  include <GL/glut.h>
#endif

#define PI 3.14159265

using namespace std;

// Globals.
static int id1, id2; // Window identifiers.
static int isClip0 = 0; // Is clipping plane 0 enabled?
static int isClip1 = 0; // Is clipping plane 1 enabled?
static int isClip3 = 0; // Is clipping plane 0 enabled?
static int isClip4 = 0; // Is clipping plane 1 enabled?

// Drawing routine for first window.
void drawScene1(void)
{
   // Choose window.
   glutSetWindow(id1);

   glClear(GL_COLOR_BUFFER_BIT);

   // A red square.
   glColor3f(1.0, 0.0, 0.0);    
   glBegin(GL_POLYGON);
      glVertex3f(10.0, 10.0, 0.0);
      glVertex3f(40.0, 10.0, 0.0);
      glVertex3f(40.0, 40.0, 0.0);
      glVertex3f(10.0, 40.0, 0.0);
   glEnd();

   glFlush();
}

// Drawing routine for second window.
void drawScene2(void)
{

   double eqn0[4] = {1, 0, 0.0, -1000}; // Data for clipping plane 0.

   // Choose window.
   glutSetWindow(id2);

   gluLookAt(0.0, 3.0, 12.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 

   glClear(GL_COLOR_BUFFER_BIT);

    glClipPlane(GL_CLIP_PLANE0, eqn0); // Specify clipping plane 0.

   if (isClip0) glEnable(GL_CLIP_PLANE0); // Clip points s.t. z > 0.25.
   else glDisable(GL_CLIP_PLANE0);

   glPushMatrix();
   glColor3f(1.0, 0.0, 0.0);
   glutWireSphere(1.0, 10, 10);
   glPopMatrix();

   glFlush();
}

// Initialization routine for first window.
void setup1(void) 
{
   // Black background.
   glClearColor(0.0, 0.0, 0.0, 0.0);
}

// Initialization routine for second window.
void setup2(void) 
{
   // Green background.
   glClearColor(1.0, 1.0, 1.0, 0.0);
}

// Reshape routine for first window.
void resize1(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();

   // Non-square aspect ratio squashes the square.
   glOrtho(0.0, 50.0, 0.0, 100.0, -1.0, 1.0);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

// Reshape routine for second window.
void resize2(int w, int h)
{
   glViewport (0, 0, (GLsizei)w, (GLsizei)h);
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(60.0, (float)w/(float)h, 1.0, 50.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();


}

// Keyboard input processing routine shared by both windows.
void keyInput(unsigned char key, int x, int y)
{
   switch(key) 
   {
      case 27:
         exit(0);
         break;
        case '0':
         if (isClip0 == 0) isClip0 = 1;
         else isClip0 = 0;
         glutPostRedisplay();
         break;
      default:
         break;
   }
}

// Main routine.
int main(int argc, char **argv) 
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);

   // First top-level window definition.
   glutInitWindowSize(250, 500); 
   glutInitWindowPosition(100, 100);

   // Create the first window and return id.
   id1 = glutCreateWindow("windows.cpp - window 1"); 

   // Initialization, display, and other routines of the first window. 
   setup1();
   glutDisplayFunc(drawScene1); 
   glutReshapeFunc(resize1);
   glutKeyboardFunc(keyInput); // Routine is shared by both windows.

   // Second top-level window definition.
   glutInitWindowSize(250, 500); 
   glutInitWindowPosition(400, 100);

   // Create the second window and return id.
   id2 = glutCreateWindow("windows.cpp - window 2"); 

   // Initialization, display, and other routines of the second window. 
   setup2(); 
   glutDisplayFunc(drawScene2); 
   glutReshapeFunc(resize2);
   glutKeyboardFunc(keyInput); // Routine is shared by both windows.

   glutMainLoop();

   return 0;   
}

球は drawScene2 で処理されます

4

1 に答える 1

1

そのため、gluLookAt() の直前に glLoadIdentity() を追加すると、動きがなくなります (既に提案したように...)。また、便利なクリップ平面方程式を設定すると、クリッピングも期待どおりに機能します。オブジェクト空間の中心を中心に半径 1 の球を定義すると、

 GLdouble eqn0[4] = {1, 0, 0.0, 0.5};

すると、球は x=-0.5 でクリップされるため、予想どおり、球の 3/4 がまだ表示されています。

于 2012-10-08T21:24:17.337 に答える