OpenGL学习笔记(四)

龙云尧个人博客,转载请注明出处。

CSDN地址:http://blog.csdn.net/michael753951/article/details/71316089

个人blog地址:http://yaoyl.cn/nehexue-xi-bi-ji-si/


图像旋转

接下来我们将学习图像旋转。图像的旋转通过调用glRotatef(Angle,Xvector,Yvector,Zvector)实现。Angle表示旋转角度(注意是角度不是弧度),Xvector表示沿X轴旋转,Yvector表示沿着Y轴旋转,Zvector表示沿着Z轴旋转。注意旋转角度和RGB设置不一样,RGB的范围是0.0f-1.0f,而角度旋转的范围是0.0f-360.0f(其实可以超过360.0f,不过为了避免溢出我们应该将其做一个约束)。

图像的旋转方向遵循右手定则,即右手握住旋转的轴,右手大拇指朝向轴的正方向,那么你右手其他手指所朝的方向便为正方向。

为了实现图像的旋转,我们将尝试调用一个glRotatef方法。

首先我们还是在DrawGLScene方法中,通过glTranslatef确定绘点以后,我们就可以插入glRotatef(rtri, 0.0f, 0.0f, 1.0f)来绕着Z轴旋转。为此我们需要定义一个GLfloat类型的全局变量rtri。同时在DrawGLScene方法结束之前我们需要不断改变rtri的值来实现图像的旋转工作。

最终的参考代码如下(注意需要自己定义一个全局变量rtri)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
int DrawGLScene(GLvoid)                                 // 从这里开始进行所有的绘制
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
glLoadIdentity(); // 重置当前的模型观察矩阵
//当您调用glLoadIdentity()之后,您实际上将当前点移到了屏幕中心,X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。
//中心左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。移入屏幕深处是负值,移出屏幕则是正值。

//glTranslatef(x, y, z)沿着 X, Y 和 Z 轴移动。
//根据前面的次序,下面的代码沿着X轴左移1.5个单位,Y轴不动(0.0f),最后移入屏幕6.0f个单位。
//注意在glTranslatef(x, y, z)中当您移动的时候,您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。
glTranslatef(-1.5f, 0.0f, -6.0f); // 左移 1.5 单位,并移入屏幕 6.0
glRotatef(rtri, 0.0f, 0.0f, 1.0f); // Rotate The Triangle On The Y axis ( NEW )
//glBegin(GL_TRIANGLES)的意思是开始绘制三角形,glEnd() 告诉OpenGL三角形已经创建好了。
//本节的简单示例中,我们只画一个三角形。如果要画第二个三角形的话,可以在这三点之后,再加三行代码(3点)。
glBegin(GL_TRIANGLES); // Drawing Using Triangles
//接下来的一行代码设置三角形的第一个顶点(三角形的上顶点),并使用当前颜色(红色)来绘制。
glColor3f(1.0f, 0.0f, 0.0f); // 设置当前色为红色
glVertex3f(0.0f, 1.0f, 0.0f); // Top
glColor3f(0.0f, 1.0f, 0.0f); // 设置当前色为绿色
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glColor3f(0.0f, 0.0f, 1.0f); // 设置当前色为蓝色
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glEnd(); // Finished Drawing The Triangle
//在屏幕的左半部分画完三角形后,我们要移到右半部分来画正方形。为此要再次使用glTranslate。
glTranslatef(3.0f, 0.0f, 0.0f); // Move Right 3 Units
//现在使用GL_QUADS绘制正方形。
glBegin(GL_QUADS); // Draw A Quad
//glColor3f(1.0f, 0.0f, 0.0f); // 将当前色设置为蓝色
glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left
glVertex3f(1.0f, 1.0f, 0.0f); // Top Right
//glColor3f(0.0f, 0.1f, 0.0f); // 将当前色设置为蓝色
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glEnd(); // Done Drawing The Quad
rtri += 0.2f; // Increase The Rotation Variable For The Triangle ( NEW )
return TRUE; // Everything Went OK
}

实现的效果如下图所示。

section3.1

上述方法实现了整个画面绕着Z轴旋转的情况,我们接下来将实现两个图像分别旋转的场景。

首先我们尝试直接在绘制矩形之前,直接开始对矩形矩形旋选,旋转结果如下所示。

section3.2

这个时候我们发现矩形的旋转很异常,他并不是按照我们理想的情况下绕着自己的X轴旋转。这是因为在之前的三角形旋转过程中,实际在旋转的是整个坐标系(这样做是很有道理里的,它能让我们很方便的画出这个三角形,而不用费心计算每个点在固定参考坐标系下旋转之后新的坐标位置)。

为了解决这个问题,我们在三角形旋转完毕之后,应该重新调用glLoadIdentity进行坐标初始化。然后我们重新设置绘点glTranslatef,注意这个时候绘点的参数应该为(1.5f, 0.0f, -6.0f),因为重置后绘点坐标为(0.0, 0.0, 0.0),我们应该将矩形的绘点设置到和三角形相同的位置上。

最终的两个图形的旋转的参考代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
int DrawGLScene(GLvoid)                                 // 从这里开始进行所有的绘制
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
glLoadIdentity(); // 重置当前的模型观察矩阵
//当您调用glLoadIdentity()之后,您实际上将当前点移到了屏幕中心,X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。
//中心左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。移入屏幕深处是负值,移出屏幕则是正值。

//glTranslatef(x, y, z)沿着 X, Y 和 Z 轴移动。
//根据前面的次序,下面的代码沿着X轴左移1.5个单位,Y轴不动(0.0f),最后移入屏幕6.0f个单位。
//注意在glTranslatef(x, y, z)中当您移动的时候,您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。
glTranslatef(-1.5f, 0.0f, -6.0f); // 左移 1.5 单位,并移入屏幕 6.0
glRotatef(rtri, 0.0f, 0.0f, 1.0f); // Rotate The Triangle On The Y axis ( NEW )
//glBegin(GL_TRIANGLES)的意思是开始绘制三角形,glEnd() 告诉OpenGL三角形已经创建好了。
//本节的简单示例中,我们只画一个三角形。如果要画第二个三角形的话,可以在这三点之后,再加三行代码(3点)。
glBegin(GL_TRIANGLES); // Drawing Using Triangles
//接下来的一行代码设置三角形的第一个顶点(三角形的上顶点),并使用当前颜色(红色)来绘制。
glColor3f(1.0f, 0.0f, 0.0f); // 设置当前色为红色
glVertex3f(0.0f, 1.0f, 0.0f); // Top
glColor3f(0.0f, 1.0f, 0.0f); // 设置当前色为绿色
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glColor3f(0.0f, 0.0f, 1.0f); // 设置当前色为蓝色
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glEnd(); // Finished Drawing The Triangle
//在屏幕的左半部分画完三角形后,我们要移到右半部分来画正方形。为此要再次使用glTranslate。
glLoadIdentity(); // 重置模型观察矩阵
glTranslatef(1.5f, 0.0f, -6.0f); // Move Right 3 Units
glRotatef(rquad, 1.0f, 0.0f, 0.0f); // 绕X轴旋转四边形
//现在使用GL_QUADS绘制正方形。
glBegin(GL_QUADS); // Draw A Quad
//glColor3f(1.0f, 0.0f, 0.0f); // 将当前色设置为蓝色
glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left
glVertex3f(1.0f, 1.0f, 0.0f); // Top Right
//glColor3f(0.0f, 0.1f, 0.0f); // 将当前色设置为蓝色
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glEnd(); // Done Drawing The Quad
if (rtri >= 360.0f) rtri -= 360.0; // control the range of the rtri
if (rtri <= 0.0f) rtri += 360.0;
rtri += 0.2f; // Increase The Rotation Variable For The Triangle ( NEW )
rquad -= 0.15f; // 减少四边形的旋转变量
return TRUE; // Everything Went OK
}

3D图像的旋转

我们已经实现了对2D图像的构建着色以及选装,接下来我们将实现一个3D图像的构建以及旋转。

我们在之前构建三角形的教程中已经知道,在glBegin和glEnd之间可以有很多次相同形状的绘制,所以我们将利用这个特点在实验中利用4个三角形绘制一个金字塔,用6个矩形绘制一个立方体。

绘制过程我们就不再赘述了,旋转方式我们在上一次实验中也已经了解了,所以我们直接上代码和结果图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
int DrawGLScene(GLvoid)                                 // 从这里开始进行所有的绘制
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
glLoadIdentity(); // 重置当前的模型观察矩阵
//当您调用glLoadIdentity()之后,您实际上将当前点移到了屏幕中心,X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。
//中心左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。移入屏幕深处是负值,移出屏幕则是正值。

//glTranslatef(x, y, z)沿着 X, Y 和 Z 轴移动。
//根据前面的次序,下面的代码沿着X轴左移1.5个单位,Y轴不动(0.0f),最后移入屏幕6.0f个单位。
//注意在glTranslatef(x, y, z)中当您移动的时候,您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。
glTranslatef(-1.5f, 0.0f, -6.0f); // 左移 1.5 单位,并移入屏幕 6.0
glRotatef(rtri, 1.0f, 0.0f, 0.0f); // Rotate The Triangle On The Y axis ( NEW )
//glBegin(GL_TRIANGLES)的意思是开始绘制三角形,glEnd() 告诉OpenGL三角形已经创建好了。
//本节的简单示例中,我们只画一个三角形。如果要画第二个三角形的话,可以在这三点之后,再加三行代码(3点)。
glBegin(GL_TRIANGLES); // Drawing Using Triangles
//接下来的一行代码设置三角形的第一个顶点(三角形的上顶点),并使用当前颜色(红色)来绘制。
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)
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)
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(); // Finished Drawing The Triangle
//在屏幕的左半部分画完三角形后,我们要移到右半部分来画正方形。为此要再次使用glTranslate。
glLoadIdentity(); // 重置模型观察矩阵
glTranslatef(1.5f, 0.0f, -6.0f); // Move Right 3 Units
glRotatef(rquad, 1.0f, 0.0f, 0.0f); // 绕X轴旋转四边形
//现在使用GL_QUADS绘制正方形。
glBegin(GL_QUADS); // Draw A Quad
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)
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)
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)
glColor3f(1.0f, 1.0f, 0.0f); // Set The Color To Yellow
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)
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)
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)
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
if (rtri >= 360.0f) rtri -= 360.0; // control the range of the rtri
if (rtri <= 0.0f) rtri += 360.0;
rtri += 0.2f; // Increase The Rotation Variable For The Triangle ( NEW )
rquad -= 0.15f; // 减少四边形的旋转变量
return TRUE; // Everything Went OK
}

4.1

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

请我喝杯咖啡吧~

支付宝
微信