Ogre材质解析代码初步分析(五)

来源:互联网 发布:电脑打碟用什么软件 编辑:程序博客网 时间:2024/04/30 00:09

本文参考:http://www.cnblogs.com/yzwalkman/archive/2013/01/20/2867793.html 尊重原创


ScriptCompilerManager是进行脚本解析的关键类型对象,在其构造函数中将会创建ScriptCompiler对象实例,并将对象指针赋给其mScriptCompiler成员变量。前面所说解析过程的三个阶段即是由此mScriptCompiler对象完成的。对于ScriptCompiler来说,除了前面涉及的各函数过程外,还有两块内容值得关注。一是,如下的枚举变量定义:

/// This enum defines the integer ids for keywords this compiler handlesenum{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_LOD_VALUES,    ID_LOD_STRATEGY,ID_LOD_DISTANCES,ID_RECEIVE_SHADOWS,ID_TRANSPARENCY_CASTS_SHADOWS,ID_SET_TEXTURE_ALIAS,ID_SOURCE,ID_SYNTAX,ID_DEFAULT_PARAMS,ID_PARAM_INDEXED,ID_PARAM_NAMED,ID_PARAM_INDEXED_AUTO,ID_PARAM_NAMED_AUTO,ID_SCHEME,ID_LOD_INDEX,ID_GPU_VENDOR_RULE,ID_GPU_DEVICE_RULE,ID_INCLUDE, ID_EXCLUDE, ID_AMBIENT,ID_DIFFUSE,ID_SPECULAR,ID_EMISSIVE,ID_VERTEXCOLOUR,ID_SCENE_BLEND,ID_COLOUR_BLEND,ID_ONE,ID_ZERO,ID_DEST_COLOUR,ID_SRC_COLOUR,ID_ONE_MINUS_DEST_COLOUR,ID_ONE_MINUS_SRC_COLOUR,ID_DEST_ALPHA,ID_SRC_ALPHA,ID_ONE_MINUS_DEST_ALPHA,ID_ONE_MINUS_SRC_ALPHA,ID_SEPARATE_SCENE_BLEND,ID_SCENE_BLEND_OP,ID_REVERSE_SUBTRACT,ID_MIN,ID_MAX,ID_SEPARATE_SCENE_BLEND_OP,ID_DEPTH_CHECK,ID_DEPTH_WRITE,ID_DEPTH_FUNC,ID_DEPTH_BIAS,ID_ITERATION_DEPTH_BIAS,ID_ALWAYS_FAIL,ID_ALWAYS_PASS,ID_LESS_EQUAL,ID_LESS,ID_EQUAL,ID_NOT_EQUAL,ID_GREATER_EQUAL,ID_GREATER,ID_ALPHA_REJECTION,ID_ALPHA_TO_COVERAGE,ID_LIGHT_SCISSOR,ID_LIGHT_CLIP_PLANES,ID_TRANSPARENT_SORTING,ID_ILLUMINATION_STAGE,ID_DECAL,ID_CULL_HARDWARE,ID_CLOCKWISE,ID_ANTICLOCKWISE,ID_CULL_SOFTWARE,ID_BACK,ID_FRONT,ID_NORMALISE_NORMALS,ID_LIGHTING,ID_SHADING,ID_FLAT, ID_GOURAUD,ID_PHONG,ID_POLYGON_MODE,ID_SOLID,ID_WIREFRAME,ID_POINTS,ID_POLYGON_MODE_OVERRIDEABLE,ID_FOG_OVERRIDE,ID_NONE,ID_LINEAR,ID_EXP,ID_EXP2,ID_COLOUR_WRITE,ID_MAX_LIGHTS,ID_START_LIGHT,ID_ITERATION,ID_ONCE,ID_ONCE_PER_LIGHT,ID_PER_LIGHT,ID_PER_N_LIGHTS,ID_POINT,ID_SPOT,ID_DIRECTIONAL,ID_LIGHT_MASK,ID_POINT_SIZE,ID_POINT_SPRITES,ID_POINT_SIZE_ATTENUATION,ID_POINT_SIZE_MIN,ID_POINT_SIZE_MAX,ID_TEXTURE_ALIAS,ID_TEXTURE,ID_1D,ID_2D,ID_3D,ID_CUBIC,ID_UNLIMITED,ID_ALPHA,ID_GAMMA,ID_ANIM_TEXTURE,ID_CUBIC_TEXTURE,ID_SEPARATE_UV,ID_COMBINED_UVW,ID_TEX_COORD_SET,ID_TEX_ADDRESS_MODE,ID_WRAP,ID_CLAMP,ID_BORDER,ID_MIRROR,ID_TEX_BORDER_COLOUR,ID_FILTERING,ID_BILINEAR,ID_TRILINEAR,ID_ANISOTROPIC,ID_MAX_ANISOTROPY,ID_MIPMAP_BIAS,ID_COLOUR_OP,ID_REPLACE,ID_ADD,ID_MODULATE,ID_ALPHA_BLEND,ID_COLOUR_OP_EX,ID_SOURCE1,ID_SOURCE2,ID_MODULATE_X2,ID_MODULATE_X4,ID_ADD_SIGNED,ID_ADD_SMOOTH,ID_SUBTRACT,ID_BLEND_DIFFUSE_COLOUR,ID_BLEND_DIFFUSE_ALPHA,ID_BLEND_TEXTURE_ALPHA,ID_BLEND_CURRENT_ALPHA,ID_BLEND_MANUAL,ID_DOT_PRODUCT,ID_SRC_CURRENT,ID_SRC_TEXTURE,ID_SRC_DIFFUSE,ID_SRC_SPECULAR,ID_SRC_MANUAL,ID_COLOUR_OP_MULTIPASS_FALLBACK,ID_ALPHA_OP_EX,ID_ENV_MAP,ID_SPHERICAL,ID_PLANAR,ID_CUBIC_REFLECTION,ID_CUBIC_NORMAL,ID_SCROLL,ID_SCROLL_ANIM,ID_ROTATE,ID_ROTATE_ANIM,ID_SCALE,ID_WAVE_XFORM,ID_SCROLL_X,ID_SCROLL_Y,ID_SCALE_X,ID_SCALE_Y,ID_SINE,ID_TRIANGLE,ID_SQUARE,ID_SAWTOOTH,ID_INVERSE_SAWTOOTH,ID_TRANSFORM,ID_BINDING_TYPE,ID_VERTEX,ID_FRAGMENT,ID_CONTENT_TYPE,ID_NAMED,ID_SHADOW,ID_TEXTURE_SOURCE,ID_SHARED_PARAMS,ID_SHARED_PARAM_NAMED,ID_SHARED_PARAMS_REF,ID_PARTICLE_SYSTEM,ID_EMITTER,ID_AFFECTOR,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 materialID_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,#ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS    ID_RT_SHADER_SYSTEM,#endifID_END_BUILTIN_IDS};
以上枚举变量中的各个值,对应着在Ogre脚本文件中出现的所有的关键字。

下面是ScriptCompiler相关的成员变量mIds,定义如下:

typedef HashMap<String,uint32> IdMap;
我们可以看看IdMap里面的值,在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;// Material idsmIds["material"] = ID_MATERIAL;mIds["vertex_program"] = ID_VERTEX_PROGRAM;mIds["geometry_program"] = ID_GEOMETRY_PROGRAM;mIds["fragment_program"] = ID_FRAGMENT_PROGRAM;mIds["technique"] = ID_TECHNIQUE;mIds["pass"] = ID_PASS;mIds["texture_unit"] = ID_TEXTURE_UNIT;mIds["vertex_program_ref"] = ID_VERTEX_PROGRAM_REF;mIds["geometry_program_ref"] = ID_GEOMETRY_PROGRAM_REF;mIds["fragment_program_ref"] = ID_FRAGMENT_PROGRAM_REF;mIds["shadow_caster_vertex_program_ref"] = ID_SHADOW_CASTER_VERTEX_PROGRAM_REF;mIds["shadow_caster_fragment_program_ref"] = ID_SHADOW_CASTER_FRAGMENT_PROGRAM_REF;mIds["shadow_receiver_vertex_program_ref"] = ID_SHADOW_RECEIVER_VERTEX_PROGRAM_REF;mIds["shadow_receiver_fragment_program_ref"] = ID_SHADOW_RECEIVER_FRAGMENT_PROGRAM_REF;    mIds["lod_values"] = ID_LOD_VALUES;    mIds["lod_strategy"] = ID_LOD_STRATEGY;mIds["lod_distances"] = ID_LOD_DISTANCES;mIds["receive_shadows"] = ID_RECEIVE_SHADOWS;mIds["transparency_casts_shadows"] = ID_TRANSPARENCY_CASTS_SHADOWS;mIds["set_texture_alias"] = ID_SET_TEXTURE_ALIAS;mIds["source"] = ID_SOURCE;mIds["syntax"] = ID_SYNTAX;mIds["default_params"] = ID_DEFAULT_PARAMS;mIds["param_indexed"] = ID_PARAM_INDEXED;mIds["param_named"] = ID_PARAM_NAMED;mIds["param_indexed_auto"] = ID_PARAM_INDEXED_AUTO;mIds["param_named_auto"] = ID_PARAM_NAMED_AUTO;mIds["scheme"] = ID_SCHEME;mIds["lod_index"] = ID_LOD_INDEX;mIds["shadow_caster_material"] = ID_SHADOW_CASTER_MATERIAL;mIds["shadow_receiver_material"] = ID_SHADOW_RECEIVER_MATERIAL;mIds["gpu_vendor_rule"] = ID_GPU_VENDOR_RULE;mIds["gpu_device_rule"] = ID_GPU_DEVICE_RULE;mIds["include"] = ID_INCLUDE;mIds["exclude"] = ID_EXCLUDE;mIds["ambient"] = ID_AMBIENT;mIds["diffuse"] = ID_DIFFUSE;mIds["specular"] = ID_SPECULAR;mIds["emissive"] = ID_EMISSIVE;    mIds["vertexcolour"] = ID_VERTEXCOLOUR;mIds["scene_blend"] = ID_SCENE_BLEND;mIds["colour_blend"] = ID_COLOUR_BLEND;    mIds["one"] = ID_ONE;    mIds["zero"] = ID_ZERO;    mIds["dest_colour"] = ID_DEST_COLOUR;    mIds["src_colour"] = ID_SRC_COLOUR;    mIds["one_minus_src_colour"] = ID_ONE_MINUS_SRC_COLOUR;    mIds["one_minus_dest_colour"] = ID_ONE_MINUS_DEST_COLOUR;    mIds["dest_alpha"] = ID_DEST_ALPHA;    mIds["src_alpha"] = ID_SRC_ALPHA;    mIds["one_minus_dest_alpha"] = ID_ONE_MINUS_DEST_ALPHA;    mIds["one_minus_src_alpha"] = ID_ONE_MINUS_SRC_ALPHA;mIds["separate_scene_blend"] = ID_SEPARATE_SCENE_BLEND;mIds["scene_blend_op"] = ID_SCENE_BLEND_OP;    mIds["reverse_subtract"] = ID_REVERSE_SUBTRACT;    mIds["min"] = ID_MIN;    mIds["max"] = ID_MAX;mIds["separate_scene_blend_op"] = ID_SEPARATE_SCENE_BLEND_OP;mIds["depth_check"] = ID_DEPTH_CHECK;mIds["depth_write"] = ID_DEPTH_WRITE;mIds["depth_func"] = ID_DEPTH_FUNC;mIds["depth_bias"] = ID_DEPTH_BIAS;mIds["iteration_depth_bias"] = ID_ITERATION_DEPTH_BIAS;    mIds["always_fail"] = ID_ALWAYS_FAIL;    mIds["always_pass"] = ID_ALWAYS_PASS;    mIds["less_equal"] = ID_LESS_EQUAL;    mIds["less"] = ID_LESS;    mIds["equal"] = ID_EQUAL;    mIds["not_equal"] = ID_NOT_EQUAL;    mIds["greater_equal"] = ID_GREATER_EQUAL;    mIds["greater"] = ID_GREATER;mIds["alpha_rejection"] = ID_ALPHA_REJECTION;mIds["alpha_to_coverage"] = ID_ALPHA_TO_COVERAGE;mIds["light_scissor"] = ID_LIGHT_SCISSOR;mIds["light_clip_planes"] = ID_LIGHT_CLIP_PLANES;mIds["transparent_sorting"] = ID_TRANSPARENT_SORTING;mIds["illumination_stage"] = ID_ILLUMINATION_STAGE;    mIds["decal"] = ID_DECAL;mIds["cull_hardware"] = ID_CULL_HARDWARE;    mIds["clockwise"] = ID_CLOCKWISE;    mIds["anticlockwise"] = ID_ANTICLOCKWISE;mIds["cull_software"] = ID_CULL_SOFTWARE;    mIds["back"] = ID_BACK;    mIds["front"] = ID_FRONT;mIds["normalise_normals"] = ID_NORMALISE_NORMALS;mIds["lighting"] = ID_LIGHTING;mIds["shading"] = ID_SHADING;    mIds["flat"] = ID_FLAT;    mIds["gouraud"] = ID_GOURAUD;    mIds["phong"] = ID_PHONG;mIds["polygon_mode"] = ID_POLYGON_MODE;    mIds["solid"] = ID_SOLID;    mIds["wireframe"] = ID_WIREFRAME;    mIds["points"] = ID_POINTS;mIds["polygon_mode_overrideable"] = ID_POLYGON_MODE_OVERRIDEABLE;mIds["fog_override"] = ID_FOG_OVERRIDE;    mIds["none"] = ID_NONE;    mIds["linear"] = ID_LINEAR;    mIds["exp"] = ID_EXP;    mIds["exp2"] = ID_EXP2;mIds["colour_write"] = ID_COLOUR_WRITE;mIds["max_lights"] = ID_MAX_LIGHTS;mIds["start_light"] = ID_START_LIGHT;mIds["iteration"] = ID_ITERATION;    mIds["once"] = ID_ONCE;    mIds["once_per_light"] = ID_ONCE_PER_LIGHT;    mIds["per_n_lights"] = ID_PER_N_LIGHTS;    mIds["per_light"] = ID_PER_LIGHT;    mIds["point"] = ID_POINT;    mIds["spot"] = ID_SPOT;    mIds["directional"] = ID_DIRECTIONAL;mIds["light_mask"] = ID_LIGHT_MASK;mIds["point_size"] = ID_POINT_SIZE;mIds["point_sprites"] = ID_POINT_SPRITES;mIds["point_size_min"] = ID_POINT_SIZE_MIN;mIds["point_size_max"] = ID_POINT_SIZE_MAX;mIds["point_size_attenuation"] = ID_POINT_SIZE_ATTENUATION;mIds["texture_alias"] = ID_TEXTURE_ALIAS;mIds["texture"] = ID_TEXTURE;    mIds["1d"] = ID_1D;    mIds["2d"] = ID_2D;    mIds["3d"] = ID_3D;    mIds["cubic"] = ID_CUBIC;    mIds["unlimited"] = ID_UNLIMITED;    mIds["alpha"] = ID_ALPHA;    mIds["gamma"] = ID_GAMMA;mIds["anim_texture"] = ID_ANIM_TEXTURE;mIds["cubic_texture"] = ID_CUBIC_TEXTURE;    mIds["separateUV"] = ID_SEPARATE_UV;    mIds["combinedUVW"] = ID_COMBINED_UVW;mIds["tex_coord_set"] = ID_TEX_COORD_SET;mIds["tex_address_mode"] = ID_TEX_ADDRESS_MODE;    mIds["wrap"] = ID_WRAP;    mIds["clamp"] = ID_CLAMP;    mIds["mirror"] = ID_MIRROR;    mIds["border"] = ID_BORDER;mIds["tex_border_colour"] = ID_TEX_BORDER_COLOUR;mIds["filtering"] = ID_FILTERING;    mIds["bilinear"] = ID_BILINEAR;    mIds["trilinear"] = ID_TRILINEAR;    mIds["anisotropic"] = ID_ANISOTROPIC;mIds["max_anisotropy"] = ID_MAX_ANISOTROPY;mIds["mipmap_bias"] = ID_MIPMAP_BIAS;mIds["colour_op"] = ID_COLOUR_OP;    mIds["replace"] = ID_REPLACE;    mIds["add"] = ID_ADD;    mIds["modulate"] = ID_MODULATE;    mIds["alpha_blend"] = ID_ALPHA_BLEND;mIds["colour_op_ex"] = ID_COLOUR_OP_EX;    mIds["source1"] = ID_SOURCE1;    mIds["source2"] = ID_SOURCE2;    mIds["modulate"] = ID_MODULATE;    mIds["modulate_x2"] = ID_MODULATE_X2;    mIds["modulate_x4"] = ID_MODULATE_X4;    mIds["add"] = ID_ADD;    mIds["add_signed"] = ID_ADD_SIGNED;    mIds["add_smooth"] = ID_ADD_SMOOTH;    mIds["subtract"] = ID_SUBTRACT;    mIds["blend_diffuse_alpha"] = ID_BLEND_DIFFUSE_ALPHA;    mIds["blend_texture_alpha"] = ID_BLEND_TEXTURE_ALPHA;    mIds["blend_current_alpha"] = ID_BLEND_CURRENT_ALPHA;    mIds["blend_manual"] = ID_BLEND_MANUAL;    mIds["dotproduct"] = ID_DOT_PRODUCT;    mIds["blend_diffuse_colour"] = ID_BLEND_DIFFUSE_COLOUR;    mIds["src_current"] = ID_SRC_CURRENT;    mIds["src_texture"] = ID_SRC_TEXTURE;    mIds["src_diffuse"] = ID_SRC_DIFFUSE;    mIds["src_specular"] = ID_SRC_SPECULAR;    mIds["src_manual"] = ID_SRC_MANUAL;mIds["colour_op_multipass_fallback"] = ID_COLOUR_OP_MULTIPASS_FALLBACK;mIds["alpha_op_ex"] = ID_ALPHA_OP_EX;mIds["env_map"] = ID_ENV_MAP;    mIds["spherical"] = ID_SPHERICAL;    mIds["planar"] = ID_PLANAR;    mIds["cubic_reflection"] = ID_CUBIC_REFLECTION;    mIds["cubic_normal"] = ID_CUBIC_NORMAL;mIds["scroll"] = ID_SCROLL;mIds["scroll_anim"] = ID_SCROLL_ANIM;mIds["rotate"] = ID_ROTATE;mIds["rotate_anim"] = ID_ROTATE_ANIM;mIds["scale"] = ID_SCALE;mIds["wave_xform"] = ID_WAVE_XFORM;    mIds["scroll_x"] = ID_SCROLL_X;    mIds["scroll_y"] = ID_SCROLL_Y;    mIds["scale_x"] = ID_SCALE_X;    mIds["scale_y"] = ID_SCALE_Y;    mIds["sine"] = ID_SINE;    mIds["triangle"] = ID_TRIANGLE;    mIds["sawtooth"] = ID_SAWTOOTH;    mIds["square"] = ID_SQUARE;    mIds["inverse_sawtooth"] = ID_INVERSE_SAWTOOTH;mIds["transform"] = ID_TRANSFORM;mIds["binding_type"] = ID_BINDING_TYPE;    mIds["vertex"] = ID_VERTEX;    mIds["fragment"] = ID_FRAGMENT;mIds["content_type"] = ID_CONTENT_TYPE;    mIds["named"] = ID_NAMED;    mIds["shadow"] = ID_SHADOW;mIds["texture_source"] = ID_TEXTURE_SOURCE;mIds["shared_params"] = ID_SHARED_PARAMS;mIds["shared_param_named"] = ID_SHARED_PARAM_NAMED;mIds["shared_params_ref"] = ID_SHARED_PARAMS_REF;// Particle systemmIds["particle_system"] = ID_PARTICLE_SYSTEM;mIds["emitter"] = ID_EMITTER;mIds["affector"] = ID_AFFECTOR;// CompositormIds["compositor"] = ID_COMPOSITOR;mIds["target"] = ID_TARGET;mIds["target_output"] = ID_TARGET_OUTPUT;mIds["input"] = ID_INPUT;    mIds["none"] = ID_NONE;    mIds["previous"] = ID_PREVIOUS;    mIds["target_width"] = ID_TARGET_WIDTH;    mIds["target_height"] = ID_TARGET_HEIGHT;    mIds["target_width_scaled"] = ID_TARGET_WIDTH_SCALED;    mIds["target_height_scaled"] = ID_TARGET_HEIGHT_SCALED;    mIds["pooled"] = ID_POOLED;    //mIds["gamma"] = ID_GAMMA; - already registered    mIds["no_fsaa"] = ID_NO_FSAA;    mIds["depth_pool"] = ID_DEPTH_POOL;mIds["texture_ref"] = ID_TEXTURE_REF;mIds["local_scope"] = ID_SCOPE_LOCAL;mIds["chain_scope"] = ID_SCOPE_CHAIN;mIds["global_scope"] = ID_SCOPE_GLOBAL;mIds["compositor_logic"] = ID_COMPOSITOR_LOGIC;mIds["only_initial"] = ID_ONLY_INITIAL;mIds["visibility_mask"] = ID_VISIBILITY_MASK;mIds["lod_bias"] = ID_LOD_BIAS;mIds["material_scheme"] = ID_MATERIAL_SCHEME;mIds["shadows"] = ID_SHADOWS_ENABLED;mIds["clear"] = ID_CLEAR;mIds["stencil"] = ID_STENCIL;mIds["render_scene"] = ID_RENDER_SCENE;mIds["render_quad"] = ID_RENDER_QUAD;mIds["identifier"] = ID_IDENTIFIER;mIds["first_render_queue"] = ID_FIRST_RENDER_QUEUE;mIds["last_render_queue"] = ID_LAST_RENDER_QUEUE;mIds["quad_normals"] = ID_QUAD_NORMALS;    mIds["camera_far_corners_view_space"] = ID_CAMERA_FAR_CORNERS_VIEW_SPACE;    mIds["camera_far_corners_world_space"] = ID_CAMERA_FAR_CORNERS_WORLD_SPACE;mIds["buffers"] = ID_BUFFERS;    mIds["colour"] = ID_COLOUR;    mIds["depth"] = ID_DEPTH;mIds["colour_value"] = ID_COLOUR_VALUE;mIds["depth_value"] = ID_DEPTH_VALUE;mIds["stencil_value"] = ID_STENCIL_VALUE;mIds["check"] = ID_CHECK;mIds["comp_func"] = ID_COMP_FUNC;mIds["ref_value"] = ID_REF_VALUE;mIds["mask"] = ID_MASK;mIds["fail_op"] = ID_FAIL_OP;    mIds["keep"] = ID_KEEP;    mIds["increment"] = ID_INCREMENT;    mIds["decrement"] = ID_DECREMENT;    mIds["increment_wrap"] = ID_INCREMENT_WRAP;    mIds["decrement_wrap"] = ID_DECREMENT_WRAP;    mIds["invert"] = ID_INVERT;mIds["depth_fail_op"] = ID_DEPTH_FAIL_OP;mIds["pass_op"] = ID_PASS_OP;mIds["two_sided"] = ID_TWO_SIDED;#ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERSmIds["rtshader_system"] = ID_RT_SHADER_SYSTEM;#endif}
可以很明显的看出,他将所有脚本里面可能出现的字符串映射到枚举变量之中,保存一一对应关系。

脚本文件的解析,在完成了之前的三个阶段后,Ogre将会根据解析所得的脚本文件类型和结构来创建脚本数据对象,读取相应的脚本数据。为此,Ogre还引入了ScriptTranslator类型,并定义了以下类型MaterialTranslator、TechniqueTranslator、PassTranslator、TextureUnitTranslator、TextureSourceTranslator、GpuProgramTranslator、SharedParamsTranslator、ParticleSystemTranslator、ParticleEmitterTranslator、ParticleAffectorTranslator、CompositorTranslator、CompositionTechniqueTranslator、CompositionTargetPassTranslator和CompositionPassTranslator作为ScriptTranslator类的派生类。这些ScriptTranslator类对象实例由ScriptTranslatorManager来管理。ScriptTranslatorManager作为ScriptCompilerManager的成员变量被保存。


Ogre脚本解析的前两个阶段——“语义分析”的准备工作和“词法分析”是在ScriptCompiler::compile(const String &str, const String &source, const String &group)函数中进行的。而生成AbstractNodeList并进行相关后期处理的过程,则会在ScriptCompiler::compile(const ConcreteNodeListPtr &nodes, const String &group)函数中完成,代码如下:

bool ScriptCompiler::compile(const ConcreteNodeListPtr &nodes, const String &group){// 设置资源组mGroup = group;// 清空错误信息mErrors.clear();// 清空环境mEnv.clear();if(mListener)mListener->preConversion(this, nodes);// 把节点翻译为AbstractNodeAbstractNodeListPtr ast = convertToAST(nodes);// 处理导入部分processImports(ast);// 处理继承部分processObjects(ast.get(), ast);// 处理设置变量部分processVariables(ast.get());// Allows early bail-out through the listenerif(mListener && !mListener->postConversion(this, ast))return mErrors.empty();// 翻译节点for(AbstractNodeList::iterator i = ast->begin(); i != ast->end(); ++i){//logAST(0, *i);if((*i)->type == ANT_OBJECT && reinterpret_cast<ObjectAbstractNode*>((*i).get())->abstract)continue;//LogManager::getSingleton().logMessage(reinterpret_cast<ObjectAbstractNode*>((*i).get())->name);ScriptTranslator *translator = ScriptCompilerManager::getSingleton().getTranslator(*i);if(translator)translator->translate(this, *i);//核心翻译部分,数据读取}mImports.clear();mImportRequests.clear();mImportTable.clear();return mErrors.empty();}
前部分代码的作用,如代码注释一致之前也说过。for循环里面才是真正的翻译部分,首先匹配到合适的翻译器,然后调用translate函数,以材质为例代码如下:
void MaterialTranslator::translate(ScriptCompiler *compiler, const AbstractNodePtr &node){ObjectAbstractNode *obj = reinterpret_cast<ObjectAbstractNode*>(node.get());if(obj->name.empty())compiler->addError(ScriptCompiler::CE_OBJECTNAMEEXPECTED, obj->file, obj->line);// Create a material with the given nameCreateMaterialScriptCompilerEvent evt(node->file, obj->name, compiler->getResourceGroup());bool processed = compiler->_fireEvent(&evt, (void*)&mMaterial);if(!processed){mMaterial = reinterpret_cast<Ogre::Material*>(MaterialManager::getSingleton().create(obj->name, compiler->getResourceGroup()).get());}else{if(!mMaterial)compiler->addError(ScriptCompiler::CE_OBJECTALLOCATIONERROR, obj->file, obj->line, "failed to find or create material \"" + obj->name + "\"");}mMaterial->removeAllTechniques();obj->context = Any(mMaterial);mMaterial->_notifyOrigin(obj->file);for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i){if((*i)->type == ANT_PROPERTY){PropertyAbstractNode *prop = reinterpret_cast<PropertyAbstractNode*>((*i).get());switch(prop->id){case ID_LOD_VALUES:{Material::LodValueList lods;for(AbstractNodeList::iterator j = prop->values.begin(); j != prop->values.end(); ++j){Real v = 0;if(getReal(*j, &v))lods.push_back(v);elsecompiler->addError(ScriptCompiler::CE_NUMBEREXPECTED, prop->file, prop->line,"lod_values expects only numbers as arguments");}mMaterial->setLodLevels(lods);}break;            case ID_LOD_DISTANCES:                {                    // Set strategy to distance strategy                    LodStrategy *strategy = DistanceLodStrategy::getSingletonPtr();                    mMaterial->setLodStrategy(strategy);                    // Read in lod distances                    Material::LodValueList lods;                    for(AbstractNodeList::iterator j = prop->values.begin(); j != prop->values.end(); ++j)                    {                        Real v = 0;                        if(getReal(*j, &v))                            lods.push_back(v);                        else                            compiler->addError(ScriptCompiler::CE_NUMBEREXPECTED, prop->file, prop->line,                                "lod_values expects only numbers as arguments");                    }                    mMaterial->setLodLevels(lods);                }                break;            case ID_LOD_STRATEGY:                if (prop->values.empty())                {                    compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);                }                else if (prop->values.size() > 1)                {                    compiler->addError(ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,                        "lod_strategy only supports 1 argument");                }                else                {                    String strategyName;                    bool result = getString(prop->values.front(), &strategyName);                    if (result)                    {                        LodStrategy *strategy = LodStrategyManager::getSingleton().getStrategy(strategyName);                        result = (strategy != 0);                        if (result)                            mMaterial->setLodStrategy(strategy);                    }                                            if (!result)                    {                        compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,                            "lod_strategy argument must be a valid lod strategy");                    }                }                break;case ID_RECEIVE_SHADOWS:if(prop->values.empty()){compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);}else if(prop->values.size() > 1){compiler->addError(ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,"receive_shadows only supports 1 argument");}else{bool val = true;if(getBoolean(prop->values.front(), &val))mMaterial->setReceiveShadows(val);elsecompiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,"receive_shadows argument must be \"true\", \"false\", \"yes\", \"no\", \"on\", or \"off\"");}break;case ID_TRANSPARENCY_CASTS_SHADOWS:if(prop->values.empty()){compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);}else if(prop->values.size() > 1){compiler->addError(ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,"transparency_casts_shadows only supports 1 argument");}else{bool val = true;if(getBoolean(prop->values.front(), &val))mMaterial->setTransparencyCastsShadows(val);elsecompiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,"transparency_casts_shadows argument must be \"true\", \"false\", \"yes\", \"no\", \"on\", or \"off\"");}break;case ID_SET_TEXTURE_ALIAS:if(prop->values.empty()){compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);}else if(prop->values.size() > 3){compiler->addError(ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,"set_texture_alias only supports 2 arguments");}else{AbstractNodeList::const_iterator i0 = getNodeAt(prop->values, 0), i1 = getNodeAt(prop->values, 1);String name, value;if(getString(*i0, &name) && getString(*i1, &value))mTextureAliases.insert(std::make_pair(name, value));elsecompiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,"set_texture_alias must have 2 string argument");}break;default:compiler->addError(ScriptCompiler::CE_UNEXPECTEDTOKEN, prop->file, prop->line, "token \"" + prop->name + "\" is not recognized");}}else if((*i)->type == ANT_OBJECT){processNode(compiler, *i);}}// Apply the texture aliasesif(compiler->getListener()){PreApplyTextureAliasesScriptCompilerEvent locEvt(mMaterial, &mTextureAliases);compiler->_fireEvent(&locEvt, 0);}mMaterial->applyTextureAliases(mTextureAliases);mTextureAliases.clear();}
在translate函数中,会对传入的AbstractNode的子链表中的结点进行逐一解析,如果子链表中的当前AbstractNode是一个属性类型的结点的话,函数就会根据它的id值,进行相应的数据处理。如果此AbstractNode自身也是一个脚本对象的话就会调用processNode()函数进行处理。processNode函数的核心部分也是一个translate调用,也就是说,实际上实现了一个translate函数的递归调用。processNode函数展开如下:

void ScriptTranslator::processNode(ScriptCompiler *compiler, const AbstractNodePtr &node){if(node->type != ANT_OBJECT)return;// Abstract objects are completely skippedif((reinterpret_cast<ObjectAbstractNode*>(node.get()))->abstract)return;// Retrieve the translator to useScriptTranslator *translator = ScriptCompilerManager::getSingleton().getTranslator(node);if(translator)translator->translate(compiler, node);elsecompiler->addError(ScriptCompiler::CE_UNEXPECTEDTOKEN, node->file, node->line,"token \"" + reinterpret_cast<ObjectAbstractNode*>(node.get())->cls + "\" is not recognized");}
这样,经过一层一层processNode的递归,直到解析完所有对象。


最近也是换工作,在新公司需要重构引擎一些材质相关的部分。这里先抱着学习的态度,记录了一下内容。希望能有进步,感谢原创作者

yzwalkman  http://www.cnblogs.com/yzwalkman/







0 0
原创粉丝点击