位置: 编程技术 - 正文

学习Nehe Lesson 6 && Lesson 7 && Lesson 8(学习计划)

编辑:rootadmin

推荐整理分享学习Nehe Lesson 6 && Lesson 7 && Lesson 8(学习计划),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:学习名言警句 励志,学习画动漫人物,学习雷锋好榜样,学习雷锋好榜样,学习雷锋好榜样,学习画动漫人物,学习英语,学习化妆的学校,内容如对您有帮助,希望把文章链接给更多的朋友!

这三课的基础都是第五课的那个正方体,无论是纹理映射或是光照键盘还是混合,都是对立方体进行的操作。当然,把正方体换成别的几何物体比如说一个多边形面或三棱锥,操作还是同样的。纹理映射是针对面的,光照是针对光源周围的3D空间的,混合是针对纹理的。而键盘是作为总体控制的。

一、纹理映射

简单的来说,纹理映射就是把一幅图贴到一个面上,在这里,由于技术限制,我们只能用2^n像素(如*像素)的bmp格式的图片,可以用画图软件或ps等改变图片的像素大小和存储格式。 首先是一个打开文件的函数,AUX_RGBImageRec *LoadBMP(char *Filename)。我们用这个函数来打开我们准备的BMP图片。接下来是int LoadGLTextures(),这个函数将我们打开的图转为纹理,并存到texture数组中。 然后将 Status 设为 TRUE,glGenTextures(3, &texture[0])创建纹理,glGenTextures函数的作用是创建一个纹理的索引(参见百度百科),接下来是三种纹理滤波方式。

两个glTexParameteri告诉OpenGL在显示图像时,当它比放大得原始的纹理大 ( GL_TEXTURE_MAG_FILTER )或缩小得比原始得纹理小( GL_TEXTURE_MIN_FILTER )时OpenGL采用的滤波方式。 第一种使用Nearest 滤波,从原理上讲,这种方式没有真正进行滤波。它只占用很小的处理能力,看起来也很差。唯一的好处是这样我们的工程在很快和很慢的机器上都可以正常运行。可以注意到我们在 MIN 和 MAG 时都采用了GL_NEAREST, 你可以混合使用 GL_NEAREST 和 GL_LINEAR。纹理看起来效果会好些,但我们更关心速度,所以全采用低质量贴图。MIN_FILTER在图像绘制时小于贴图的原始尺寸时采用。MAG_FILTER在图像绘制时大于贴图的原始尺寸时采用。 第二种线性滤波,它使得纹理从很远处到离屏幕很近时都平滑显示,这也是相对常用的一种滤波方式。 第三种Mipmapping 滤波,当图像在屏幕上变得很小的时候,很多细节将会丢失。刚才还很不错的图案变得很难看。当您告诉OpenGL创建一个 mipmapped的纹理后,OpenGL将尝试创建不同尺寸的高质量纹理。当您向屏幕绘制一个 mipmapped纹理的时候,OpenGL将选择它已经创建的外观最佳的纹理(带有更多细节)来绘制,而不仅仅是缩放原先的图像(这将导致细节丢失)。在这里,有办法可以绕过OpenGL对纹理宽度和高度所加的限制——、、,等等,就是 gluBuild2DMipmaps。可以使用任意的位图来创建纹理。OpenGL将自动将它缩放到正常的大小。 最后就是常规性的检查了,看纹理是否存在,纹理图像是否存在,若存在则释放内存和图像结构。 以上这些纹理的内容都在int LoadGLTextures()函数中。

二、光照

光照的实现较为简单。 首先要在InitGL()函数中增加有关光照的参数设定,这是在透视修正后进行的。在这里用到了glLightfv这个函数。这个函数有三个参数,第一个参数说明了我们要设置的是几号光源,第三个参数是存放了数据的数组,而第二个参数说明了第三个参数的用途,比如环境光、漫反射或光源位置。最后用glEnable(GL_LIGHT1)启用光源。要注意的是到目前为止我们仅仅是设定好了光源并让它处于可以打开的状态,但它并没有真正打开,对于光源而言,只有glEnable(GL_LIGHTING)才能让它亮起来。 接下来在DrawGLScene函数中出现的是一个新的内容:法线。我们都知道法线是垂直于平面的向量,因此法线的主要作用就是设定光发出的方向,是从里向外还是从外向里,是照亮哪个面的,等等这些问题。关于法线,Nehe的解释很详细。总的来说,以正方形为例,有光源时我们要增加的就是每画一个面都要先有一句类似glNormal3f(0.0f, 0.0f, 1.0f)这样设定法线的,由于正常情况下光线应该指向物体外部,所以要注意在正面法线指向观察者,而在背面,法线则背离观察者,其他面同理。这样就使得我们在旋转物体时物体总是亮的。 最后,一切参数都设定好了,我们到主函数中控制它是否发光。这里用到的键盘控制很简单,按下L键则启用光源(glEnable(GL_LIGHTING)),再次按下则禁用光源(glDisable(GL_LIGHTING))。

三、键盘控制

键盘虽然是在第7课中出现,但在前面的内容中都可以用到,目前我见到的键盘控制主要有两种,一种是通过按下某个键来实现某种效果是否出现,比如说按下L则灯亮或灭,按下F1则在全屏和窗口切换,等等;一种是通过按同一个键来实现在好几种相似情况下切换,比如说一直按下F,会在几种纹理处理方式之间切换,一直按空格会在三角形、四边形、多边形等之间切换。我把这两种切换分别叫做布尔切换和选择切换,要注意,这两种说法纯粹是个人想法,为了记起来方便,目前大概就我一个人这样说……

1、布尔切换学习Nehe Lesson 6 && Lesson 7 && Lesson 8(学习计划)

之所以说是布尔切换,是因为这种切换和布尔代数一样,有两个状态,事实上这个切换也确实是通过布尔代数来实现的。 首先要定义两个全局变量,比如 BOOL light 和 BOOL lp,前一个跟踪当前状态,在这里是光源是否打开,后一个是存储按键是否按下,在这里是”L”键。 接下来就跳到主程序中,在SwapBuffers(hDC) 这一句后面加键盘控制。先回顾一下SwapBuffers(hDC)这句,其作用是交换缓存。交换缓存后我们绘制的图像就显示出来,接下来就可以通过键盘来控制了。 首先,要检查L键是否在没被按下的前提下被按下(这句话好绕…),Nehe 教程上对这句的注释是“ L 键已按下并且松开了?”,个人对这样的注释不是特别理解(这样听起来好像这个if可以检测出按下后松开没…)。如果我们在L键没被按下的情况下按下了L键,那么就把lp的值设为TRUE,然后通过这句light = !light来切换光源状态,即,如果光源亮着,那么就让光源灭了,如果光源没亮,那就让它亮了。接下来我们还要检查是否存在光源,如果没有,就禁用光源(glDisable(GL_LIGHTING)),如果有,就启用光源(glEnable(GL_LIGHTING))。在这里,要说一下glEnable和glDisable这两个函数,glEnable用于启用各种功能,glDisable用以关闭各项功能。函数参数应为unsigned int 类型,参数具体取值为OpenGl所预设的常量,如下表:(这个表真的不很重要,可以跳过不看…)

类型 值 说明 GL_ALPHA_TEST 根据函数glAlphaFunc的条件要求来决定图形透明的层度是否显示。具体参见glAlphaFunc GL_AUTO_NORMAL 执行后,图形能把光反射到各个方向 GL_BLEND 启用颜色混合。例如实现半透明效果 GL_CLIP_PLANE0 ~ GL_CLIP_PLANE5 ~ 根据函数glClipPlane的条件要求  启用图形切割管道。这里指六种缓存管道 GL_COLOR_LOGIC_OP 启用每一像素的色彩为位逻辑运算 GL_COLOR_MATERIAL 执行后,图形(材料)将根据光线的照耀进行反射。  反射要求由函数glColorMaterial进行设定。 GL_CULL_FACE 根据函数glCullFace要求启用隐藏图形材料的面。 GL_DEPTH_TEST 启用深度测试。  根据坐标的远近自动隐藏被遮住的图形(材料) GL_DITHER 启用抖动 GL_FOG 雾化效果  例如距离越远越模糊 GL_INDEX_LOGIC_OP 逻辑操作 GL_LIGHT0 ~ GL_LIGHT7 ~ 启用0号灯到7号灯(光源)  光源要求由函数glLight函数来完成 GL_LIGHTING 启用灯源 GL_LINE_SMOOTH 执行后,过虑线段的锯齿 GL_LINE_STIPPLE 执行后,画虚线 GL_LOGIC_OP 逻辑操作 GL_MAP1_COLOR_4 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成RGBA曲线 GL_MAP1_INDEX 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成颜色索引曲线 GL_MAP1_NORMAL 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成法线 GL_MAP1_TEXTURE_COORD_1 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成文理坐标 GL_MAP1_TEXTURE_COORD_2 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成文理坐标 GL_MAP1_TEXTURE_COORD_3 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成文理坐标 GL_MAP1_TEXTURE_COORD_4 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成文理坐标 GL_MAP1_VERTEX_3 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1在三维空间里生成曲线 GL_MAP1_VERTEX_4 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1在四维空间里生成法线 GL_MAP2_COLOR_4 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成RGBA曲线 GL_MAP2_INDEX 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成颜色索引 GL_MAP2_NORMAL 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成法线 GL_MAP2_TEXTURE_COORD_1 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成纹理坐标 GL_MAP2_TEXTURE_COORD_2 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成纹理坐标 GL_MAP2_TEXTURE_COORD_3 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成纹理坐标 GL_MAP2_TEXTURE_COORD_4 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成纹理坐标 GL_MAP2_VERTEX_3 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2在三维空间里生成曲线 GL_MAP2_VERTEX_4 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2在三维空间里生成曲线 GL_NORMALIZE 根据函数glNormal的设置条件,启用法向量 GL_POINT_SMOOTH 执行后,过虑线点的锯齿 GL_POLYGON_OFFSET_FILL 根据函数glPolygonOffset的设置,启用面的深度偏移 GL_POLYGON_OFFSET_LINE 根据函数glPolygonOffset的设置,启用线的深度偏移 GL_POLYGON_OFFSET_POINT 根据函数glPolygonOffset的设置,启用点的深度偏移 GL_POLYGON_SMOOTH 过虑图形(多边形)的锯齿 GL_POLYGON_STIPPLE 执行后,多边形为矢量画图 GL_SCISSOR_TEST 根据函数glScissor设置,启用图形剪切 GL_STENCIL_TEST 开启使用模板测试并且更新模版缓存。参见glStencilFunc和glStencilOp GL_TEXTURE_1D 启用一维纹理 GL_TEXTURE_2D 启用二维文理 GL_TEXTURE_GEN_Q 根据函数glTexGen,启用纹理处理 GL_TEXTURE_GEN_R 根据函数glTexGen,启用纹理处理 GL_TEXTURE_GEN_S 根据函数glTexGen,启用纹理处理 GL_TEXTURE_GEN_T 根据函数glTexGen,启用纹理处理

在我们启用/禁用光源之后,退出关于按下L键的if语句,然后就要判断一下L键是否放开了,如果放开了,就把light设为FALSE。

2、选择切换

选择切换,是根据我们定义的一个GLuint变量的值,或通过switch语句,或通过数组下标,或是其他能想到的方式,来选择我们执行哪一种情况。 比如说数组,在第7课中,三种处理方式的纹理分别存在texture[0]、texture[1]和texture[2]中,通过变量filter的取值,在DrawGLScene函数的绑定纹理的语句glBindTexture,用glBindTexture(GL_TEXTURE_2D, texture[filter]); 来实现切换,并在主函数中,增加语句,使得每次按下F键,filter的值都加一,当filter为2时再加一就变成0 。然后还要检查按下后放开没,如果放开就把对应键的跟踪值设为false。代码如下:

如果是switch语句,那么同样是在DrawGLScene函数中,通过switch来表示在不同情况下绘制不同的图形,在主函数中控制switch的变量在按键的情况下加一,值满则回到初始,和上面的一样。

四、混合(混色)

混合这里真的很简单,一个函数glBlendFunc()设定好就完成了。但作为数学渣表示完全看不懂这个函数…… 忽略掉那些数学式子,先来看程序中的混合过程。混合主要是指图像的透明度混合,说的专业一些就是红绿蓝和 alpha 源/目标混合因子进行计算,使得图像的色调和透明度有了变化。 混合的实现只有两行:

在Nehe的教程中,这两行是出现在InitGL函数中,作为OpenGL的整体环境的设置。很容易理解,这两行分别设定了亮度和混合方式。可以试着把第一行中的参数进行修改,会看到不同的效果,比如都是1.0f,那么看到的图像就很亮,并且接近黑白的效果。第二行是glBlendFunc函数,glBlendFunc有两个参数,前者表示源因子,后者表示目标因子。这两个参数可以是多种值,比如这里是GL_SRC_ALPHA 和 GL_ONE,那么得到的图像就是半透明状态;如果是glBlendFunc(GL_ONE, GL_ZERO),那么得到的图像就是没有混合的样子。这个函数很重要,关于它的更详细的解释可以看这个链接: 。关于混合函数的数学方面的内容,可以看百度百科中的介绍。 设置好混合参数以后,就要在主函数中启用混合,这里的方法和光照的启用和关闭完全一样,不过要注意的是一旦启用混合就要关了深度测试,一关了混合就要启用深度测试。如果在混合时没关深度测试,那么正方体的某几个面会出现像阴影一样的效果,如果关了混合没开深度测试,那么正方体的几个面就会像是不完整一样。 在实现了一个正方体的混合之后,实现两个甚至更多的正方体、棱柱、棱锥等等的混合就很容易了,都是一样的内容,只是多画几个点。接下来面临的问题是如果有两个贴图,而我们需要其中一个透明另一个不透明,或者说两个贴图要采用不同的混合方式该怎么办。因为InitGL函数是针对整个场景的环境设置,因此这个问题就显得有些麻烦。 其实解决办法也很简单,就是不在InitGL函数中设置混合的方式,而是在DrawGLScene函数中,因为InitGL函数是对整个场景的设置,而DrawGLScene是对每个物体、每个面的设置。以两个正方体为例,载入两个贴图并转为纹理后,在DrawGLScene函数中,画正方体之前,根据混合的启用与否的判断,加入if语句,然后是我们之前提到的那两行,和启用混合以及关闭深度测试,else语句中再关闭混合并启用深度测试。同样的,当多个物体要有不同的混合方式时,就在每个物体前面加这样一组if-else语句。两个正方体的例子下载: 。

简析OpenGL的2D、3D切换 最近做游戏的时候遇到了一个小问题,我们的游戏是2D、3D结合的(准确的说是主菜单、议会界面是2D的,但是真实打斗场景为3D),由2D切换到3D没有问

OpenGL--图元 基础概念1,图元:组成3D物体最小的单位,包括:点,直线,多边形。就和化学里所有物体都是由原子组成的一样。2,点:数学上的点,只有位置,没

GLSL经典入门教程汇总 权威官方文档:

标签: 学习计划

本文链接地址:https://www.jiuchutong.com/biancheng/373066.html 转载请保留说明!

上一篇:OpenGL Framebuffer Object (FBO)

下一篇:简析OpenGL的2D、3D切换(opengl 2)

  • 偷税行为五年后被发现要接受行政处罚吗?
  • 个人租房缴纳由谁缴纳增值税
  • 税务检查是什么行政行为
  • 计入投资收益的手续费
  • 短期借款会计核算
  • 商铺售后返租的会计分录
  • 残保金上年在职工资总额
  • 企业购进货物发生的下列相关税费中,应计入货物
  • 企业转给法人的流程
  • 原来已入帐的款现在收回帐务处理?
  • 交增值税入什么科目
  • 营业外收入做多了怎么办
  • 上期留抵税额计算
  • 保安服务税目
  • 小规模与一般纳税人哪个好
  • 企业的成本费用包括哪些
  • 汽车的增值税可以退税吗
  • 三个点的专票要交多少税
  • 商场赠送购物券是真的吗
  • 核定征收如何做账务处理
  • 怎么解决百度打不开页面
  • 华为鸿蒙系统如何刷机
  • win11任务栏没有输入法图标
  • linux下xhost命令报错:unable to open display的解决办法
  • 租赁合同维修费用
  • 公司发行股票如何做账
  • 利得和损失计入哪里
  • remind32.exe - remind32是什么进程 有什么用
  • erl.exe是什么进程
  • 增值税一般纳税人资格登记表
  • 技术服务辅助设施包括
  • 非货币性资产对外投资会计处理
  • php数组函数大全
  • 成都划拨土地出让金计算
  • 停车缴费怎么交
  • 如何用php做到页数显示
  • 经营收益是净利润吗
  • 增值税附加税的税率
  • 个体户可以不办公户吗
  • 小规模餐饮业如何征税
  • 不良品扣款范本
  • 公司年底封账时间
  • 电子承兑利息
  • 对公账户的资金怎么转出
  • 一般纳税人在哪里报税
  • 非正常损失的原材料进项税额可以抵扣吗
  • phpcms 标签
  • 小微企业确定条件
  • 公司雇佣退休人员工资怎么发
  • 农产品加计扣除10%进项税账务处理
  • 差旅费会计科目怎么做
  • 出口退税的会计科目
  • 技术服务费属于什么科目
  • 专利转让费一般是多少
  • 常见的递延所得税
  • 以原材料投入资本
  • 保险工资单怎么开
  • 房屋租赁的注意问题
  • 会计实务实操
  • 营业外支出明细科目有哪些
  • 旅游饮食服务企业的特点包括
  • MySQL replace into 语句浅析(二)
  • windows2003 IIS6.0 asp配置技巧
  • mac怎么打开mac系统
  • win7系统损坏无法开机怎么重装
  • 如何设置打开wincc不弹出项目管理
  • linux如何安装软件教程
  • javascriptz
  • css网页布局在线生成
  • 如何用python进行数据处理
  • node.js使用教程
  • jquery移出class
  • unity3d documentation
  • python console不能用
  • JavaScript基本语法与页面对象的应用
  • 扣税13个点实际支付金额该怎么算
  • 报价单盖什么公章
  • 工商跟税务的区别
  • 我是一般纳税人对方给我开的普票
  • 四川增值税发票图片
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设