杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告_第1页
杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告_第2页
杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告_第3页
杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告_第4页
杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实时三维图形绘制实验报告基于粒子系统的雪花场景模拟1、 实验目的通过一学期对实时三维图形绘制的学习,在熟练掌握OpenGL理论的前提下,动手实践,将课本知识转化为实际应用。2、 实验要求编程实现绘制OpenGL场景并可交互式操作,体现课堂所学内容。3、 实验内容1、搭建OpenGL程序框架首先在VS2015中新建项目,在该项目中建立3个主要的类:GLWindow、Keys和GLApplication,其中GLWindow类负责窗口属性的设置,包括建立、更新、删除窗口等操作。Keys类负责读取键盘的输入,这样才能实现交互的要求。GLApplication类负责建立我们的应用程序,包括初始化、更新、绘制图形等操作。(1) 窗口类GLWindow的设计在新建项目中添加类GLWindow,它包括程序主窗口的属性,以及建立、改变和删除窗口的方法(具体程序见代码)。/* windows窗口类 */class GLWindowpublic:/* 构造函数 */GLWindow();/* 创建windows窗口 */boolCreate(const char * window_title, const char * class_name, bool fullscreen,HINSTANCE h_instance, LPVOID lpParam);/* 删除OpenGL窗口 */voidDestroy();/* 改变窗口的显示设置 */boolChangeScreenSetting();/* 当窗口大小改变时,通知OpenGL调整大小 */voidReshapeGL();/* Swap Buffers (Double Buffering) */voidSwapBuffers() :SwapBuffers(m_hDC); /* 设置窗口左上角的位置 */voidSetPosX(int x);voidSetPosX(unsigned short x) SetPosX(signed short)x); voidSetPosY(int y);voidSetPosY(unsigned short y) SetPosY(signed short)y); /* 返回窗口的大小 */intGetWidth();intGetHeight();/* 设置窗口的大小 */voidSetWidth(int width);voidSetHeight(int height);/* 返回窗口左上角的位置 */intGetPosX();intGetPosY();/* 设置窗口的颜色位深 */voidSetHiColor() m_BitsPerPixel = 16; voidSetTrueColor() m_BitsPerPixel = 32; /* 重载运算符,可以让GL_Window m_Window声明后的m_Window作为窗口句柄使用 */operator HWND() return m_hWnd; private:HWNDm_hWnd;/* 窗口句柄 */HDCm_hDC;/* 设备描述表 */HGLRCm_hRC;/* OpenGL渲染描述表 */intm_WindowPosX;/* 窗口的左上角的X位置 */intm_WindowPosY;/* 窗口的左上角的Y位置 */intm_WindowWidth;/* 窗口的宽度 */intm_WindowHeight;/* 窗口的高度 */intm_ScreenWidth; /* 全屏的宽度 */intm_ScreenHeight; /* 全屏的高度 */intm_BitsPerPixel;/* 颜色位深 */bool m_IsFullScreen; /* 是否全屏 */;(2) 键盘类Keys的设计定义键盘类Keys对我们的按键信息进行记录,用于程序达到交互的目的。/* 定义键盘类 */class Keys public:/* 构造函数 */Keys() Clear(); /* 清空所有的按键信息 */void Clear() ZeroMemory(&m_KeyDown, sizeof(m_KeyDown); /* 判断某个键是否按下 */bool IsPressed(unsigned int key) return (key MAX_KEYS) ? (m_KeyDownkey = true) : false; /* 设置某个键被按下 */void SetPressed(unsigned int key) if (key MAX_KEYS) m_KeyDownkey = true; /* 设置某个键被释放 */void SetReleased(unsigned int key) if (key MAX_KEYS) m_KeyDownkey = false; private:static const unsigned int MAX_KEYS = 256;bool m_KeyDownMAX_KEYS; /* 保存256个按键的状态 */;(3) 应用程序类GLApplication的设计类GLApplication为我们的应用程序提供统一的接口,当我们实现不同的程序时不用再从头开始,只要实现其对应的接口方法即可。/* 基本的程序类,继承它用来创建OpenGL程序 */class GLApplicationpublic:/* 创建一个全局的Create函数,这个函数必须被继承类实现 */static GLApplication * Create(const char * class_name);/* 创建你自己的子类 */* 虚析构函数 */virtual GLApplication() ;protected:/* 下面的函数必须被继承类实现,完成基本的OpenGL渲染过程 */virtual boolInit() = 0;/* OpenGL的初始化 */ virtual voidUninit() = 0;/* OpenGL的卸载 */virtual voidUpdate(DWORD milliseconds) = 0; /* 执行OpenGL程序的更新 */virtual voidDraw() = 0; /* 绘制OpenGL场景 */* 通用的函数 */voidToggleFullscreen(); /* 切换 全屏/窗口模式 */voidTerminateApplication(); /* 结束程序 */voidResizeDraw(bool enable) m_ResizeDraw = enable; /* 设置在窗口改变大小的时候,可以绘制 */Keysm_Keys; /* 按键类 */* 构造函数 */GLApplication(const char * class_name);private:/* 程序的主循环 */friend int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);intMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);/* 消息处理回调函数 */friend LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);LRESULTMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);static const UINT WM_TOGGLEFULLSCREEN = (WM_USER + 1);/* 自定义消息,在切换窗口模式的时候发送 */GLWindowm_Window;/* Window类 */const char* m_ClassName;/* 程序名 */boolm_IsProgramLooping;/* 程序循环标记,如果为false,则退出程序 */bool m_CreateFullScreen; /* 若为true,则创建全屏模式 */boolm_IsVisible;/* 窗口是否可见 */boolm_ResizeDraw;/* 是否在改变大小时,调用了绘制函数 */DWORD m_LastTickCount; /* 上一次计时器的值 */;2、 纹理贴图(1)BMP位图文件的载入BMP格式是windows采用的常见的图像文件存储格式。定义位图类CBMPLoader,实现位图文件的载入。/* 位图载入类 */class CBMPLoader public: CBMPLoader(); CBMPLoader(); bool LoadBitmap(const char *filename); /* 装载一个bmp文件 */ void FreeImage(); /* 释放图像数据 */ bool Load(const char* fileName); /* 载入位图并创建纹理 */ unsigned int ID; /* 生成纹理的ID号 */ int imageWidth; /* 图像宽度 */ int imageHeight; /* 图像高度 */ unsigned char *image; /* 指向图像数据的指针 */;(2) 绘制场景并纹理贴图绘制正方体和球体,并贴图。/* 绘制球体 */void SnowDemo:DrawSphere()glPushMatrix();glTranslatef(3.0f, 0.0f, -10.0f);glRotatef(rot, 1.0f, 1.0f, 1.0f);/* 指定纹理 */glBindTexture(GL_TEXTURE_2D, texture2.ID);GLUquadricObj * sphere = gluNewQuadric();gluQuadricOrientation(sphere, GLU_OUTSIDE);gluQuadricNormals(sphere, GLU_SMOOTH);gluQuadricTexture(sphere, GL_TRUE);gluSphere(sphere, 2.5, 50, 50);gluDeleteQuadric(sphere);glPopMatrix();/* 绘制立方体 */void SnowDemo:DrawBox()/* 设置材质属性 */GLfloat mat_ambient = 0.8f, 0.8f, 0.8f, 1.0f ;GLfloat mat_diffuse = 0.8f, 0.8f, 0.8f, 1.0f ;glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);glPushMatrix();glTranslatef(-5.0f, 0.0f, -10.0f);glRotatef(rot, 1.0f, 1.0f, 0.0f);/* 绘制六个面 */ 前侧面glBindTexture(GL_TEXTURE_2D, texture0.ID);glBegin(GL_QUADS);glNormal3f(0.0f, 0.0f, 1.0f); /* 指定法线指向观察者 */glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.0f, -2.0f, 2.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(2.0f, -2.0f, 2.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(2.0f, 2.0f, 2.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.0f, 2.0f, 2.0f);glEnd();/ 后侧面glBindTexture(GL_TEXTURE_2D, texture1.ID);glBegin(GL_QUADS);glNormal3f(0.0f, 0.0f, -1.0f);/* 指定法线背向观察者 */glTexCoord2f(1.0f, 0.0f); glVertex3f(-2.0f, -2.0f, -2.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(-2.0f, 2.0f, -2.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(2.0f, 2.0f, -2.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(2.0f, -2.0f, -2.0f);glEnd();/ 顶面glBindTexture(GL_TEXTURE_2D, texture2.ID);glBegin(GL_QUADS);glNormal3f(0.0f, 1.0f, 0.0f);/* 指定法线向上 */glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.0f, 2.0f, -2.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.0f, 2.0f, 2.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(2.0f, 2.0f, 2.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(2.0f, 2.0f, -2.0f);glEnd();/ 底面glBindTexture(GL_TEXTURE_2D, texture3.ID);glBegin(GL_QUADS);glNormal3f(0.0f, -1.0f, 0.0f);/* 指定法线朝下 */glTexCoord2f(1.0f, 1.0f); glVertex3f(-2.0f, -2.0f, -2.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(2.0f, -2.0f, -2.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(2.0f, -2.0f, 2.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-2.0f, -2.0f, 2.0f);glEnd();/ 右侧面glBindTexture(GL_TEXTURE_2D, texture4.ID);glBegin(GL_QUADS);glNormal3f(1.0f, 0.0f, 0.0f);/* 指定法线朝右 */glTexCoord2f(1.0f, 0.0f); glVertex3f(2.0f, -2.0f, -2.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(2.0f, 2.0f, -2.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(2.0f, 2.0f, 2.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(2.0f, -2.0f, 2.0f);glEnd();/ 左侧面glBindTexture(GL_TEXTURE_2D, texture5.ID);glBegin(GL_QUADS);glNormal3f(-1.0f, 0.0f, 0.0f);/* 指定法线朝左 */glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.0f, -2.0f, -2.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-2.0f, -2.0f, 2.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(-2.0f, 2.0f, 2.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.0f, 2.0f, -2.0f);glEnd();glPopMatrix();3、 位图字体(1)位图字体类显示位图字体需要用到OpenGL显示列表和绘制位图字符的相关知识。定义字体类GLFont./* 定义字体类 */class GLFontpublic: /* 构造函数和析构函数 */GLFont();GLFont(); /成员方法bool InitFont(); /* 初始化字体 */void PrintText(char *string, float x, float y); /* 在(x,y)处输出string内容 */protected:HFONT m_hFont; /* 字体句柄 */;4、 粒子系统设计(1) 粒子的结构粒子的结构定义了粒子的位置、速度、加速度、生命时间值、消失掉速度、尺寸以及颜色等信息。在定义这个结构后我们就可以在具体程序中对这些值进行设置、更新等操作。/* 粒子结构 */struct ParticleVector3 position; /* 粒子的位置 */Vector3 velocity; /* 粒子的速度 */Vector3 acceleration; /* 粒子的加速度 */float lifetime; /* 粒子生命值 */float dec; /* 粒子消失的速度 */float size; /* 粒子尺寸 */float color3; /* 粒子的颜色 */;(2) 粒子类在粒子系统类中封装一些共有属性和操作,包括粒子的数目,初始化函数、更新函数等。这样对于具体的粒子系统就可以从该类中继承,重载实现这些接口,就可以创造出不同的实际效果。/* 粒子类 */class CParticlepublic:CParticle(); /* 构造函数 */virtual CParticle(); /* 析构函数 */* 粒子的初始化 */virtual bool Init(int _num);/* 粒子的渲染 */virtual void Render() = 0;/* 粒子的更新 */virtual void Update() = 0;protected:int m_iNum; /* 粒子总数目 */Particle* m_pList; /* 粒子指针 */;(3) 粒子系统模拟雪花由粒子系统类CParticle派生雪花类。/* 雪花渲染类 */class CSnow : public CParticlepublic:CSnow() ;CSnow() ;boolInit(int num ); /* 初始化过程 */voidRender(); /* 渲染过程 */voidUpdate(); /* 更新过程 */private:CBMPLoader m_texture; /* 粒子的纹理 */; 4、 实验结果本次实验主要绘制了一个雪花粒子场景,其中有正方体和球体,还有飞舞的变色文字。通过按住空格键来实现正方体和球体的旋转,按F1键来实现半透明场景的展现。(1)主程序/* 从GL_Application派生出一个子类 */class SnowDemo : GLApplicationpublic:boolInit();/* 执行所有的初始化工作 */voidUninit();/* 执行所有的卸载工作 */voidUpdate(DWORD milliseconds);/* 执行所有的更新操作 */voidDraw();/* 执行所有的绘制操作 */bool LoadTexture(); /* 载入纹理 */void DrawSphere(); /* 绘制球体 */void DrawBox(); /* 绘制正方体 */private:friend class GLApplication;/* 父类为它的一个友元类 */SnowDemo(const char * class_name); /* 构造函数 */* 用户自定义的程序变量 */ CSnow m_Snow; /* 雪花实例 */GLFont m_Font; /* 字体类 */CBMPLoader texture6; /* 位图载入类 */CBMPLoader texture2; /* 位图载入类 */float rot; /* 用于旋转物体 */float cnt1; /* 字体移动计数器1 */float cnt2; /* 字体移动计数器2 */;/* 创建一个程序的实例 */GLApplication * GLApplication:Create(const char * class_name)SnowDemo * demo = new SnowDemo(class_name);return reinterpret_cast(demo);/* 构造函数 */SnowDemo:SnowDemo(const char * class_name) : GLApplication(class_name) / 初始化用户自定义的程序变量rot = 0.0;cnt1 = 0.0;cnt2 = 0.0; bool SnowDemo:LoadTexture()/* 载入位图文件 */if (!texture0.Load(image1.bmp) | !texture1.Load(image2.bmp) | !texture2.Load(image3.bmp) | !texture3.Load(image4.bmp) | !texture4.Load(image5.bmp) | !texture5.Load(image6.bmp) /* 载入位图文件 */MessageBox(NULL, 装载位图文件失败!, 错误, MB_OK); /* 如果载入失败则弹出对话框 */return false;if (!texture2.Load(image.bmp)MessageBox(NULL, 装载位图文件失败!, 错误, MB_OK);/* 启用纹理映射 */glEnable(GL_TEXTURE_2D);return true;/* 初始化OpenGL */bool SnowDemo:Init()/* 用户自定义的初始化过程 */glClearColor(0.0f, 0.0f, 0.0f, 0.5f);glClearDepth(1.0f);glDepthFunc(GL_LEQUAL);glEnable(GL_DEPTH_TEST);glShadeModel(GL_SMOOTH);glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);ResizeDraw(true); /* 载入纹理 */if (!LoadTexture()MessageBox(NULL, 载入纹理失败!, 错误, MB_OK);/* 初始化字体 */if(!m_Font.InitFont()MessageBox(NULL,初始化字体失败!,错误,MB_OK);/* 初始化雪花实例 */if(!m_Snow.Init(400)MessageBox(NULL,雪花系统初始化失败!,错误,MB_OK);exit(-1);return true; /* 用户自定义的卸载函数 */void SnowDemo:Uninit()/* 程序更新函数 */void SnowDemo:Update(DWORD milliseconds)if (m_Keys.IsPressed(VK_ESCAPE) = true)/* 按ESC退出 */TerminateApplication();if (m_Keys.IsPressed(VK_SPACE) = true) /* 按空格键开始旋转 */rot += milliseconds / 20.0;cnt1 += milliseconds / 1500.0; /* 更新计数器值 */cnt2 += milliseconds / 1000.0; /* 更新计数器值 */* 绘制球体 */void SnowDemo:DrawSphere()glPushMatrix();glTranslatef(3.0f, 0.0f, -10.0f);glRotatef(rot, 1.0f, 1.0f, 1.0f);/* 指定纹理 */glBindTexture(GL_TEXTURE_2D, texture2.ID);GLUquadricObj * sphere = gluNewQuadric();gluQuadricOrientation(sphere, GLU_OUTSIDE);gluQuadricNormals(sphere, GLU_SMOOTH);gluQuadricTexture(sphere, GL_TRUE);gluSphere(sphere, 2.5, 50, 50);gluDeleteQuadric(sphere);glPopMatrix();/* 绘制立方体 */void SnowDemo:DrawBox()/* 设置材质属性 */GLfloat mat_ambient = 0.8f, 0.8f, 0.8f, 1.0f ;GLfloat mat_diffuse = 0.8f, 0.8f, 0.8f, 1.0f ;glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);glPushMatrix();glTranslatef(-5.0f, 0.0f, -10.0f);glRotatef(rot, 1.0f, 1.0f, 0.0f);/* 绘制六个面 */ 前侧面glBindTexture(GL_TEXTURE_2D, texture0.ID);glBegin(GL_QUADS);glNormal3f(0.0f, 0.0f, 1.0f);/* 指定法线指向观察者 */glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.0f, -2.0f, 2.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(2.0f, -2.0f, 2.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(2.0f, 2.0f, 2.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.0f, 2.0f, 2.0f);glEnd();/ 后侧面glBindTexture(GL_TEXTURE_2D, texture1.ID);glBegin(GL_QUADS);glNormal3f(0.0f, 0.0f, -1.0f);/* 指定法线背向观察者 */glTexCoord2f(1.0f, 0.0f); glVertex3f(-2.0f, -2.0f, -2.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(-2.0f, 2.0f, -2.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(2.0f, 2.0f, -2.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(2.0f, -2.0f, -2.0f);glEnd();/ 顶面glBindTexture(GL_TEXTURE_2D, texture2.ID);glBegin(GL_QUADS);glNormal3f(0.0f, 1.0f, 0.0f);/* 指定法线向上 */glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.0f, 2.0f, -2.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.0f, 2.0f, 2.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(2.0f, 2.0f, 2.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(2.0f, 2.0f, -2.0f);glEnd();/ 底面glBindTexture(GL_TEXTURE_2D, texture3.ID);glBegin(GL_QUADS);glNormal3f(0.0f, -1.0f, 0.0f);/* 指定法线朝下 */glTexCoord2f(1.0f, 1.0f); glVertex3f(-2.0f, -2.0f, -2.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(2.0f, -2.0f, -2.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(2.0f, -2.0f, 2.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-2.0f, -2.0f, 2.0f);glEnd();/ 右侧面glBindTexture(GL_TEXTURE_2D, texture4.ID);glBegin(GL_QUADS);glNormal3f(1.0f, 0.0f, 0.0f);/* 指定法线朝右 */glTexCoord2f(1.0f, 0.0f); glVertex3f(2.0f, -2.0f, -2.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(2.0f, 2.0f, -2.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(2.0f, 2.0f, 2.0f);glTexCoord2f(0.0f, 0.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论