新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 C/C++编程思想 』 → [推荐]NeHe OpenGL教程(中英文版附带VC++源码)Lesson 05-lesson 06 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 32449 个阅读者浏览上一篇主题  刷新本主题   平板显示贴子 浏览下一篇主题
     * 贴子主题: [推荐]NeHe OpenGL教程(中英文版附带VC++源码)Lesson 05-lesson 06 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     一分之千 帅哥哟,离线,有人找我吗?射手座1984-11-30
      
      
      威望:1
      等级:研一(随老板参加了WWW大会还和Tim Berners-Lee合了影^_^)
      文章:632
      积分:4379
      门派:XML.ORG.CN
      注册:2006/12/31

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给一分之千发送一个短消息 把一分之千加入好友 查看一分之千的个人资料 搜索一分之千在『 C/C++编程思想 』的所有贴子 引用回复这个贴子 回复这个贴子 查看一分之千的博客楼主
    发贴心情 

    Lesson 05
       
    Expanding on the last tutorial, we'll now make the object into TRUE 3D object, rather than 2D objects in a 3D world. We will do this by adding a left, back, and right side to the triangle, and a left, right, back, top and bottom to the square. By doing this, we turn the triangle into a pyramid, and the square into a cube.

    We'll blend the colors on the pyramid, creating a smoothly colored object, and for the square we'll color each face a different color.   
       

    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

       
    A few of you have taken the code from the last tutorial, and made 3D objects of your own. One thing I've been asked quite a bit is "how come my objects are not spinning on their axis? It seems like they are spinning all over the screen". In order for your object to spin around an axis, it has to be designed AROUND that axis. You have to remember that the center of any object should be 0 on the X, 0 on the Y, and 0 on the Z.

    The following code will create the pyramid around a central axis. The top of the pyramid is one high from the center, the bottom of the pyramid is one down from the center. The top point is right in the middle (zero), and the bottom points are one left from center, and one right from center.

    Note that all triangles are drawn in a counterclockwise rotation. This is important, and will be explained in a future tutorial, for now, just know that it's good practice to make objects either clockwise or counterclockwise, but you shouldn't mix the two unless you have a reason to.

    We start off by drawing the Front Face. Because all of the faces share the top point, we will make this point red on all of the triangles. The color on the bottom two points of the triangles will alternate. The front face will have a green left point and a blue right point. Then the triangle on the right side will have a blue left point and a green right point. By alternating the bottom two colors on each face, we make a common colored point at the bottom of each face.   
       

      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)

       
    Now we draw the right face. Notice then the two bottom point are drawn one to the right of center, and the top point is drawn one up on the y axis, and right in the middle of the x axis. causing the face to slope from center point at the top out to the right side of the screen at the bottom.

    Notice the left point is drawn blue this time. By drawing it blue, it will be the same color as the right bottom corner of the front face. Blending blue outwards from that one corner across both the front and right face of the pyramid.

    Notice how the remaining three faces are included inside the same glBegin(GL_TRIANGLES) and glEnd() as the first face. Because we're making this entire object out of triangles, OpenGL will know that every three points we plot are the three points of a triangle. Once it's drawn three points, if there are three more points, it will assume another triangle needs to be drawn. If you were to put four points instead of three, OpenGL would draw the first three and assume the fourth point is the start of a new triangle. It would not draw a Quad. So make sure you don't add any extra points by accident.   
       

      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)

       
    Now for the back face. Again the colors switch. The left point is now green again, because the corner it shares with the right face is green.   
       

      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)

       
    Finally we draw the left face. The colors switch one last time. The left point is blue, and blends with the right point of the back face. The right point is green, and blends with the left point of the front face.

    We're done drawing the pyramid. Because the pyramid only spins on the Y axis, we will never see the bottom, so there is no need to put a bottom on the pyramid. If you feel like experimenting, try adding a bottom using a quad, then rotate on the X axis to see if you've done it correctly. Make sure the color used on each corner of the quad matches up with the colors being used at the four corners of the pyramid.   
       

      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

       
    Now we'll draw the cube. It's made up of six quads. All of the quads are drawn in a counter clockwise order. Meaning the first point is the top right, the second point is the top left, third point is bottom left, and finally bottom right. When we draw the back face, it may seem as though we are drawing clockwise, but you have to keep in mind that if we were behind the cube looking at the front of it, the left side of the screen is actually the right side of the quad, and the right side of the screen would actually be the left side of the quad.

    Notice we move the cube a little further into the screen in this lesson. By doing this, the size of the cube appears closer to the size of the pyramid. If you were to move it only 6 units into the screen, the cube would appear much larger than the pyramid, and parts of it might get cut off by the sides of the screen. You can play around with this setting, and see how moving the cube further into the screen makes it appear smaller, and moving it closer makes it appear larger. The reason this happens is perspective. Objects in the distance should appear smaller :)   
       

     glLoadIdentity();
     glTranslatef(1.5f,0.0f,-7.0f);    // Move Right And Into The Screen

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

     glBegin(GL_QUADS);     // Start Drawing The Cube

       
    We'll start off by drawing the top of the cube. We move up one unit from the center of the cube. Notice that the Y axis is always one. We then draw a quad on the Z plane. Meaning into the screen. We start off by drawing the top right point of the top of the cube. The top right point would be one unit right, and one unit into the screen. The second point would be one unit to the left, and unit into the screen. Now we have to draw the bottom of the quad towards the viewer. so to do this, instead of going into the screen, we move one unit towards the screen. Make sense?   
       

      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 The Quad (Top)
      glVertex3f( 1.0f, 1.0f, 1.0f);   // Bottom Right Of The Quad (Top)

       
    The bottom is drawn the exact same way as the top, but because it's the bottom, it's drawn down one unit from the center of the cube. Notice the Y axis is always minus one. If we were under the cube, looking at the quad that makes the bottom, you would notice the top right corner is the corner closest to the viewer, so instead of drawing in the distance first, we draw closest to the viewer first, then on the left side closest to the viewer, and then we go into the screen to draw the bottom two points.

    If you didn't really care about the order the polygons were drawn in (clockwise or not), you could just copy the same code for the top quad, move it down on the Y axis to -1, and it would work, but ignoring the order the quad is drawn in can cause weird results once you get into fancy things such as texture mapping.   
       

      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)

       
    Now we draw the front of the Quad. We move one unit towards the screen, and away from the center to draw the front face. Notice the Z axis is always one. In the pyramid the Z axis was not always one. At the top, the Z axis was zero. If you tried changing the Z axis to zero in the following code, you'd notice that the corner you changed it on would slope into the screen. That's not something we want to do right now :)   
       

      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 The Quad (Front)
      glVertex3f( 1.0f,-1.0f, 1.0f);   // Bottom Right Of The Quad (Front)

       
    The back face is a quad the same as the front face, but it's set deeper into the screen. Notice the Z axis is now minus one for all of the points.   
       

      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)

       
    Now we only have two more quads to draw and we're done. As usual, you'll notice one axis is always the same for all the points. In this case the X axis is always minus one. That's because we're always drawing to the left of center because this is the left face.   
       

      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 The Quad (Left)

       
    This is the last face to complete the cube. The X axis is always one. Drawing is counter clockwise. If you wanted to, you could leave this face out, and make a box :)

    Or if you felt like experimenting, you could always try changing the color of each point on the cube to make it blend the same way the pyramid blends. You can see an example of a blended cube by downloading Evil's first GL demo from my web page. Run it and press TAB. You'll see a beautifully colored cube, with colors flowing across all the faces.   
       

      glColor3f(1.0f,0.0f,1.0f);   // Set The Color To Violet
      glVertex3f( 1.0f, 1.0f,-1.0f);   // Top Right Of The 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
    }

       
    By the end of this tutorial, you should have a better understanding of how objects are created in 3D space. You have to think of the OpenGL screen as a giant piece of graph paper, with many transparent layers behind it. Almost like a giant cube made of of points. Some of the points move left to right, some move up and down, and some move further back in the cube. If you can visualize the depth into the screen, you shouldn't have any problems designing new 3D objects.

    If you're having a hard time understanding 3D space, don't get frustrated. It can be difficult to grasp right off the start. An object like the cube is a good example to learn from. If you notice, the back face is drawn exactly the same as the front face, it's just further into the screen. Play around with the code, and if you just can't grasp it, email me, and I'll try to answer your questions.

    Jeff Molofee (NeHe)

    ----------------------------------------------
    越学越无知

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/10/13 9:54:00
     
     GoogleAdSense射手座1984-11-30
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/5/20 6:05:06

    本主题贴数8,分页: [1]

     *树形目录 (最近20个回帖) 顶端 
    主题:  [推荐]NeHe OpenGL教程(中英文版附带VC++源码)Lesson 0..(8498字) - 一分之千,2007年10月13日
        回复:  TextureImage[0]=LoadBMP("Data/NeHe.bmp")loadbmp(..(106字) - 陆仁贾,2012年8月19日
        回复:  如果六个面要六个不同的纹理,楼主该怎么弄啊?(44字) - guhl112233,2010年9月14日
        回复:  非常感谢,努力学习中(20字) - jisuanjituxingxue,2009年4月11日
        回复:  好好好!没下载一份都觉得特感激,楼主真的是辛苦了![em16](56字) - skflip,2009年2月13日
        回复:  Lesson 06 Learning how to texture map has m..(18137字) - 一分之千,2007年10月13日
        回复:  第六课[IMG]http://www.owlei.com/DancingWind/Pic/..(12289字) - 一分之千,2007年10月13日
        回复:  Lesson 05 Expanding on the last tutorial, w..(13079字) - 一分之千,2007年10月13日

    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    78.125ms