虚拟现实与数据可视化课程作业董元 22011207
5、黑板移动效果图
6、局部细节效果图
6 / 40
虚拟现实与数据可视化课程作业董元 22011207
四、 内容介绍
下面我将从代码的角度简单介绍一下我的整个教室程序。
代码部分包括一个头文件(MyHeader.h)和一个cpp文件(main.cpp)。为了增加程序
7 / 40
虚拟现实与数据可视化课程作业董元 22011207
的可读性,我将相关的变量定义、函数声明等集中放置在头文件下面。在我的全部代码中,除了主函数外,共定义了19个子函数。如下图所示:
主程序部分和一般的openGL程序一样,完成初始化、窗口的绘制、显示回调函数和键盘以及一些特殊事件的响应。
主函数如下:
初始化部分由函数init()完成,而init中又调用了进行灯光初始化的函数initlight()以及进行纹理图像载入的LoadTexture1()、LoadTexture2()、LoadTexture3()。这主要是因为灯光初始化和载入纹理相关代码较多,这么做是为了使代码看上去更加层次分明
绘制教室的工作由回调函数display()完成。而所有子函数中与绘制教室相关的子函数还有DrawRoom()、DrawDesk()、DrawBlackboard()以及Drawotherthings();分别完成教室墙面、
8 / 40
虚拟现实与数据可视化课程作业董元 22011207
黑板、桌椅及其他物体的绘制。其中,整个教室空间有六个大矩形拼接而成;桌椅由梯形不一的长方体拼接而成。可以这样说,整个教室基本上都是由不同的立方体和矩形构成的。所以从这一点上来说,绘制教室并没有使用任何复杂的openGL内置函数。
响应按键主要是由OnKeyboard()和OnSpecial()完成的。OnSpecia()函数其实只是响应退出窗口的ECS键,为了从逻辑上区分这一事件与普通按键响应的不同,我把响应这一事件的代码放在了OnSpecia()函数下。而其他响应普通事件的代码则在OnKeyboard()下。而普通事件的响应程序,又调用到了函数InitFMOD(),(响应播放音乐),函数projector_dispaly1()、projector_dispaly2(),(响应投影仪的放下与收起,实质是在对窗口的重新绘制时改变投影仪的相关参数)。
五、 收获感想
1、对于任何一种编程语言或者是API,当我们在使用它们编程时,都首先要对其基本原理有一个最基本的认识。贸然地调用函数或是凭感觉去编程,往往会造成不可预知的错误。而且一旦错误发生,往往很难解决。在程序的编写过程中,最开始时对openGL了解甚少,在参考示例程序时移植他人的代码往往很难产生自己希望的效果,就是这个道理。而且,在编写整个程序的过程中,出现过一个我一直无法解决的问题:通过编译后程序运行一段时间自己会卡死。在请教了老师以后才知道,该问题出现的原因是我把载入纹理的代码放在了显示回调函数中,这样一来每一次重新绘制窗口,程序都会开辟新的内存用以储存相关信息。因此程序运行一段时间之后内存不足,便会报错。这个问题是我自己很难考虑到的,这也是让我认识到自己对程序的基本理解的不足,这方面需要进一步加强。
2、我觉得这次作业给我带来最大的收获就是它起到了一个抛砖引玉的效果。虚拟教室的创立不仅让我对openGL这个图像程序接口产生了很大的兴趣,也让我对虚拟现实技术产生了更多的期待。而且,在编写程序的过程中我又接触到一个有趣的音乐引擎FMOD。这些都让我觉得这门课程的学习妙趣横生。虽然我在这个作业上花费了很多时间,但是收获了很多乐趣。
3、在编写程序的过程中,我进一步意识到网络这个公开平台资源的强大。在自学的过程中,别人的经验给了我许多启发。网络上许多达人开放式的共享资源的态度值得我们学习。互联网的发展为打开了巨大的学习空间,而在未来的学习生活中,我想我也会秉承这样一种开源共享的态度,学习知识,并且传播知识。
六、 附录
(一) 参考书目
[1]Mason Woo Jakie Neider Tom Davis Dave Shreiner/著吴斌段海波薛凤舞/译《openGL编程权威指南》中国电力出版社
[2]网络资源:Nehe的中文openGL教程http://www.yakergong.net/nehe/ (二)代码 1、main.cpp
#include
9 / 40
虚拟现实与数据可视化课程作业董元 22011207
#include
#include\//相关变量和函数定义放入头文件中,增加程序可读性 #include\
// 音频库的头文件
// 把音频库加入到链接器中
#pragmacomment(lib, \) #pragmacomment(lib, \)
#pragmawarning(disable:4996) //强制忽略VS2012对于老版本一些函数不安全的警告 usingnamespace std; FSOUND_SAMPLE * handle1;
int main(intargc, char ** argv) { Eye.x = 0.0f;//f代表这个数据是GLfloat类型的常量 Eye.y = 0.0f; Eye.z = 18.0f;
glutInit(&argc,argv);//对glut进行初始化
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);//指定 glutInitWindowSize(700,600);//窗口大小,以像素为单位窗 glutInitWindowPosition(650,100);//口左上角的屏幕位置 glutCreateWindow(argv[0]); init();//初始化
glutDisplayFunc(display);//显示回调函数 glutReshapeFunc(reshape); glutKeyboardFunc(OnKeyboard);
constGLubyte* test=glGetString(GL_EXTENSIONS); glutSpecialFunc(OnSpecial); glutIdleFunc(OnIdle); PrintInformation();
glutMainLoop();//调用来启动程序 return 0;
}
/***************函数名称:
LoadBitmap***************************************************************************函数作用:检查文件能否被正常打开,不能则返回一个空指针***************************/
AUX_RGBImageRec *LoadBitmap(char *Filename) { // 声明一个文件句柄用于打开文件 FILE *File=NULL;
// 文件名不能空
if (!Filename)
10 / 40