第32课拾取,alpha混合测试_第1页
第32课拾取,alpha混合测试_第2页
第32课拾取,alpha混合测试_第3页
第32课拾取,alpha混合测试_第4页
第32课拾取,alpha混合测试_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

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

文档简介

32Alpha混合Alpha测试:欢迎来到32.这课大概是在我所写作已来最大的一课.超过1000行代码和约1540L.这也是第一课用到我新的NeHeGL基本代码.这课写了很长时间,但他是值得期待的.一些知识点用到是:Alpha混合,Alpha测试,鼠标,同时用到Ortho和,显示客户鼠标,按深度排列物体,动画帧从单张材质图和要点,你将学到精选的内容!最初的版本是在屏幕上显示三个物体,当你单击他们将改变颜色.很有趣!?!不怎样!象往常样,给这些家伙留下一个超极好的课程.使课程有趣,丰富当然..美观.所以,经过几个星期的编码之后,这课程完成了!即使你不编码,你仍会喜欢这课.这是个完整的.的目标是射击的靶子,在你失去一定数的靶子后,你将不能再用鼠标单击物体.我确信会有批评,但我非常乐观对这课!我已在从深度里选择和排序物体这个里找到一些需要注意的代码.我仅仅会在lesson32.cpp里.有一些不成改动在NeHeGL代里.最重要的改动是我加入鼠标支持在WindowProc().我也加入intmouse_x,mouse_y在存鼠标运动.在NeHeGL.h以下两条代码被加入:externintmouse_x;&externintmouse_课程用到的材质是用AdobePhotoshop做的.每个.TGA文件是32位有一个alpha通道.若你不确信自已能在一个加入alpha通道,找一本好书,上网,或读AdobePhotoshop帮助.全部的过程非常相似程.调入你物体在AdobePhotoshop(或一些其它图形处理程序,且支持alpha通道).用选择颜色工具选你的背景.选区.新建一个图.粘贴生成新文件.取消选择你图的背景应是黑色.使周围是白色.选全部图.回到最初的图且建一个alpha通道.粘贴黑和白透明图你就完成建立alpha通道.存为32位t.TGA文件.使确定保存透明背景是选中的,保存!如以往我希望你喜欢这课程.我感你对他的想法.若你有些问题或你发现一些问题,告诉我.我匆忙的完成这课程所以若你发现哪部分很难懂,给我发些邮件,然后我会用不同的方式或更详细的解释!#include<windows.h>#include<stdio.h>#include<stdarg.h>#include<time.h>#include"NeHeGL.h"在第1里,我提倡关于适当的方法连接到OpenGL库.在VisualC++里点击’项目’,设置,连接项.移下到对象/库模块加入OpenGL32.lib,GLu32.lib和GLaux.lib.预编译一个需要的库将使编译器找出所出的错误.有时你不想发生!使事情更坏,若你仅仅预编译库在debug模式,和有人试在release模式建立你程序...的错误.有许多人看代码.他们大多数是新程序员.他们取到你的代码,试着编译.他们得到错误,删掉代码,移走.下而的代码告诉编译者去连接需要的库.一点多些的字,但少些以后的头痛.在这个课程,连接OpenGL32库,GLu32库和WinMM库(用来放音乐).在这课程会调入.TGA文件所以我们不用GLaux"opengl32.lib" 在时连接Opengl32.lib"glu32.lib" glu32.lib"winmm.lib" winmm.lib下而的3行检查若CDS_FULLSCREEN已被你的编译器定义.若还没被定义,给CDS_FULLSCREEN为4.马上你完全部丢掉...一些编译器不给CDS_FULLSCREEN变量,将返回一个错误,但是CDS_FULLSCREEN是有用的!防止出错消息,检查若CDS_FULLSCREEN是否定义,若出错,定义他.使每人生活更简单再定义Draws函数,为窗口和按键设变量.你若不懂定义,读一遍MSDN术语表.保持清醒,我不是教C/C++,买一本好书若你对非gl帮助! CDS_FULLSCREEN4voidDrawGL_Window* 下面的代码是用户设置变量.base是将用到的字体显示列表的开始列表值.roll是将用到的移动的大地和建立旋转的云.level应是级别(开始是1级).miss保留失去了多少物体.他还用来显示用户的士气(不丢失意味着高士气).kills保留每级打到多少靶子.score会保存运行时打中的总数,同时用到结束比赛!最后一行是让通过结构比较的函数.是等待qsort最后参数到type(const*void,const*//////旋转的////////当前的分 typedefint(*compfn)(constvoid*,const //定义用来比较的函现在为物体的结构.这个结构存了所有一个物体的信息.旋转的方向,若被打中,在屏幕的位置,等等.一个快速运动的变量...rot让物体旋转特别的方向.hit若物体没被打中将是FALSE.若物体给打中或飞出,变量将是TRUE.变量frame是用来存动画的周期.每一帧改变增加一个材质.在这课有在用变量dir.dir个值:0-物体左移,-体右移,2-和最后3-texid是从04数.0表示是蓝面材质,1是水桶材质,2是靶子的材质,3是可乐的材质和4是花瓶材质.最近在调入材质的代码,你将看到先前5种材质来自目标.x和y两者都用来记屏模上物体的位置.x表示物体在x-轴,y表示物体在y-轴物体在z-轴上的旋转是记在变量spin.在以后的代码,加或减spin基数在旅行的方向上最后,distance保存物体到屏幕的距离.距离是重要的变量,用他来计算屏幕的左右两边,而且在对象关闭之前排序物体,画出物体的距离.structobjectsGLuint //旋转(0-不转,1-顺时针转,2-逆时针转bool //GLuint //当前效果的动画GLuint //物体的方向(0-左,1-右,2-上,3-下GLuinttexid; //物体材质IDGLfloatx; //物体X位置GLfloaty; //物体Y位置GLfloatspin; //物体旋转GLfloatdistance; //物体距离解释下面的代码没有真正的结果.在这课调入TGA图代替bitmaps.下面的用来表示TGA图片数据的结构是尽可能好的.若你需要详细的解释下面的代码TGA文件的课程.typedef //新建一个结{GLubyte*imageData; //数据(最大32位)GLuintbpp; //颜色深度每象素GLuint //宽GLuint //高GLuint //贴图材质ID用来选择一个材} //结构名紧接下面的代码为们10个材质和个30物体留出空间.若你打算在里加物体得增加这个变量TextureImage //定义10材objects //定义30我不想限制每个物体的大小.瓶子(vase)比can高,水桶bucket比瓶子宽.去改变一切是简单的,我建了一个结构存物体的宽和高.我然后在最后一行代码中设每个物体的宽高.得到这个cokecans宽,我将检查size[3].w.蓝面是0,水桶是1,和靶子是2,等.宽度表现在w.使有意义?structdimensions //物体维GLfloat //GLfloat ////每个物体的大小:蓝面,水桶,靶子,可乐,瓶dimensionssize[5]={{1.0f,1.0f},{1.0f,1.0f},{1.0f,1.0f},{0.5f,1.0f},{0.75f,1.5f}};下面是大段代码是调入TGA和转换他为材质.这是同我在第25课所用的一样的代码你可我用TGA的原因是他们是有alpha通道的.这个alpha通道告诉OpenGL哪一部分图是透明的,哪一部分是白底.alpha通道是被建立在处理程序,并保存在.TGA里面.OpenGL调入,能用alpha通道设置中每个象素透明的数量.boolLoadTGA(TextureImage*texture,char //调入一个TGA文件到内{ (未)压缩的TGA //用来比较TGA //首先6个有用 //每象素字节数在文件使 //用来大小 // //设置默认的GL模为FILE*file=fopen(filename, //打开TGA文if(file==NULL //文件是否已存在 pare)||//是否读出12个字节? pare,sizeof(TGAheader))!=0|| //文件头是不是想要的? //若正确则读下6个Bytes{if(file==NULL) //文件是否已存在?returnFALSE; //返回错误 //否{ //若有任何错误,关掉文return //返回错}} =header[1]*256+ //定义TGAtexture->height=header[3]*256+ //定义TGAif(texture->width<=0|| //若宽<=0texture->height<=0|| //若高<=0(header[4]!=24&& //若TGA是24or32位{ //若有任何错误,关掉文return //返回错}texture->bpp=header[4]; //取TGA的位每象素(24或32)bytesPerPixel=texture->bpp/8; //除以8得到字节每象素 =texture->width*texture->height*bytesPerPixel; //计算所需内存为TGA数据texture->imageData=(GLubyte //分配内存为TGA数if(texture->imageData==NULL //这个内存是否存在fread(texture->imageData,1,imageSize,file)!=imageSize) //大小与保留内存的大小想等?{ //数据的调 //若成功 图象数 //return //返回错}fLuinti=0;i<int(imageSize); //在图象数据里循 //交换第1和第3Bytes(’红’red和’蓝’blue) //临时图象的’i’texture->imageData[i]=texture->imageData[i+2]; //设第1Byte得到变量第3Bytetexture->imageData[i+2]=temp; //设第3Byte得到变量’temp1Byte变量)}fclose //关掉文//建立一个贴图材质从以上数glGenTextures(1, //生成OpenGL材质glBindTexture(GL_TEXTURE_2D,texture[0].texID); //绑定的材质glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //线过滤器glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, //线过滤if //若TGA24位{ //设’type’为}glTexImage2D(GL_TEXTURE_2D,0,type,texture[0].width,texture[0].height,0,type,GL_UNSIGNED_BYTE,texture[0].imageData);return //材质建立成功,返回正}2D字体材质代码同我已一课用的是一样的.然而,有一些小不同.第一是你将看到仅仅唯一生成95显示列表.若你看字体材质,你会看到只有95字母计算空间在顶,左.第二个事是你将通知分在16.0f为cx和只分在8.0f为cy.我这样做的结果是因为字体材质是256象素宽,但仅仅一伴就高(128象素).所以计算cx分为16.0f和计算分cy为一半(8.0f).若你不懂下面的代码,回去读17.建立字体的代码的详细解释在第17GLvoid //建立字体显示列{ //建立95显示列表glBindTexture(GL_TEXTURE_2D,textures[9].texID); //绑字体材质for(intloop=0;loop<95;loop++) //循环在95列表{float //X位置在当前字float //Y位置在当前字 //开始建 //用四边形组成每个字 1.0f-cy-0.120f);glVertex2i(0,0);//质地/点座标(底左)glTexCoord2f(cx+0.0625f,1.0f-cy-0.120f);glVertex2i(16,0);//质地/点座标(底右)glTexCoord2f(cx+0.0625f,1.0f-cy); glVertex2i(16,16);//质地/点座标(顶右) glVertex2i(0,16);//质地/点座标(顶左) //完成建 的四边形(字母 //移到字体的右 //完成建军立这个显示列表 //循环直到所有256}输出的代码也在第17课,但已修改为在屏幕输出的分数,等级和士气(不断改变的值GLvoid置{GLvoid置{GLinty,constchar*string, //保存在的字符 //if(string== //若文字为 //返va_start(ap,string,//转换字符 //结果的字符glBindTexture(GL_TEXTURE_2D, //选择字体材 //存模式矩 //设模式矩 //文字输出位置(0,0-底左-BottomLeft) //选择字体设置glCallLists(strlen(text),GL_UNSIGNED_BYTE, //输出显示列表中的文 //取出以前的模式矩阵}这些代码调用排序程序.它比较距离在两个结构并返回-1若第一个结构的距离小于第二个,1若第一个结构的距离大于第二个0否则(若距离相等intCompare(structobjects*elem1,structobjects //比较函{if(elem1->distance<elem2 //若第一个结构的距离小于第二个return-//返回-elseif(elem1->elem2-//返回 //否则(若距离相等)return0; //返回0}InitObject()代码是来建立每个物体.开始设rot为1.这使物体顺时针旋转.然后设效果动画帧为0(不想效果从中间开始).下面设hit为FALSE,意思是物体还没被或正开如.选一个物体材质,texid用来给一个随机的变量从0到4.0blueface材质和4是vase材质.这给5种随机物体距离变量是在-0.0fto-40.0f(4000/100is40)的随机数.当真实的画物体,透过在屏幕上的另10个单位.所以当物体在画时,他们将画从-10.0fto-50.0f单位在屏幕(不挨着,也不离得太远).我分随机数为100.0f得到更精确的浮点数值.在给完随机的距离之后,给物体一个随机的y.不想物体低于-1.5f,否则他将低于大地,且不想物体高于3.0f.所以留在的区间的随机数不能高于4.5f(-1.5f+4.5f=3.0f).去计算x位置,用一些狡猾的数学.用的距离减去15.0f.除以2减5*level.再减随机数(0.0f到5)乘level.减5*levelrndom(0.0fto5*level)这是.使事情简单明白x,写一个快的例子.距离是-30.0f,当前级是object[num].x=(-22.5f)-5-{letssay开始在屏模上移10个单位,距离是-30.0f.其实是-40.0f.用的代码在NeHeGL.cpp文件.GLvoidInitObject(int //初始化一{ //顺时针旋 //设效果动画帧为 //设点击检测为0 //设一个材质 //随机距离 //随机Y位置//随机开始X位置基于物体的距离和随机的延时量(确定变量) //选一个随机的方向if //若随机的方{ // //开始在左边(否定}现在检查texid来找出所选的的物体.若texid为0,所选的物体是Blueface.blueface总是在大地上面旋转.确定开始时在地上的层,设y是-2.0f.if //蓝色天空表 //总是在大地上面旋下面检查若texid是1.这样,电脑所选物体的是Bucket.bucket不从左到右运动,它从天上掉下来.首先不得不设dir是3.这告诉电脑的水桶bucket是掉下来或向下运动.最初的代码假定物体从左到右运动.因为bucket是向下落的,得不给它一个新的随机的变量x.若不是这样,bucket会被看不到.它将不在左边落下就在屏幕外面.给它一个新的随机距离变量在屏幕上.代替减去15,仅仅减去10.这给一些幅度,保持物体在屏幕??.设的distance是-30.0f,从0.0f-40.0f的随量.为什么从0.0f到f?不是从0.0fto-40.0f?答案很简单.rand()函数总返回正数.所以总是正数.另外,回到的故事.有个正数从0.0f到40.0f.加距离最小10.0f除以2.举个例子,x量为15,距离是-object[num].x=float(15{assuming15wasreturned))+(-20.0f);下面设y.想水桶从天上下来.我人不想穿过云.所以设y为4.5f.刚在去的下面一if //水桶{ //下 //随机X,开始在屏模上}想靶子从地面突出到天上.检查物体为(texid是2).若是,设方向(dir)是2(上).用精确的数x位置.不想开始在地上.设y初值为-3.0f(在).然后减一个值从0.0f到5乘当前level.靶子不是立即出现.在高级别是有延时,delay,靶子将出现在一个在另一个以后,给你很少时间打到他们.if //靶{ //开始向上 //随机X,开始在下面的大地+随变}所有其它的物体从右到左旅行,因而不必给任何变量付值来改变物体.它们应该刚好工作在所给的随现在来点有趣的材料!"为了alpha混合技术正常的工作,透明的原物必须不断地排定在从后向前".当画alpha混合物体是,在远处的物体是先画的,这是非常重要的,下面画紧临的上面的物体理由是简单的...Z缓冲区防止OpenGL从已画好的混合东西再画象素.这就是为什么会发生物体画在透明混合之后而不再显示出来.为什么你最后看到的是一个四边形与物体...很不好看!已知道每个物体的深度.因而在初始化一个物体之后,能通过把物体排序,而用qsort函数(快速排序sort),来解决这个问题.通过物体排序,能确信第一个画的是最远的物体.这意味着当画物体时,起始于第一个物体,物体通过用距离将被先画.紧挨着那个物体(晚一会儿画)将看到先前的物体在他们的后面,再将适度的混合这文中的这行线注释是我在MSDN网上花时间查找之后找到的解答.他们工作的很好,允许各种的排序结构.qsort传送4个参数.第一个参数指向物体数组(被排序的数组d).第二个参数是想排序数组的个数...当然,想所有的排序的物体普遍的被显示(各个level).第三个参数规定物体结构的大不,第四个参数指向的Compare()函数.大概有更好的排序结构的方法,但是qsort()工作起来...这个是重要的知识点,若想用glAlphaFunc()和glEnable(GL_ALPHA_TEST),排序是没必要的.然而,用Alpha功能你被限制在完全透明或完全白底混合,没有中间值.用Blendfunc()排序用一些的工作,但他顾及半透明物体.//排序物体从距离:物体数组的开始地址***MSDN代码修改为这个TUT***//各种的数//各自的要素的//qsort((void*)&object,level,sizeof(structobjects),(compfn)Compare}初始化的代码总是一样的.首先的现两行取得window的消息和建盘消息.然后用srand()建一个基于时间的多样化的.之后调入TGA并用LoadTGA()转换到材质.先前的5个是将穿过屏幕的物体.Explode是动画,大地和天空弥补现场背景,crosshair是你在屏幕上看到表现鼠标当前位置的光标,最后,用来显示分数,标题和士气值的字体的图片.若任何调入的,则到返回FALSE值,并程序结束.值得注意的是这些基本代码不是返回整数型(INIT)的FAILED错误消息.BOOLInitialize(GL_Window*window,Keys* //任何OpenGL{g_window=window; =keys;srand((unsigned)time(NULL) //使随机化事件if((!LoadTGA(&textures[0],"Data/BlueFace.tga"))|| //调入蓝面材质(!LoadTGA(&textures[1],"Data/Bucket.tga"))|| //调入水桶材质(!LoadTGA(&textures[2],"Data/.tga"))|| //调入靶子材质(!LoadTGA(&textures[3],"Doke.tga"))|| //调入可乐材质(!LoadTGA(&textures[4],"Data/Vase.tga"))|| //调入花瓶材质(!LoadTGA(&textures[5],"Data/Explode.tga"))|| //调入材质(!LoadTGA(&textures[6],"Data/Ground.tga"))|| //调入地面材质(!LoadTGA(&textures[7],"Data/Sky.tga"))|| //调入天空材质 rosshair.tga"))|| //调入 光标材质 //调入字符材{return //若调入失败,}若所有调入成功则轮到材质,能继续初始化.字体材质被调入,因而保险能建立的字体.跳入BuildFont()来做这些.然后设置OpenGL.背景色为黑,alpha也设为0.0f.深度缓冲区设为激活小于或等于测试glBlendFunc()是很重要的一行代码.设混合函数(GL_SRC_ALPHA,A).这些加上alpha变量的屏幕上的混合物体存在物体的材质.在设置混合模式之后,激活blending(混合).然后打开2D材质贴图,最后,打开GL_CULL_FACE.这是去除每个物体的后面(没有一点浪费在一些看不到的循环).画一些四边形逆时针卷动,因而精致而适当的面片早先的我谈论使用glAlphaFunc()代替alpha混合.若你想用Alpha函数,注释出的两行混合代码和不注释的两行在glEnable(GL_BLEND)之下.你也能注释出qsort()函数在InitObject()部分里程序应该运行ok,但sky为sky质已是一个alpha变量0.5f.当早在我说关于Alpha数工作在alpha变量0或1.若你想它出现,你将不得不修改sky材质alpha通道!再则,若你决定用Alpha函数代替,你不得排序物体.两个方法都有好处!再下而是从SGI的快速:"alpha函数丢弃细节,代替画他们在结构缓冲器里.因此排序原来的物体不是必须的(除了一些其它像混合alpha开的).不占优势的是象素必须完全白底或完全透明". //建立的字体显示列glClearColor(0.0f,0.0f,0.0f,0.0f); //黑色背景 //安装深度缓冲器 //深度的类型测试 //打开深度测glBlendFunc(GL_SRC_ALPHA, //打开Alpha混//设Alpha测//打开Alpha测//打开材质贴//在程序的这段,还没有物体被定义,所以循环30都调for(intloop=0;loop<30;loop++) //循环在30个物体Objects //初始化每个物体return //返回正确(设初值成功}在初始化代码里,调入BuildFont()建立95的显示列表.所以这里在程序结束前删掉95表voidDeinitialize //任何user{glDele //删掉所有95字体显示列}现在为急速原始物体...是实际被选?形锾宓拇?.第一行为选择物体的信息分配内存.hits是当选择时碰撞迅检测的次数.void{//这是选择正GLuint GLint下面的代码,若结束(FALSE).没有选任何,返回(exit).若还在运行(TRUE),用Playsound()命令放射击

温馨提示

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

评论

0/150

提交评论