NeHe OpenGL教程 第四课 旋转

在上一课中,我们学习了如何给三角形和正方形着色。在这一课中,我们将学习如何沿一条坐标轴旋转这些着色物体。使用上节课的代码,我们将在其中添加一些新的代码。我将重写下面这部分代码,以便于你知道哪些是新添加的代码,哪些是应该替换的代码。

我们从新添加的两个变量开始,它们是用来记录每个物体的旋转角度的。在程序的最上面,其它的全局变量下面添加这两个变量。 'bool fullscreen=TRUE;'语句下面将有两行新添加的代码。我们定义了两个浮点型的变量,它们能精确地控制物体的旋转。浮点型变量可以使用小数。意味着我们不会被限制于只能使用1,2,3来表示角度,我们可以使用在1.1, 1.7, 2.3,甚至 1.015来表示更精确的角度值。你会发现浮点型变量在OpenGL编程中非常重要。rtri变量用来控制三角形的旋转,rquad变量用来控制正方形的旋转。

#include <windows.h>  // Windows头文件
#include <gl\gl.h>    // OpenGL32库头文件
#include <gl\glu.h>   // GLu32库头文件
#include <gl\glaux.h> // GLaux库头文件
HGLRC      hRC=NULL;   // 永久的渲染上下文( Rendering Context)
HDC                hDC=NULL;  // 私有的GDI设备上下文( GDI Device Context)
HWND              hWnd=NULL;  // 获得我们窗口的句柄
HINSTANCE   hInstance; // 获得应用程序的实例
bool   keys[256];   // 用于键盘行为的数组
bool    active=TRUE;  // 窗口活动标记,默认设置为TRUE
bool   fullscreen=TRUE; // 全屏标记,默认设置为全屏
GLfloat     rtri;     // 三角形的旋转角度 ( 新加代码 )
GLfloat     rquad;    // 正方形的旋转角度 (新加代码 )

现在我们需要修改DrawGLScene() 函数的代码。我将重写整个函数。以便于你能知道,和以前的代码相比,哪里做了修改。我将会解释为什么有些代码需要改变,以及新添加的代码的用途。下面这部分代码和上节课的完全一样。

int DrawGLScene(GLvoid)  //我们绘制图形的地方

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除颜色和深度缓存

glLoadIdentity(); //重置模型视图矩阵

glTranslatef(-1.5f,0.0f,-6.0f); //向左移动1.5个单位,向屏幕里移动6.0个单位

下面的这行代码是新添加的。 glRotatef(Angle,Xvector,Yvector,Zvector) 函数负责沿某一个坐标轴旋转物体。这条命令有很多用法。(原文:You will get alot of use out of this command. )Angle变量(通常存储在一个变量中)是你想要这个物体旋转的角度。Xvector , Yvector 和  Zvector 三个参数则共同决定旋转轴的矢量方向。比如(1,0,0),将沿x轴单位向量向右旋转。而 (-1,0,0),将沿x轴单位向量向左旋转。

D. Michael Traub:提出对 Xvector , Yvector 和 Zvector 的上述解释。

为了更好的理解X, Y 和 Z的旋转,我举些例子。


X Axis - You're working on a table saw. The bar going through the center of the blade runs left to right (just like the x axis in OpenGL). The sharp teeth spin around the x axis (bar running through the center of the blade), and appear to be cutting towards or away from you depending on which way the blade is being spun. When we spin something on the x axis in OpenGL it will spin the same way.

Y Axis - Imagine that you are standing in the middle of a field. There is a huge tornado coming straight at you. The center of a tornado runs from the sky to the ground (up and down, just like the y axis in OpenGL). The dirt and debris in the tornado spins around the y axis (center of the tornado) from left to right or right to left. When you spin something on the y axis in OpenGL it will spin the same way.

Z Axis - You are looking at the front of a fan. The center of the fan points towards you and away from you (just like the z axis in OpenGL). The blades of the fan spin around the z axis (center of the fan) in a clockwise or counterclockwise direction. When You spin something on the z axis in OpenGL it will spin the same way.

这几段话翻译不太明白,(英语水平有限)大家自己看吧。以后如果有能力,我会把它们译成中文。

所以,在下面的代码中,如果rtri等于7,我们将沿y轴旋转7度。(从左至右)你可以用代码做一些试验。把0.0f变为1.0f,把1.0f变为0.0f,让三角形同时沿x和z轴旋转。

请注意,旋转是依据角度的。(原文:It's important to note that rotations are done in degrees. )如果rtri等于10,我们将沿y轴旋转10度。

glRotatef(rtri,0.0f,1.0f,0.0f);   // 沿y轴旋转三角形( 新加代码 )
下面的代码没有修改。它将绘制一个颜色平滑混合的三角形。三角形将被绘制在屏幕的左半边,将会沿y轴从左向右旋转。

glBegin(GL_TRIANGLES);     //使用GL_TRIANGLES参数绘制三角形

glColor3f(1.0f,0.0f,0.0f);  //设置颜色为红色

glVertex3f( 0.0f, 1.0f, 0.0f);// 从中点向上移动一个单位 (上顶点)

glColor3f(0.0f,1.0f,0.0f); //设置颜色为绿色

glVertex3f(-1.0f,-1.0f, 0.0f); //左下顶点

glColor3f(0.0f,0.0f,1.0f);         //设置颜色为蓝色

glVertex3f( 1.0f,-1.0f, 0.0f);    // 右下顶点

glEnd();  //绘制三角形完成

你会注意到,我们在下面的代码中右添加了一个 glLoadIdentity()函数。我们重新设置视图。如果我们不重新设置视图。如果我们在物体旋转后平移,你会得到一个意外的结果。因为坐标轴已经旋转了,它并没有指向你认为的方向。所以,如果我们沿x轴向左平移,结果可能是向上或向下平移了,依据我们在每个坐标轴的旋转角度。试着去掉 glLoadIdentity()这行代码,看看会发生什么。
glLoadIdentity();       //重置当前模型视图矩阵
glTranslatef(1.5f,0.0f,-6.0f); //向右移动1.5个单位,向内移动6.0个单位
glRotatef(rquad,1.0f,0.0f,0.0f); // 沿x轴旋转正方形 ( 新加代码 )
下面的代码没有修改。它将绘制一个蓝色的正方形。它将把正方形绘制在屏幕右边正方形旋转的位置。

glColor3f(0.5f,0.5f,1.0f);    //把颜色设置为蓝色

glBegin(GL_QUADS);   //开始绘制正方形

glVertex3f(-1.0f, 1.0f, 0.0f); //左上顶点

glVertex3f( 1.0f, 1.0f, 0.0f);  //右上顶点

glVertex3f( 1.0f,-1.0f, 0.0f);  //右下顶点

glVertex3f(-1.0f,-1.0f, 0.0f);  //左下顶点

glEnd();    //正方形绘制完成

下面是新加的代码。把 rtri 和 rquad 想象为容器。在程序的开始我们创建了这两个容器 ( GLfloat rtri , 和 GLfloat rquad )。当容器创建之后,里面是空的。下面的第一行代码是向rtri容器中添加0.2。因此每次运行完这段代码,rtri 容器中的值都会增 长0.2。 rquad 容器中的值减少0.15。同样每次运行完这段代码,rquad 容器中的值都会减少0.15。角度值逐渐减少会和角度值逐渐增加的旋转方向相反。

rtri+=0.2f;     // 增加三角形的旋转角度 (新加代码 )

rquad-=0.15f;  // 减少正方形的旋转角度   (新加代码 )
return TRUE;   //返回
}

最后,修改一下切换窗口\全屏模式部分的代码,以便于窗口有一个合适的标题。

if(keys[VK_F1])  //如果F1被按下

{

    keys[VK_F1]=FALSE;  //设置为FALSE

    KillGLWindow();  //销毁当前的窗口

    fullscreen=!fullscreen;  //切换全屏/窗口模式

    // Recreate Our OpenGL Window ( 修改的部分)

    if(!CreateGLWindow("NeHe's Rotation Tutorial",640,480,16,fullscreen))

    {

        return0;  //如果窗口创建失败,程序退出

    }

}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值