3D游戏设计中,什么是渲染,什么是地图着色课程设计,有什么区别吗,求解

听人说如今的2D游戏很多都是用3D来渲染的?有没有详细的原因? - 知乎102被浏览13056分享邀请回答118 条评论分享收藏感谢收起2添加评论分享收藏感谢收起更多1 个回答被折叠()与世界分享知识、经验和见解工具类服务
编辑部专用服务
作者专用服务
3D游戏渲染引擎的设计与实现
3D游戏引擎是3D游戏的技术核心,它在计算机图形学知识的基础上,充分利用计算机的软硬件平台,使3D游戏的开发更加高效快捷。游戏开发人员在游戏引擎的支撑下,可以只需关注游戏的逻辑实现,从而大大降低游戏开发的成本。因此游戏引擎的好坏直接关系到一款游戏的成败。  
现在游戏引擎除了国际上知名的外,并没有形成很好的开发环境,而国内在游戏引擎方面也没有很多的核心技术。本人在充分学习现有引进的游戏引擎技术的基础上,主要探讨了游戏引擎中的3D渲染部分,建立了一款基于DirectX的游戏渲染引擎模型,并利用该渲染引擎实现了对地形、模型以及特效的渲染。  
首先本人在介绍3D游戏渲染引擎相关的知识的同时,综合运用面向对象的思想和方法,在DirectX的基础上架构和实现了一款3D游戏渲染引擎。该渲染引擎包括场景管理、地形管理、模型动画、特效管理等几个重要部分;对于各个子模块本人给了详细的架构图并对子模块中使用的技术进行了相应的介绍,例如在地形管理模块,使用高度图描述地形生成的算法和地形分块处理的算法;在场景管理中,使用场景裁剪的算法,裁剪掉视口外的模型,减少场景渲染数量,提高引擎渲染的效率;在特效模块本文给出了特效模块整体的架构图,并且给出了特效部分粒子系统、雾化效果、公告板技术等各个子模块设计的详细流程图;在模型动画模块给出了骨架层次结构以及动画生成的方法。  
其次本人在设计框架的基础上,给出了引擎各个子系统具体实现的方法;其中包含该引擎各个子系统具体类图以及类与类之间的关系图,并对部分类的数据结构进行了必要的说明,对各个子系统主要的实现函数的功能进行了相应的说明。对各个子模块,本文展示了本引擎在利用商业模块渲染后的效果图。  
最后本人分析了该渲染引擎各个方面的性能,并且与商业使用的游戏引擎渲染部分进行了对比,提供了一组比对的数据,说明了优化的方向。
学科专业:
授予学位:
学位授予单位:
导师姓名:
学位年度:
在线出版日期:
本文读者也读过
相关检索词
万方数据知识服务平台--国家科技支撑计划资助项目(编号:2006BAH03B01)(C)北京万方数据股份有限公司
万方数据电子出版社16秋学期《3D游戏软件设计》在线作业_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
16秋学期《3D游戏软件设计》在线作业
|0|0|暂无简介
文化艺术交流活动,远程教育学习辅助,商务信...|
总评分0.0|
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩5页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢3D游戏引擎中的材质与纹理
大家好,我是quosin,这是我毕业设计里的部分,与大家分享,希望大家能批评指正,本人才疏学浅,愿与大家共同学习与进步。
材质与纹理
2D档平面图像,这些纹理通过图形适配器的计算,然后参照多边形的纹理坐标被映射到多边形上以形成组成那些多边形的像素。在纹理映射后会产生一些颜色,这些颜色还受到的光照和材质的影响,不同的光照与不同的材质会导致多边形最后的像素颜色值。在游戏中皮肤会占用大量的内存,特别是当我们支持了多重纹理以后,内存的应用就更加的大。目前的3D游戏需要强大的场景去支持,那么就导致了内存之中需要大量的纹理贴图,那么我们对纹理和材质的管理就会对游戏的性能产生极大是影响。
游戏中的灯光、材质与纹理
&& &3D场景中,我们想尽可能的得到真实效果的图像,其中一个我们不能忽视的属性就是灯光,灯光不仅会改变纹理映射结果,而且还会产生阴影效果。如果没有合适的灯光我们在屏幕上将看到不切实际的效果。在计算机图形处理中我们会用到各种光源,环境光、方向光源、点光源、聚光灯等。为了更好的实现3D场景的灯光,Direc3D和OpenGL都为灯光设置了一些结构,我们只要在结构中为图形适配器设置好属性,那么这些API会结合灯光处理的硬件加速为我们渲染图形。
&& 渲染的过程实际上是在一个变换过程中,
通常是在称为观察空间的坐标空间中, 我们遇到了最重要的运算之一: 光照计算。
它是一种这样的事情,当它工作时,你不关注它,但当它不工作时,你就非常关注它了。有很多不同的光照方法,从简单的计算多边形对于灯光的朝向,并根据灯光到多边形的方向和距离加上灯光颜色的百分比值,一直到产生边缘平滑的灯光贴图叠加基本纹理。而且一些
API 实际上提供预先建造的光照方法。
在顶点光照中,你要决定一个顶点被多少个多边形共享,并计算出共享该顶点的所有多边形法向量的均值(称为法向量),并将该法向量赋顶点。一个给定多边形的每个顶点会有不同的法向量,所以你需要渐变或插值多边形顶点的光照颜色以便得到平滑的光照效果。
你没有必要用这种光照方式查看每个单独的多边形。这种方式的优点是时常可以使用硬件转换与光照来帮助快速完成。
不足之处是它不能产生阴影。
&&对于顶点着色 ( Gouraud 着色)
,你让渲染引擎给每个顶点赋予特定的颜色。在绘制多边形上各点投影所对应的像素时,根据它们与各顶点的距离,对这些顶点的颜色进行插值计算。
(实际上Quake III 模型使用的就是这种方法, 效果好的令人惊奇)。
&&还有就是 Phong 着色。如同 Gouraud
着色,通过纹理工作,但不对每个顶点颜色进行插值决定像素颜色值, 它对每个顶点的法向量进行插值,会为每个顶点投影的像素做相同的工作。对于
Gouraud 着色,你需要知道哪些光投射在每个顶点上。对于 Phong 着色,你对每个像素也要知道这么多。一点也不令人惊讶,
Phong 着色可以得到更加平滑的效果,因为每个像素都需要进行光照计算,其绘制非常耗费时间。平面光照处理方法很快速,
但比较粗糙。Phong 着色比 Gouraud 着色计算更昂贵,但效果最好,可以达到镜面高光效果("高亮")。
这些都需要你在游戏开发中折衷权衡。&我们的游戏引擎采用的是Phong模型。
(即,灯光移动,或者没有程序的干预而打开和关闭),你得必须在每一幀重新生成照明映射,按照动态灯光的运动方式修改这些照明映射。灯光映射能够快速的渲染,但对存储这些灯光纹理所需的内存消耗非常昂贵。你可以使用一些压缩技巧使它们占用较少的的内存空间,或减少其尺寸大小,
甚至使它们是单色的 (这样做就不会有彩色灯光了),等等。 如果你确实在场景中有多个动态灯光,
重新生成照明映射将以昂贵的CPU周期而告终。
&& &一旦场景经过转换和照明,
我们就进行裁剪运算。 不进入血淋淋的细节而,剪断运算决定哪些三角形完全在场景 (被称为观察平截头体)
之内或部份地在场景之内。完全在场景之内的三角形被称为细节接受,它们被处理。对于只是部分在场景之内的三角形,位于平截头体外面的部分将被裁剪掉,余下位于平截头体内部的多边形部分将需要重新闭合,以便其完全位于可见场景之内。场景经过裁剪以后,流水线中的下一个阶段就是三角形生成阶段(也叫做扫描线转换),场景被映射到2D
屏幕坐标。到这里,就是渲染运算了。
3D场景看起来真实方面异常重要,它们是你应用到场景区域或对象的一些分解成多边形的小图片。多重纹理耗费大量的内存,有不同的技术来帮助管理它们的尺寸大小。纹理压缩是在保持图片信息的情况下,让纹理数据更小的一种方法。纹理压缩占用较少的游戏CD空间,更重要的是,占用较少内存和3D
显卡存储空间。另外,在你第一次要求显卡显示纹理的时候,压缩的(较小的) 版本经过 AGP 接口从 PC 主存送到3D
显卡,会更快一些。纹理压缩是件好事情。 在下面我们将会更多的讨论纹理压缩。
MIP 映射。 MIP
映射技术通过预先处理纹理,产生它的多个拷贝纹理,每个相继的拷贝是上一个拷贝的一半大小。为什么要这样做?要回答这个问题,你需要了解 3D
显卡是如何显示纹理的。最坏情况,你选择一个纹理,贴到一个多边形上,然后输出到屏幕。我们说这是一对一的关系,最初纹理映射图的一个纹素
(纹理元素) 对应到纹理映射对象多边形的一个像素。如果你显示的多边形被缩小一半,纹理的纹素就每间隔一个被显示。这样通常没有什么问题
但在某些情况下会导致一些视觉上的怪异现象。让我们看看砖块墙壁。假设最初的纹理是一面砖墙,有许多砖块,砖块之间的泥浆宽度只有一个像素。如果你把多边形缩小一半,纹素只是每间隔一个被应用,这时候,所有的泥浆会突然消失,因为它们被缩掉了。你只会看到一些奇怪的图像。
&&使用 MIP
映射,你可以在显示卡应用纹理之前,自己缩放图像,因为可以预先处理纹理,你做得更好一些,让泥浆不被缩掉。当 3D
显卡用纹理绘制多边形时,它检测到缩放因子,说,"你知道,我要使用小一些的纹理,而不是缩小最大的纹理,这样看起来会更好一些。" 在这里,
MIP 映射为了一切,一切也为了 MIP 映射。
& 单一纹理映射给整个3D
真实感图形带来很大的不同,但使用多重纹理甚至可以达到一些更加令人难忘的效果。过去这一直需要多遍渲染(绘制),严重影响了像素填充率。
但许多具有多流水线的3D 加速卡,如ATI's Radeon 和 nVidia's GeForce
2及更高级的显卡,多重纹理可以在一遍渲染(绘制)过程中完成。产生多重纹理效果时,
你先用一个纹理绘制多边形,然后再用另外一个纹理透明地绘制在多边形上面。这让你可以使纹理看上去在移动,或脉动,甚至产生阴影效果
(我们在照明一节中描述过)。绘制第一个纹理映射,然后在上面绘制带透明的全黑纹理,引起一种是所有的织法黑色的但是有一个透明分层堆积过它的顶端
,这就是 -- 即时阴影。 该技术被称为照明映射 ( 有时也称为 暗映射),直至新的Doom
,一直是Id引擎里关卡照明的传统方法。
API将会废弃每个纹理,结果是所有的纹理在下一幀将被重新加载,这非常耗时和浪费。对游戏玩家来说,当API重新加载纹理高速缓存时,会导致幀速率迟钝。&
&&在纹理高速缓存管理中,有各种不同的技术将纹理高速缓存抖动减到最少
& 这是确保任何 3D 游戏引擎速度的一个决定性因素。 纹理管理是件好事情 &
这意味着只要求显卡使用纹理一次,而不是重复使用。这阻止API ( 或图形驱动软件)
上传多次向显卡加载纹理。象OpenGL这样的API实际上通常处理纹理高速缓存管理,意谓着,根据一些规则,比如纹理存取的频率,API决定哪些纹理储存在显卡上,哪些纹理存储在主存。
真正的问题来了:
1) 你时常无法知道API正在使用的准确规则。&
2) 你时常要求在一幀中绘制更多的纹理,以致超出了显卡内存空间所能容纳的纹理。
文件,尽管无法达到那样的压缩比率,但纹理可以被压缩。 从声音波形文件到MP3的压缩可以达到
11:1的压缩比率,而绝大多数硬件支持的纹理压缩运算法则只有 4:1
的压缩比率,尽管如此,这样能产生很大的差别。除此之外,在渲染(绘制)过程中,只有在需要时,硬件才动态地对纹理进行解压缩。这一点非常棒,我们仅仅擦除即将可能用到的表面。
如上所述,另外一种技术确保渲染器要求显卡对每个纹理只绘制一次。确定你想要渲染(绘制)的使用相同纹理的所有多边形同时送到显卡,而不是一个模型在这里,另一个模型在那里,然后又回到最初的纹理论。仅仅绘制一次,你也就通过AGP接口传送一次。Quake
在其阴影系统就是这么做的。处理多边形时,把它们加入到一个内部的阴影列表,一旦所有的多边形处理完毕,渲染器遍历纹理列表,就将纹理及所有使用这些纹理的多边形同时传送出去。&
& &上述过程在使用显卡的硬件 T
L(如果支持的话)时,并不怎么有效。你面临的结局是,满屏幕都是使用相同纹理的大量的多边形小群组,所有多边形都使用不同的变换矩阵。这意谓着更多的时间花在建立显卡的硬件
T & L 引擎
,更多的时间被浪费了。无论如何,因为他们有助于对整个模型使用统一的纹理,所以它对实际屏幕上的模型可以有效地工作。但是因为许多多边形倾向使用相同的墙壁纹理,所以对于世界场景的渲染,它常常就是地狱。通常它没有这么严重,因为大体而言,世界的纹理不会有那么大,这样一来API的纹理缓存系统将会替你处理这些,并把纹理保留在显卡以备再次使用。
&&事实上,在今天的现代PC FPS
游戏中,试图通过AGP接口传送大量纹理是第二个最通常的瓶颈。最大的瓶颈是实际几何处理,它要使东西出现在它应该出现的地方。在如今的3D
游戏中,最耗费时间的工作,显然是那些计算模型中每个顶点正确的世界位置的数学运算。如果你不把场景的纹理保持在预算之内,仅居其次的就是通过AGP接口传送大量的纹理了。然而,你确实有能力影响这些。
通过降低顶层的 MIP
级别(还记得系统在哪里不断地为你细分纹理吗?),你就能够把系统正在尝试送到显卡的纹理大小减少一半。你的视觉质量会有所下降,尤其是在引人注目的电影片断中,但是你的幀速率上升了。这种方式对网络游戏尤其有帮助。
皮肤管理类
& &皮肤管理类是为了能够更加合理的使用皮肤资源而设计的类,皮肤是游戏渲染当中非常重要的资源,在内存中占据了一定的空间。皮肤由纹理和材质组成,其中要求管理的是纹理数据。我们接下来要对3D纹理进行介绍,然后才能了解皮肤管理类的设计需求。
2D的图像,但是1D的和3D
的图像也被用来产生一些特效。1D图像的纹理坐标是1元祖(s),2D图像的的纹理坐标是一个二元组(s,t),3D就是一个3元组(s,t,r)。如果一个高级特效药用到投影纹理,那么这个纹理就是一个四元齐次纹理(s,t,r,q).这种情况下,真实的纹理是通过透视除法获得的。s/q是1D的,(s/q,t/q)是2D的,(s/q,t/q,r/q)是3D的。纹理坐标可以用到复杂的表达式,例如阴影地图会用到深度纹理,此时r值代表的是到光源的距离。通过对纹理坐标的操作我们可以实现离散采样等技术。一般说来,如果u代表一个纹理坐标,那么C(u)就是一个颜色值了,C代表一个计算方式。
顶点模式(coordinate modes),过滤器模式(filter modes),映射模式(mipmap
modes)。我的设计中会用到这些模式,下面也对他们进行简单介绍。
:纹理坐标是指纹理空间坐标,即它们和纹理中的(0,伪位置相对应。当我们将一个纹理应用于一个图元时,它的纹理像素地址必须要映射到对象坐标系中。然后再被平移到屏幕坐标系或像素位置上。
:创建和使用纹理,必须先创建Direet3D对象,函数IDirectDDevice9中的CreateTexture()来创建一个Direct3D对象。
:所谓的纹理过滤就是指Direct3D在使用纹理渲染三维图形时,Direct3D必须使用该纹理为二维图像上的每一个像素着色,这个着色的过程就称为纹理过滤。在很多的情况下,屏幕显示的图形大小与纹理贴图大小不相同,这样在纹理映射时就会被放大或者缩小。对纹理的放大会造成许多像素被映射到同一个纹理元素,图像看上去就会失真或者有锯齿,为了解决这一问题,一般采用将相关纹理元素的颜色融合到一个像素上,融合的方式取决于纹理过滤的方式。Direct3D中支持纹理过滤的方式有四种
:Direct3D计算得到的纹理元素的地址通常是一个浮点值而不是整数的纹理下标值,使用最近点采样时,Direet3D会复制这个浮点值最近的整数地址的纹理元素的颜色,在颜色有变化时就会出现误差。因此最近点采样是效果很差的一种纹理过滤方式。线性纹理过滤:线性纹理取得与计算得到的纹理元素的浮点地址最近的上、下、左、右四个纹理元素,并对其加权平均,得到最终的颜色值。与最近点采样相比,能有效的提高图像的显示质量,并且对系统的性能影响不大。各项异性纹理过滤:主要是为了解决当三维物体表面与投影表面不平行时,它在屏幕上的投影拉长或扭曲的现象。Direct3D根据屏幕像素反向转换到纹理元素的延长度,决定各向异性程度。多级渐进纹理过滤:多级渐进纹理是由一组分辨率逐渐降低的纹理序列组成的,每一级纹理宽度和高度都是上一级纹理宽度和高度的一半。
:Direct3D中支持的纹理寻址的方式有:重叠纹理寻址模式:Direct3D会为每个整数纹理坐标连接处自动重复纹理。镜像纹理寻址模式:Direct3D为每个整数纹理坐标连接处自动复制并翻转纹理。夹取纹理寻址模式:夹取纹理寻址模式是将纹理坐标夹取在[0.0,1.0]范围内,即它将纹理复制一遍,然后将纹理边缘像素的颜色延伸。边框颜色纹理寻址模式:采用这种寻址模式也就是说,当纹理坐标超出
[0.0,1.0]范围时,Direct3D使用边框颜色代替纹理颜色。
皮肤管理类的设计需求
&& 论文中加了这个内容是因为,我觉得作为一个游戏开发人员,和游戏引擎开发的初学者,对需求的了解程度,即通过目前的应用环境、技术水平等去合理的构想我们将要设计的东西的内容。从而有这么个标准可以参照。但是由于本人对设计模式和软件需求过程不是很了解,所以只是概念上的阐述我的设计原则和目标,希望这个管理器能达到什么样的效果。
3D几何物体我们通过纹理来实现更多的细节,而不仅仅是让模型自己去建立如此多的细节。
model需要纹理的时候就在这个纹理列表中来索引,如果纹理存在我们就返回纹理资源指针,如果纹理不存在,导入纹理并且添加到列表,返回指向数据的指针。
,我们首先要通过他们之间的组合关系,将这些元素整合到一个数据结构中去,以便于我们很轻易的可以分析和应用这些材质和纹理信息。我在设计中管这种结构叫皮肤(skin),所以后面我将设计的纹理管理器叫皮肤管理器。他们的结构关系如下,一个皮肤包含一种材质和灯光,一个皮肤又包含一种纹理或者多重纹理,一个模型可以有多种皮肤。所以从上到下是对皮肤的管理,皮肤对纹理的管理,然后才是对纹理的渲染。
皮肤管理类要做的不过就是,定义数据结构,能创建皮肤和纹理,能修改皮肤、纹理和材质,能通过数据结构高效索引和管理皮肤和纹理,可以对有高度纹理的皮肤进行设置,需要皮肤管理日志文件记录程序日志。然后结合顶点管理类交给D3D环境进行渲染。
皮肤管理类的实现
,它是总接口的一个子接口,被单独分离出来,在持续中表现为一个纯虚类,专职处理皮肤方面的问题。它的实现类是HSD3D_skinmanager,继承了虚接口HSSkinManager。这个设计的简要类关系图如:
Direct3D的设备环境对皮肤进行设置和处理,然后才能将它们的结果送往下一站去渲染。
API相关的变量,那些变量之后会出现在接口的实现中,接口中的属性,是我们将来提取的那些属性。接口中的函数也就是需求中提到过的内容,在需求中要求过,我们的资源应该能够识别已经存在的资源,然后合理的利用资源,这些都是游戏渲染引擎的基本设计要求。如AddSkin()函数就是通过已经给的材质颜色和反光强度生成一个皮肤对象,在生成皮肤时,要对输入参数即材质进行检测,检测这个材质是不是已经在材质列表中了,正如以下代码所示,对所有材质进行遍历,检查材质的是否。
& for (nMat=0;
nMat&m_nNumM nMat++) {
if ( MaterialEqual(&mat,
&m_pMaterials[nMat]) ) {
} // for [MATERIALS]
否则就要将这个新材质添加到材质列表中去。接下来还得检测材质的类表的大小,如果列表长度已经到最大值,那个就得为材质数组列表申请一段新的内存,然后记录材质数。代码示例下:
(m_nNumMaterialsP) == 0 ) {
n = (m_nNumMaterials+50)*sizeof(HSMATERIAL);
m_pMaterials = (HSMATERIAL*)realloc(m_pMaterials, n);
if (!m_pMaterials) return HS_OUTOFMEMORY;
memcpy(&m_pMaterials[m_nNumMaterials],
&mat, sizeof(HSMATERIAL));
m_nNumMaterials++;
&& 在皮肤管理类接口中我们看到有三个结构体,他们分别是,HSMATEARAL和HSTEXTURE。对这三个结构体的理解会有助于我们更好的理解皮肤管理的机制和内涵。HSSKIN的定义如下:
typedef struct HSSKIN_TYPE {
// 是否需要开启alpha融合
//皮肤管理器材质ID
nTexture[8];&& //
SkinManager中对应纹理的ID
&& } HSSKIN;
alpha控制,材质ID和纹理ID索引。那么材质的结构定义如何,请看下面定义:
typedef struct HSMATERIAL_TYPE {
&& HSCOLOR
RGBA diffuse light value
&& HSCOLOR
cA&& // RGBA ambient light
&& HSCOLOR
cS& // RGBA specular light value
&& HSCOLOR
cE& // RGBA emissive light value
// specular power
HSMATERIAL;
HSCOLOR是数学库中定义的一个RGBA颜射数据结构。这几种类型的光颜射和光强的组合足以产生出我们想要的效果值了。
HSTEXTRUE了,可想而知啦,一个纹理是有数据的,它的数据就是一连串的像素值啦,那么结构体需要做的就是记录保存一个纹理属性和它的数据,结构体定义如下:
typedef struct HSTEXTURE_TYPE {
fA&& // 纹理透明参数值
*chN&& // 纹理名称
&& HSCOLOR
*pClrK& // 颜色索引数组
颜射索引key的数目
HSTEXTURE;
fAlpha是控制纹理透明度是一个浮点值,这个值在0到1之间,1表示完全不透明。然后两个变量就是纹理名和纹理数据,纹理数据保存了一系列的RGB像素值。pClrKey是颜色索引数组,它记录了一个纹理颜射索引所需要的颜射,即表示了一个颜色模板,如果是16位的位图,那么颜色索引数组就有256个颜色索引值,但是对于像32为高位的颜色值一般就不采用颜色模板了。由于一个位图是使用像素阵列来表示的图像,每个像素的色彩信息由RGB组合或者灰度值表示。根据颜色信息所需的数据位分为1、4、8、16、24及32位等,位数越高颜色越丰富,相应的数据量越大。在引擎中纹理数据为了避免不必要的错误和降低复杂性,所以最后采用统一的format:D3DFMT_A8R8G8B8&
& 介绍了纹理的添加,当然还有一个皮肤中的材质操作和皮肤中的纹理操作。他们虽然只包含与被包含关系,但是他们之间的引用只是通过索引来完成的,实际的内容和数据是放在上面定义的结构体中的,这样的话,我们才能够有一个资源列表统一的对资源进行管理,方便地做到对数据的高效存取。如返回一个材质,我们是通过材质ID去获得那个材质的实际数据,如下面这个代码所示:
HSMATERIAL HSD3DSkinManager::GetMaterial(UINT
&& if (nMatID
& m_nNumMaterials)
return m_pMaterials[nMatID];
HSMATERIAL EmptyM
return EmptyM
GetMaterial
&& &nMatID是一个材质资源的索引ID,通过对资源ID的判断后,确定返回那个材质资源或则返回一个空材质对象。
这个皮肤管理类中最重要的也是最复杂的一个函数莫过于AddTexture()函数了,这个函数作用是为一个皮肤添加一个3D纹理,并且要设置纹理的各种数据,例如alpha数据,而且还封装了把纹理数据保存在D3D纹理内存中的操作。在论文中当然没有篇幅去详细论述这些细节,我只能从设计方法上去解析这个函数。
这个函数的设计步骤和思路如下:
函数传入的值
&&&&//皮肤ID
*chName,//皮肤名&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
fAlpha,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
HSCOLOR *cColorKeys,&
//颜色索引值&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
dwNumColorKeys//颜色索引
3D纹理处理机制。过程细节如下。
realloc()为纹理列表重新分配一个固定长度的内存,这里为50。然后为新的纹理数据结构填入参数,如纹理名称、alpha、然后就是创建纹理
alpha模式去决定纹理像素格式,如果是alpha模式,那么我们该用ARGB32模式,否者采用RGB16为模式生成3D纹理数据。因为导入BMP位图要求是24为RGB位图,所以我们获得设备无关信息后,要将位图信息转换到指定16为或32为模式,然后存入纹理指针指向的纹理数据结构中去。我们对数据处理,无非是遍历每个像素,然后对像素的位进行处理,然后将结果保存到纹理数据。例如下面代码,将24位图的RGB像素数据扩张32的ARGB纹理数据。
for (int cy = 0; cy & lH cy++)
for (int cx = 0; cx & lW cx++) {
//将24位图的RGB像素数据扩张32的ARGB数据
if (bAlpha) {
&&&&&&&&&&&
DWORD Color = 0xff000000;
&&&&&&&&&&&
int&& i = (cy*lWidth + cx)*3;
&&&&&&&&&&&
memcpy(&Color, &pBMPBits[i],
sizeof(BYTE)*3);
&&&&&&&&&&&
((DWORD*)pMemory)[cx + (cy*LineWidth)] = C
&&&&&&&&&&&
} // 32 Bit
&&&&&&&&&&&
//将24位像素值转换到16位
&&&&&&&&&&&
UCHAR B = (pBMPBits[(cy*lWidth + cx)*3 + 0])
&&&&&&&&&&&&&&&&&
G = (pBMPBits[(cy*lWidth + cx)*3 + 1])
&&&&&&&&&&&&&&&&&
R = (pBMPBits[(cy*lWidth + cx)*3 + 2])
&&&&&&&&&&&
&&&&&&&&&&&
USHORT Color = RGB16BIT( (int)(((float) R / 255.0f) * 32.0f),
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
(int)(((float) G / 255.0f) * 64.0f),
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
(int)(((float) B / 255.0f) * 32.0f) );
&&// put pixel as 16 Bit
&&&&&&&&&&&
((USHORT*)pMemory)[cx + (cy*LineWidth)] = C
&&&&&&&&&&&
} // 16 Bit
fAlpha给数据写入alpha值,因为自创建纹理是alpha值全设置为0xff了,所以现在要遍历所有像素更新纹理数据中所有的alpha值改变图像的透明度。在这之前是还得为所有RGB值的像素设置alpha通道,将颜色索引值转换成
id正是添加给皮肤。在D3D环境中,已经有了纹理数据的索引,我们可以直接调用纹理数据进行下一步的渲染了。
&到此纹理添加结束,实际过程和细节要比我描述的更加详细,但是基本设计原理和思路基本阐述完了。至于皮肤管理类其他接口函数,实现都比较简单了。比如添加凹凸贴图函数就和以上的方法非常的类似,不同之处在于纹理之中具有高度信息,会由于高度影响纹理颜色,因为产生凹凸效果。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 iray渲染器和vray区别 的文章

 

随机推荐