早期的天龙八部跟武侠世界基本相似。
先简单地说一下载入场景的大致过程:
解释下地形相关文件,以场景苏州为例:
.scene
场景的一些基本信息,包括Light,SkyDome,环境光,雾以及场景中静态模型StaticEntity等。摘录部分文件如下:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <Scene formatVersion="0.1.1" name="suzhou"> <Terrain filename="suzhou.Terrain" maxheight="7431.5" minheight="-2898"/> <Object name="#Enviroment" type="Enviroment"> <Property name="ambient" value="0.345098 0.345098 0.345098"/> <Property name="fog.colour" value="0.52549 1 0.960784"/> <Property name="fog.linear start" value="2000"/> <Property name="fog.linear end" value="25000"/> </Object> <Object name="#MainLightOne" type="Light"> <Property name="type" value="directional"/> <Property name="diffuse" value="1 0.984314 0.909804"/> <Property name="specular" value="0.3 0.3 0.3"/> <Property name="direction" value="0.369397 -0.465085 -0.101099"/> </Object> <Object name="#MainLightTwo" type="Light"> <Property name="type" value="directional"/> <Property name="diffuse" value="0.478431 0.478431 0.552941"/> <Property name="direction" value="-0.981796 -0 0.534884"/> </Object> <Object name="#SkyDome" type="SkyDome"> <Property name="material" value="CloudySky"/> </Object> <Object type="StaticEntity"> <Property name="mesh name" value="苏州_建筑_墙转角a.mesh"/> <Property name="position" value="-1147.3 117 1612.42"/> </Object> ... </Scene>
.Terrain
地形的分块方式,一个Tile由N个grid组成,Tile为Ogre的Mesh,grid不可再分。scale为grid缩放比例。heightmap,gridInfo分别对应相应的文件,lightmap场景阴影图。<texture>中包含地形所需的纹理信息。<pixmaps>将对应的texture再次细分。<material>关于地形使用两层纹理的材质,Ogre中材质概念包含shader。摘录部分文件如下:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <Terrain name="suzhou" tileSize="32" xsize="512" zsize="512"> <scale x="100" y="100" z="100"/> <heightmap filename="suzhou.Heightmap" type="standard"/> <gridInfo filename="suzhou.GridInfo" type="standard"/> <lightmap filename="suzhou.lightmap.png" type="image"/> <textures> <texture filename="草原/草原浅草底层.jpg" type="image"/> <texture filename="草原/草原浅草上层.tga" type="image"/> ... </textures> <pixmaps> <pixmap bottom="0.2480469" left="0.001953125" right="0.2480469" textureId="0" top="0.001953125"/> <pixmap bottom="0.4980469" left="0.001953125" right="0.2480469" textureId="0" top="0.2519531"/> ... <pixmaps> <materials> <template material="Terrain/OneLayer" name="OneLayer"/> <template material="Terrain/OneLayerLightmap" name="OneLayerLightmap"/> <template material="Terrain/TwoLayer" name="TwoLayer"/> <template material="Terrain/TwoLayerLightmap" name="TwoLayerLightmap"/> <fog_replacement exp="Terrain/OneLayer_ps%fog_exp" exp2="Terrain/OneLayer_ps%fog_exp2" linear="Terrain/OneLayer_ps%fog_linear" none="Terrain/OneLayer_ps"/> <fog_replacement exp="Terrain/TwoLayer_ps%fog_exp" exp2="Terrain/TwoLayer_ps%fog_exp2" linear="Terrain/TwoLayer_ps%fog_linear" none="Terrain/TwoLayer_ps"/> <fog_replacement exp="Terrain/OneLayerLightmap_ps%fog_exp" exp2="Terrain/OneLayerLightmap_ps%fog_exp2" linear="Terrain/OneLayerLightmap_ps%fog_linear" none="Terrain/OneLayerLightmap_ps"/> <fog_replacement exp="Terrain/TwoLayerLightmap_ps%fog_exp" exp2="Terrain/TwoLayerLightmap_ps%fog_exp2" linear="Terrain/TwoLayerLightmap_ps%fog_linear" none="Terrain/TwoLayerLightmap_ps"/> <surface> <specular b="0" g="0" r="0"/> </surface> </materials> </Terrain>
FairTerrain.material中包含材质Terrain/OneLayer,Terrain/OneLayerLightmap等,部分如下:
material Terrain/OneLayer { technique { pass { vertex_program_ref Terrain/OneLayer_vs { } fragment_program_ref Terrain/OneLayer_ps { } texture_unit { texture_alias <layer0> texture <layer0> tex_address_mode clamp filtering trilinear } } } // Fixed-function pipeline technique { pass { texture_unit { texture_alias <layer0> texture <layer0> tex_address_mode clamp filtering trilinear } } pass { scene_blend dest_colour zero lighting off texture_unit { colour_op_ex source1 src_diffuse src_current } } } }FairyTerrain.program中相应的vs,ps
vertex_program Terrain/OneLayer_vs cg { source FairyTerrain.cg entry_point OneLayer_vs profiles vs_1_1 arbvp1 default_params { param_named_auto worldViewProjMatrix worldviewproj_matrix param_named_auto eyePosition camera_position_object_space param_named_auto lightPosition light_position 0 param_named_auto lightDiffuse light_diffuse_colour 0 param_named_auto lightSpecular light_specular_colour 0 param_named_auto lightPosition1 light_position 1 param_named_auto lightDiffuse1 light_diffuse_colour 1 param_named_auto lightSpecular1 light_specular_colour 1 param_named_auto ambientColor ambient_light_colour param_named_auto ambientMat surface_ambient_colour param_named_auto specularMat surface_specular_colour } } fragment_program Terrain/OneLayer_ps cg { source FairyTerrain.cg entry_point OneLayer_ps profiles ps_1_1 arbfp1 }FairyTerrain.cg中的shader
void OneLayer_ps( in float2 uv0 : TEXCOORD0, in uniform sampler2D layer0, in float4 diffuse : COLOR0, in float4 specular : COLOR1, in float fog: FOG, out float4 oColour : COLOR) { float4 c0 = tex2D(layer0, uv0); float3 texturedColour = c0.rgb; float4 baseColour = diffuse; float3 finalColour = baseColour.rgb * texturedColour + specular.rgb * (1-c0.a) ;//+ diffuse2.rgb; float3 resultColour = Fogging(finalColour,fog); oColour = float4(resultColour, baseColour.a); } void OneLayer_vs ( float4 pos :POSITION, float4 vertexcolor:COLOR, float4 vertexcolor2:COLOR1, float2 tex :TEXCOORD0, float4 normal :NORMAL, out float4 oPosition :POSITION, out float4 oDiffuseColor :COLOR0, out float4 oSpecularColor :COLOR1, out float2 oOrigTex :TEXCOORD0, out float oFog: FOG, uniform float4x4 worldViewProjMatrix, uniform float4 eyePosition, uniform float4 lightPosition, uniform float4 lightDiffuse, uniform float4 lightPosition1, uniform float4 lightDiffuse1, uniform float4 lightSpecular, uniform float4 lightSpecular1, uniform float4 ambientColor, uniform float4 ambientMat, uniform float4 specularMat ) { // 变换顶点位置 oPosition = mul(worldViewProjMatrix, pos); oFog = oPosition.z; float3 adjustNormal = normalize(normal.xyz); float4 tEyePosition = float4((eyePosition.xyz - pos.xyz).xyz,0); oOrigTex = tex; float4 tLightPosition = float4(lightPosition.xyz,0); float3 L = normalize(tLightPosition.xyz); float diffuseLight = max(dot(adjustNormal.xyz, L), 0); float4 tLightPosition1 = float4(lightPosition1.xyz,0); float3 L1 = normalize(tLightPosition1.xyz); float diffuseLight1 = max(dot(adjustNormal.xyz, L1), 0); float3 tempLightDiffuse = diffuseLight *lightDiffuse.xyz+ diffuseLight1 *lightDiffuse1.xyz; oDiffuseColor.xyz = vertexcolor.xyz * (tempLightDiffuse + ambientColor.xyz*ambientMat.xyz ); //oDiffuseColor.xyz = oDiffuseColor.xyz oDiffuseColor.a = vertexcolor.w; float3 specularColor = float3(0,0,0); //float3 defaultSpecular = float3(1,1,1); if(diffuseLight>0) { float3 V = normalize(tEyePosition.xyz); float3 H = normalize(L + V); specularColor = lightSpecular*pow(max(dot(adjustNormal.xyz, H), 0),64); } if(diffuseLight1>0) { float3 V = normalize(tEyePosition.xyz); float3 H = normalize(L1 + V); specularColor += lightSpecular1*pow(max(dot(adjustNormal.xyz, H), 0),64); } //specularColor *=defaultSpecular; oSpecularColor.rgb = vertexcolor.xyz*specularColor.rgb*specularMat.rgb; oSpecularColor.a = 1; }
先前有文章介绍过: http://blog.csdn.net/anye3000/article/details/6671798
.heightmap
地形高度图
.region
代表地形中不可行走区域
.wcollision
游戏中用来实现“碰撞”的,下图粉红色区域即为WCollision信息:
桥的下面是熔浆,不允许行走的,但是可以从桥上通过,而游戏不是根据桥这个mesh来实时检测玩家所应该处的高度,而是通过WCollision里所记录的信息来判断的。
部分摘自: http://www.mobilegamebase.com/blog/article.asp?id=8
http://www.cnblogs.com/syqking/archive/2009/10/20/1586993.html