o3d基本程序框架-(转 这个比我写的全面)

O3d 是一套开源的javascript API, 用来制作在浏览器中运行的3D 游戏,当然也可以用来展示商家的产品,做一些3D 模型。这系列教程会用一个个例子来展示如何写一个o3d 程序,展示o3d 所能够做的应用。

 


    巧妇难为无米之炊,首先当然需要一些基本的东西,像o3d 插件,这个可以在google code 中获取,给个链接http://code.google.com/intl/zh-CN/apis/o3d/ ,还有O3d 的库文件,这个我是在下载的demo 中直接拷出来了(在本章最后上传的附件中)所需要的基本上就这些了,到后来要导入模型的话就再说了,至于IDE ,哪个写js 写得顺手就是哪个了,我比较喜欢用aptana 。调试的话个人觉得firebug 就已经很强大了,像设置断点,查看局部变量等都很方便了。

 


    这一章介绍一个最基本的o3d 程序应该有的框架,就像在windows 下要写一个最基本的opengl 程序一样,需要建立一个窗口,处理一些键盘和鼠标的消息,设置回调函数,还有建立一个3D 世界所必须的视口等等,刚开始会做很多像这样的初始化和设置工作,像windows 编程一样,一开始可能会让人感到迷茫,这么多繁杂的东西,都不知道是用来干嘛的,为什么不能调用一个函数就搞定一切呢,其实如果搞不懂的话,可以先完全不管这些,正如这章的标题,这只是个框架,你可以从教程中把demo 下下来,作为程序框架,然后在上面改就可以了。随着学习的深入,再回过头去看看,便会逐渐理解那些东西了。

 


    好了,现在开始写一个最基本的o3d 程序吧。

    首先,这个毕竟是在浏览器中运行的,所以一个基本的HTML 结构是必须的,当然还要包含一些基本的js 库文件

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

  "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="content-type" content="text/html; charset=UTF-8">

<title>my first o3d application</title>

<script type="text/javascript" src="o3djs/base.js"></script>

<script type="text/javascript">

// 下面包含一些实用库

o3djs.require('o3djs.util');

o3djs.require('o3djs.math');

o3djs.require('o3djs.rendergraph');

o3djs.require('o3djs.primitives') ;

o3djs.require('o3djs.effect');

o3d 有一系列的库来帮助你简化一些繁琐的活,而你要调用其中的函数的话,只需要调用 o3djs.require('o3djs. ... ') 来包含所需要的类库。比如o3djs.math 中有许多数学运算的方法,进行矩阵的转换等等。

 


    接下来就要设置这个o3d 开始的地方吧(其实就是当页面加载完后回调的函数,一般js 程序都要做的一件事)

// 当页面加载完后调用init() 函数

// 当页面被关掉后调用uninit() 函数

window.onload = init;

window.onunload = uninit;

     在具体实现这两个函数前, 先把接下来要用的一些全局变量定义好

var g_o3d ;

var g_math ;

var g_client ;

var g_pack ;

var g_finished = false ;   // for selenium testing

    


    然后就要定义init ()函数了,这个函数其实就做了一件事,那就是再调用 o3djs.util.makeClients() 函数, 这个函数是已经实现了的,它用来查找在整个html 文档中是否有id 用o3d 开头的元素(像o3d ,o3d_elem,o3d_lang 都是可以的),然后再这个元素里面开辟一块区域( 一个object) ,这个就相当于windows 的窗口了,以后操作都是在这里面进行的,所以这个函数所做的其实跟windows 编程中的建立窗口差不多。

 


    你也可以手工操作在html 中插入一个div

<!-- Start of O3D plugin -->
<div id="o3d" style="width: 600px; height: 600px;"></div>
<!-- End of O3D plugin -->

 

不过makeClients 毕竟是自动化的,它会在开始检测你的浏览器是否装了o3d 插件,你的插件是否过时了等等(很婆妈啊。。。。),然后据说这个函数能够帮你的o3d 应用加速。

    扯了这么多,下面是这个很简洁的init 函数

function init () {
  o3djs . util . makeClients ( initStep2 )
}

makeclients 的参数initStep2 是这个函数执行完毕后的回调函数。也就是说这个函数执行完后就执行initStep2 函数了。

 


如果说Init 函数是用来建立窗口的话,initStep2 函数就是用来初始化视口等这些一个3D 世界必须的东西。这些都可以说是套路吧,你程序不管怎么写,这些操作是必须的。

 


     下面一步步来看initStep2 这个函数:

 


    首先当然是定义这个函数了,clientElements 作为穿进去的参数,是makeClients 在找到id 是o3d 开头的元素后所建立的各个object 。

function initStep2(clientElements) {

   

     接下来就要用到上面定义的各个全局变量了

var o3dElement = clientElements [ 0 ];
g_client = o3dElement . client ;
g_o3d = o3dElement . o3d ;
g_math = o3djs . math ;

    o3dElement 是在HTML 中的一个元素,是DOM 的一部分(即是那个object )

    g_client 是  整个o3d 应用的入口点,

    g_o3d 是o3d 的命名空间,

    g_math 是整个数学库的命名空间。

 


    下面要创建一个包(pack) 来管理所有的对象(object) 和这些对象的生存时间,到后面讲到创建的模型,效果和材质时都是一个个对象。而这些对象就都由这个包来管理了

    g_pack = g_client.createPack();

接下来创建一个渲染图(renderGraph) ,用库函数renderGraph.createBasicView() 产生一个标准的渲染图。这个渲染图有两个绘图列表,一个用于绘制非透明材质的元素(性能绘图列表),另一个用于绘制透明材质元素(透明效果绘图列表)

var viewInfo = o3djs . rendergraph . createBasicView (
    g_pack ,
    g_client . root ,
    g_client . renderGraphRoot );

    然后就是建立绘制背景(drawContext) 。绘制背景定义了投影方式(让一个3d 世界显示在平面的显示器中需要用到投影的知识了,其实就是把3 维坐标系中各个点的坐标乘以一个矩阵,然后就得到一个2 维坐标系的坐标,在游戏编程中基本上用到的只有透视投影),还有照相机的位置,这个照相机只是个比较形象的概念,跟真实世界中相似,3D 世界中的东西最后都是投到这个照相机上,而坐在电脑前的玩家也通过这个照相机看到了一个接近真实的世界。


// 建立一个基本的透视投影
viewInfo . drawContext . projection = g_math . matrix4 . perspective (
   g_math . degToRad ( 30 ),

   g_client . width / g_client . height ,
    1 ,                   // 近切面的Z 轴坐标.
    5000 );               // 远切面的Z 轴坐标.

// 设置照相机
viewInfo . drawContext . view = g_math . matrix4 . lookAt ([ 0 , 1 , 5 ],   // eye
                                                  [ 0 , 0 , 0 ],   // target
                                                  [ 0 , 1 , 0 ]); // up

 

 

lookAt 方法有三个参数,第一个是照相机的位置坐标,第二个是照相机朝向的位置,第三个是照相机朝上位置的向量,比如[0,1,0] 就是正朝上。

 

好了,现在该基本的绘制背景已经设好了,照相机也准备好了,对准了适当的位置,现在就要在照相机前面的这个世界中放入你自己喜欢的东西了。这个要涉及到具体的模型,材质,纹理贴图等等细节了。这章暂不讨论。

 

到这里这章本该差不多结束了,除了在最后加个 unload() 然后把html 中的body 里的东西填一下。但是只是这样的话看不出有什么效果,这个是让人很不爽的,写了这么大堆东西连行不行都不知道,于是至少得在里面加一个东西,看看有什么效果啊。

 


下面这段代码就是用来创造一个球。

var effect = g_pack.createObject('Effect');

   

    var material = g_pack.createObject('Material');

    // Set the material's drawList.

    material.drawList = viewInfo.performanceDrawList;

    

    material.effect = effect;

   

     var shape = o3djs.primitives.createSphere(g_pack, material, 0.5, 20, 20);

   

    // Create a new transform and parent the Shape under it.

       g_cubeTransform = g_pack.createObject('Transform');

      g_cubeTransform.addShape(shape);

      // Parent the cube's transform to the client root.

g_cubeTransform.parent = g_client.root;

 

加一个结束的标志

    g_finished = true ;   // for selenium testing.

}

   


    程序结束调用的uninit() 函数,

function uninit() {

  if (g_client) {

    g_client.cleanup();

  }

}

</script>

</head>

    


    到这里还只是写了Html 中的head ,然后在body 中加入上文提到的id 是o3d 。。。的元素

<body>

<div id="o3d" style="width: 600px; height: 600px;"></div>

</body>

</html>

     到这里一个简单的o3d 程序就完成了。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值