首页>
技术资讯>
详情

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

2016-05-27 来源:CloudBest 阅读量: 1,419
关键词: 程序设计


  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
  //--------------------------------------

热门推荐 查看更多