分享
 
 
 

分享——Nebula引擎原理技术讲解

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

Nebula是德国一套开源的3d引擎,具体怎样这里不作评价,相关资料可从网上搜索.

官方网站参见: http://www.radonlabs.de

使用Nebula也算蛮久了, 为了给网站充数点内容,现在来说说它所用到的一些c++相关技术

如何实现一套与脚本紧密联系的对象管理系统(将在后面给出自己仿照nebula而写的完整可运行的程序):

一.基本的思想:

1. 程序中所产生的对象用类似于windows操作系统中的目录结构来管理,

也就是每个对象是一个结点(有对应的名称),每个结点下可以有多个子结点(也有各自对应的名称).如此循环...

2. 程序中有了以上的"目录结构式的对象管理系统", 脚本可通过与程序结合来实现在脚本中调用相应方法来创建

各目录及对象,并可在脚本中通过相应的目录结构名称来访问每一个对象,以及在各对象之间传递消息.当然也可以通过目录

结构名来删除对象(包括其目录下的子对象也会自动删除).

3. 有了以上的一切就有了一套与脚本紧密联系的对象管理系统.下面给出一个使用tcl脚本来撰写的例子参考如下

(这个例子只供参考,具体可实际编译运行通过的例子将在后面详解后给出):

#--------------------------------------------------------------------------

# 创建:

new

nd3d8server

/sys/servers/gfx

# 访问:

sel /sys/servers/gfx

.setdisplaymode

"-type(win)-w(800)-h(600)"

.setclearcolor

0.0 0.0 0.0 0

.setperspective

45 1.33 1.0 10000.0

sel ..

# 删除:

delete /sys/servers/gfx

#--------------------------------------------------------------------------

[说明:]

前面带"#"号的行表示注释.

new 是nebula实现的方法, 可以根据给出的字符串参数产生对应的类型对象

sel 是nebula实现的方法, 可以根据给出的字符串参数选择对应的类型对象, 当参数为".."时表示退到上一层目录

二.具体实现:

首先我们分析要实现如上的脚本目录对象系统所需要的技术:

1. 程序中要实现目录结构的对象管理系统.

2. 要有一套脚本系统,这可以用现成开源的.这里我们选择nebula习惯所用的tcl(当然你可以选择其它)

3. 程序与脚本结合(交互).

下面我们先分别讨论一下nebula是如何如何实现上述各点的:

-- 1.先看如何实现第1点:

a. 首先nebula有一个叫nRoot的类,它是所有对象类的基类,nRoot中有一个名字变量,有一个parent指针指向它的父结点,

还有一个childlist链表保存它所拥有的子结点.因为结点也是nRoot类,所有结点的子结点中也可能有子结点,

这样就形成了一个树形目录结构.nRoot中有一个nRoot* Find( const char* name )方法,功能很简单,就是遍历自已的

childlist链表对比每一个nRoot结点对象的名字,如果相同就返回些对象的指针.

b. 然后nebula还有一个叫nKernelServer的核心管理类,

1) 一开始nKernelServer就产生了一个全局可见的单件对象(单件就是只有一件,也就是全局唯一,你可以把它想象成一个全局的静态对象)

2) 这个nKernelServer对象有一个根据类名字符串来创建对象的方法: CheckCreatePath( const char* szClassName, const char *szPath );

第一个参数是类名字符串,第2个参数就是目录对象名.例如你有一个图形管理类:nGfxServer,你可以创建它的一个对象并起名为"/sys/servers/gfx",

如: ks-CheckCreatePath( "nGfxServer", "/sys/servers/gfx" );[注:ks即nKernelServer的单件对象]因为传的是类名字符串,所以从脚本中写下:

new nGfxServer /sys/servers/gfx

这样的语句时,tcl会把"nGfxServer"字符串返回给nebula的tclcmd_New函数(这个函数是nebula在初始tcl时注册告知tcl的),

然后tclcmd_New通过调用单件ks的CheckCreatePath( "nGfxServer", "/sys/servers/gfx" );方法来创建了这么一个对象.

3) 另外nKernelServer中有一个nRoot* Lookup( const char* szPath )的函数, 功能是你传入目录对象名,它会查到并返回对应对象指针.

4) 当然nKernelServer中还有一个nRoot *cwd变量, 它是用来指向当前目录(或是对象)的,例如,你在脚本中写下:

sel /sys/servers/gfx

这样的语句时,tcl分析到sel时就调用nebula告诉它的tclcmd_Sel函数(如何注册函数告知tcl这是我们在后面第2点的内容), 而tclcmd_Sel函数

会调用上述所说ks-Lookup函数来找到"/sys/servers/gfx"对象的地址,并把它赋给nKernelServer的cwd变量,以后,写下:

.setdisplaymode

"-type(win)-w(800)-h(600)"

.setclearcolor

0.0 0.0 0.0 0

.setperspective

45 1.33 1.0 10000.0

[注意:前面带"."号]

这时,tcl脚本没有这样的用法,于是它就把这些字符串传给一个叫tclcmd_Unknown的函数,nebula在其中分析字符串,把"."与后面的字符串一一分开,

并把"."后的第一个字符串(如:"setdisplaymode")作为nKernelServer的cwd所指向的对象的方法来调用,并传给它接着后面的参数

(如:"-type(win)-w(800)-h(600)").当然要让cwd对象把"setdisplaymode"字符串当成它的函数来调用是比较麻烦的.nebula是如何实现的呢?

我们将在后面第3点祥细说明:), 说了这么多,现在还是让我们来看看一个实现上述目录对象管理系统的代码:

[注: 这是我仿nebula写的简单程序,不考虑效率等问题,只作说明用]

// tnd.cpp : Defines the entry point for the console application.

//

#include

#include

#include

#pragma warning(disable: 4786)

using namespace std;

#ifndef MAX_PATH

# define MAX_PATH 1024

#endif

//----------------------------------------------------------------

class nRoot

{

string

m_strName;

nRoot

*m_pParent;

vector m_vecChild;

public:

nRoot(const char *szName) : m_strName(szName), m_pParent(0){}

nRoot* Find( const char *szName ){

for( unsigned int i=0; i

nRoot *pRoot = m_vecChild[i];

if( 0 == pRoot-m_strName.compare( szName ) ){

return m_vecChild[i];

}

}

return 0;

}

void SetName( const char *szName ){

m_strName = szName;

}

void AddChild( nRoot *pChild ){

m_vecChild.push_back( pChild );

}

};

//----------------------------------------------------------------

class nGfxServer : public nRoot

{

public:

nGfxServer(const char *szName) : nRoot(szName){}

void Test(){

__asm int 3 // 这里是测试看是否到这里中断(vc下支持的写法,其它编译器请用类似std::cout方法代替)

}

};

//----------------------------------------------------------------

class nKernelServer

{

nRoot *m_pRoot;

nRoot *m_pCWD;

nRoot* NewObject( const char *szClassName, const char *szName );

public:

nKernelServer(){

this-m_pRoot = new nRoot("/");

this-m_pCWD = this-m_pRoot;

}

nRoot* CheckCreatePath( const char* szClassName, const char *szPath );

nRoot* Lookup( const char* szPath );

void SetCwd( nRoot *o ){

this-m_pCWD = o ? o : this-m_pRoot;

}

};

static nKernelServer g_ks;

//----------------------------------------------------------------

//----------------------------------------------------------------

nRoot* nKernelServer::CheckCreatePath( const char* szClassName, const char *szPath )

{

nRoot* parent = 0;

nRoot* child

= 0;

if( '/' == szPath[0] ){ // AbsolutePath

parent = this-m_pRoot;

}else{

parent = this-m_pCWD;

}

char strBuf[MAX_PATH];

strcpy(strBuf, szPath);

char *pNextPathComponent = NULL;

char *pCurrPathComponent = strtok(strBuf, "/");

if( pCurrPathComponent )

{

// for each directory path component

while( (pNextPathComponent = strtok(NULL, "/") ))

{

child = parent-Find( pCurrPathComponent );

if (!child)

{

child = new nRoot( pCurrPathComponent );

parent-AddChild( child );

}

parent = child;

pCurrPathComponent = pNextPathComponent;

}

}

// curPathComponent is now name of last path component

child = parent-Find( pCurrPathComponent );

if (!child)

{

child = (nRoot*) this-NewObject( szClassName, pCurrPathComponent );

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有