其中最左边的桌子循环上移(即匀速上移到一定位置后回到原点继续匀速上移),中间的桌子不断旋转(即绕自身中间轴旋转),最右边的桌子循环缩小(即不断缩小到一定大小后回归原来大小继续缩小)。

桌子的模型尺寸如下:

操作方法和实验步骤

绘制桌子

根据题目要求,主要实现的是桌子的移动、旋转和缩放,因此首先需要绘制出桌子的形状。

由于题目要求的桌子主要由五个立法体组成,分别是一个桌面和四个桌脚,而立方体又是由6个面组成的,因此通过绘制模式GL_QUAD绘制所有的面即可;如图:

一个立方体的大小和位置有中心点位置和长宽高决定(假设中点位置坐标为x、y、z),因此我们可以得到四个面、二十四个点的位置为:

1
2
3
4
5
6
7
8
9
10
11
{ x + width,y + depth,z },{ x + width,y - depth,z },{ x - width,y - depth,z },{ x - width,y + depth,z },

{ x - width,y + depth,z },{ x - width,y - depth,z },{ x - width,y - depth,z - height },{ x - width,y + depth,z - height },

{ x - width,y + depth,z - height },{ x - width,y - depth,z - height },{ x + width,y - depth,z - height },{ x + width,y + depth,z - height },

{ x + width,y + depth,z - height },{ x + width,y - depth,z - height },{ x + width,y - depth,z },{ x + width,y + depth,z },

{ x + width,y + depth,z },{ x - width,y + depth,z },{ x - width,y + depth,z - height },{ x + width,y + depth,z - height },

{ x + width,y - depth,z },{ x - width,y - depth,z },{ x - width,y - depth,z - height },{ x + width,y - depth,z - height }

设置多边形的绘制模式为glPolygonMode(GL_FRONT_AND_BACK,GL_LINE),绘制出立方体来:

1
2
3
4
glBegin(GL_QUADS);
for (int i = 0; i < 24; i++)
glVertex3f(point[i][0], point[i][1],point[i][2]);
glEnd();

最后把绘制立方体的过程封装成函数,传入中心点位置和长宽高即可绘制出桌子;

桌子循环上移、旋转、缩小放大

循环上移通过函数glTranslatefglRotateglScale完成桌子移动、旋转和缩放的操作;这几个函数的操作原理是将当前的栈顶矩阵乘以一个操作矩阵(移动、旋转、缩放),因此每次绘制前我们都需要通过glLoadIdentity()将当前的操作矩阵矩阵重置为单位矩阵;然在具体的移动或旋转或缩放操作时,将操作矩阵压进栈中,避免这三个操作相互影响;

移动

void glTranslatef(GLfloatx,GLfloat y,GLfloat z);

函数功能: 沿X轴正方向平移x个单位

​ 沿Y轴正方向平移y个单位

​ 沿Z轴正方向平移z个单位

旋转

void glRotatef(GLfloatangle,GLfloat x,GLfloat y,GLfloat z);

函数功能:以点(0,0,0)到点(x,y,z)为轴,旋转angle角度;

根据题目要求,绕着y轴旋转,即用右手握住这条y轴向量,大拇指指向向量的正方向,四指环绕的方向就是旋转的方向;

缩放

void glScalef(GLfloat Sx, GLfloat Sy, GLfloat Sz);

函数功能:Sx,Sy,Sz分别为模型在x,y,z轴方向的缩放比;

源代码

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

float fTranslate;
float fRotate;
float fScale = 1.0f; void (GLfloat x, GLfloat y , GLfloat z,GLfloat width_, GLfloat depth_, GLfloat height_) {
GLfloat width = width_ * 0.5;
GLfloat depth = depth_ * 大专栏  OpenGL的矩阵使用——绘制桌子pan class="number">0.5;
GLfloat height = height_; GLfloat point[24][3] = {
{ x + width,y + depth,z },{ x + width,y - depth,z },{ x - width,y - depth,z },{ x - width,y + depth,z },
{ x - width,y + depth,z },{ x - width,y - depth,z },{ x - width,y - depth,z - height },{ x - width,y + depth,z - height },
{ x - width,y + depth,z - height },{ x - width,y - depth,z - height },{ x + width,y - depth,z - height },{ x + width,y + depth,z - height },
{ x + width,y + depth,z - height },{ x + width,y - depth,z - height },{ x + width,y - depth,z },{ x + width,y + depth,z },
{ x + width,y + depth,z },{ x - width,y + depth,z },{ x - width,y + depth,z - height },{ x + width,y + depth,z - height },
{ x + width,y - depth,z },{ x - width,y - depth,z },{ x - width,y - depth,z - height },{ x + width,y - depth,z - height }
}; glBegin(GL_QUADS);
for (int i = 0; i < 24; i++)
glVertex3f(point[i][0], point[i][1],point[i][2]);
glEnd();
} void Draw_Dest() // This function draws a triangle with RGB colors
{
Draw_Cube(0, 0, 0, 1, 0.8, 0.2); //桌面
Draw_Cube(0.3, 0.2, -0.2, 0.2, 0.2, 0.6);//桌脚
Draw_Cube(-0.3, 0.2, -0.2, 0.2, 0.2, 0.6);
Draw_Cube(0.3, -0.2, -0.2, 0.2, 0.2, 0.6);
Draw_Cube(-0.3, -0.2, -0.2, 0.2, 0.2, 0.6);
} void reshape(int width, int height)
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
} glViewport(0,0,width,height); // Reset The Current Viewport glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix // Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
} void idle()
{
glutPostRedisplay();
} void redraw()
{ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity(); // Reset The Current Modelview Matrix glPushMatrix();
glTranslatef(-2.0f, 0.0f,-6.0f); // Place the triangle Left
glTranslatef(0.0f, fTranslate, 0.0f); // Translate in Y direction
Draw_Dest(); // Draw desk
glPopMatrix(); glPushMatrix();
glTranslatef(0.0f, 0.0f,-6.0f); // Place the dest at Center
glRotatef(fRotate, 0, 3.0f, 0); // Rotate around Y axis
Draw_Dest(); // Draw desk
glPopMatrix(); glPushMatrix();
glTranslatef(2.0f, 0.0f, -6.0f); // Place the dest right
glScalef(fScale, fScale, fScale); // Scale
Draw_Dest(); // Draw Draw desk
glPopMatrix(); fScale -= 0.005f;
fTranslate += 0.005f;
fRotate += 0.3f; if (fTranslate > 0.5f) fTranslate = 0.0f;
if (fScale < 0.5f) fScale = 1.0f; glutSwapBuffers();
} void processNormalKeys(unsigned char key, int x, int y)
{ if (key == 27) //按ESC退出
exit(0);
} int main (int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(640,480);
glutCreateWindow("Exercise2"); glutDisplayFunc(redraw);
glutReshapeFunc(reshape);
glutIdleFunc(idle); glutKeyboardFunc(processNormalKeys); glutMainLoop(); return 0;
}

效果

OpenGL的矩阵使用——绘制桌子的更多相关文章

  1. Opengl中矩阵和perspective/ortho的相互转换

    Opengl中矩阵和perspective/ortho的相互转换 定义矩阵 Opengl变换需要用四维矩阵.我们来定义这样的矩阵. +BIT祝威+悄悄在此留下版了个权的信息说: 四维向量 首先,我们定 ...

  2. OpenGL投影矩阵

    概述 透视投影 正交投影 概述 计算机显示器是一个2D平面.OpenGL渲染的3D场景必须以2D图像方式投影到计算机屏幕上.GL_PROJECTION矩阵用于该投影变换.首先,它将所有定点数据从观察坐 ...

  3. OpenGL投影矩阵【转】

    OpenGL投影矩阵 概述 透视投影 正交投影 概述 计算机显示器是一个2D平面.OpenGL渲染的3D场景必须以2D图像方式投影到计算机屏幕上.GL_PROJECTION矩阵用于该投影变换.首先,它 ...

  4. Opengl ES之四边形绘制

    四边形的绘制在Opengl ES是很重要的一项技巧,比如做视频播放器时视频的渲染就需要使用到Opengl ES绘制四边形的相关知识.然而在Opengl ES却没有直接提供 绘制四边形的相关函数,那么如 ...

  5. OPENGL之矩阵

    前面的若干重要概念中描述了OPENGL中的几个重要变换,而矩阵是线性代数中的重要数学工具,它被用来对这些变换进行数学上的实现. 矩阵主要有以下几种: 模型视图矩阵:模型视图矩阵是个4*4的矩阵,代表经 ...

  6. openGL线s的绘制

    /** * 缓冲区工具类 */ public class BufferUtil { /** * 将浮点数组转换成字节缓冲区 */ public static ByteBuffer arr2ByteBu ...

  7. 3D Computer Grapihcs Using OpenGL - 16 使用DrawElementsInstanced绘制立方体

    我们使用15节学到的知识来绘制14节的立方体. 在第14节我们使用了两次glDrawElements实现了OpenGL实例化,发现这样仍然不太方便,如果需要绘制成千上万的立方体,就需要手写成千上万次的 ...

  8. IOS 中openGL使用教程2(openGL ES 入门篇 | 绘制一个多边形)

    在上一篇我们学习了如何搭建IOS下openGL的开发环境,接下来我们来学习如何绘制一个多边形. 在2.0之前,es的渲染采用的是固定管线,何为固定管线,就是一套固定的模板流程,局部坐标变换 -> ...

  9. ogre, dx, opengl坐标矩阵

    opengl 右手坐标系 列向量 左乘 列主序存储矩阵osg   右手坐标系 行向量 右乘 行主序存储矩阵d3d       左手坐标系 行向量 右乘 行主序存储矩阵ogre    右手坐标系 列向量 ...

随机推荐

  1. 理解python的可变参数

    以 str.format(*args,**kwargs) 为例. "type1:{},{},{},{}_type2:{a},{b},{c},{d}".format('a',2,*[ ...

  2. python解一元一次方程

    将未知数看成是虚数 将常数看成是实数 最终求解. import re class Item: def __init__(self,imag=0,real=0): self.imag = imag se ...

  3. 文件操作符|-e|-M|-s|-A|_|-r -w $filename|stat|localtime|&|>>|<<

    TTY:终端是一种字符型设备,它有多种类型,通常使用tty 来简称各种类型的终端设备 #!/usr/bin/perl use strict; use warnings; print "exi ...

  4. 在win10下安装ubuntu双系统总结

    在打算装双系统前两天,我事先在网上买了一个16G大小的U盘,用来坐启动盘.后来发现其实有4G大小就远远足够的,16G的太浪费了,忘后来人吸取教训.呜呜呜.....下面给大家讲讲我的安装步骤: 参考文章 ...

  5. Unittest - Python 使用总结

    Unittest - Python 使用总结 批量执行 一.UnitTest TestSuite 控制用例执行的顺序 UnitTest 框架默认 main() 方法根据 ASCII 码的顺序加载测试用 ...

  6. sql表变量,临时表

    @test是表变量,存在于内存中:#是临时表,存在于tempdb数据库空间.

  7. mysql,user表中各字段的含义

    1.查询user表 select * from mysql.user 2.修改用户密码 ALTER user ' 3.user表中各字段的含义 Select_priv:用户可以通过SELECT命令选择 ...

  8. C++ 类中使用dllimport和dllexport

    在Windows平台下: 您可以使用dllimport或dllexport属性声明C ++类.这些形式意味着导入或导出整个类.以这种方式导出的类称为可导出类. 以下示例定义可导出的类.导出其所有成员函 ...

  9. openssl 密钥注意

    使用openssl生成的密钥,在对加密字符串进行数字签名的时候,程序一直报错,错误异常: algid parse error, not a sequence​ 其原因是因为,openssl生成的私钥没 ...

  10. dubbo服务调用

    1.Dubbo的缺省(默认)协议:采用单一长连接和NIO异步通讯. 2.  3.调用关系说明 0. 服务容器负责启动,加载,运行服务提供者. 1. 服务提供者在启动时,向注册中心注册自己提供的服务. ...