战魂小筑

讨论群:309800774 知乎关注:http://zhihu.com/people/sunicdavy 开源项目:https://github.com/davyxu

   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  257 随笔 :: 0 文章 :: 506 评论 :: 0 Trackbacks

#

很久没有用WindowsAPI来读取INI,在公司写服务器逻辑需要用到,拿来试了下。

记得很早以前就用过GetPrivateProfile*系的INI读取函数,有一个问题很烦:ini的文件路径必须是绝对路径,否则即便工作路径是设置正确的,也是无法读取到ini文件。以前有查过,说是内部搜索路径的问题。默认是在system32去找。4,5年前的处理方法就是把绝对路径拿过来和当前路径组合后传给GetPrivateProfile*系API。

之后,我自己一直是用自己封装的文本解析类来读取ini,很久没碰这个API,也就没有路径烦恼

今天再次碰到,故询问了下其他人有没有什么好的方法:

只需要将路径改为当前路径标识即可,即:

setting.ini   -->     ./setting.ini

 

再次诅咒这个恶心的API

posted @ 2010-09-02 10:11 战魂小筑 阅读(5214) | 评论 (6)编辑 收藏

 

Actor - 一个可以放置在世界中或者在世界中产生的对象。这包括类似于Players(玩家)、Weapons(武器)、StaticMeshes(静态网格物体)、Emitters(发射器)、 Infos以及 Sounds(声效)等。

ActorX - 是一个导出插件,它可以把骨架网格物体和动画导入到一个可以导入到虚幻引擎中的文件内。

Additive BSP(添加型BSP) - 添加到挖空型BSP空间中的BSP空间。 Additive BSP(添加型BSP) 是固体,是游戏环境中不可穿透的空间。

AI - (人工智能)这个术语用于描述通过计算机控制的人物的行为和外观。这可以包括简单的不具有交互的脚本序列到复杂的学习玩家动作并进行调整的计算机人物。

AI Controller(AI控制器) - 一个类,定义了一个计算机控制的人物或者一组计算机控制的人物的行为。

Alpha Channel(Alpha通道) - 这是贴图的一个额外通道,它不仅可以使贴图处于透明状态而且也可以使它处于半透明状态。要想使用 Alpha Channel(Alpha通道) ,则必须设置贴图的bAlphaTexture属性为真。

AmbientSound(环境声效) - 它是一个Actors,当把它放置在关卡中时,它可以循环地从声效浏览器中选择声效文件进行播放。

Anim/Animation(动画) -这是为您具有骨骼的3D模型创建的动作,它可以使3D模型在游戏中移动。 Animations(动画) 存储在.PSA文件中并且可以为一个单独的骨架网格物体导入多个动画。

AnimNode(动画节点) -是动画树中的一个单独组件。许多不同类型的AnimNode(动画节点)连接到一起来组成复杂的程序化的动画混合。

AnimTree(动画树) - 是应用到骨架网格物体上的动画设置,包括多个动画、混合以及骨架骨骼控制器。

AnimTreeEditor(动画树编辑器) - 虚幻编辑器中的这个工具用于创建并预览动画树。

Beam Emitter(光束发射器) - 是一个独立的发射器,它可以把贴图拉伸为长的条带,并且可以按照在虚幻编辑器中设计的方式来发射这些条带。要获得关于 Beam Emitters(光束发射器) 的更多信息,请参照 光束发射器参考页面 。

Blocking Volume(阻挡体积) -它是一个可以在编辑器中创建的体积,它可以阻挡玩家和其它actors但是它不阻挡零粗细跟踪。要想获得关于 Blocking Volumes(阻挡体积) 的更多信息,请参照碰撞参考文档。

Bot -一个计算机控制的玩家,它具有它自己的AI。

Browser(浏览器) - 是一个标签菜单,您可以使用它来查看编辑器的各个方面。要想获得关于 Browsers(浏览器) 的更多信息,请参照Trash.虚幻编辑器用户指南页面。

Brush(画刷) - 它是使用在编辑器左侧的 Brush(画刷) 图元工具创建的任何几何体,包括那个红色的构建画刷。要想获得关于 Brushes(画刷) 的更多信息,请参照BSP画刷指南?文档。

Build(构建) - 它是指编译关卡,以便它可以执行所有必须要的预计算处理比如光照、路径生成以及分解几何体。也被称为 Rebuilding(重新构建) 。

          - 虚幻编辑器的版本。比如:UT2003使用引擎的2136 Build(版本) ,UT2004使用引擎的3186 Build(版本) 。虚幻引擎3是以经过QA验证的版本进行发布的(发布信息)。要想获得关于各种版本的虚幻引擎的信息,请参照虚幻技术开发路线图文档。

Builder Brush(画刷构建器) - 您可以使用红色的画刷来在关卡中挖空或者添加BSP体积。要想获得关于 Builder Brush(画刷构建器) 的更多信息,请参照使用BSP画刷?页面。

BSP - 二叉空间分割树(有时候指 CSG ) 是一个数据结构,用于组织关卡空间中的物体。虽然使用这个术语来指代几何体从语义上讲并不正确,但是因为它指向由画刷构建器创建的几何体,这样便可以轻松地接受。要想获得关于 BSP 的更多信息,请参照使用BSP画刷?。

      用更简单的话说, BSP 是一种几何体类型,您可以在关卡中添加或挖空几何体来雕刻出环境空间。

BSP Holes(BSP洞) - BSP几何体中无法解释的打断,在那里挖空型BSP空间和添加型BSP空间彼此相交。它们发生在非常复杂的BSP添加/挖空中。它除了减慢场景的帧频率外,我们已经发现它们会导致其它的一些奇怪的问题包括但不限于使静态网格物体消失和不可间的阻挡玩家的墙壁。

Camera(相机) -玩家在游戏中和虚幻编辑器中所看到的视图。在正交视口中,您可以把正交视图的相机看成眼睛。

CollisionCylinder(碰撞圆柱体) - 每个actor周围的圆柱空间,用于决定碰撞。对于大多数actors来说,这项设置默认情况下是关闭状态,但是对于类似于player(玩家)和triggers(触发器)这样的actors, CollisionCylinder(碰撞圆柱体) 默认情况下处于打开状态,它能检测其它actor和它的碰撞。 CollisionCylinder(碰撞圆柱体) 的高度和半径可以通过在了碰撞属性标签底下的属性进行改变。

Collision Model(碰撞模型) - 它们不是非常复杂的几何体积,随着静态网格物体进行创建并保存在静态网格物体中。 Collision Model(碰撞模型) 用于加速碰撞计算,而不是仅使用复杂的静态网格物体进行计算。关于 Collision Modles(碰撞模型) 的更多信息,请参照碰撞参考文档。

Commandlet(命令开关) - Commandlet(命令开关)是一个您添加到您游戏的可执行文件上的可选参数用于执行各种动作或者输出信息。请参照命令开关列表 和 制作命令开关页面。

Combiner(组合器) -一种材质类型,它把两个贴图或材质组合并混合它们成为一种新的材质。

Console(控制台) - (也成为 命令提示符、命令行)它是虚幻编辑器底部的一个文本域,允许您在编辑器中输入控制台命令。关于 Console(控制台) 的更多信息,请参照控制台命令文档。

CSG -构造实体几何体(也称为 CSG )这是BSP从语义上来说更加精确的属于表示。术语 CSG 指使用构建画刷创建的几何体。关于 CSG 的更多信息,请参照使用BSP画刷?文档。

Cubemap(立体贴图) - Cubemap(立方体贴图) 是创建具有反光性的材质的外观所使用的环境贴图所需要的。关于 Cubemaps(立方体贴图) 的更多信息,请参照材质概要文档。

Cull(剔除) - 使某物体从渲染的物体中隐藏,或者换句话说,使渲染的物体不描画某个东西。

Decolayer(装饰层) - 地形中的一个层,用于生成一组静态网格物体的随机样式,这些样式仍然附加到地形上并且它们的缩放值和方向可以基于每个静态网格物体实例随机地偏离。关于 Decolayers(装饰层) 的更多信息,请参照 地形编辑器用户指南文档。

Deintersect(反交集) - 这个动作将会保留在 负/挖空 空间中的画刷构建器选项的剩余部分。关于使用 Deintersect(反交集) 按钮的更多信息,请参照Trash.虚幻编辑器用户指南文档。

Demiurge - 它是一个理想的工具,它可以从混沌中定制并制作材质。请参照Demiurge Studios页面。

Drag Grid(拖拽表格) - (也称为 表格) 它是个切换开关,允许您把某些特定actors(比如静态网格物体、Mover(移动者)以及画刷)对齐到编辑器的网格上。 Drag Grid (拖拽网格) 的大小可以根据2的幂数进行调整,范围从最低的1到最高的4096。关于 Drag Grid(拖拽网格) 的更多信息,请参照Trash.虚幻编辑器用户指南文档。

DXTC - (也称为 Trash.DirectX贴图压缩 )这是一种贴图压缩方法,它是虚幻编辑器中进行贴图压缩的主要算法。

Emitter(发射器) - (也称为 粒子系统)它是一个Actor,可以产生一系列的actors比如静态网格物体和平面粒子来获得各种各样的特效。发射器可以相互结合使用来创建"粒子系统"。关于 Emitters(发射器) 的更多信息,请参照粒子系统参考文档文档。

EnvMap(环境贴图) - (也称为 环境贴图) 它是一种材质类型,可以用于创建具有反射光材质的外观。关于 EnvMaps(环境贴图) 的更多信息,请参照材质概要文档。

Event(事件) -一个调用函数,某些actors监听它们,从而引起actors进行相应的动作。_Events(事件)_ 可以从触发器、移动者、发射器以及代码中进行调用。

Face(面) - BSP物体的一侧。一个 Face(面) 由两个三角形组成。 

FaceFX -它是一个集成到虚幻编辑器中的工具,允许您使得人物嘴唇的动画和人物模型同步。关于这个插件的更多信息,请参照 FaceFX简介文档。

FPS - (每秒中播放的帧数) 动画视频显示图片的速率的测量。电视运行大致在30 FPS ,电影通常运行在24 FPS ,然而游戏的 FPS. 通常是变化的。

          - (First Person Shooter(第一人称射击)) 一种游戏类型,它从第一人称的视角来描写场景,并且和世界的主要交互是某种枪。

Garbage collection(垃圾回收) -自动销毁未被引用的对象(正如在Java、C#或者Three.UnrealScript中所存在的)。

G16 -灰度图16位图片。地形的高度图和alpha层使用 G16 位图。

Geometry(几何体) - 它是指关卡中的由三角形构成的任何东西,比如Trash.静态网格物体、BSP、地形等。

Grid(网格) - See Drag Grid. 请参照拖拽网格。

Group(组) - ( 组 浏览器) 通过使用 组浏览器 可以把Actors分配给一个 Group(组) 。这些 Group(组) 可以用于更好地可视化地管理这些使场景变的凌乱的各种不同actors。关于使用这些 组 的更多信息,请参照组浏览器参考文档。

          - (包 组 ) 组是对包中资源(比如 贴图、静态网格物体、以及声效 包)的细分,允许您在浏览器中更加容易地管理资源。

HOM(充满镜子的厅) - (Hall of Mirrors[充满镜子的厅]),它是一种效果。当渲染不能正确地重新描画场景时便会创建一种混乱的视觉效果,其外观和一个 充满镜子的大厅 类似。通过向关卡中的一个antiportal(阻挡体)或者穿过BSP洞看便会获得这种效果。

Impersonator -它是集成到虚幻引擎3中的一个工具,允许您使嘴唇的动画同步到人物模型上。请参照FaceFX。

Instance(实例) - a)任何类的对象;b)基于一个模板创建的子对象,包含在一个对象实例内。

Intersect(交集) - 这个动作将仅留下构建画刷和添加型BSP几何体相叠加的部分。关于使用 Intersect(交集) 按钮的更多信息,请参照编辑器按钮文档。

Invisible(不可见) - BSP几何体的表面属性,它将导致不渲染标志为 不可见 的表面。然而,如果 不可见 的表面处于可见状态,那么它们仍然可以发生碰撞。

KActor - 一个可以移动的静态网格物体,它使用物理引擎和其它具有真实物理的世界几何体发生碰撞。KActors是单独的刚体。

KAsset - 关卡中的一个物理资源实例。KAsset使用物理来驱动骨架网格物体,这对于放置的布娃娃或者其它有很多刚体躯干和关节组成的带皮肤的物体是有效的。

Karma - 集成到虚幻引擎2的组成物理引擎的Math Engine(数学引擎)。虚幻引擎3使用Ageia(以前的Novodex)物理引擎。

Keyframe(关键帧) - 动画中或者mover(移动者)路径中的一个姿势,该姿势可以对动画运动或移动着的移动进行插值。

Layers System(层次系统) - (Layers[层次]) 它是一种允许多个人同时在一张地图上工作的机制。一个层次是一份地图,它可以独立于其它的层次地图进行编辑。这个工作流程的一个例子便是,一个光照层次和一个几何体层次,这允许两个人在地图的这些区域独立地进行工作,不会产生相互的重叠。

Level(关卡) - 关卡定义了一组actors和其它的可以被自动加载及卸载的复杂数据。虚幻引擎3中的世界可以有很多关卡组成;一个典型的游戏可以包含几百个独立的关卡。这些关卡可以基于接近度、精确的加载/卸载触发器以及其它的标准来动态地被加载及卸载。关于关卡的更多信息,请参照创建关卡和关卡动态载入文档。

Light(光源) -在附近的表面上投射光线的actor。

Light-map(光照贴图) -虚幻引擎3使用这个技术来解码投射到表面上的光照,包括光源入射光线的近似方向。

Lightwave(光波) -它是第三方的建模程序,用于创建复杂的静态网格物体和/或 骨架网格物体。

LOD - (Level of Detail[关卡细节层次]) 这个功能允许几何体的分辨率随着距离降低,从而可以提高场景(尤其是带动画的人物)的帧频率。关于如何使用模型上的 LOD 的更多信息,请参照静态网格物体编辑器用户指南文档。

Log(日志) -这个窗口打印出在游戏中或编辑器中发生的每个动作。

Map(地图) -这个保存的文件包含了放置在地图中的所有actor的属性以及您所创建的整个场景的布局。

Masked(遮罩) -一个贴图属性,它使用alpha通道决定贴图的一部分是透明的还是不透明的。 Masked(遮罩) 的贴图没有半透明。要想使用 Masked(遮罩) 设置,您必须把bMasked属性设置为False。

Material(材质) - 一个工具,用于使用贴图创建特殊效果。_Materials_ 可以在贴图浏览器中进行显示和浏览,并且它们也被保存在贴图包中。关于使用不同类型的 Materials(材质) 的更多信息,请参照贴图和材质文档。

Matinee -编辑器中的一个关键帧工具,它允许您在游戏中移动物体并改变其属性。您也可以在相机路径及创建游戏中的镜头剪切时使用它。关于使用 Matinee 的更多信息,请参照Matinee用户指南文档。

Max - (3DS Max) 一个第三方的建模程序,用于创建复杂的静态网格物体 和/或 骨架网格物体。

Maya - 一个第三方的建模程序,用于创建复杂的静态网格物体 和/或 骨架网格物体。

Mesh Emitter(网格物体发射器) - 一个独立的发射器,可以按照在虚幻编辑器中设置的模式发射静态网格物体。关于 Mesh Emitters(网格物体发射器) 的更多信息,请参照粒子系统参考文档。

Meshes(网格物体) - 它是在第三方程序中创建的模型,代表某个实体;术语 Mesh(网格物体) 通常可以和术语 static mesh(静态网格物体) 和 skeletal mesh(骨架网格物体) 替换地使用。

Mod -用户主要基于另一个商业游戏所创建的内容 (比如虚幻竞技场),但是这个游戏已经被修改来创建不同的内容或者进行修改来创建不同游戏性体验。

Modifier(修改器) -一个材质可以使用各种方式来修改一个贴图或者另一个材质,这些方式包括(但不限于)平移、起浮、旋转和缩放。

Mover(移动者) -一个特殊的静态网格物体,可以在编辑器中对其设置关键帧,然后当类似于玩家碰撞、武器开火或者触发器这样的事件触发时,使得该静态网格物体沿着这些关键帧定义的路径移动。

Music(音乐) -歌曲文件,可以被添加到关卡中,使它在背景中播放或者当触发一个事件后播放这个歌曲。这些歌曲文件必须是.ogg文件格式。

NonZeroExtentTraces(非零粗细跟踪) -它是跟踪方式,使用沿着直线运行的盒子来决定碰撞。换句话说,如果两个点之间可以连线,它不再使用投射的2维的线来决定碰撞,而是使用沿着线投射的三维的盒子来检测什么东西会组织盒子。

Notifies(通知) -一个调用函数,可以放置在给定动画的任何地方,可以触发另一个事件包括但不限于产生声音、粒子系统或者可执行的UnrealScript函数。在一个走动动画中,当脚部接触地面是所播放的脚步声是 Notifies(通知) 的一个很好的例子。

Novodex - 这是虚幻引擎3中所使用的刚体物理引擎,用于模拟物体间的真实的运动和碰撞。Novodex也用于UE3的车辆系统。Novodex归Ageia所有,它们的网站是http://www.ageia.com

Outer(外部容器) - 对于存储在包中的物体,该物体的外部容器通常是它们所在的组或包。对于存储在关卡中的物体,它们的外部容器是关卡。

Order(顺序) - 排序

P8 - 8位palletized贴图。

Package(包) -高层次的数据结构,用作为UObjects的容器。所有包含在一个包中的UObjects将会把那个包作为它的外部容器属性的值。

Particle System(粒子系统) -请参照发射器。

Particle Emitter(粒子发射器) - 粒子系统中的一种独立类型的发射器(比如 Beam Emitter(光束发射器)、 Mesh Emitter(网格物体发射器)、Spark Emitter(火花发射器) 或 Sprite Emitter(平面粒子发射器) )。

Pass(遍数) - 场景在着色器中被描画一次为一Pass(遍) 。一个场景在被描画出来之前可以要求着色其渲染多 Passes(遍) 。换句话说,如果一个三角形要求渲染3遍,那么它将被着色器描画三次。

Path Node(路径节点) - 它是由很多线组成的网络中的一个点,它决定了bot可以运行到的位置。在编辑器中 Path Nodes(路径节点) 呈现为苹果。关于 Path Nodes(路径节点) 的更多信息,请参照NavigationAI(导航AI)文档。

Pawn -一个人物或者类,它可以在整个关卡中到处运动(或者靠它自己或者由玩家控制)。

PhAT - 物理资源工具,它是编辑器的一部分,用于创建PhysicsAssets(物理资源)。PhAT允许您取入一个网格物体,然后把碰撞模型和关节分配给骨骼。它也允许您实时地预览物理设置,并和它进行交互。您参照 Trash.物理资源工具文档获得关于PhAT的更多内容。

PhysicsAsset(物理资源) -一组碰撞形状和关节设置组成了关于骨架网格物体的物理信息。比如,布娃娃(ragdoll)的设置,您也可以使用PhysicsAssets(物理资源)来展示任何具有关节的物体的物理。PhysicsAssets(物理资源)也可以用于更新骨架网格物体的包围盒,以及基于每个骨骼的碰撞检测。PhAT是用于创建物理资源的一个工具。

PhysX -集成到虚幻引擎3中的Ageia(以前的Novodex)物理引擎。

Play Map(播放地图) - 当最终用户正在运行地图时实时地运行关卡。

Player(玩家) - 当地图在实时地运行时,使用地图的人类用户。

PlayerStart -玩家的pawn或bot在关卡中的产生点。

Portal(入口) - (也称为 Zone Portal(区域入口) ) 特殊化刷的一种特定类型,通常以薄片的形式出现,它可以把一个区域分为两个不同的区域。关于

Poly(多边形) - (也称为 Polygon(多边形) )一个三角形。

Primitive(图元) -一个标准的、不可改变的BSP图形,可以使用编辑器左侧的这些工具进行创建(也就是曲线楼梯、圆柱体、圆锥、薄片等)。关于 Primitives(图元) 的更多信息,请参照Trash.用户指南页面。

Projector(投射器) -它是一个actor,可以在场景中以各种类型几何体投射贴图。

Properties(属性) -任何actor或贴图的设置。要想访问actor的 Properties(属性) ,只要简单地按下F4键或者右击actor即可。

Quad(方形) - 两个三角形组成一个方形,在线框模式下的地图中很容易看到它。

Ragdoll(布娃娃) - 应用到人物模型上的真实地物理仿真,这可以使的人物像布娃娃那样进行动作。

Rebuild(重新构建) -请参照Build(构建)。

Refpose(参考姿势) - ( Reference Pose )一个带动画的任务在进行动画之前所处的默认姿势(通常是直立姿势)

Renderer(着色器) -虚幻引擎的一部分,它是真正地把玩家看在场景中看到的东西描画出来的工具。

RGBA8 -一个红蓝绿8位图片。

Root(根骨骼) - 在骨架动画层次中的最顶部的主要骨骼。当人物在关卡中运行时, Root(根骨骼) 会不断地平移 和/或旋转。

Rotation Gizmo(旋转小工具) - 一个用于旋转和平移actors的界面。

Rotation Grid(旋转网格) - 这个切换开关允许您以离散的时间间隔围绕着支点旋转actors。

Runtime(实时) -这个模式是指当关卡正在真正地运行时您可以作为玩家和关卡世界进行交互。

Seamless Worlds(无缝的世界) -无缝世界系统的目标是动态地加载背景或者卸载和关卡相关的复杂数据。这个功能和动态载入协同工作,以便所有和世界相关的数据都可以动态地加载。

Script(脚本) - 请参照 Unreal Script。

Shadow depth buffer(阴影深度缓冲) -这是一种渲染软边动态阴影的技术。虚幻引擎3使用阴影深度缓冲来渲染静态光源下的动态物体所投射的阴影。

Shadow-map(阴影贴图) - 一个贴图或基于每个顶点的蒙板,它存储着网格物体或者BSP表面上每个点的特定光源的预计算阴影。

Shadow volume(阴影体积) - 一种渲染硬边动态阴影的技术。虚幻引擎3使用阴影体积渲染动态光源投射的阴影。

Shape Editor(图形编辑器) - (也成为 2D 图形编辑器 ) A tool in the Unreal Editor that allows one to create unique BSP brushes. 虚幻编辑器中的一个工具,允许您常见特殊的BSP画刷。

Sheet(薄片) -创建ZonePortals(区域入口)通常使用的2D画刷。

SimpleBoxCollision(简化的盒式碰撞) - 一种静态网格物体碰撞类型,它使用NonZeroExtentTraces(非零粗细跟踪)来计算碰撞。关于_SimpleBoxCollision(简化的盒式碰撞)_ 的更多信息,请参照碰撞参考文档。

SimpleRigidBodyCollision(简单的刚体碰撞) -一种静态网格物体碰撞类型,它使用Hulls(外壳)来计算刚体的碰撞。关于 SimpleRigidBodyCollision(简单的刚体碰撞) 的更多信息,请参照碰撞参考文档。

SimpleLineCollision(简化的线性碰撞) -一种静态网格物体碰撞类型,它使用ZeroExtentTraces(零粗细跟踪)来计算碰撞。关于 SimpleLineCollision(简化的线性碰撞) 的更多信息,请参照碰撞参考文档。

Skeletal Mesh(骨架网格物体) - 这个网格物体可以使用在第三方建模程序中所创建的骨架和动画来使得骨架网格物体产生动画。关于 Skeletal Mesh(骨架网格物体) 设置的更多信息,请参照导入骨架网格物体指南页面。

Skeleton(骨架) -在第三方建模程序中为带动画的人物所设立的骨骼。

Skin(皮肤) - 应用到网格物体(静态网格物体、骨架网格物体等)上的贴图。

Skins Array(皮肤数组) -属性窗口中的一个文本域,允许您在一个模型上切换不同的皮肤或贴图。

Sky Dome(天幕) -一个大的半球形静态网格物体,可以用于创建远处天空的假象。请参照SkyZone(天空区域)。

Snap(对齐) - (指的是网格 Snap(对齐) )当它移动或旋转时,这个功能把几何体对齐到网格上。

Socket(插槽) -它是骨架网格物体的骨骼上的指定的附加点。关于设立和使用插槽的信息请参照SkeletalMeshSockets(骨架网格物体)插槽文档。

Sorting(排序) -选择着色器先描画什么的顺序和层次。

Special Brush(特殊画刷) -它是一个画刷,可以通过使用 Add Special Brush(添加特殊画刷) 按钮来添加,这不仅为您提供了可能的默认 Special Brushes(特殊画刷) 下拉列表选项,也允许您自定义一个唯一的 Special Brush(特殊画刷) 。关于 Specail Brushes(特殊画刷) 的更多信息,请参照Trash.虚幻编辑器用户指南文档。

Sprite(平面粒子) -应用到平面上的一个贴图(通常和粒子系统一同使用)。

Sprite Emitter(平面粒子发射器) -一个独立的发射器,它可以按照在虚幻编辑器中定义的方式发射平面粒子。关于 Sprite Emitters(平面粒子发射器) 的更多信息,请参照粒子系统参考文档。

StaticMesh(静态网格物体) - (也称为 _Static Mesh(静态网格物体) _ )它是在第三方程序中创建的模型,当把它添加到地图中时,它仍然保持固定性。

Streaming(动态载入) - (也称为 Content Streaming[内容动态载入])这种机制允许您根据需要从源媒体中加载大量的游戏和场景信息。这对于那些不能一次在内存里存储整个场景的控制台游戏平台和其它机器是有利的。关卡、贴图和其它类型的数据也可以进行动态载入。

Subobject(子对象) - 一个对象中包含另一个对象,(除了UObjects包含在包)中意外。一般通过使用Begin Object/End Object'语法把子对象声明在类的.u文件的默认属性中。

Subtractive BSP(挖空型BSP) -从固体 和/或 添加型世界空间中挖出的BSP空间。 Subtractive BSP(挖空型BSP) 是关卡中的一个开发空间,玩家可以在它的内部到处走动。请参照BSP。

Surface(表面) - BSP的可见贴图。

Surface Properties(表面属性) -可以分配给BSP表面的属性。关于 Surface Properties(表面属性) 的更多信息,请参照 Trash.虚幻编辑器用户指南文档。

Tag(标签) -世界中的一个特定actor在它的属性窗口中的事件标签下所赋予该actor的名称。

Targa - 虚幻引擎可以导入的一种贴图文件的格式。

Teleporter(电传) -它是一个actor,它可以立即地把玩家从地图的一个点发送到地图的另一个点或者甚至是另一张地图中的某个点。

Template(模板) - 包含在一个类的默认对象中的子对象。

Terrain(地形) - (也称为 TerrainInfo(地形信息) )一种几何体类型,它以一种高度多边形细分的片,并且可以使用虚幻编辑器中的 Terrain Editor(地形编辑器) 工具使它发生变形以及对其进行雕刻。关于使用 Terrain(地形) 的更多信息,请参照地形编辑器用户指南页面。

Terrain Layer(地形层次) -地形的分级层次,可以在这些层次上描画贴图并把它们在地形上进行混合。关于 Layers(层次) 的更多信息,请参照设置地形文档。

Texture - 一个可以分配给世界中的几何体的图片文件。材质有时也被指为 Textures(贴图) 。关于 Textures(贴图) 的更多信息,请参照贴图和材质文档。

Trace(踪迹) - 从一个点到另一个点(比如从一个枪支到目标)之间的一条连线(仅用于计算目的),它可以用于决定碰撞。

Triangle(三角形) - 最小的可渲染的世界几何体构建块,场景中的任何东西都是基于这些三角形进行构建的。

Trigger(触发器) - 一个actor,它可以在游戏播放过程中触发一个事件。

Umod - (也称为 Unreal MOD(虚幻MOD) )这是一个平台独立的文档服务器,它允许mod创建者把它们的游戏内容发布给虚幻引擎游戏玩家。(仅虚幻引擎1和虚幻引擎2)。

UnEdit - 这是为虚幻引擎2授权用户提供的邮件列表,它作为虚幻引擎内容创建和虚幻编辑器应用的支持组提供。

UnEdit3 - 这是为虚幻引擎3授权用户提供的邮件列表,它作为虚幻引擎内容创建和虚幻编辑器应用的支持组提供。关于 UnEdit 的更多信息,请参照UnEdit3文档。

Unreal Developer Network(虚幻开发者网络) - (也称为 UDN )这个团队为虚幻引擎3的授权用户提供支持。关于 Unreal Developer Network(虚幻开发者网络) 的更多信息,请参照Main.WebHome页面。

UnrealEd - (也称为 Unreal Editor(虚幻编辑器) )这个编辑工具允许您创建可播放的交互式的世界。

UnrealScript -它是Unreal本身具有的一个编程语言,它可以用于为AI和游戏事件创建脚本序列(一系列的动作)。

URU - (也称为 Unreal Rotation Unit(虚幻旋转单位); Unreal Unit(虚幻单位)) 虚幻编辑器中用于度量距离和旋转量的单位。注意虚幻引擎的旋转单位 16384 = 90� 。

UT - (也称为 Unreal Tournament(虚幻竞技场))使用虚幻引擎的第一代版本发行的一个游戏。要想查看第一代虚幻引擎版本发行的其它游戏,请参照 FirstGenerationTitles(第一代游戏)文档。

UT2003 - (也称为 虚幻竞技场2003)这是基于虚幻引擎2110版本上进行了很多修改后发行的版本。关于 UT2003 的更多信息,请参照Powered.UnrealTournament2003(虚幻竞技场2003)页面。

Vertex(顶点) - (复数 Vertices(顶点) )几何三角形的一个点。

Vertex Color(顶点颜色) -一种基于顶点添加颜色来对几何体进行着色的技术。

Viewport(视口) -虚幻编辑器的一个显示窗口,它可以显示前视口、侧视口、顶视口和透视口。

Volume(体积) -一个三维空间,它可以影响各种游戏性功能,比如移动、可见性和玩家损害。

WarpZone(电传区域) - 一个特殊的区域,它包含着WarpZoneInfo信息,该信息可以使得玩家从一个 WarpZone 立即运行到另一个相应的 WarpZone 。

Wiki - 一个网页格式的系统,它允许进行容易的快速的在线维护。UDN网站是基于 Wiki 的。

Wiki wiki - 夏威夷语的意思是 快速的 。

World(世界) - (参照 Map(地图)、Levels(关卡))这个构造组成了游戏中的整个场景。虚幻引擎3中的世界可以由很多较小的已知关卡进行构建,世界存储在地图文件中。

Zone(区域) -为了优化目的,关卡中的区域都使用入口进行了区域划分。

ZoneInfo(区域信息) -它是一个actor,允许您改变它所在区域的属性。

ZBuffer - 显卡中的某段视频内存,它跟踪可以看到的和隐藏在其它物体后面的场景元素。

ZeroExtentTraces(零粗细跟踪) -一个跟踪,它使用从源到目标之间的一维的线来决定碰撞。

ZFight- 一种闪动的视觉失真现象,当两个表面或者占用同一个平面或者它们接近于占用同一个平面和空间时,在那里可以显示的贴图看上去就像在“打斗”一样来获得显示权。

Zone Portal(区域入口) -请参照入口。

 

转载自http://www.udkcn.com/bbs/viewthread.php?tid=114&extra=&page=1

posted @ 2010-08-05 10:22 战魂小筑 阅读(2871) | 评论 (0)编辑 收藏

 Google上个月Https搜索转到另外一个域名encrypted.google.com下面,所有的https搜索都会自动重定向,Google称这个操作是为了方便美国学校和企业过滤新的域名,但当时我就知道,这个域名危险了。

  整整一个月后的今天,终于还是等到了这一天,虽然对于没做任何设置的中国用户,Google默认会把https搜索重定向到谷歌香港的http搜索,尽量避免中国用户使用HTTPS搜索,但这一天终于还是来了,Google的HTTPS加密搜索服务器域名 encrypted.google.com 被DNS污染而无法访问。

  关于判断DNS污染的文章可以参看此文,我们在命令行下通过这样一条命令 nslookup encrypted.google.com 144.223.234.234,即可判断该域名是否被污染,由于144.223.234.234不存在,理应没有任何返回。但我们却得到了一个错误的IP:93.46.8.89。可见 encrypted.google.com 这个域名已经被DNS污染了。

  解决的方法有三个:

  1、使用各种SSH加密代理,在加密代理里进行远程DNS解析,或者使用VPN上网。

  2、修改hosts文件,Windows系统中Hosts文件的优先级高于DNS服务器,操作系统在访问某个域名时,会先检测HOSTS文件,然后再查询DNS服务器。可以在hosts添加受到污染的DNS地址来解决DNS污染和DNS劫持,目前可用的encrypted.google.com的IP有66.249.89.104和209.85.225.104。

  3、通过一些软件编程处理,可以直接忽略返回结果是虚假IP地址的数据包,直接解决DNS污染的问题。这类软件可参见这里这里

 

转载自月光博客 [ http://www.williamlong.info/ ]

posted @ 2010-07-30 09:51 战魂小筑 阅读(1813) | 评论 (0)编辑 收藏

C++的界面库经过几天来的搜索,总结了下面几种的优缺点

1. MFC

   优点:VS2008以及VS2010的扩展确实很强大,特别是原生的窗口运行时停靠以及PropertyGrid确实很强大

   缺点:默认字体很模糊,无论你对MFC多了解,C++多熟悉,每次写代码时依然要重新熟悉代码,更不用提分析别人写的MFC代码,一个字:乱。

2. WTL

   优点:Windows下有个最好的例子:Google Chrome

   缺点:缺乏设计器,文档例子很少

3. wxWidgets

   优点:虚幻3编辑器在用(不是广告),wxAUI的布局设计器很方便,Windows原生界面很舒服,各种功能封装都很到位。

   缺点:布局没有类似GTK+的Fixed绝对坐标方式(Windows SDK默认的左上角像素定位方式),在某些界面显得设计麻烦。 动态链接库多的吓人,工程过于臃肿。

4. Qt, GTK+

    据说Windows下不是很好用。

5. DirectUI

    有很多个人封装类似功能的库。界面,代码分离, 但99%都是收费

6. C# Windows Form

    这是很好的选择,语言方面可以用C++/CLI 免得转换语言

   自由停靠功能可以使用WeiFenLuo.winFormsUI.Docking 非常简单

7. WPF

   有童鞋已经使用MFC/C++通过加载XML显示界面,不过通过资料显示,WPF的控件很少,甚至连原生的PropertyGrid都没有,设计器倒是很华丽

 

总结:界面库的选择最重要的一点就是看有没有很好的设计器,这个是高效开发的重中之重。我尊重MFC,敬仰MFC,它作为C++的框架库来说很不错,但是对于界面设计还是过老了。我们开发的是产品,出的是程序,而不是研究MFC,怎样用好MFC。

posted @ 2010-07-28 17:22 战魂小筑 阅读(24936) | 评论 (28)编辑 收藏

偶然一次查看RenderMonkey例子中的Particle System.rfx 的 FireParticleSystem 中发现了一种提高DX9渲染效率的设计方法

image

这里仅列出Vertex Shader参考:

 

   1:  float4x4 view_proj_matrix: register(c0);
   2:  float4x4 view_matrix: register(c4);
   3:  float time_0_X: register(c8);
   4:  float4 particleSystemPosition: register(c9);
   5:  float particleSystemShape: register(c10);
   6:  float particleSpread: register(c11);
   7:  float particleSpeed: register(c12);
   8:  float particleSystemHeight: register(c13);
   9:  float particleSize: register(c14);
  10:  // The model for the particle system consists of a hundred quads.
  11:  // These quads are simple (-1,-1) to (1,1) quads where each quad
  12:  // has a z ranging from 0 to 1. The z will be used to differenciate
  13:  // between different particles
  14:   
  15:  struct VS_OUTPUT {
  16:     float4 Pos: POSITION;
  17:     float2 texCoord: TEXCOORD0;
  18:     float color: TEXCOORD1;
  19:  };
  20:   
  21:  VS_OUTPUT main(float4 Pos: POSITION){
  22:     VS_OUTPUT Out;
  23:   
  24:     // Loop particles
  25:     float t = frac(Pos.z + particleSpeed * time_0_X);
  26:     // Determine the shape of the system
  27:     float s = pow(t, particleSystemShape);
  28:   
  29:     float3 pos;
  30:     // Spread particles in a semi-random fashion
  31:     pos.x = particleSpread * s * cos(62 * Pos.z);
  32:     pos.z = particleSpread * s * sin(163 * Pos.z);
  33:     // Particles goes up
  34:     pos.y = particleSystemHeight * t;
  35:   
  36:     // Billboard the quads.
  37:     // The view matrix gives us our right and up vectors.
  38:     pos += particleSize * (Pos.x * view_matrix[0] + Pos.y * view_matrix[1]);
  39:     // And put the system into place
  40:     pos += particleSystemPosition;
  41:   
  42:     Out.Pos = mul(view_proj_matrix, float4(pos, 1));
  43:     Out.texCoord = Pos.xy;
  44:     Out.color = 1 - t;
  45:   
  46:     return Out;
  47:  }

由于RenderMonkey本身只能使用Shader,而不能进行任何CPU方的算法设计,因此要实现一个例子系统,只能使用另外的方法,这个例子就是使用纯Shader来实现了一个粒子系统的效果。

注意第31,32行中出现的Pos.z,这是本例子最有参考价值的地方。如果把Particles这个模型引用的QuadArray.3ds用MAX打开你就能发现,这其实是一个多层叠出来的片, 每个片的间隔就是Pos.z。让我们来整理下渲染出例子的整个流程:

由QuadArray.3ds提供Vertex数据,也就是VertexBuffer.片状的VB数据被送入管线,然后由上面的VertexShader程序,通过Pos.z将他们切开,控制这些片的顶点重塑例子的外观。最后的PS只是简单的将光栅化后的像素点根据纹理采样显示出来。

2008年时,我曾经根据这个原理,设计了一套粒子系统,原理与这个差不多,只不过VB是由Constant设置进来,在DX10/11以上就叫ConstantBuffer。测试了下,传统的粒子系统,在我的本子上大约只能跑60多帧,但是这个不锁定VB的粒子系统却可以跑300多帧。

最近决定使用这个技术优化下我的引擎中绘制线段及片的系统,以下是VertexShader的代码:

#define VERTEX_COUNT 80
 
float4 PositionBuffer[VERTEX_COUNT];
float2 UVBuffer[VERTEX_COUNT];
float4 ColorBuffer[VERTEX_COUNT];
 
float4x4 Transform;
 
void Main(
    in float InIndex : TEXCOORD0,
    out float4 OutPosition : POSITION,
    out float2 OutTexCoord : TEXCOORD1,
    out float4 OutColor : COLOR0
    )
{
    OutPosition = mul( PositionBuffer[ InIndex ] , Transform );
    OutColor = ColorBuffer[ InIndex ];
    OutTexCoord = UVBuffer[ InIndex ];
}

这里有个细节需要注意。从最初分析看来,多边形的构造都是由Constant输入,并由VS代码构造,在VB中的数据好像只需要一个Index就够了。但是实际测试下来发现,这样是错误的,还是必须在顶点定义中添加绘制的基本元素,例如位置和纹理坐标。

DX9因为不开源,我们并不了解下面3种绘制方式的性能差异:

1. Constant发送

2. 锁定VB发送

3. DrawPrimitiveUP系列使用系统内建缓冲渲染

 

经过测试发现,DrawPrimitive在数据量小时,比锁定VB快些,而Constant发送方式没有DrawPrimitiveUP快。

因此,使用Constant发送多边形数据进行构造的方法在量小且固定的情况下对于性能提升是很有帮助的,但大量的顶点及变化的数据还是必须使用传统的方法。

posted @ 2010-07-27 14:46 战魂小筑 阅读(2200) | 评论 (1)编辑 收藏

虚幻中的材质系统集合了节点代码生成,shader参数绑定及设置,渲染状态管理等多种功能。UDK中使用的是2个资源类型Material和MaterialInstance,他们都可以赋予任何对象。但同时,他们的用途也是有区别的

Material更接近于传统我们见过的材质,可以使用MaterialEditor进行节点编辑生成一种材质,设置各种参数,直接在编辑器中绑定使用的纹理,并将Material赋予对象

MaterialInstance的原理有点类似于C++的虚表,这点可以从材质实例编辑器中看得出来

image

当前的既是MaterialInstance,其父就是Material,这种层次可以是多层的

Material在添加节点时有一种带有Parameter的节点例如

TextureSample是普通的材质采样器

TextureSampleParameter2D就是可以共享出来给外部设置的参数,换句话说,就是这个采样器可以在后期修改。

MaterialInstance就是可以修改这些Parameter。

通过这种结构的设置,我们就可以轻易的使用1种样式的材质效果,通过更换局部效果图片,变换组合出更多的效果。

posted @ 2010-07-16 09:59 战魂小筑 阅读(2520) | 评论 (4)编辑 收藏

参考了下OGRE的静态模型策略,分析出两种:

第一种就是我们常见的n个静态模型使用n个VB渲染n次,这种方法适用于变换矩阵总是要变化的静态模型绘制,比如说月球围绕地球。

第二种有点类似于LineBatcher的概念,静态模型管理器将所有在编的静态模型,按照材质分组,每个材质1个VB大缓冲,然后将所有的Mesh顶点乘上其变换矩阵变换为世界坐标系后塞入VB,绘制1次。这种方法在同材质,大量静态物体时很高效,可以说是用空间换时间,具体应用如:草原上的一片一片的草。 重建的时机为:有模型创建,销毁,或者矩阵,材质有变化时。

OGRE中利用了Entity和SceneNode来给模型管理器提供一个遍历整理数据的流程。默认的,都是使用第一种方法渲染。

原本最简单的静态模型渲染,在追求效率的要求下,变得比骨骼动画都还复杂。

posted @ 2010-07-08 16:18 战魂小筑 阅读(1931) | 评论 (1)编辑 收藏

image

 

终于完成了结构最复杂的Shader管理器,特性如下:

GlobalShader管理:

也就是传统的手写Shader,完成特殊的任务,例如线条绘制,2D绘制等等

    class ElementPixelShader : public ShaderBinder
    {
        DECLARE_RTTIOBJECT( ElementPixelShader )
        DECLARE_RTTISERIAL( ElementPixelShader )
        DECLARE_SHADER_METAINFO(ST_PixelShader, L"Shader\\SimpleElementPixelShader.usf",L"Main")
 
    public:
 
        virtual void BindShaderParameter( eShaderType ShaderType, const ShaderParameterMap& ParameterMap )
        {
            mTexture.Bind( ParameterMap, "Texture" );
        }
 
        void SetTexture( RenderTexture* NewTexture )
        {
            mShaderRHI->SetTextureParameter( mTexture, NewTexture );
        }
 
        virtual void Serialize( BinarySerializer& Ser )
        {
            __super::Serialize( Ser );
 
            Ser << mTexture;
        }
 
    private:
        ShaderParameter mTexture;
    };
 
    IMPLEMENT_GLOBAL_SHADER( ElementPixelShader, 1);

管理器中,是一种类似单件存储,通过类型可以直接取到实例

MaterialPixelShader管理

这种Shader通过材质节点生成的shader代码来记录每个Shader信息,每个MaterialVertexShader需要只做MaterialPixelShader需要的信息并在Shader代码中传送给它

MaterialVertexShader管理

这类Shader最复杂,其中的控制代码生成的宏需要由材质提供,例如是否使用TangentSpace。还有一些参数就更头疼了, 不是材质在制作时能决定的,例如:一个材质可以应用给地形,模型,甚至粒子,所以我把这部分参数叫做晚绑定参数(Later Bind Material Parameter)

MaterialVertexShader本身是抽象的,需要在材质应用到具体对象时,由对象提供其特殊的VertexShader处理Shader,同时根据特性设定晚绑定参数

 

晚绑定参数:

  MaterialParameter Parameter;
  Parameter.Set( MPT_UseSkin, mSkinned );
  mMaterialInstance->SetVertexShaderProvider( RTTI_CLASS_INFO( ModelMaterialVertexShader),Parameter );

 

材质缓冲系统

Shader 动态编译在很多游戏里都有应用,例如:战地2。游戏第一次启动时,就会编译一次Shader。按照很多文章说的,编译器会根据你显卡及配置编译出最优化的代码。 我就纳闷了, D3D编译函数根本没有传入设备句柄,怎么可能根据机器配置编译?我也尝试过,不同机器上编译出来根本就是一样的。

在以后引擎启动时,Shader系统就会自动从保存好的缓冲内读取,不用再次编译。

这里还要提一个微软为D3DX做的升级Patch系统很恶心,类似于D3DXCompileShader及Shader相关的函数,在每次调用函数时,会载入一个D3DX9_xx.dll,调用完毕后又会卸载,极大的影响性能。 若不是因为这个,估计我不会写缓冲系统的

动态编译更新Shader

这个功能是很多引擎都有的,RenderMonkey也一样,实现起来很简单,就是一个文件时间戳比较问题,此功能完全是为以后编辑器做准备。

 

MaterialShader部分终于告一段落,下面终于可以进入材质节点系统的进一步完善了

posted @ 2010-07-02 15:28 战魂小筑 阅读(2272) | 评论 (1)编辑 收藏

我的节点材质系统已经基本搭建完毕,ShaderFX和虚幻UDK给于了极大的启发与支持,感谢感谢

以下效果图是骨骼动画的各通道效果图

O)4)_]QB8BQO`@NL1C{C6K7Ambient Map

~MCHE$KW9QM0KIMC4XDB(LTDiffuse Map

M%O$B~{J24G1[12[TTY2TEKSpecular Map

 

节点暂时还是用C++构造的,之后会改为二进制存储

        MaterialCompiler Compiler;
 
        MaterialNodeTextureSampler SamplerNode(&Compiler);
 
        /*MaterialNodeVector VectorNode(&Compiler);
        VectorNode.mData = Vector4( 1,1,0,0);*/
 
        MaterialNodeAdd AddNode(&Compiler);
        MaterialNodePointLight PointLightNode(&Compiler);
 
        
        //VectorNode.mRGB.LinkTo( &AddNode.mDataX );
        //SamplerNode.mRGB.LinkTo( &AddNode.mDataY );
 
        SamplerNode.mRGB.LinkTo( &PointLightNode.mAmbient );
 
 
        //AddNode.mResult.LinkTo( &PointLightNode.mDiffuse );
 
        if ( Compiler.GetErrorCount() == 0 )
        {    
            PointLightNode.Compile();
            Compiler.SaveCode( StringConverter().AnsiToUnicode( mShaderFile.c_str() ) );
        }
生成的代码格式和虚幻的shader模板一摸一样,不过我的利用了点不定参数列表的小技巧,代码更漂亮的,呵呵
 
    MaterialNodePointLight::MaterialNodePointLight(MaterialCompiler* Compiler)
        : MaterialNode( Compiler )
    {
        mAmbient    .BindSlot( L"Ambient",        this, MVT_Float3, "float3(0.0f,0.0f,0.0f)" );
        mDiffuse    .BindSlot( L"Diffuse",        this, MVT_Float3, "float3(0.0f,0.0f,0.0f)" );
        mNormal     .BindSlot( L"Normal",        this, MVT_Float3, "Parameters.VertexNormal" );
        mSpecular   .BindSlot( L"Specular",        this, MVT_Float3, "float3(0.0f,0.0f,0.0f)");
        mSpecularPow.BindSlot( L"SpecularPow",    this, MVT_Float,  "16.0f");
        mOpacity    .BindSlot( L"Opacity",        this, MVT_Float,  "1.0f");
    }
 
 
    typedef std::vector<void*> FormatParameterArray;
 
    void MaterialNodePointLight::Compile(  )
    {
        dword CodeGenLength = 0;
 
        FormatParameterArray tFormatParameterArray;
 
        // 编译代码,并构建格式化数组
        for ( SlotList::iterator it = mSlotList.begin();
            it != mSlotList.end();
            ++it )
        {
            MaterialSlot* Slot = *it;
            Slot->Compile();
 
            CodeGenLength += StringHelperA::Length( Slot->GetResultCode() );
            CodeGenLength += StringHelperA::Length( Slot->GetCaculateCode() );
 
            tFormatParameterArray.push_back( (void*)Slot->GetCaculateCode() );
            tFormatParameterArray.push_back( (void*)Slot->GetResultCode() );
        }
 
        // 读取模板文件
        FileStream ShaderFile;
        if ( !ShaderFile.Open(L"shader/MaterialTemplatePixelShader.usf", FAM_Read ) )
        {
            Assert( false );
        }
 
        dword ShaderFileSize = ShaderFile.GetSize();
        
        AString ShaderTemplateCode;
        ShaderTemplateCode.resize( ShaderFileSize + 1);
        ShaderFile.ReadBuffer( (void*)ShaderTemplateCode.data(), ShaderFileSize * sizeof( char ) );
        ShaderTemplateCode[ShaderFileSize] = 0;
 
        mCompiler->WriteFinalCode( ShaderFileSize + CodeGenLength , ShaderTemplateCode.c_str(), &tFormatParameterArray[0] );
 
    }
posted @ 2010-06-29 11:30 战魂小筑 阅读(1800) | 评论 (0)编辑 收藏

最近使用材质节点生成HLSL代码并开始编译,也顺手开始搭建一个正规的Shader包含及编译流程,所以用到了D3DXCompileShader及ID3DXInclude

ID3DXInclude的使用方法在OGRE 1.65(或者类似的版本)的OgreD3D9HLSLProgram.cpp中有源代码可供参考

        STDMETHOD(Open)(D3DXINCLUDE_TYPE IncludeType,
            LPCSTR pFileName,
            LPCVOID pParentData,
            LPCVOID *ppData,
            UINT *pByteLen
            )

此函数发生在代码中有#include XXX时, FileName就是XXX

ppData需要由用户提供FileName对应的源码内容,ANSI格式

pByteLen是代码长度

STDMETHOD(Close)(LPCVOID pData)

此函数的pData既是Open中提供的ppData, 用户可以用于自行释放内存等操作

 

本来按照正常流程, HLSL代码应该可以正常编译,我的HLSL功能大概描述:

Material.hlsl 提供基础光照模型函数

Material_Generated.hlsl 由材质节点生成的代码,包含Main入口, #include "Material.hlsl"

结果D3DXCompileShader报了一个莫名其妙的错误,找不到Main入口. 找了很久都没发现代码有什么问题. 于是开始回看OGRE代码,发现了大侠们的一句救命留言:

// copy into separate c-string
// Note - must NOT copy the null terminator, otherwise this will terminate
// the entire program string!
马上查阅我的代码,为LoadFileToString函数添加一个参数,是否添加终结符0
    bool LoadFileToString( const char* FileName, AString& Content, bool TerminateString )
    {
        wchar Buffer[MAX_PATH];
        FileStream TFile;
        if ( !TFile.Open(StringConverter::AnsiToUnicode( Buffer, MAX_PATH, FileName), FAM_Read ) )
        {
            return false;
        }
 
        dword FileSize = TFile.GetSize();
 
        Content.resize( FileSize + (TerminateString ? 1: 0) );
        TFile.ReadBuffer( (void*)Content.data(), FileSize * sizeof( char ) );
 
        if ( TerminateString )
            Content[FileSize] = 0;
 
        return true;
    }

D3DXCompileShader的Source 是需要终结的源码, 但是在ID3DXInclude的实现类Open函数中,返回给ppData的,坚决不能有终止符0.

 

总结:

   HLSL的代码编译过程是依赖#include将不同的文件碎片组合到一起后才开始解析,因此用户提供的字符串尾部带有终结符, 编译器是没有理由为你检查数据的正确性的.去掉包含终结符才是正确的做法

posted @ 2010-06-18 17:01 战魂小筑 阅读(1667) | 评论 (0)编辑 收藏

仅列出标题
共26页: First 11 12 13 14 15 16 17 18 19 Last