ogre 学习笔记 - Day 13

时隔多日,先回想一下,ogre把资源配置文件称为脚本。ogre内置了几种脚本。

ScriptCompilerManager::ScriptCompilerManager()
{
    OGRE_LOCK_AUTO_MUTEX;
    mScriptPatterns.push_back("*.program");
    mScriptPatterns.push_back("*.material");
    mScriptPatterns.push_back("*.particle");
    mScriptPatterns.push_back("*.compositor");
    mScriptPatterns.push_back("*.os");
    // ...
}

在资源文件里打开几个指定后缀的文件。

Examples.material

material Examples/SphereMappedRustySteel
{
	technique
	{
		pass
		{
			texture_unit
			{
				texture RustySteel.jpg
			}

			texture_unit
			{
				texture spheremap.png
				colour_op_ex add src_texture src_current
				colour_op_multipass_fallback one one
				env_map spherical
			}
		}
	}
}

.pbr.program

vertex_program glTF2/PBR_vs hlsl glsl glsles
{
	source pbr-vert.glsl
    preprocessor_defines HAS_NORMALS,HAS_TANGENTS,HAS_UV
}

fragment_program glTF2/PBR_fs_glsl glsl
{
	source pbr-frag.glsl
    preprocessor_defines MANUAL_SRGB,SRGB_FAST_APPROXIMATION,HAS_NORMALS,HAS_TANGENTS,HAS_BASECOLORMAP,HAS_NORMALMAP,HAS_EMISSIVEMAP,HAS_METALROUGHNESSMAP,HAS_OCCLUSIONMAP,USE_IBL,USE_TEX_LOD
}

Examples.particle

particle_system Examples/GreenyNimbus
{
    material        Examples/FlarePointSprite
    particle_width  35
    particle_height 35
    cull_each       false
    quota           5000
    billboard_type  point
    point_rendering true
    
    // Area emitter.
    emitter Box
    {
        angle           30
        emission_rate   30
        time_to_live    1
        direction       0 1 0
        velocity    	0
        colour_range_start  1 1 0
        colour_range_end    0.3 1 0.3
        width           60
        height          60
        depth           60
    }

    // Make 'em float upwards.
    affector LinearForce
    {
        force_vector      0 100 0
        force_application add
    }

    // Fader.
    affector ColourFader
    {
        red -0.25
        green -0.25
        blue -0.25
    }
}

ssao.compositor

compositor SSAO/Volumetric // Szirmay-Kalos et al 2010
{
    technique
    {
        texture_ref occlusion SSAO/GBuffer occlusion

        target occlusion
        {
            input none
            
            pass render_quad
            {
                material SSAO/Volumetric
            }
        }
    }
}

.os(没找到)

//...

从上面的文件内容以及查找个ScriptCompiler分析,

        .material 是材质

        .program 是 shader

        .particle 是粒子

        .compostor 是后处理

        .os 暂时不知道

但是,重点来了,Examples.material 里面发现了其他东西


fragment_program Examples/MorningCubeMapHDRfp cg
{
	source hdr.cg
	entry_point morningcubemap_fp
	profiles ps_2_0 arbfp1

}

在 .material 文件里发现了 .program的内容。这几个脚本文件实际上没有明确的界限,可以混搭?什么乱七八糟的,定义了特定后缀,不需要遵守?定义它们干嘛?

        算了算了,已经不是第一次吐槽了。

按照顺序,先看看每一种脚本怎么加载。都有哪些内容。

竟然 这个类叫做,ScriptComplierManager,那么就有 ScriptComplier,找到了 ScriptComplier,却没找到任何ScriptComplier的子类,难道就一个 ScriptComplier?就一个还管理个啥?继续继续

在 ScriptComplierManager 类中查找 ScriptCompiler

ScriptCompiler mScriptCompiler;

真的只有一个!???那么所有的脚本都是通过它来解析的?难怪可以混搭。

继续找,在 ScriptCompilerManager里找到一个函数

void ScriptCompilerManager::parseScript(DataStreamPtr& stream, const String& groupName)
{
        ConcreteNodeListPtr nodes =
            ScriptParser::parse(ScriptLexer::tokenize(stream->getAsString(), stream->getName()), stream->getName());
        {
            // compile is not reentrant
            OGRE_LOCK_AUTO_MUTEX;
            mScriptCompiler.compile(nodes, groupName);
        }
}

下断点调试,看看堆栈,找到它正在编译的脚本:

\Media\packs\SdkTrays.zip 中的 SdkTrays.material

打开它,回到 parseScript函数,

        它首先分析 token,调试发现又一个吐槽点,这个 skytrays.mateial 竟然找到了 718 个token,甚至连注释跟空行都算在内了。而且注释里的每一个文字都当成一个token。

        继续,分析完所有的token,就分析每一个token,创建 ConcreteNode,然而,它竟然连 # 也当成了一个Node。不仅如此,什么空行, ctrl ,都当成了node,这完全就是一个无特定定义的文本解析器。作为一个特定后缀,特殊定义的文本,有点浪费时间。注释分析来干嘛。每一个token都是有特定意义的,不如直接分析来得快。       

        所以,只要是文本格式的都可以通过它来分析,无关后缀,无关格式。混搭啥的,小意思了。

        当然,为什么脚本编译性能考虑,还是把注释,空行啥的,去掉吧。

        既然,这只是经过了文本分析器,它分析完后,还是文本,当然也不具备特定的意义了。那,它是什么时候成为有特定意义的对象的呢?换一个问法,Material 是什么时候new的呢?问题转换后,就很容易了。直接在 Material的构造函数里下断点。

      调试发现,在 compile之前,创建几个material :DefaultSettings, BaseWhite, BaseWhiteNoLighting。继续,分析完后,通过 ScriptTranslator 转换为 Material等。通过各种 Translator 转换成各种类型。这其中有两个类型比较特别,一个是gpuprogram,一个是texture,这两个都是需要转换成硬件/平台API支持的类型的。那么,他们是在这个时候编译/加载的吗?

        使用的是D3D11,D3D11 shader, D3D11Texture,老规律,断点调试。

        得到的结果是, texture 实际被使用的时候才加载成D3D11Texture。例如,SetMateriaName(...)的时候创建D3D11Texture。gpu program 有点奇怪,在此时,它会先编译一遍默认的参数,实际使用时通过RTShader再编译一遍。第一遍的编译,应该只是为了获取shader中的参数,RTShader才是真正使用的。需要后续再细看。

        那么,资源脚本如何编译的已经了解了。就具体看看每个对象的配置。也就是各个 Translator。translator没有单个的文件,都在 OgreBuildInScriptTranslators.h里。

  • MaterialTranslator
  • TechniqueTranslator
  • PassTranslator
  • TextureUnitTranslator
  • SamplerTranslator
  • TextureSourceTranslator
  • GpuProgramTranslator
  • SharedParamsTranslator
  • ParticleSystemTranslator
  • ParticleEmitterTranslator
  • ParticleAffectorTranslator
  • CompositorTranslator
  • CompositionTechniqueTranslator
  • CompositionTargetPassTranslator
  • CompositionPassTranslator

先从 MaterialTranslator 开始:

void MaterialTranslator::translate(ScriptCompiler *compiler, const AbstractNodePtr &node)
{
    // ...
    case ID_LOD_VALUES:
    case ID_LOD_DISTANCES:
    case ID_LOD_STRATEGY:
    // ...
}

        发现里面有很多的ID,直接看这些ID的定义,找到了所有的buildInID。

    enum
    {
        ID_MATERIAL = 3,
        ID_VERTEX_PROGRAM,
        ID_GEOMETRY_PROGRAM,
        ID_FRAGMENT_PROGRAM,
        ID_TECHNIQUE,
        ID_PASS,
        ID_TEXTURE_UNIT,
        ID_VERTEX_PROGRAM_REF,
        ID_GEOMETRY_PROGRAM_REF,
        ID_FRAGMENT_PROGRAM_REF,
        ID_SHADOW_CASTER_VERTEX_PROGRAM_REF,
        ID_SHADOW_CASTER_FRAGMENT_PROGRAM_REF,
        ID_SHADOW_RECEIVER_VERTEX_PROGRAM_REF,
        ID_SHADOW_RECEIVER_FRAGMENT_PROGRAM_REF,
        ID_SHADOW_CASTER_MATERIAL,
        ID_SHADOW_RECEIVER_MATERIAL,
        

     // ...

        ID_END_BUILTIN_IDS
    };

这些就是脚本文件内容的定义了。了解完这些ID,并弄清层级关系,就知道脚本的所有功能了。

这些值是枚举,而文本中是 字符串,字符串如何转换为枚举的呢。通过搜索任一ID发现在ScriptCompiler::initWordMap里进行了一一对应。


    void ScriptCompiler::initWordMap()
    {
        mIds["on"] = ID_ON;
        mIds["off"] = ID_OFF;
        mIds["true"] = ID_TRUE;
        mIds["false"] = ID_FALSE;
        mIds["yes"] = ID_YES;
        mIds["no"] = ID_NO;
        // ...
    }

继续回到 MaterialTranslator,它是通过ID,来获取值,设置到对应的属性里。知道了这些,就不需要每一个translator都看了。只要知道了每个ID的意义以及层级结构就可以了。

  • ID_MATERIAL  
    • ID_LOD_VALUES
    • ID_LOD_DISTANCES
    • ID_LOD_STRATEGY
    • ID_RECEIVE_SHADOWS
    • ID_SET_TEXTURE_ALIAS
    • ID_TECHNIQUE
      • ID_SCHEME
      • ID_LOD_INDEX
      • ID_SHADOW_CASTER_MATERIAL
      • ID_SHADOW_RECEIVER_MATERIAL
      • ID_GPU_VENDOR_RULE
      • ID_GPU_DEVICE_RULE
      • ID_PASS
        • ID_AMBIENT
        • ID_DIFFUSE
        • ID_SPECULAR
        • ID_EMISSIVE
        • ID_SCENE_BLEND
        • ID_SEPARATE_SCENE_BLEND
        • ID_SCENE_BLEND_OP
        • ID_SEPARATE_SCENE_BLEND_OP
        • ID_DEPTH_CHECK
        • ID_DEPTH_WRITE
        • ID_DEPTH_BIAS
        • ID_DEPTH_FUNC
        • ID_ITERATION_DEPTH_BIAS
        • ID_ALPHA_REJECTION
        • ID_ALPHA_TO_COVERAGE
        • ID_LIGHT_SCISSOR
        • ID_LIGHT_CLIP_PLANES
        • ID_TRANSPARENT_SORTING
        • ID_ILLUMINATION_STAGE
        • ID_CULL_HARDWARE
        • ID_CULL_SOFTWARE
        • ID_NORMALISE_NORMALS
        • ID_LIGHTING
        • ID_SHADING
        • ID_POLYGON_MODE
        • ID_POLYGON_MODE_OVERRIDEABLE
        • ID_FOG_OVERRIDE
        • ID_COLOUR_WRITE
        • ID_MAX_LIGHTS
        • ID_START_LIGHT
        • ID_LIGHT_MASK
        • ID_ITERATION
        • ID_LINE_WIDTH
        • ID_POINT_SIZE
        • ID_POINT_SPRITES
        • ID_POINT_SIZE_ATTENUATION
        • ID_POINT_SIZE_MIN
        • ID_POINT_SIZE_MAX
        • ID_FRAGMENT_PROGRAM_REF
        • ID_VERTEX_PROGRAM_REF
        • ID_GEOMETRY_PROGRAM_REF
        • ID_TESSELLATION_HULL_PROGRAM_REF
        • ID_TESSELLATION_DOMAIN_PROGRAM_REF
        • ID_COMPUTE_PROGRAM_REF
        • ID_SHADOW_CASTER_VERTEX_PROGRAM_REF
        • ID_SHADOW_CASTER_FRAGMENT_PROGRAM_REF
        • ID_SHADOW_RECEIVER_VERTEX_PROGRAM_REF
        • ID_SHADOW_RECEIVER_FRAGMENT_PROGRAM_REF
        • ID_FRAGMENT_PROGRAM
        • ID_VERTEX_PROGRAM
        • ID_GEOMETRY_PROGRAM
        • ID_TESSELLATION_HULL_PROGRAM
        • ID_TESSELLATION_DOMAIN_PROGRAM
        • ID_COMPUTE_PROGRAM
        • ID_TEXTURE_UNIT
          • ID_TEX_ADDRESS_MODE
          • ID_TEX_BORDER_COLOUR
          • ID_FILTERING
          • ID_CMPTEST
          • ID_CMPFUNC
          • ID_COMP_FUNC
          • ID_MAX_ANISOTROPY
          • ID_MIPMAP_BIAS
          • ID_SAMPLER_REF
          • ID_TEXTURE_ALIAS
          • ID_TEXTURE
          • ID_ANIM_TEXTURE
          • ID_CUBIC_TEXTURE
          • ID_TEX_COORD_SET
          • ID_COLOUR_OP
          • ID_COLOUR_OP_EX
          • ID_COLOUR_OP_MULTIPASS_FALLBACK
          • ID_ALPHA_OP_EX
          • ID_ENV_MAP
          • ID_SCROLL
          • ID_SCROLL_ANIM
          • ID_ROTATE
          • ID_ROTATE_ANIM
          • ID_SCALE
          • ID_WAVE_XFORM
          • ID_TRANSFORM
          • ID_BINDING_TYPE
          • ID_CONTENT_TYPE

粗略列举了material包含的一些ID,具体细分的话,会很长的时间,等到具体使用的时候再考虑,现在只是梳理。

GpuTranslator

vertex_program glTF2/PBR_vs hlsl glsl glsles
{
	source pbr-vert.glsl
    preprocessor_defines HAS_NORMALS,HAS_TANGENTS,HAS_UV
}

fragment_program glTF2/PBR_fs_glsl glsl
{
	source pbr-frag.glsl
    preprocessor_defines MANUAL_SRGB,SRGB_FAST_APPROXIMATION,HAS_NORMALS,HAS_TANGENTS,HAS_BASECOLORMAP,HAS_NORMALMAP,HAS_EMISSIVEMAP,HAS_METALROUGHNESSMAP,HAS_OCCLUSIONMAP,USE_IBL,USE_TEX_LOD
}

fragment_program glTF2/PBR_fs_hlsl hlsl glsles
{
	source pbr-frag.glsl
	target ps_2_a
    preprocessor_defines MANUAL_SRGB,SRGB_FAST_APPROXIMATION,HAS_NORMALS,HAS_TANGENTS,HAS_BASECOLORMAP,HAS_NORMALMAP,HAS_EMISSIVEMAP,HAS_METALROUGHNESSMAP,HAS_OCCLUSIONMAP,USE_IBL
}

fragment_program glTF2/PBR_fs unified
{
	delegate glTF2/PBR_fs_glsl
	delegate glTF2/PBR_fs_hlsl
}

gpu program 稍微不一样,

vertex_program glTF2/PBR_vs hlsl glsl glsles, 表示 类型:顶点着色器,名称: glTF2/PBR_vs,支持的shader语言:hlsl, glsl, glsles

  • source 源文件
  • target shader类型以及版本
  • preprocessor_defines 预定义宏,与C/C++宏定义作用相同

fragment_program glTF2/PBR_fs unified 这种定义方式表示未定义语言

  • delegate 表示它再运行时可使用的配置

通过delegeta的方式,在运行时决定使用哪一种语言,每种语言又可以用不同的配置。

  • compositor
    • ID_Composition_Technique
      • ID_TEXTURE
        • ID_TARGET_WIDTH
        • ID_TARGET_HEIGHT
        • ID_TARGET_WIDTH_SCALED
        • ID_TARGET_HEIGHT_SCALED
        • ID_POOLED
        • ID_CUBIC
        • ID_SCOPE_LOCAL
        • ID_SCOPE_CHAIN
        • ID_SCOPE_GLOBAL
        • ID_GAMMA
        • ID_NO_FSAA
        • ID_DEPTH_POOL
      • ID_TEXTURE_REF
      • ID_SCHEME
      • ID_COMPOSITOR_LOGIC
      • //...

        compositor的层级关系,在enum中已经分出来了,就不用再自己列举了。为什么上面的它不表明层级呢?

        ID_COMPOSITOR,
            ID_TARGET,
            ID_TARGET_OUTPUT,

            ID_INPUT,
                ID_PREVIOUS,
                ID_TARGET_WIDTH,
                ID_TARGET_HEIGHT,
                ID_TARGET_WIDTH_SCALED,
                ID_TARGET_HEIGHT_SCALED,
            ID_COMPOSITOR_LOGIC,
            ID_TEXTURE_REF,
            ID_SCOPE_LOCAL,
            ID_SCOPE_CHAIN,
            ID_SCOPE_GLOBAL,
            ID_POOLED,
            //ID_GAMMA, - already registered for material
            ID_NO_FSAA,
            ID_DEPTH_POOL,
            ID_ONLY_INITIAL,
            ID_VISIBILITY_MASK,
            ID_LOD_BIAS,
            ID_MATERIAL_SCHEME,
            ID_SHADOWS_ENABLED,

            ID_CLEAR,
            ID_STENCIL,
            ID_RENDER_SCENE,
            ID_RENDER_QUAD,
            ID_IDENTIFIER,
            ID_FIRST_RENDER_QUEUE,
            ID_LAST_RENDER_QUEUE,
            ID_QUAD_NORMALS,
                ID_CAMERA_FAR_CORNERS_VIEW_SPACE,
                ID_CAMERA_FAR_CORNERS_WORLD_SPACE,

            ID_BUFFERS,
                ID_COLOUR,
                ID_DEPTH,
            ID_COLOUR_VALUE,
            ID_DEPTH_VALUE,
            ID_STENCIL_VALUE,

            ID_CHECK,
            ID_COMP_FUNC,
            ID_REF_VALUE,
            ID_MASK,
            ID_FAIL_OP,
                ID_KEEP,
                ID_INCREMENT,
                ID_DECREMENT,
                ID_INCREMENT_WRAP,
                ID_DECREMENT_WRAP,
                ID_INVERT,
            ID_DEPTH_FAIL_OP,
            ID_PASS_OP,
            ID_TWO_SIDED,

.os 文件没有发现,暂时忽略吧。

到这里,就分析完了脚本。知道了材质,纹理,shader什么时候加载的。具体的数值如何使用,等待使用时再分析。

纹理,材质,shader,资源当中还有模型没有加载。看看模型如何加载的。通过之前的学习,知道了模型需要通过SceneManager::CreateEntity来加载。既然知道了,就不需要再看了。

        之前导入的是.mesh文件。还能加载模型哪些文件呢?这个文件就需要回到cmake的时候了,cmake的时候有一个选项叫做,OGRE_BUILD_PLUGIN_ASSIMP,ogre的插件,打开plugins.cfg,有一行配置  Plugin=Codec_Assimp,如果这行没有被注释,就说明我们使用了 Assimp插件。

        Assimp : The official Open-Asset-Importer-Library Repository. Loads 40+ 3D-file-formats into one unified and clean data structure.

        assimphttps://github.com/assimp/assimphttps://github.com/assimp/assimp

 使用了Assimp可以加载多达40多种3D模型。

        资源还包括动画,通过之前的学习,知道了动画也包含在模型里了。

到这里,资源模块就了解完了。

to be continue...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值