OGRE 材质脚本解析的分析

material 08-Default
{
	technique
	{
		pass
		{
			ambient 0.588235 0.588235 0.588235 1
			diffuse 0.588235 0.588235 0.588235 1
			specular 0 0 0 1 10

			texture_unit
			{
				texture liuxing1.bmp
			}
		}

	}

}

上述材质脚本,OGRE 解析是在如下函数中

	bool ScriptCompiler::compile(const String &str, const String &source, const String &group)
	{
		ScriptLexer lexer;
		ScriptParser parser;
		ConcreteNodeListPtr nodes = parser.parse(lexer.tokenize(str, source));
		return compile(nodes, group);
	}

输入的 str 就是最上边的材质脚本,已经处理为一个字符串。整个解析分3步。

1、lexer.tokenize(str, source))。进行词法分析,输出为一个词数组。结构为:

	/** This struct represents a token, which is an ID'd lexeme from the
		parsing input stream.
	*/
	struct ScriptToken
	{
		/// This is the lexeme for this token
		String lexeme, file;
		/// This is the id associated with the lexeme, which comes from a lexeme-token id mapping
		uint32 type;
		/// This holds the line number of the input stream where the token was found.
		uint32 line;
	};
	typedef SharedPtr<ScriptToken> ScriptTokenPtr;
	typedef vector<ScriptTokenPtr>::type ScriptTokenList;
	typedef SharedPtr<ScriptTokenList> ScriptTokenListPtr;


处理的字符数组剔除了空格,保留了换行符(10)。处理的字符数组剔除了空格,保留了换行符(10)。处理的字符数组剔除了空格,保留了换行符(10)。

2、parser.parse()。进行类似CST(Concrete Syntax Tree) 分析,输出为一个语法节点,结构如下:

	/** The ConcreteNode is the struct that holds an un-conditioned sub-tree of parsed input */
	struct ConcreteNode;
	typedef SharedPtr<ConcreteNode> ConcreteNodePtr;
	typedef list<ConcreteNodePtr>::type ConcreteNodeList;
	typedef SharedPtr<ConcreteNodeList> ConcreteNodeListPtr;
	struct ConcreteNode : public ScriptCompilerAlloc
	{
		String token, file;
		unsigned int line;
		ConcreteNodeType type;
		ConcreteNodeList children;
		ConcreteNode *parent;
	};

该语法树已经剔除了换行符,输出节点实例如下:

 

material
 
--- 08-Default
 
---{   父节点A
 
---}
 
     父节点A
 
    technique
 
    --- {  父节点B
 
    --- }
 
          父节点B
 
          pass
 
          --- {  父节点C
 
          --- }
 
                 父节点C
 
                 --- ambient 

                      --- 0.588235
 
                      --- 0.588235 

                      --- 0.588235
 
                      --- 1
 
                --- diffuse 

                     --- 0.588235 

                     --- 0.588235  

                     --- 0.588235
 
                     --- 1
 
                --- specular 

                     ---  0
 
                     ---  0
 
                     ---  0
 
                     ---  1
 
                     --- 10
 
                 --- texture_unit
 
                      --- { 父节点D
 
                      --- }
 
                             父节点D 

                              texture
 
                              --- liuxing1.bmp


 3、return compile(nodes, group)。实际包含两步:进行类似AST(Abstract  Syntax Tree) 分析; 之后把AST信息转化为Material。

 3.1 AST。所用的结构为:

	class _OgreExport AbstractNode : public AbstractNodeAlloc
	{
	public:
		String file;
		unsigned int line;
		AbstractNodeType type;
		AbstractNode *parent;
		Any context; // A holder for translation context data
	public:
		AbstractNode(AbstractNode *ptr);
		virtual ~AbstractNode(){}
		/// Returns a new AbstractNode which is a replica of this one.
		virtual AbstractNode *clone() const = 0;
		/// Returns a string value depending on the type of the AbstractNode.
		virtual String getValue() const = 0;
	};

context 为 Any 类型, 在3.2步根据具体的类型进行相应的转换。
它有众多子类,列举几个: 

	/** This specific abstract node represents a script object */
	class _OgreExport ObjectAbstractNode : public AbstractNode
	{
	private:
		map<String,String>::type mEnv;
	public:
		String name, cls;
		std::vector<String> bases;
		uint32 id;
		bool abstract;
		AbstractNodeList children;
		AbstractNodeList values;
		AbstractNodeList overrides; // For use when processing object inheritance and overriding
	public:
		ObjectAbstractNode(AbstractNode *ptr);
		AbstractNode *clone() const;
		String getValue() const;

		void addVariable(const String &name);
		void setVariable(const String &name, const String &value);
		std::pair<bool,String> getVariable(const String &name) const;
		const map<String,String>::type &getVariables() const;
	};

其中 name = "08-Default", cls  即类名 material, id 为该类的标志ID。

	/** This abstract node represents a script property */
	class _OgreExport PropertyAbstractNode : public AbstractNode
	{
	public:
		String name;
		uint32 id;
		AbstractNodeList values;
	public:
		PropertyAbstractNode(AbstractNode *ptr);
		AbstractNode *clone() const;
		String getValue() const;
	};

以及

	/** This is an abstract node which cannot be broken down further */
	class _OgreExport AtomAbstractNode : public AbstractNode
	{
	public:
		String value;
		uint32 id;
	public:
		AtomAbstractNode(AbstractNode *ptr);
		AbstractNode *clone() const;
		String getValue() const;
	private:
		void parseNumber() const;
	};


  

经过   AbstractNodeListPtr ast = convertToAST(nodes); 处理后,材质脚本实例为

  1>  ObjectAbstractNode .

          name = "08-Default",  cls="material", id = 3. child 指向下一级, 有1个子节点。

  2> ObjectAbstractNode .

          name = "",  cls="technique", id = 7. child 指向下一级, 有1个子节点。

  3>  ObjectAbstractNode .

          name = "",  cls="pass", id = 8. child 指向下一级, 有4个子节点。

  4>  PropertyAbstractNode. 有3个,分别为 ambient, diffuse, specular

          name = "ambient",   id = 37. values 有4个值,指向下一级。

ObjectAbstractNode . 有一个,即纹理

name = "", cls="texture_unit", id = 9. child 指向下一级, 有1个子节点, 为PropertyAbstractNode,不再列举了。

5> AtomAbstractNode

value = "0.588235", id = 0.

3.2 做了2件事。

A 获得AbstractNode对应的ScriptTranslator:

ScriptTranslator *translator = ScriptCompilerManager::getSingleton().getTranslator(*i);

B 根据ScriptTranslator 生成 material。注意:生成的material各相关量保存在AbstractNode的Any类型的变量context中。

 

CSDN 真垃圾,编辑器现在又乱了,代码和普通文字已经区分不开。

 

 


 





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值