杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告.docx

上传人:b****4 文档编号:12043710 上传时间:2023-04-16 格式:DOCX 页数:25 大小:643.86KB
下载 相关 举报
杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告.docx_第1页
第1页 / 共25页
杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告.docx_第2页
第2页 / 共25页
杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告.docx_第3页
第3页 / 共25页
杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告.docx_第4页
第4页 / 共25页
杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告.docx

《杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告.docx》由会员分享,可在线阅读,更多相关《杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告.docx(25页珍藏版)》请在冰豆网上搜索。

杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告.docx

杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告

实时三维图形绘制

实验报告

 

基于粒子系统的雪花场景模拟

一、实验目的

通过一学期对《实时三维图形绘制》的学习,在熟练掌握OpenGL理论的前提下,动手实践,将课本知识转化为实际应用。

二、实验要求

编程实现绘制OpenGL场景并可交互式操作,体现课堂所学内容。

三、实验内容

1、搭建OpenGL程序框架

首先在VS2015中新建项目,在该项目中建立3个主要的类:

GLWindow、Keys和GLApplication,其中GLWindow类负责窗口属性的设置,包括建立、更新、删除窗口等操作。

Keys类负责读取键盘的输入,这样才能实现交互的要求。

GLApplication类负责建立我们的应用程序,包括初始化、更新、绘制图形等操作。

(1)窗口类GLWindow的设计

在新建项目中添加类GLWindow,它包括程序主窗口的属性,以及建立、改变和删除窗口的方法(具体程序见代码)。

/**windows窗口类*/

classGLWindow

{

public:

/**构造函数*/

GLWindow();

/**创建windows窗口*/

boolCreate(constchar*window_title,constchar*class_name,boolfullscreen,HINSTANCEh_instance,LPVOIDlpParam);

/**删除OpenGL窗口*/

voidDestroy();

/**改变窗口的显示设置*/

boolChangeScreenSetting();

/**当窗口大小改变时,通知OpenGL调整大小*/

voidReshapeGL();

/**SwapBuffers(DoubleBuffering)*/

voidSwapBuffers(){:

:

SwapBuffers(m_hDC);}

/**设置窗口左上角的位置*/

voidSetPosX(intx);

voidSetPosX(unsignedshortx){SetPosX((signedshort)x);}

voidSetPosY(inty);

voidSetPosY(unsignedshorty){SetPosY((signedshort)y);}

/**返回窗口的大小*/

intGetWidth();

intGetHeight();

/**设置窗口的大小*/

voidSetWidth(intwidth);

voidSetHeight(intheight);

/**返回窗口左上角的位置*/

intGetPosX();

intGetPosY();

/**设置窗口的颜色位深*/

voidSetHiColor(){m_BitsPerPixel=16;}

voidSetTrueColor(){m_BitsPerPixel=32;}

/**重载运算符,可以让GL_Windowm_Window声明后的m_Window作为窗口句柄使用*/

operatorHWND(){returnm_hWnd;}

private:

HWNDm_hWnd;/**<窗口句柄*/

HDCm_hDC;/**<设备描述表*/

HGLRCm_hRC;/**

intm_WindowPosX;/**<窗口的左上角的X位置*/

intm_WindowPosY;/**<窗口的左上角的Y位置*/

intm_WindowWidth;/**<窗口的宽度*/

intm_WindowHeight;/**<窗口的高度*/

intm_ScreenWidth;/**<全屏的宽度*/

intm_ScreenHeight;/**<全屏的高度*/

intm_BitsPerPixel;/**<颜色位深*/

boolm_IsFullScreen;/**<是否全屏*/

};

(2)键盘类Keys的设计

定义键盘类Keys对我们的按键信息进行记录,用于程序达到交互的目的。

/**定义键盘类*/

classKeys

{

public:

/**构造函数*/

Keys(){Clear();}

/**清空所有的按键信息*/

voidClear(){ZeroMemory(&m_KeyDown,sizeof(m_KeyDown));}

/**判断某个键是否按下*/

boolIsPressed(unsignedintkey){return(key

(m_KeyDown[key]==true):

false;}

/**设置某个键被按下*/

voidSetPressed(unsignedintkey){if(key

/**设置某个键被释放*/

voidSetReleased(unsignedintkey){if(key

private:

staticconstunsignedintMAX_KEYS=256;

boolm_KeyDown[MAX_KEYS];/**<保存256个按键的状态*/

};

(3)应用程序类GLApplication的设计

类GLApplication为我们的应用程序提供统一的接口,当我们实现不同的程序时不用再从头开始,只要实现其对应的接口方法即可。

/**基本的程序类,继承它用来创建OpenGL程序*/

classGLApplication

{

public:

/**创建一个全局的Create函数,这个函数必须被继承类实现*/

staticGLApplication*Create(constchar*class_name);/**<创建你自己的子类*/

/**虚析构函数*/

virtual~GLApplication(){};

protected:

/**下面的函数必须被继承类实现,完成基本的OpenGL渲染过程*/

virtualboolInit()=0;/**

virtualvoidUninit()=0;/**

virtualvoidUpdate(DWORDmilliseconds)=0;/**<执行OpenGL程序的更新*/

virtualvoidDraw()=0;/**<绘制OpenGL场景*/

/**通用的函数*/

voidToggleFullscreen();/**<切换全屏/窗口模式*/

voidTerminateApplication();/**<结束程序*/

voidResizeDraw(boolenable){m_ResizeDraw=enable;}/**<设置在窗口改变大小的时候,可以绘制*/

Keysm_Keys;/**<按键类*/

/**构造函数*/

GLApplication(constchar*class_name);

private:

/**程序的主循环*/

friendintWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow);

intMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow);

/**消息处理回调函数*/

friendLRESULTCALLBACKWindowProc(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam);

LRESULTMessage(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam);

staticconstUINTWM_TOGGLEFULLSCREEN=(WM_USER+1);/**<自定义消息,在切换窗口模式的时候发送*/

GLWindowm_Window;/**

constchar*m_ClassName;/**<程序名*/

boolm_IsProgramLooping;/**<程序循环标记,如果为false,则退出程序*/

boolm_CreateFullScreen;/**<若为true,则创建全屏模式*/

boolm_IsVisible;/**<窗口是否可见*/

boolm_ResizeDraw;/**<是否在改变大小时,调用了绘制函数*/

DWORDm_LastTickCount;/**<上一次计时器的值*/

};

2、纹理贴图

(1)BMP位图文件的载入

BMP格式是windows采用的常见的图像文件存储格式。

定义位图类CBMPLoader,实现位图文件的载入。

/**位图载入类*/

classCBMPLoader

{

public:

CBMPLoader();

~CBMPLoader();

boolLoadBitmap(constchar*filename);/**<装载一个bmp文件*/

voidFreeImage();/**<释放图像数据*/

boolLoad(constchar*fileName);/**<载入位图并创建纹理*/

unsignedintID;/**<生成纹理的ID号*/

intimageWidth;/**<图像宽度*/

intimageHeight;/**<图像高度*/

unsignedchar*image;/**<指向图像数据的指针*/

};

(2)绘制场景并纹理贴图

绘制正方体和球体,并贴图。

/**绘制球体*/

voidSnowDemo:

:

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();

}

/**绘制立方体*/

voidSnowDemo:

:

DrawBox()

{

/**设置材质属性*/

GLfloatmat_ambient[]={0.8f,0.8f,0.8f,1.0f};

GLfloatmat_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,texture[0].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,texture[1].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,texture[2].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,texture[3].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,texture[4].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,texture[5].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.

/**定义字体类*/

classGLFont

{

public:

/**构造函数和析构函数*/

GLFont();

~GLFont();

///成员方法

boolInitFont();/**<初始化字体*/

voidPrintText(char*string,floatx,floaty);/**<在(x,y)处输出string内容*/

protected:

HFONTm_hFont;/**<字体句柄*/

};

4、粒子系统设计

(1)粒子的结构

粒子的结构定义了粒子的位置、速度、加速度、生命时间值、消失掉速度、尺寸以及颜色等信息。

在定义这个结构后我们就可以在具体程序中对这些值进行设置、更新等操作。

/**粒子结构*/

structParticle

{

Vector3position;/**<粒子的位置*/

Vector3velocity;/**<粒子的速度*/

Vector3acceleration;/**<粒子的加速度*/

floatlifetime;/**<粒子生命值*/

floatdec;/**<粒子消失的速度*/

floatsize;/**<粒子尺寸*/

floatcolor[3];/**<粒子的颜色*/

};

(2)粒子类

在粒子系统类中封装一些共有属性和操作,包括粒子的数目,初始化函数、更新函数等。

这样对于具体的粒子系统就可以从该类中继承,重载实现这些接口,就可以创造出不同的实际效果。

/**粒子类*/

classCParticle

{

public:

CParticle();/**<构造函数*/

virtual~CParticle();/**<析构函数*/

/**粒子的初始化*/

virtualboolInit(int_num);

/**粒子的渲染*/

virtualvoidRender()=0;

/**粒子的更新*/

virtualvoidUpdate()=0;

protected:

intm_iNum;/**<粒子总数目*/

Particle*m_pList;/**<粒子指针*/

};

(3)粒子系统模拟雪花

由粒子系统类CParticle派生雪花类。

/**雪花渲染类*/

classCSnow:

publicCParticle

{

public:

CSnow(){};

~CSnow(){};

boolInit(intnum);/**初始化过程*/

voidRender();/**<渲染过程*/

voidUpdate();/**<更新过程*/

private:

CBMPLoaderm_texture;/**<粒子的纹理*/

};

四、实验结果

本次实验主要绘制了一个雪花粒子场景,其中有正方体和球体,还有飞舞的变色文字。

通过按住空格键来实现正方体和球体的旋转,按F1键来实现半透明场景的展现。

(1)主程序

/**从GL_Application派生出一个子类*/

classSnowDemo:

GLApplication

{

public:

boolInit();/**<执行所有的初始化工作*/

voidUninit();/**<执行所有的卸载工作*/

voidUpdate(DWORDmilliseconds);/**<执行所有的更新操作*/

voidDraw();/**<执行所有的绘制操作*/

boolLoadTexture();/**<载入纹理*/

voidDrawSphere();/**<绘制球体*/

voidDrawBox();/**<绘制正方体*/

private:

friendclassGLApplication;/**<父类为它的一个友元类*/

SnowDemo(constchar*class_name);/**<构造函数*/

/**用户自定义的程序变量*/

CSnowm_Snow;/

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 电子电路

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1