NEHE的OpenGL-Lesson 05 Solid Objects

来源:互联网 发布:移动网络下载不了bt 编辑:程序博客网 时间:2024/05/04 08:33

Lesson 05 Solid Objects

 

在上一篇教程的基础上, 我们将把原来的物体变为真正3D的物体, 而不是之前的3D空间中的2D物体。于是我们将给三角形增加左面, 背面和右面, 这样它就变成了一个金字塔形状的四棱锥;给四边形增加左面, 右面, 背面, 顶面和底面,这样它就变成了一个立方体。

 

对于四棱锥, 我们将使用混合色彩上色。而对于立方体, 我们会让它的每一面都有不同的纯色。

 

int DrawGLScene(GLvoid)                                      // Here's Where We Do All The Drawing

{

       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     // Clear The Screen And The Depth Buffer

       glLoadIdentity();                                            // Reset The View

       glTranslatef(-1.5f,0.0f,-6.0f);                          // Move Left And Into The Screen

 

       glRotatef(rtri,0.0f,1.0f,0.0f);                           // Rotate The Pyramid On It's Y Axis

 

       glBegin(GL_TRIANGLES);                                // Start Drawing The Pyramid

 

 

可能有些人已经使用上一篇的代码创建了自己的3D物体。我收到了好多类似这样的问题: “我创建的物体为什么不能绕着它们自身旋转呢? 它们好像在绕着整个屏幕旋转”。如果想使物体绕某一轴旋转, 就必须要计划好。 有一点你得记住,物体的中心应该在 (0,0,0) 上。

 

下面的代码将围绕中心轴来创建一个四棱锥。 其顶部在中心以上一个单位的位置,底部在中心以下一个单位的位置。 其顶端顶点刚好在中间(0),而底部的顶点一个在中心左侧, 一个在中心右侧。(译注:参看源代码)

 

注意所有三角形都是逆时针绘制的, 这一点很重要, 将在以后的教程中作解释。现在只需要知道这是一个良好的习惯做法, 顺时针或逆时针都可以, 但不要一起使用,除非你有很好的理由。

 

我们就从正面开始绘制。 因为所有的面都共享一个顶端顶点,所以我们把所有三角形的这个顶点都设置为红色。 三角形底部的两个顶点的颜色将是交替的, 正面是从绿到蓝,右面是从蓝到绿, 在每一个面的底部这样交替, 这样底部这些顶点将有共通的颜色。

 

              glColor3f(1.0f,0.0f,0.0f);                   // Red

              glVertex3f( 0.0f, 1.0f, 0.0f);                     // Top Of Triangle(Front)

              glColor3f(0.0f,1.0f,0.0f);                   // Green

              glVertex3f(-1.0f,-1.0f,1.0f);                    // Left Of Triangle(Front)

              glColor3f(0.0f,0.0f,1.0f);                   // Blue

              glVertex3f( 1.0f,-1.0f,1.0f);                     // Right Of Triangle(Front)

 

 

现在绘制右面。 注意其底部的两个顶点在中心右侧一个单位处,其顶部顶点在y轴上是向上一个单位的,而且恰好在x轴的中心。 这样这个面是按照中心倾斜的,从顶端开始, 延续到右侧的底端。

 

这个面底端的左侧顶点将设置为蓝色, 与正面底端右侧的点相同。以这种方法, 蓝色将从四棱锥的一角开始向外扩散。

 

请注意其它三个面的顶点是如何像第一个面的顶点一样添加到 glBegin(GL_TRIANGLES) 和 glEnd() 中的。因为我们完全是用三角形创建物体, 所以 OpenGL 会自动将3个顶点看作一个三角形。 如果绘制完3个顶点后还有3个顶点,它会开始绘制另一个三角形。 所以如果你用了4个顶点,它将把第四个顶点看作是另一个三角形的开始, 而不会绘制一个四边形。 因此,要避免不小心使用了多余的顶点。

 

              glColor3f(1.0f,0.0f,0.0f);                   // Red

              glVertex3f( 0.0f, 1.0f, 0.0f);                     // Top Of Triangle(Right)

              glColor3f(0.0f,0.0f,1.0f);                   // Blue

              glVertex3f( 1.0f,-1.0f,1.0f);                     // Left Of Triangle(Right)

              glColor3f(0.0f,1.0f,0.0f);                   // Green

              glVertex3f( 1.0f,-1.0f,-1.0f);                   // Right Of Triangle(Right)

 

然后绘制背面, 同样的颜色交替。

 

              glColor3f(1.0f,0.0f,0.0f);                   // Red

              glVertex3f( 0.0f, 1.0f, 0.0f);                     // Top Of Triangle (Back)

              glColor3f(0.0f,1.0f,0.0f);                   // Green

              glVertex3f( 1.0f,-1.0f,-1.0f);                   // Left Of Triangle(Back)

              glColor3f(0.0f,0.0f,1.0f);                   // Blue

              glVertex3f(-1.0f,-1.0f,-1.0f);                   // Right Of Triangle(Back)

 

 

下面我们将完成四棱锥的绘制。 因为我们仅仅是让其绕着y轴旋转, 这样永远都不会看到底部,所以我们根本就没有绘制它的底部。  如果有兴趣, 你可以用四边形给它增加一个底,然后让四棱锥绕着x轴旋转, 这样你就可以看到结果了。

 

              glColor3f(1.0f,0.0f,0.0f);                   // Red

              glVertex3f(0.0f, 1.0f, 0.0f);                     //Top Of Triangle (Left)

              glColor3f(0.0f,0.0f,1.0f);                   // Blue

              glVertex3f(-1.0f,-1.0f,-1.0f);                    //Left Of Triangle (Left)

              glColor3f(0.0f,1.0f,0.0f);                   // Green

              glVertex3f(-1.0f,-1.0f,1.0f);                    // Right Of Triangle (Left)

       glEnd();                                            //Done Drawing The Pyramid

 

 

下面我们绘制立方体, 它包含6个四边形。 所有四边形都是按逆时针顺序绘制的:右上, 左上, 左下, 右下这样的顺序。请注意我们的观察方向与顺逆时针的关系问题。

 

我们要将立方体再向屏幕里面移动一点, 这样能使它看起来和四棱锥差不多大小。如果仅仅向屏幕里移6个单位的话, 立方体就显得太大了。

 

       glLoadIdentity();

       glTranslatef(1.5f,0.0f,-7.0f);                           // Move Right And IntoThe Screen

 

       glRotatef(rquad,1.0f,1.0f,1.0f);               // Rotate The Cube On X, Y & Z

 

       glBegin(GL_QUADS);                               // Start Drawing The Cube

 

 

我们就从立方体的顶面开始绘制。 我们从中心位置上升一个单位,注意y坐标始终是1。 其实我们就是在一个与x-z相平行的平面上绘制一个四边形。

 

              glColor3f(0.0f,1.0f,0.0f);                   // Set The Color To Green

              glVertex3f( 1.0f, 1.0f,-1.0f);                     // Top Right Of The Quad(Top)

              glVertex3f(-1.0f, 1.0f,-1.0f);                    // Top Left Of The Quad(Top)

              glVertex3f(-1.0f, 1.0f, 1.0f);                     // Bottom Left Of TheQuad (Top)

              glVertex3f( 1.0f, 1.0f, 1.0f);                     // Bottom Right Of TheQuad (Top)

 

 

然后我们绘制立方体的底面, 和顶面相类似, 不过这次y坐标始终是负1,在中心以下。

 

如果你不担心顺时针逆时针的顺序问题, 你完全可以复制上面的代码,然后把1都改成负1, 这同样可以。 不过, 如果忽略了顺序问题,在使用纹理影射的时候或在其它某些情况下将会出现不希望的结果。

 

              glColor3f(1.0f,0.5f,0.0f);                   // Set The Color To Orange

              glVertex3f( 1.0f,-1.0f,1.0f);                     // Top Right Of The Quad(Bottom)

              glVertex3f(-1.0f,-1.0f,1.0f);                    // Top Left Of The Quad(Bottom)

              glVertex3f(-1.0f,-1.0f,-1.0f);                    // Bottom Left Of The Quad (Bottom)

              glVertex3f( 1.0f,-1.0f,-1.0f);                    // Bottom Right Of The Quad (Bottom)

 

 

现在我们绘制立方体的正面, 从中心向屏幕外移动一个单位,注意z坐标将总是1。

 

              glColor3f(1.0f,0.0f,0.0f);                   // Set The Color To Red

              glVertex3f( 1.0f, 1.0f, 1.0f);                     // Top Right Of The Quad(Front)

              glVertex3f(-1.0f, 1.0f, 1.0f);                     // Top Left Of The Quad(Front)

              glVertex3f(-1.0f,-1.0f,1.0f);                    // Bottom Left Of TheQuad (Front)

              glVertex3f( 1.0f,-1.0f,1.0f);                     // Bottom Right Of TheQuad (Front)

 

 

然后背面与正面类似, 不过是从中心深入屏幕1个单位, z坐标总是负1。

 

              glColor3f(1.0f,1.0f,0.0f);                   // Set The Color To Yellow

              glVertex3f( 1.0f,-1.0f,-1.0f);                    // Bottom Left Of The Quad (Back)

              glVertex3f(-1.0f,-1.0f,-1.0f);                    // Bottom Right Of The Quad (Back)

              glVertex3f(-1.0f, 1.0f,-1.0f);                    // Top Right Of The Quad(Back)

              glVertex3f( 1.0f, 1.0f,-1.0f);                     // Top Left Of The Quad(Back)

 

 

我们只剩下两个面要绘制了。 你会注意到, 每一个面上的顶点都有一个坐标是相同的。而这一次, x坐标始终为负1, 这是因为这次我们绘制的是立方体的左面。

 

              glColor3f(0.0f,0.0f,1.0f);                   // Set The Color To Blue

              glVertex3f(-1.0f, 1.0f, 1.0f);                     // Top Right Of The Quad(Left)

              glVertex3f(-1.0f, 1.0f,-1.0f);                    // Top Left Of The Quad(Left)

              glVertex3f(-1.0f,-1.0f,-1.0f);                    // Bottom Left Of The Quad (Left)

              glVertex3f(-1.0f,-1.0f,1.0f);                    // Bottom Right Of TheQuad (Left)

 

 

然后是最后一面, x坐标将始终是1。 我们逆时针绘制。 如果愿意, 你可以将这个面去掉,将其变成一个盒子。

 

或者如果你喜欢, 你可以改变立方体每一个顶点的颜色,生成就像四棱锥那样的混合颜色。 你可以到我的主页上下载“Evil'sfirst GL demo” 这个例子, 运行它然后按 TAB 键, 你就可以看见一个色彩漂亮的立方体。

 

 

              glColor3f(1.0f,0.0f,1.0f);                   // Set The Color ToViolet

              glVertex3f(1.0f, 1.0f,-1.0f);                     // Top Right OfThe Quad (Right)

              glVertex3f(1.0f, 1.0f, 1.0f);                     //Top Left Of The Quad (Right)

              glVertex3f(1.0f,-1.0f,1.0f);                     // Bottom Left Of The Quad (Right)

              glVertex3f(1.0f,-1.0f,-1.0f);                    //Bottom Right Of The Quad (Right)

       glEnd();                                            // Done Drawing The Quad

 

       rtri+=0.2f;                                        // Increase The Rotation Variable For The Triangle

       rquad-=0.15f;                                         //Decrease The Rotation Variable For The Quad

       return TRUE;                                    // Keep Going

}

 

 

 

这一篇教程又结束了, 你应该已经较好地掌握了在3D空间中创建物体的方法。 你可以把OpenGL 场景想象为一大张绘图纸, 上面有好多层,或者是一个巨大的盒子, 里面有好多的点。 其中有一些点从左移至右,一些是上下移动, 还有一些里外移动。 如果你能形象化的理解这个空间,那么创造新的物体不成问题。

 

如果你理解这些会很吃力, 请不要灰心, 开始往往是艰难的。像立方体这样的例子是很好的学习材料。 如果有什么问题可以给我来信, 我会尽力给你解答。

 

Jeff Molofee (NeHe)

 

 

(译著) 注意在整个NeHe 的教程中作者所叙述的方法不一定是唯一的方法。关于3D空间那些基本概念在这里你其实是学不到的,重复一遍, 对于任何学习 OpenGL 的人手头都应该有一本OpenGL红皮书。如果你发现了什么问题或者疏漏, 请即时反馈给我,这样我就能做出相应的补救或者更正。 十分欢迎你的支持和鼓励, 那将会使我更有动力。