基于OpenGL的3D旋转魔方的实现终期报告加源码.docx
- 文档编号:248520
- 上传时间:2022-10-07
- 格式:DOCX
- 页数:61
- 大小:293.30KB
基于OpenGL的3D旋转魔方的实现终期报告加源码.docx
《基于OpenGL的3D旋转魔方的实现终期报告加源码.docx》由会员分享,可在线阅读,更多相关《基于OpenGL的3D旋转魔方的实现终期报告加源码.docx(61页珍藏版)》请在冰豆网上搜索。
华中科技大学电子科学与技术系
课程设计报告
(2011--2012年度第2学期)
名 称:
软件课程设计 题 目:
基于OpenGL的3D旋转魔方实现院 系:
XXXXXX 班 级:
XXXXX 学 号:
U201014185
学生姓名:
XXX 指导教师:
XXX 设计周数:
XXXX
成 绩:
日期:
2012年 5月 24日
目 录
1.课程设计介绍………………………………………………………………
1
1.1.内容 1
1.2.目的 1
1.3.取得的成果 1
2.程序分析 2
2.1.程序原理 2
2.1.程序流程 3
2.3.数据结构 8
2.4.重要函数用法分析 8
3.结果演示与程序分析……………………………………………………
9
3.1.成果演示 9
3.2.程序分析 11
4.编程中遇到的问题 12
5.课程设计小
结 13
参考文献 14
基于OpenGL的3D旋转魔方实现
1.课程设计介绍
1.1目的
当今计算机技术流行,引领了各行各业。
而程序是计算机的灵魂,因此编程能力对当今的学生而言至关重要。
虽然我们在前期已经学习了C语言,但是还只对程序有一些简单的认识,说实话,是很浅显的认识。
通过本软件课程设计的学习,可以从整体上对软件工程和项目有全面的认识。
通过此次课程设计,可以锻炼编程
能力,激发对编程的兴趣,同时也能培养良好的编程习惯。
这对于个人今后的学习,今后的工作乃至今后的生活都会产生重要的影响。
对于国家而言,极大的推动了计算机普及教育,提高了大学生的计算机使用水平,具有重大的意义。
1.2内容
(1)通过此次项目掌握软件开发模式,模块化结构分析以及程序设计流程
(2)学会使用VC++6.0进行编程
(3)掌握有关程序设计的思想,数据结构的知识,掌握C语言算法,掌握
OpenGL编程知识如贴图与键盘控制
(4)掌握win32编程知识,了解windows程序内部运行机制
(5)初步培养需求分析、软件测试、调试的能力
(6)在2X2魔方的基础上,尝试编写3X3的魔方,并实现其旋转
1.3取得的成果
在理解Magic2D例子程序的基础上,借助了Win32平台进行了一系列调试和学习。
在此次项目中,学习了Visual C++6.0软件开发环境,熟练掌握了Win32
Application开发流程。
同时也学习了OpenGL的基本知识,掌握了一些OpenGL的重要技术与重要函数的使用,编写了一些简单的OpenGL程序。
参考Magic2D例子流程,我对原程序进行了比较大的修改,并换上了自己的图片,实现了一个立方体
贴六张不同的图片,并编写出了自己的2X2魔方程序。
根据相似度分析,成功的编写出了3X3旋转魔方,并自己设计了算法,实现了各个层面的转动,转动效果很完美。
同时,为了增加程序的娱乐效果,我加入了歌曲最炫民族风,虽然很简单,不过感觉非常实用且有趣。
2.程序分析
2.1程序原理
(1)OpenGL
OpenGL是一个开放的三维图形软件包,它独立于窗口系统和操作系统,以它为基础开发的应用程序可以十分方便地在各种平台间移植;OpenGL可以与Visual
C++紧密接口,便于实现机械手的有关计算和图形算法,可保证算法的正确性和可靠性;OpenGL使用简便,效率高。
本设计是在Visual C++6.0开发环境下,使用OpenGL(Open Graphics
Library)函数库,绘制魔方并实现魔方的绘制、随机旋转、贴图以及键盘控制等功能。
采用基本图形的绘图函数及定位函数,添加相应纹理来实现魔方模型的绘制。
通过读取载入BMP文件,应用纹理贴图技术来完成对魔方旋转面的处理。
(2)模型的旋转
首先对立方体进行建模。
一个立方体由8个点组成,8个点组成6个面片,对立方体的几何操作本质上就是对这6个平面的操作(绘制、纹理、旋转和平移等)。
点的索引号确定后,每个面片也就确定了,如{0,1,2,3}四个点构成Z向正投影面。
立方体在空间的旋转,归根到底是其顶点的旋转,如空间点(x,y,z)绕Z轴旋转
a对应的旋转矩阵:
cosa sina
-sina cosa
一个立方体pCube绕Z轴旋转a后对应的坐标变化为:
for(inti=0;i<8;i++)
{
floatx,y;
x=pCube->CubePoint[i].p[0];y=pCube->CubePoint[i].p[1];
pCube->CubePoint[i].p[0]=x*cosa-y*sina;pCube->CubePoint[i].p[1]=x*sina+y*cosa;
}
其它轴的旋转类似。
由于魔方体层面的旋转是90°,在某个层面内一个子立方体Ci会被另外一个Cj完全替换,因此旋转后必须同步更新魔方体Cube各层面内包含的子立方的索引号。
为了简化算法,只需查找旋转后Cube[i]在Static_Cube中对应的小立方编号j与i的位置匹配。
2.2程序的流程
通过分析,整个程序大致可以分为6个子功能模块
(1)Win32应用程序框架
WinMain主函数是所有Win32程序的入口点。
在WinMain函数里实现Window是窗体的建立和消息循环,在消息循环中实现键盘、鼠标输入事件处理响应,具体内容可参考VC程序参考手册。
在本课程程序中,不仅要创建Window窗体,而且构建
OpenGL设备绘图环境。
Window窗体创建步骤:
l窗体类注册:
RegisterClass
l设置显示分辨率:
ChangeDisplaySettings
l设置窗体大小:
AdjustWindowRectEx
l创建窗体:
CreateWindowEx
OpenGL绘图环境搭建:
l获取设备绘图环境(DC,DeviceContext):
hDC=GetDC(hWnd)
l选择绘图环境像素格式:
ChoosePixelFormat(hDC,&pfd),其中pfd为像素格式描述符,如果设置不对,OpenGL绘图失败,看不到正确的显示结果。
l设置绘图环境像素格式:
SetPixelFormat(hDC,PixelFormat,&pfd)
l获取OpenGL绘图环境:
hRC=wglCreateContext(hDC)
l设置OpenGL绘图环境:
wglMakeCurrent(hDC,hRC)
(2)空间建模得到3阶魔方
显然,要建立3X3的魔方必须首先建立单个魔方的模型,然后通过对单个立方体进行平移从而得到3X3的魔方。
平移单个立方体通过reset_model()函数中的语句实现for(i=0;i<8;i++)
{
Cube[0].CubePoint[i].p[0]=CubePoint[i].p[0]-2.0f;
Cube[0].CubePoint[i].p[1]=CubePoint[i].p[1]-2.0f;
Cube[0].CubePoint[i].p[2]=CubePoint[i].p[2]+2.0f;
}
上述代码只得到了编号为0的立方体,其他编号的立方体同理可以得到
构成2X2的魔方需要8个立方体,构建3X3的魔方则需要27个立方体。
根据
2阶魔方的一些方法,类比到3阶魔方。
则首先对魔方的立方体进行编号,然后通过编号得到魔方各层所包含立方体的编号。
其中编号为
BYTE
ZP[9]={0,1,2,3,4,5,6,7,8};
//z轴方向正向一层
BYTE
ZZ[9]={9,10,11,12,13,14,15,16,17};
//z轴方向中间一层
BYTE
ZM[9]={18,19,20,21,22,23,24,25,26};
//z轴方向负向一层
BYTE
YM[9]={0,1,2,11,10,9,18,19,20};
//y轴方向负向一层
BYTE
YZ[9]={3,4,5,14,13,12,21,22,23};
//y轴方向中间一层
BYTE
YP[9]={6,7,8,17,16,15,24,25,26};
//y轴方向正向一层
BYTE
XM[9]={2,3,8,17,12,11,20,21,26};
//x轴方向正向一层
BYTE
XZ[9]={1,4,7,16,13,10,19,22,25};
/x轴方向中间一层
BYTE
XP[9]={0,5,6,15,14,9,18,23,24};
//x轴方向负向一层
(3)OpenGL纹理贴图
以下是纹理贴图的流程,其中实现了一个立方体贴六张图片
GLuinttexture[6]
创建纹理存储
AUX_RGBImageRec*
创建纹理的存储空间
TextureImage[6];
TextuteImage[i]=auxDIBImageLoad(“picture/y1.bmp)
调用此函数六次载入六张不同的图片
glGenTexTures(1,&texture[i])
用载入的图像生成六
glBindTextures(GL_TEXTURE_2D,texture[i]
选择生成的纹理
glBegin(GL_QUADS);glTexCoord(0.0f,0.0f);glVertex3fv(CubePoint[0].p);
……
glEnd();
每次选择不同的纹理,然后利用
OpenGL是状态机的性质,可以给每个面贴上不同的图片
(4)同步更新索引
在整个程序中,同步更新索引所涉及到的算法可以算是最核心的了。
当然,你也可以让每层每个周期转动360度,这样就不需要动态更新索引了,因为每次转动前后,立方体的相对坐标位置并没有改变。
但是这样得到的旋转效果并不好,因为这并没有考虑到魔方旋转的所有情况,每次旋转后魔方都没有被打乱。
由于涉及到动态刷新索引,于是按照常理定义一个静态的魔方与动态的魔方进行比较。
类似动态魔方的编号可以得到静态魔方的编号。
constBYTESZP[9]={0,1,2,3,4,5,6,7,8}; //z轴方向正向一层constBYTESZZ[9]={9,10,11,12,13,14,15,16,17};//z轴方向中间一层constBYTESZM[9]={18,19,20,21,22,23,24,25,26};//z轴方向负向一层
constBYTESYM[9]={0,1,2,11,10,9,18,19,20}; //y轴方向负向一层constBYTESYZ[9]={3,4,5,14,13,12,21,22,23};//y轴方向中间一层constBYTESYP[9]={6,7,8,17,16,15,24,25,26};//y轴方向正向一层
constBYTESXM[9]={2,3,8,17,12,11,20,21,26};//x轴方向正向一层constBYTESXZ[9
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 OpenGL 旋转 魔方 实现 报告 源码