OGRE脚本解析流程分析扫描阶段

Ogre的脚本解析分为以下步骤:

TOKEN化阶段

这个阶段主要是进行预处理,忽略空格并去掉注释,并将有用的脚本数据整理到ScriptTokenList结构中以供下阶段使用。

在OgreScriptLexer.cpp 中有一函数ScriptLexer::tokenize完成此功能。

这里有两个关键的数据结构

//Token结构

struct ScriptToken

{

  String lexeme;     //token内容

  String file;       //脚本文件名  

  uint32 type;       //token类型

  uint32 line;      //token所在文件行号

}

typedef SharedPtr<ScriptToken> ScriptTokenPtr;

//Token容器

typedef vector<ScriptTokenPtr>::type ScriptTokenList;

比如example.program中有如下数据

//example 脚本

vertex_program AmbientOneTexture cg

{

  source Example_Basic.cg

}

token化后,ScriptTokenList中每一个ScriptToken结构中的lexeme成员为如下数据:

"vertex_program",

"AmbientOneTexture",

"cg",

"{",

"source",

"Example_Basic.cg",

"}"

PARSE阶段  

token阶段只是将有用的数据存入ScriptTokenList,数据之间仅仅是线性平行关系。在PARSE阶段,Ogre将数据进一步处理,形成树状层次关系

还是先介绍该阶段的基本数据结构

struct ConcreteNode:public ScriptCompilerAlloc

{

  String token,file;

  unsigned int line;

  ConcreteNodeType type;

  ConcreteNodeList children;

  ConcreteNode* parent;

};

typedef SharedPtr<ConcreteNode> ConcreteNodePtr;

typedef list<ConcreteNodePtr>::type ConcreteNodeList;

很显然,PARSE阶段实质上就是生成ConcreteNodeList数据。

材质脚本解析

分析之前先简单介绍下材质脚本的结构。一个典型的material脚本如下:

material Core/NodeMaterial

{

  technique

  {

    pass

    {

      lighting off

      scene_blend add

      depth_check off

      depth_write off

      cull_hardware none

      texture_unit

      {

        texture axes.png

      }

    }

  }

}

可见,material是一个层次结构,一个material可以包含若干个technique,一个technique包含若干个pass,一个pass包含若干个texture,一个texture对应一张picture。

材质脚本解析器读取*.material文件,生成相应的Material对象,并读取其中的technique,pass,赋值给材质对象(Material)统一管理。所以,Ogre的Shader由材质对象(Material)管理。

解析material文件主要由两个函数完成:

void MaterialSerializer::parseScript(DataStreamPtr& stream,const String& groupName)

bool MaterialSerializer::parseScriptLine(String& line)

经过这两个函数的处理,系统就已经把material脚本读取并生成material对象,并添加到resourcegroup以备以后加载资源和渲染。注意,material中的材质单元在解析阶段默认是不会加载到显存中的。

原文地址:https://www.cnblogs.com/billin/p/2089128.html