0

我一直在试验我教科书中的程序,这些程序涉及使用 glOrtho 剪切二维多边形,然后在 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;

有人可以帮我找到正确的方向来剪裁 3-D 对象吗?因为这适用于二维多边形,但是当我尝试将其应用于球体时,切换按钮甚至不像切换按钮。


编辑:完整代码:

#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 回答