starling教程-显示列表(The Display List )(二)

显示列表

starling和flash本地的显示列表有一样的规则,在没有东西添加进stage之前,stage是null的。在本地flash中,为了能更安全的使用stage,我们通常使用一些Flash中的重要的事件,这些事件在starling中同样可用:

•  Event.ADDED : the object was added to a parent. •  Event.ADDED_TO_STAGE  : the object was added to a parent that is connected to the stage, thus becoming visible now. •  Event.REMOVED : the object was removed from a parent. •  Event.REMOVED_FROM_STAGE  : the object was removed from a parent that is connected to the stage, thus becoming invisible now.

在下面的例子中,我们会经常用到这些事件,就像在flash中一样,这些事件可以用在初始化,组件销毁等很多重要的地方。

下面是DisplayObject类声明的部分方法列表:

•  removeFromParent : Removes the object from its parent, if it has one. •  getTransformationMatrixToSpace :  Creates a matrix that represents the transformation from the local coordinate system to another. •  getBounds : Returns a rectangle that completely encloses the object as it appears in another coordinate system. •  hitTestPoint : Returns the object that is found topmost on a point in local coordinates, or nil if the test fails. •  globalToLocal : Transforms a point from global (stage) coordinates to the local coordinate system. •  localToGlobal : Transforms a point from the local coordinate system to global (stage) coordinates.

下面是DisplayObject类声明的部分属性,让人高兴的是大部分的属性都和flash本事的display一样,并且还有一些拓展的属性,比如用来动态改变一个DisplayObject类注册点的pivotX和pivotY,如下:

•  transformationMatrix : The transformation matrix of the object relative to its parent. •  bounds : The bounds of the object relative to the local coordinates of the parent. •  width : The width of the object in points. •  height : The height of the object in points. •  root : The topmost object in the display tree the object is part of. •  x : The x coordinate of the object relative to the local coordinates of the parent. •  y : The y coordinate of the object relative to the local coordinates of the parent. •  pivotX : The x coordinate of the object’s origin in its own coordinate space (default: 0). •  pivotY : The y coordinate of the object’s origin in its own coordinate space (default: 0). •  scaleX : The horizontal scale factor. “1” means no scale, negative values flip the object. •  scaleY : The vertical scale factor. “1” means no scale, negative values flip the object. •  rotation : The rotation of the object in radians. (In Sparrow, all angles are measured in radians.) •  alpha : The opacity of the object. •  visible : The visibility of the object. An invisible object will be untouchable. •  touchable : Indicates if this object (and its children) will receive touch events. •  parent : The display object container that contains this display object. •  stage : The stage the display object is connected to, or null if it is not connected to a stage.

就像在flash本地的api中一样,Sprite是你可以使用的最轻量级的容器。Sprite继承自DisplayObjectContainer, 而DisplayObjectContainer继承自DisplayObject,我们的例子中的Game都是集成字Sprite的,是一个DisplayObjectContainer。

下面是DisplayObjectContainer的一部分api:

•  addChild : Adds a child to the container. It will be at the topmost position. •  addChildAt : Adds a child to the container at a certain index. •  dispose : Removes the GPU buffers and all the listeners registered to the o •  removeFromParent : Removes the child from its parent. •  removeChild : Removes a child from the container. If the object is not a ch •  removeChildAt : Removes a child at a certain index. Children above the c •  removeChildren : Removes all children from the container. •  getChildAt : Returns a child object at a certain index. •  getChildByName : Returns a child object with a certain name (non-recursi •  getChildIndex : Returns the index of a child within the container. •  setChildIndex : Changes the index of the specified child.

•  swapChildren : Swaps the indexes of two children. •  swapChildrenAt : Swaps the indexes of two children. •  contains : Determines if a certain object is a child of the container (recursively).

一旦你进入了stage之后你就可以使用绝大部分DisplayObjectContainer的api,当然了你可以为stage设置一个颜色。Starling默认会采用SWF的背景色,你可以通过设置下面的SWF标签来实现:

[SWF(width="1280", height="752", frameRate="60", backgroundColor="#990000")]

你也可以通过stage对象来手工设置一个颜色,stage对象可以通过任意一个添加到显示列表中的DisplayObject对象中获得:

 1 package
 2 {
 3     import starling.display.Quad;
 4     import starling.display.Sprite;
 5     import starling.events.Event;
 6
 7     public class Game extends Sprite
 8     {
 9       private var q:Quad;
10
11         public function Game()
12         {
13       addEventListener(Event.ADDED_TO_STAGE, onAdded);
14         }
15
16     private function onAdded ( e:Event ):void
17     {
18       // set the background color to blue
19       stage.color = 0x002143;
20
21       q = new Quad(200, 200);
22       q.setVertexColor(0, 0x000000);
23       q.setVertexColor(1, 0xAA0000);
24       q.setVertexColor(2, 0x00FF00);
25       q.setVertexColor(3, 0x0000FF);
26       addChild ( q );
27     }
28     }
29 } 

现在我们还没有使用任何texture(纹理),我们主要是用两个三角形拼了一个Quad,并且每个顶点拥有不同的颜色(会自动篡改成gpu可识别的颜色)。

当然了你可以调用quad的color属性来实现纯色的quad:

 1 package    2 {   3     import starling.display.Quad;   4     import starling.display.Sprite;   5     import starling.events.Event;   6    7     public class Game extends Sprite   8     {   9     private var q:Quad;  10       11         public function Game()  12         {    13       addEventListener(Event.ADDED_TO_STAGE, onAdded);  14         }  15       16     private function onAdded ( e:Event ):void  17     {  18       q = new Quad(200, 200);  19       q.color = 0x00FF00;  20       q.x = stage.stageWidth - q.width >> 1;  21       q.y = stage.stageHeight - q.height >> 1;  22       addChild ( q );  23     }  24     }  25 } 

效果如下:

下面我们来使用Event.ENTER_FRAME事件修改quad的颜色来实现一个简单缓动特效:

 1 package
 2 {
 3   import starling.display.Quad;
 4     import starling.display.Sprite;
 5     import starling.events.Event;
 6
 7     public class Game extends Sprite
 8   {
 9     private var q:Quad;
10
11     private var r:Number = 0;
12     private var g:Number = 0;
13     private var b:Number = 0;
14
15     private var rDest:Number;
16     private var gDest:Number;
17     private var bDest:Number;
18
19         public function Game()
20         {
21       addEventListener(Event.ADDED_TO_STAGE, onAdded);
22         }
23
24     private function onAdded ( e:Event ):void
25     {
26       resetColors();
27
28       q = new Quad(200, 200);
29       q.x = stage.stageWidth - q.width >> 1;
30       q.y = stage.stageHeight - q.height >> 1;
31       addChild ( q );
32
33       s.addEventListener(Event.ENTER_FRAME, onFrame);
34     }
35
36     private function onFrame (e:Event):void
37     {
38       r -= (r - rDest) * .01;
39       g -= (g - gDest) * .01;
40       b -= (b - bDest) * .01;
41
42       var color:uint = r << 16 | g << 8 | b;
43       q.color = color;
44
45       // when reaching the color, pick another one
46       if ( Math.abs( r - rDest) < 1 && Math.abs( g - gDest) < 1 && Math.abs( b - bDest) )
47         resetColors();
48     }
49
50     private function resetColors():void
51     {
52       rDest = Math.random()*255;
53       gDest = Math.random()*255;
54       bDest = Math.random()*255;
55     }
56     }
57 }

我们可以使用rotation这个属性来旋转quad,但是注意,在Starling中使用的是弧度而Flash Player中使用的是角度。这样做是为了保持Sparrow和Starling的一致性(Sparrow是Strarling的姊妹篇,同一作者)。如果你想使用度数来实现旋转的话,只要使用 starling.utils.deg2rad 这个放来来转换一下就可以了:

sprite.rotation = deg2rad(Math.random()*360);

我们可以在运行时设置DisplayObject的pivotX和pivotY属性来改变注册点:

q.pivotX = q.width >> 1; q.pivotY = q.height >> 1;

对于as3开发者来说使用starling会感觉很自然,下面的这个例子,一个quad和一个textfield被添加到一个sprite中,并且可以作为一个组合一起移动,这和我们使用本地的显示列表时一样的:

package   {      import starling.display.DisplayObject;      import starling.display.Quad;      import starling.display.Sprite;      import starling.events.Event;      import starling.text.TextField;        public class Game extends Sprite      {      private var q:Quad;      private var s:Sprite;            private var r:Number = 0;      private var g:Number = 0;      private var b:Number = 0;            private var rDest:Number;      private var gDest:Number;      private var bDest:Number;                public function Game()          {          addEventListener(Event.ADDED_TO_STAGE, onAdded);          }            private function onAdded ( e:Event ):void      {        resetColors();                q = new Quad(200, 200);                s = new Sprite();                var legend:TextField = new TextField(100, 20, "Hello Starling!", "Arial", 14, 0xFFFFFF);                s.addChild(q);        s.addChild(legend);                s.pivotX = s.width >> 1;        s.pivotY = s.height >> 1;                s.x = (stage.stageWidth - s.width >> 1 ) + (s.width >> 1);        s.y = (stage.stageHeight - s.height >> 1) + (s.height >> 1);                addChild(s);          s.addEventListener(Event.ENTER_FRAME, onFrame);      }            private function onFrame (e:Event):void      {          r -= (r - rDest) * .01;        g -= (g - gDest) * .01;        b -= (b - bDest) * .01;                var color:uint = r << 16 | g << 8 | b;        q.color = color;                // when reaching the color, pick another one        if ( Math.abs( r - rDest) < 1 && Math.abs( g - gDest) < 1 && Math.abs( b - bDest) )          resetColors();                (e.currentTarget as DisplayObject).rotation += .01;      }            private function resetColors():void      {        rDest = Math.random()*255;        gDest = Math.random()*255;        bDest = Math.random()*255;      }            }  } 

我们现在围绕着注册点旋转这个包含quad和textfield的sprite:

我们的代码现在看起来开始有些杂乱了,那么我们提取一些代码来组建一个CustomSprite类,用这个类封装颜色的变化、quad和textfield。代码如下:

 1 package
 2 {
 3     import starling.display.Quad;
 4 import starling.display.Sprite;
 5 import starling.events.Event;
 6 import starling.text.TextField;
 7  public class CustomSprite extends Sprite
 8  {
 9   private var quad:Quad;
10   private var legend:TextField;
11
12   private var quadWidth:uint;
13   private var quadHeight:uint;
14
15   private var r:Number = 0;
16   private var g:Number = 0;
17   private var b:Number = 0;
18
19   private var rDest:Number;
20   private var gDest:Number;
21   private var bDest:Number;
22
23   public function CustomSprite(width:Number, height:Number, colo
24   {
25     // reset the destination color component
26     resetColors();
27
28     // set the width and height
29     quadWidth = width;
30     quadHeight = height;
31
32     // when added to stage, activate it
33     addEventListener(Event.ADDED_TO_STAGE, activate);
34   }
35
36   private function activate(e:Event):void
37   {
38     // create a quad of the specified width
39     quad = new Quad(quadWidth, quadHeight);
40     // add the legend
41     legend = new TextField(100, 20, "Hello Starling!", "Arial
42
43     // add the children
44     addChild(quad);
45     addChild(legend);
46
47     // change the registration point
48     pivotX = width >> 1;
49     pivotY = height >> 1;
50   }
51
52   private function resetColors():void
53   {
54     // pick random color components
55     rDest = Math.random()*255;
56     gDest = Math.random()*255;
57     bDest = Math.random()*255;
58   }
59
60   /**
61    * Updates the internal behavior
62    *
63    */
64     public function update ():void
65     {
66       // easing on the components
67       r -= (r - rDest) * .01;
68       g -= (g - gDest) * .01;
69       b -= (b - bDest) * .01;
70
71       // assemble the color
72       var color:uint = r << 16 | g << 8 | b;
73       quad.color = color;
74
75       // when reaching the color, pick another one
76       if ( Math.abs( r - rDest) < 1 && Math.abs( g - gDest) < 1 && Math.abs( b - bDest) )
77         resetColors();
78
79       // rotate it!
80       //rotation += .01;
81     }
82   }
83 } 

这样的话,我们的Game类变为这样:

 1 package    2 {   3   import starling.display.Sprite;   4     import starling.events.Event;   5    6     public class Game extends Sprite   7     {   8     private var customSprite:CustomSprite;   9       10         public function Game()  11         {    12       addEventListener(Event.ADDED_TO_STAGE, onAdded);  13         }  14       15     private function onAdded ( e:Event ):void  16     {  17       // create the custom sprite  18       customSprite = new CustomSprite(200, 200);  19         20       // positions it by default in the center of the stage  21       // we add half width because of the registration point of the custom sprite (middle)  22       customSprite.x = (stage.stageWidth - customSprite.width >> 1 ) + (customSprite.width >> 1);  23       customSprite.y = (stage.stageHeight - customSprite.height >> 1) + (customSprite.height >> 1);  24         25       // show it  26       addChild(customSprite);  27   28       // need to comment this one ? ;)  29       stage.addEventListener(Event.ENTER_FRAME, onFrame);  30     }  31       32     private function onFrame (e:Event):void  33     {        34       // we update our custom sprite   35       customSprite.update();  36     }  37     }  38 } 

注意,我们使用CustomSprite中的update方法来在主sprite中进行循环操作(即一个组建提取的概念), 通过使用这样的方法,我们增加一个全局暂停的方法将会变的很简单。

让我们来给我们的小测试增加一些功能,让我们的quad跟随鼠标移动。在下面的代码中,我们新增了一小段代码来实现这个功能:

 1 package
 2 {
 3     import flash.geom.Point;
 4
 5     import starling.display.Sprite;
 6     import starling.events.Event;
 7     import starling.events.Touch;
 8     import starling.events.TouchEvent;
 9
10     public class Game extends Sprite
11     {
12     private var customSprite:CustomSprite;
13     private var mouseX:Number = 0;
14     private var mouseY:Number = 0;
15
16         public function Game()
17         {
18       addEventListener(Event.ADDED_TO_STAGE, onAdded);
19         }
20
21     private function onAdded ( e:Event ):void
22     {
23       // create the custom sprite
24       customSprite = new CustomSprite(200, 200);
25
26       // positions it by default in the center of the stage
27       // we add half width because of the registration point of the custom sprite (middle)
28       customSprite.x = (stage.stageWidth - customSprite.width >> 1 ) + (customSprite.width >> 1);
29       customSprite.y = (stage.stageHeight - customSprite.height >> 1) + (customSprite.height >> 1);
30
31       // show it
32       addChild(customSprite);
33
34       // we listen to the mouse movement on the stage
35       stage.addEventListener(TouchEvent.TOUCH, onTouch);
36       // need to comment this one ? ;)
37       stage.addEventListener(Event.ENTER_FRAME, onFrame);
38     }
39
40     private function onFrame (e:Event):void
41     {
42       // easing on the custom sprite position
43          customSprite.x -= ( customSprite.x - mouseX ) * .1;
44       customSprite.y -= ( customSprite.y - mouseY ) * .1;
45
46       // we update our custom sprite
47       customSprite.update();
48     }
49
50     private function onTouch (e:TouchEvent):void
51     {
52       // get the mouse location related to the stage
53       var touch:Touch = e.getTouch(stage);
54       var pos:Point = touch.getLocation(stage);
55       // store the mouse coordinates
56       mouseX = pos.x;
57       mouseY = pos.y;
58     }
59     }
60 } 

这里需要注意的是,我们没有使用任何鼠标事件,实际上在starling中没有鼠标的概念。下面将会很快提到这里(event模块)。

通过监听 TouchEvent.TOUCH事件,我们可以处理任何鼠标/手指的运动(starling的设计其实目标很明确就是照着平板去的,让你的程序技能在pc有很好的交互,到了平板上依旧ok,不用重复编码)。比如典型的MousEvent.MOUSE_MOVE事件。上例中,我们使用TouchEvent监听来获得鼠标位置,并存贮到变量中,然后在frame监听中使用简单的赋值来移动customSprite。

就像前面提到的,Starling不只是可以简化gpu编程,并且简化了对象的释放操作。假设我们想要在点击的quad的时候将它从场景中移除,代码如下:

 1 package    2 {   3     import flash.geom.Point;   4    5     import starling.display.DisplayObject;   6     import starling.display.Sprite;   7     import starling.events.Event;   8     import starling.events.Touch;   9     import starling.events.TouchEvent;  10     import starling.events.TouchPhase;  11   12     public class Game extends Sprite  13     {  14     private var customSprite:CustomSprite;  15     private var mouseX:Number = 0;  16     private var mouseY:Number = 0;  17       18         public function Game()  19         {    20       addEventListener(Event.ADDED_TO_STAGE, onAdded);  21         }  22       23     private function onAdded ( e:Event ):void  24     {  25       // create the custom sprite  26       customSprite = new CustomSprite(200, 200);  27         28       // positions it by default in the center of the stage  29       // we add half width because of the registration point of the custom sprite (middle)  30       customSprite.x = (stage.stageWidth - customSprite.width >> 1 ) + (customSprite.width >> 1);  31       customSprite.y = (stage.stageHeight - customSprite.height >> 1) + (customSprite.height >> 1);  32         33       // show it  34       addChild(customSprite);  35   36       // we listen to the mouse movement on the stage  37       stage.addEventListener(TouchEvent.TOUCH, onTouch);  38       // need to comment this one ? ;)  39       stage.addEventListener(Event.ENTER_FRAME, onFrame);  40         // when the sprite is touched  41         customSprite.addEventListener(TouchEvent.TOUCH, onTouchedSprite);  42     }  43   44     private function onFrame (e:Event):void  45     {  46       // easing on the custom sprite position  47         customSprite.x -= ( customSprite.x - mouseX ) * .1;  48       customSprite.y -= ( customSprite.y - mouseY ) * .1;  49   50       // we update our custom sprite  51       customSprite.update();  52     }  53   54     private function onTouch (e:TouchEvent):void  55     {  56       // get the mouse location related to the stage  57       var touch:Touch = e.getTouch(stage);  58       var pos:Point = touch.getLocation(stage);  59   60       // store the mouse coordinates  61       mouseX = pos.x;  62       mouseY = pos.y;  63     }  64   65         private function onTouchedSprite(e:TouchEvent):void  66         {  67             // get the touch points (can be multiple because of multitouch)  68             var touch:Touch = e.getTouch(stage);  69             var clicked:DisplayObject = e.currentTarget as DisplayObject;  70   71             // detect the click/release phase  72             if ( touch.phase == TouchPhase.ENDED )  73             {  74                 // remove the clicked object  75                 removeChild(clicked);  76             }  77         }  78     }  79 } 

注意在这里我们移除了子对象但是并没有移除Event.ENTER_FRAME监听,我们可以使用hasEventListener来看看customSprite的监听是否被移除掉了:

 1 private function onTouchedSprite(e:TouchEvent):void
 2 {
 3   // get the touch points (can be multiple because of multitouch)
 4   var touch:Touch = e.getTouch(stage);
 5   var clicked:DisplayObject = e.currentTarget as DisplayObject;
 6
 7     // detect the click/release phase
 8     if ( touch.phase == TouchPhase.ENDED )
 9     {
10          // remove the clicked object
11          removeChild(clicked);
12
13      // outputs : true
14      trace ( clicked.hasEventListener(e.type) );
15     }
16 } 

为了能安全的移除子对象,你可以启用removeChild方法中的第二个参数dispose。它可以自动的将被删除的子对象的所有监听移除:

 1 private function onTouchedSprite(e:TouchEvent):void   2 {   3   // get the touch points (can be multiple because of multitouch)   4   var touch:Touch = e.getTouch(stage);   5   var clicked:DisplayObject = e.currentTarget as DisplayObject;   6    7     // detect the click/release phase   8     if ( touch.phase == TouchPhase.ENDED )   9     {  10     // remove and dispose all the listeners  11     removeChild(clicked, true);  12   13     // outputs : false  14     trace ( clicked.hasEventListener(e.type) );  15     }  16 } 

如果子对象也是一个容器,还包含着其他子对象,那么这些所有的对象也都将被移除掉(是不是非常方便!)。其他用来移除对象的api也可以使用dispose参数,比如:removeChildren或者removeChildAt。这里需要注意的是dispose操作也会清除掉gpu针对该对象的缓冲,但是该对象的texture不会被清除(为了复用嘛,并且starling中的texture和本地对象中的bitmapdata类似)。你可以通过调用Texture/TextureAtlas的dispose方法来释放texture。

你也可以通过调用任何DisplayObject对象的dispose方法来移除对象的所有监听:

1 clicked.dispose() 
时间: 2024-10-13 10:19:58

starling教程-显示列表(The Display List )(二)的相关文章

OpenGL显示列表

OpenGL显示列表(Display List)是由一组预先存储起来的留待以后调用的OpenGL函数语句组成的,当调用这张显示列表时就依次执行表中所列出的函数语句.前面内容所举出的例子都是瞬时给出函数命令,则OpenGL瞬时执行相应的命令,这种绘图方式叫做立即或瞬时方式(immediate mode).本章将详细地讲述显示列表的基本概论.创建.执行.管理以及多级显示列表的应用等内容. 16.1.显示列表概论     16.1.1 显示列表的优势 OpenGL显示列表的设计能优化程序运行性能,尤其

NeHe OpenGL教程 第十二课:显示列表

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第十二课:显示列表 显示列表: 想知道如何加速你的OpenGL程序么?这一课将告诉你如何使用OpenGL的显示列表,它通过预编译OpenGL命令来加速你的程序,并可以为你省去很多重复的代码. 这次我将教你如何使用显示列表,显示列表将

计算机图形学(二)输出图元_18_显示列表_1_创建和命名OpenGL显示表

OpenGL显示列表 把对象描述成一个命名的语句序列(或任何其他的命令集)并存储起来既方便又高效.在OpenGL中使用称为显示表(display list)的结构可以做到这一点.一旦建立了显示表,就可以用不同的显示操作来多次引用该表.在网格中,描述图形的显示表存放在服务器中,以避免每次显示场景时都要传送表中的命令.我们可以为以后的执行来建立并存储显示表,或指定表中的命令立即执行.显示表对层次式建模特别有用,因为一个复杂的对象可以用一组简单的对象来描述. 创建和命名OpenGL显示表 使用glNe

SeaJS入门教程系列之使用SeaJS(二)

SeaJS入门教程系列之使用SeaJS(二) 作者: 字体:[增加 减小] 类型:转载 时间:2014-03-03我要评论 这篇文章主要介绍了SeaJS入门教程系列之使用SeaJS,着重介绍了SeaJS的使用方法.关键方法的使用等,需要的朋友可以参考下 下载及安装 要在项目中使用SeaJS,你所有需要做的准备工作就是下载sea.js然后放到你项目的某个位置.SeaJS项目目前托管在GitHub上,主页为 https://github.com/seajs/seajs/ .可以到其git库的buil

无废话ExtJs 入门教程十七[列表:GridPanel]

无废话ExtJs 入门教程十七[列表:GridPanel] extjs技术交流,欢迎加群(201926085) 在Extjs中,GridPanel用于数据显示,即我们平时说的列表页.在本节中,我们先对GridPanel有个基本的认识,后继过程再做Demo练习详细讲解在开发中的应用. 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/

[转]starling教程-触摸事件(Touch Events)(四)

在前面提到过,Starling是Sparrow的姊妹篇,正因为这样,Starling里的touch事件的机制其实是为移动设备的触摸交互设计的,所以当你使用它进行使用鼠标交互的桌面应用开发时,第一眼会感觉有些困惑. 首先,如果你看一下starling的类结构图的话,你会发现starling和本地显示列表结构不同的地方在于它没有InteractiveObject类(InteractiveObject 类是用户可以使用鼠标和键盘与之交互的所有显示对象的抽象基类),所有的显示对象使用默认的交互,换句话说

OpenGL中glVertex、显示列表(glCallList)、顶点数组(Vertex array)、VBO及VAO区别

OpenGL中glVertex.显示列表(glCallList).顶点数组(Vertex array).VBO及VAO区别 1.glVertex 最原始的设置顶点方法,在glBegin和glEnd之间使用.OpenGL3.0已经废弃此方法.每个glVertex与GPU进行一次通信,十分低效. glBegin(GL_TRIANGLES); glVertex(0, 0); glVertex(1, 1); glVertex(2, 2); glEnd(); 2.显示列表(glCallList) 每个gl

[iTyran原创]iPhone中OpenGL ES显示3DS MAX模型之二:lib3ds加载模型

[iTyran原创]iPhone中OpenGL ES显示3DS MAX模型之二:lib3ds加载模型 作者:u0u0 - iTyran 在上一节中,我们分析了OBJ格式.OBJ格式优点是文本形式,可读性好,缺点也很明显,计算机解析文本过程会比解析二进制文件慢很多.OBJ还有个问题是各种3D建模工具导出的布局格式还不太一样,face还有多边形(超过三边形),不利于在OpenGL ES里面加载. .3ds文件是OBJ的二进制形式,并且多很多信息.有一个C语言写的开源库可以用来加.3ds文件,这就是l

[OpenGL] 斯坦福兔子与显示列表

1.调整桌子的大小.         在OpenGL绘制长方体,能够通过函数: glutSolidCube(Size)          绘制得到的是一个正方体,再利用缩放矩阵使其变成长方体.使得桌子的大小刚好能够放下16仅仅兔子. 2.兔子的增多降低 使用一个全局变量rabbitNum来记录兔子的数量. 在键盘回调函数中,在按下I,K后令rabbitNum添加或降低,并维护兔子的数量在1~16,等于16或1不再进行对应操作. 绘制兔子时.通过循环控制,每画完一仅仅兔子,平移一段距离,画到第4i