《面向对象的程序设计》课程设计作业.docx
- 文档编号:23791258
- 上传时间:2023-05-20
- 格式:DOCX
- 页数:22
- 大小:33.23KB
《面向对象的程序设计》课程设计作业.docx
《《面向对象的程序设计》课程设计作业.docx》由会员分享,可在线阅读,更多相关《《面向对象的程序设计》课程设计作业.docx(22页珍藏版)》请在冰豆网上搜索。
《面向对象的程序设计》课程设计作业
郑州大学环境与水利学院
《面向对象的程序设计》课程设计
计算说明书
专业:
地理信息系统
学生姓名:
学生学号:
指导教师:
2011年12月7日
Lesson07TextureFilters,Lighting&KeyboardControl
第八课纹理滤波方式,和键盘控制
InthistutorialI'llteachyouhowtousethreedifferenttexturefilters.I'llteachyouhowtomoveanobjectusingkeysonthekeyboard,andI'llalsoteachyouhowtoapplysimplelightingtoyourOpenGLscene.Lotscoveredinthistutorial,soiftheprevioustutorialsaregivingyouproblems,gobackandreview.It'simportanttohaveagoodunderstandingofthebasicsbeforeyoujumpintothefollowingcode.
We'regoingtobemodifyingthecodefromlessononeagain.Asusual,ifthereareanymajorchanges,Iwillwriteouttheentiresectionofcodethathasbeenmodified.We'llstartoffbyaddingafewnewvariablestotheprogram.
这一课我将教你如何使用三种不同的纹理滤波方式。
我将教你如何使用键盘来移动场景中的对象,还会教你在OpenGL场景中添加简单的光照。
这一课包含了很多内容,所以如果你之前的课程仍存在问题,就先回头复习一下。
学习后面的代码之前,很好的理解基础知识十分重要。
我们准备在第一课的代码上稍作修改。
跟以前一样,只要有任何大的改动,我都会写出整段被改动的代码。
我们将以添加几个新的变量作为开始。
#include
#include
#include
#include
#include
HDChDC=NULL;//GDIDeviceContext
HGLRChRC=NULL;//RenderingContext
HWNDhWnd=NULL;//窗体Window句柄
HINSTANCEhInstance;//程序Instance句柄
boolkeys[256];//用于键盘控制的矩阵
boolactive=TRUE;//窗体激活标志
boolfullscreen=TRUE;//全屏标志,缺省为真
Thelinesbelowarenew.We'regoingtoaddthreebooleanvariables.BOOLmeansthevariablecanonlybeTRUEorFALSE.Wecreateavariablecalledlighttokeeptrackofwhetherornotthelightingisonoroff.Thevariableslpandfpareusedtostorewhetherornotthe'L'or'F'keyhasbeenpressed.I'llexplainwhyweneedthesevariableslateroninthecode.Fornow,justknowthattheyareimportant
下面几行是新的。
我们将增加三个布尔变量。
BOOL意味着变量只能是TRUE和FALSE。
我们创造了light变量跟踪光照是否打开。
变量lp和fp用来存储'L'和'F'键是否按下。
后面我会解释为什么我们在代码中需要这些变量。
现在,仅仅先记住他们很重要。
BOOL light; //光源的开/关
BOOL lp; //L键按下了么?
BOOL fp; //F键按下了么?
Nowwe'regoingtosetupfivevariablesthatwillcontroltheangleonthexaxis(xrot),theangleontheyaxis(yrot),thespeedthecrateisspinningatonthexaxis(xspeed),andthespeedthecrateisspinningatontheyaxis(yspeed).We'llalsocreateavariablecalledzthatwillcontrolhowdeepintothescreen(onthezaxis)thecrateis
现在我们设置5个变量来控制绕x轴和y轴旋转角度的步长,以及绕x轴和y轴的旋转速度。
另外我们还创建了一个z变量来控制进入屏幕的深度。
GLfloat xrot; //X旋转
GLfloat yrot; //Y旋转
GLfloatxspeed; //X旋转速度
GLfloatyspeed; //Y旋转速度
GLfloat z=-5.0f; //深入屏幕的距离
Nowwesetupthearraysthatwillbeusedtocreatethelighting.We'llusetwodifferenttypesoflight.Thefirsttypeoflightiscalledambientlight.Ambientlightislightthatdoesn'tcomefromanyparticulardirection.Alltheobjectsinyourscenewillbelitupbytheambientlight.Thesecondtypeoflightiscalleddiffuselight.Diffuselightiscreatedbyyourlightsourceandisreflectedoffthesurfaceofanobjectinyourscene.Anysurfaceofanobjectthatthelighthitsdirectlywillbeverybright,andareasthelightbarelygetstowillbedarker.Thiscreatesaniceshadingeffectonthesidesofourcrate.
Lightiscreatedthesamewaycoloriscreated.Ifthefirstnumberis1.0f,andthenexttwoare0.0f,wewillendupwithabrightredlight.Ifthethirdnumberis1.0f,andthefirsttwoare0.0f,wewillhaveabrightbluelight.Thelastnumberisanalphavalue.We'llleaveitat1.0ffornow.
Sointhelinebelow,wearestoringthevaluesforawhiteambientlightathalfintensity(0.5f).Becauseallthenumbersare0.5f,wewillendupwithalightthat'shalfwaybetweenoff(black)andfullbrightness(white).Red,blueandgreenmixedatthesamevaluewillcreateashadefromblack(0.0f)towhite(1.0f).Withoutanambientlight,spotswherethereisnodiffuselightwillappearverydark
现在,我们来设置创建光源的数组。
我们将使用两种不同的光。
第一种光被称为环境光。
环境光是一种来自于各个方向的光。
所有场景中的对象都处于环境光的照射中。
第二种光被称为漫射光。
漫射光由特定的光源产生,并在你的场景中的对象表面上产生反射。
处于漫射光直接照射下的任何对象表面都变得很亮,而几乎未被照射到的区域就显得要暗一些。
这样在我们所创建的木板箱的棱边上就会产生的很不错的阴影效果。
创建光源的过程和颜色的创建过程一样。
如果第一个数字是1.0f,接下来的两个数字是0.0f,我们将得到艺术明亮的蓝色光。
最后一个数字是阿尔法值。
我们将把它设为1.0f。
所以在接下来的代码中,我们得到的是半亮(0.5f)的白色环境光。
因为所有的数字都是0.5f,我们将得到一束一半黑一半白的光。
红,蓝和绿混合在一起将出现从黑到白的阴影。
如果没有环境光,未被漫射光照到的地方会变得十分黑暗。
GLfloatLightAmbient[]={0.5f,0.5f,0.5f,1.0f}; //环境光参数
Inthenextlinewe'restoringthevaluesforasuperbright,fullintensitydiffuselight.Allthevaluesare1.0f.Thismeansthelightisasbrightaswecangetit.Adiffuselightthisbrightlightsupthefrontofthecratenicely.
下一行代码我们将得到最亮的漫射光。
所有的参数值都取成最大值1.0f。
这意味着这束光和我们能得到的一样亮。
它将照在我们木板箱的前面。
GLfloatLightDiffuse[]={1.0f,1.0f,1.0f,1.0f}; //漫射光参数
Finallywestorethepositionofthelight.ThefirstthreenumbersarethesameasglTranslate'sthreenumbers.Thefirstnumberisformovingleftandrightonthexplane,thesecondnumberisformovingupanddownontheyplane,andthethirdnumberisformovingintoandoutofthescreenonthezplane.Becausewewantourlighthittingdirectlyonthefrontofthecrate,wedon'tmoveleftorrightsothefirstvalueis0.0f(nomovementonx),wedon'twanttomoveupanddown,sothesecondvalueis0.0faswell.Forthethirdvaluewewanttomakesurethelightisalwaysinfrontofthecrate.Sowe'llpositionthelightoffthescreen,towardstheviewer.Letssaytheglassonyourmonitorisat0.0fonthezplane.We'llpositionthelightat2.0fonthezplane.Ifyoucouldactuallyseethelight,itwouldbefloatinginfrontoftheglassonyourmonitor.Bydoingthis,theonlywaythelightwouldbebehindthecrateisifthecratewasalsoinfrontoftheglassonyourmonitor.Ofcourseifthecratewasnolongerbehindtheglassonyourmonitor,youwouldnolongerseethecrate,soitdoesn'tmatterwherethelightis.Doesthatmakesense?
There'snorealeasywaytoexplainthethirdparameter.Youshouldknowthat-2.0fisgoingtobeclosertoyouthan-5.0f.and-100.0fwouldbeWAYintothescreen.Onceyougetto0.0f,theimageissobig,itfillstheentiremonitor.Onceyoustartgoingintopositivevalues,theimagenolongerappearsonthescreencauseithas"gonepastthescreen".That'swhatImeanwhenIsayoutofthescreen.Theobjectisstillthere,youjustcan'tseeitanymore.
Leavethelastnumberat1.0f.ThistellsOpenGLthedesignatedcoordinatesarethepositionofthelightsource.Moreaboutthisinalatertutorial
最后我们保存光源的位置。
前三个参数和glTranslate中的一样。
依次分别是XYZ轴上的位移。
由于我们想要光线直接照射在木箱的正面,所以XY轴上的位移都是0.0f。
第三个值是Z轴上的位移。
为了保证光线总在木箱的前面,所以我们将光源的位置朝着观察者挪出屏幕。
我们通常将屏幕也就是显示器的屏幕玻璃所处的位置称作Z轴的0.0f点。
所以Z轴上的位移最后定为2.0f。
假如你能够看见光源的话,它就浮在显示器的前方。
当然,如果木箱不在显示器的屏幕玻璃后面的话,你也无法看见箱子。
没有解释三个参数的简单方法。
你应该知道,-2.0f比-5.0f更接近你。
-100.0f将成为进入屏幕的方法。
一旦你得到了0.0f,图像就大了,它充满了监视设备,一旦你进入,图像不再在屏幕上显示造成它已经穿过屏幕。
这就是我所说的穿出屏幕。
物体还在,只是你看不见了。
最后一个参数取为1.0f。
这将告诉OpenGL这里指定的坐标就是光源的位置,以后的教程中我会有更多解释。
GLfloatLightPosition[]={0.0f,0.0f,2.0f,1.0f}; //光源位置
Thefiltervariablebelowistokeeptrackofwhichtexturetodisplay.Thefirsttexture(texture0)ismadeusinggl_nearest(nosmoothing).Thesecondtexture(texture1)usesgl_linearfilteringwhichsmoothstheimageoutquiteabit.Thethirdtexture(texture2)usesmipmappedtextures,creatingaverynicelookingtexture.Thevariablefilterwillequal0,1or2dependingonthetexturewewanttouse.Westartoffwiththefirsttexture.
GLuinttexture[3]createsstoragespaceforthethreedifferenttextures.Thetextureswillbestoredattexture[0],texture[1]andtexture[2].
filter变量跟踪显示时所采用的纹理类型。
第一种纹理(texture0)使用gl_nearest(不光滑)滤波方式构建。
第二种纹理(texture1)使用gl_linear(线性滤波)方式,离屏幕越近的图像看起来就越光滑。
第三种纹理(texture2)使用mipmapped滤波方式,这将创建一个外观十分优秀的纹理。
根据我们的使用类型,filter变量的值分别等于0,1或2。
下面我们从第一种纹理开始。
GLuinttexture[3]为三种不同纹理分配储存空间。
它们分别位于在texture[0],texture[1]和texture[2]中
GLuint filter; //滤波类型
GLuint texture[3]; //3种纹理的储存空间
Nowweloadinabitmap,andcreatethreedifferenttexturesfromit.Thistutorialusestheglauxlibrarytoloadinthebitmap,somakesureyouhavetheglauxlibraryincludedbeforeyoutrycompilingthecode.IknowDelphi,andVisualC++bothhaveglauxlibraries.I'mnotsureaboutotherlanguages.I'monlygoingtoexplainwhatthenewlinesofcodedo,ifyouseealineIhaven'tcommentedon,andyou'rewonderingwhatitdoes,checktutorialsix.Itexplainsloading,andbuildingtexturemapsfrombitmapimagesingreatdetail.
Immediatelyaftertheabovecode,andbeforeReSizeGLScene(),wewanttoaddthefollowingsectionofcode.Thisisthesamecodeweusedinlesson6toloadinabitmapfile.Nothinghaschanged.Ifyou'renotsurewhatanyofthefollowinglinesdo,readtutorialsix.Itexplainsthecodebelowindetail.
现在我们载入一个位图,并用它创建三种不同的纹理。
这一课使用glaux文库来载入位图,因此在编译时你应该确认是否包含了glaux库。
我知道Delphi和VC++都包含了glaux库,但别的语言我不确定。
我只准备解释新增的代码。
如果你想知道它是干什么的,请查看教程六。
那一课很详细的解释了载入、创建纹理的内容。
AUX_RGBImageRec*LoadBMP(char*Filename)//载入ABitmap图像
{
FILE*File=NULL;//文件句柄
if(!
Filename)//确A的文件名为Given
{
returnNULL;//错误返回NULL
}
File=fopen(Filename,"r");//检查文件是否存在
if(File)//文件存在吗?
{
fclose(File);//关闭句柄
returnauxDIBImageLoad(Filename);//载入Bitmap然后返回APointer
}
returnNULL;//如果载入失败返回NULL
}
Thisisthesectionofcodethatloadsthebitmap(callingthecodeabove)andconvertsitinto3textures.Statusisusedtokeeptrackofwhetherornotthetexturewasloadedandcreated.
这段代码调用前面的代码载入位图,并将其转换成3个纹理。
Status变量跟踪纹理是否已载入并被创建了。
intLoadGLTextures() //载入位图并转换成纹理
{
intStatus=FALSE; //状态指示器
AUX_RGBImageRec*TextureImage[1]; //创建纹理的存储空间
memset(TextureImag
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 面向对象的程序设计 面向 对象 程序设计 课程设计 作业