opengl球体剪辑

时间:2012-10-08 16:50:07

标签: opengl glut clipping

我一直在试验我的教科书中的程序,包括使用glOrtho剪切二维多边形,然后在gluPerspective中创建glutWireSpheres。我的目标是用一个平面夹住一半球体,但是,我在修剪三维物体时遇到了麻烦。我创建了一个切换按钮来显示剪裁和未剪切的球体,但是,按钮显示球体以椭圆运动移动我认为。

这是我用于创建球体的绘图

   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;

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


编辑:完整代码:

#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

中处理

1 个答案:

答案 0 :(得分:1)

因此,在gluLookAt()之前添加glLoadIdentity()之后,移动将消失(正如我已经建议的那样......)。当设置有用的剪裁平面方程时,剪辑也按预期工作。在对象空间中心周围定义半径为1的球体时,请设置

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

将导致球体被裁剪为x = -0.5,因此其中3/4仍然可见,正如人们所期望的那样。