查看: 2823|回复: 2
打印 上一主题 下一主题

AGAL逻辑判断-----剖析

[复制链接]

12

主题

1

听众

385

积分

设计实习生

Rank: 2

纳金币
385
精华
0

最佳新人

跳转到指定楼层
楼主
发表于 2013-5-17 02:48:09 |只看该作者 |倒序浏览
创建VertexBuffer3D
VertexBuffer3D 类表示上载到渲染上下文的一组顶点数据。
使用 VertexBuffer3D 对象定义与一组顶点中每个点相关联的数据。您可以从 Vector 数组或 ByteArray 上载顶点数据。(上载完成后,将不再引用原始数组中的数据;更改或放弃源数组不会更改顶点数据。)
与每个顶点相关联的数据采用应用程序定义的格式,并用作顶点着色器程序的输入。使用 Context3D setVertexBufferAt() 函数标识哪些值属于哪个顶点程序输入。一个顶点程序最多可以使用 8 个输入(也称为顶点属性寄存器)。每个输入可能需要 1 到 4 个 32 位值。例如,一个顶点的 [x,y,z] 位置坐标可以作为包含 3 个 32 位值的矢量传递到顶点程序。Context3DVertexBufferFormat 类定义表示着色器输出支持的格式的常量。您最多可以为每个点提供 64 个 32 位值(256 字节)数据(但在这种情况下,单个顶点着色器无法使用所有数据)。
setVertexBufferAt() 函数还标识渲染任何后续 drawTriangles() 调用要使用哪个顶点缓冲区。要渲染来自其他顶点缓冲区的数据,请使用适当的参数再次调用 setVertexBufferAt()。(您可以在多个顶点缓冲区中存储同一个点的数据,例如将位置数据存入一个缓冲区并将坐标数据存入另一个缓冲区,但如果一个点的所有数据来自单个缓冲区,渲染效率通常会更高。)
传递到 Context3D drawTriangles() 方法的 Index3DBuffer 对象会将顶点数据组织为三角形。索引缓冲区中的每个值是顶点缓冲区中某个顶点的索引。按顺序排列的由 3 个索引组成的一组索引定义一个三角形。
您无法直接创建 VertexBuffer3D 对象。请改用 Context3D createVertexBuffer() 方法。
要释放与顶点缓冲区相关联的渲染上下文资源,请调用对象的 dispose() 方法。
例子:
下面的示例说明如何创建和加载顶点数据缓冲区。此示例中的缓冲区为每个顶点包含两种数据类型:位置,表示为 x、y、z 坐标;颜色,表示为 rgb 组件。创建顶点缓冲区后,该示例调用 setVertexBufferAt() 方法以指定前三个数据点作为 va0 中的 3 个浮点值传递到顶点程序,后三个数据点作为 va1 中的 3 个浮点值传递到顶点程序。顶点程序最多可以有 8 个输入,也称为顶点属性寄存器,按下面的方式定义。
const dataPerVertex:int = 6;
var vertexData:Vector.<Number> = Vector.<Number>
                                                             (    [      // x, y, z    r, g, b format      
                                                                             0, 0, 0,   1, 1, 1,        
                                                                            -1, 1, 0,   0, 0,.5,        
                                                                             1, 1, 0,   0, 0, 1,     
                                                                             1,-1, 0,  .5, 0, 0,   
                                                                            -1,-1, 0,   1, 0, 0    ]);
var vertexes:VertexBuffer3D = renderContext.createVertexBuffer( vertexData.length/dataPerVertex, dataPerVertex );
vertexes.uploadFromVector( vertexData, 0, vertexData.length/dataPerVertex );            //Identify vertex data inputs for vertex programrender
Context.setVertexBufferAt( 0, vertexes, 0, Context3DVertexBufferFormat.FLOAT_3 ); //Defines shader input va0 as the position datarender
Context.setVertexBufferAt( 1, vertexes, 3, Context3DVertexBufferFormat.FLOAT_3 ); //Defines shader input va1 as the color data

Context3D
Context3D 类提供了用于呈现几何定义图形的上下文。
渲染上下文包括一个绘图表面及其关联的资源和状态。在可能的情况下,渲染上下文使用硬件图形处理单元 (GPU)。否则,渲染上下文使用软件。(如果在某个平台上不支持通过 Context3D 呈现,则 Stage 对象的 stage3Ds 属性包含一个空列表。)
Context3D 渲染上下文是一个可编程的管道,与 OpenGL ES 2 类似,不过它是抽象的,从而可与某一范围内的硬件和 GPU 接口兼容。尽管专为 3D 图形设计,但是呈现管道并不强制呈现必须是三维的。因此,您可以通过提供适当的顶点和像素片段程序来创建 2D 渲染器。在 3D 和 2D 这两种情况下,支持的几何基元只有三角形。
通过调用 Stage3D 对象的 requestContext3D() 方法可以获取 Context3D 类的实例。每个页面只能存在有限数量的 Context3D 对象;Stage.stage3Ds 列表中的每个 Stage3D 只能有一个。当创建上下文时,Stage3D 对象会调度一个 context3DCreate 事件。渲染上下文可能会随时被损坏并重新创建,例如,当使用 GPU 的另一个应用程序获得焦点时。您的代码将会接收到多个context3DCreate 事件。使用相关联 Stage3D 实例的 x 和 y 属性指定舞台上渲染区域的位置。

若要呈现并显示某个场景(在获取 Context3D 对象后),下面是典型的步骤:
  • 通过调用 configureBackBuffer() 来配置主显示缓冲区属性。
  • 创建并初始化您的呈现资源,包括:
    • 定义场景几何的顶点和索引缓冲区
    • 用于呈现场景的顶点和像素程序(着色器)
    • 纹理
  • 呈现帧:
    • 为场景中的一个对象或一组对象设置适当的呈现状态。
    • 调用 drawTriangles() 方法可以呈现一组三角形。
    • 更改下一组对象的呈现状态。
    • 调用 drawTriangles() 可以绘制定义对象的三角形。
    • 重复直至场景全部呈现。
    • 调用 present() 方法可以在舞台上显示呈现的场景。
资源                 允许的数量              总内存
Vertex buffers  4096                     256 MB
Index buffers   4096                     128 MB
Programs        4096                     16 MB
Textures        4096                     128 MB¹
Cube textures   4096                     256 MB
AGAL 限制:每个程序 200 个 opcode。
绘制调用限制:每个 present() 调用 32,768 个 drawTriangles() 调用。
¹350 MB 是纹理的绝对限制,包括 mipmap 所需的纹理内存。但是,许多设备不支持这么多的纹理内存。为了最大限度地保证兼容性,请将使用的纹理内存限制为 128 MB 或更少。
您无法使用 Context3D 构造函数创建 Context3D 对象。它是作为 Stage3D 实例的属性构建并提供的。Context3D 类仅可以用于桌面平台上,在 Flash Player 和在 AIR 中运行时都适用。

例子(附件)

package
{
    import com.adobe.utils.AGALMiniAssembler;
    import com.adobe.utils.PerspectiveMatrix3D;

    import flash.display.Sprite;
    import flash.display.Stage3D;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Context3DRenderMode;
    import flash.display3D.Context3DTriangleFace;
    import flash.display3D.Context3DVertexBufferFormat;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.VertexBuffer3D;
    import flash.events.ErrorEvent;
    import flash.events.Event;
    import flash.geom.Matrix3D;
    import flash.geom.Vector3D;

    public class Context3DExample extends Sprite
    {
        public const viewWidth:Number = 320;
        public const viewHeight:Number = 200;
        public const zNear:Number = 1;
        public const zFar:Number = 500;

        public const fov:Number = 45;

        private var stage3D:Stage3D;
        private var renderContext:Context3D;
                /*IndexBuffer3D 用于表示顶点索引列表,由图形子系统保留的图形元素构成。
                由 IndexBuffer3D 对象管理的索引可用于从顶点流中选择顶点。索引为 16 位无符号整数。
                所允许的最大索引值为 65535 (0xffff)。图形子系统不会保留对提供给此对象的顶点的引用。
                修改或丢弃上载到此对象中的数据不会影响已存储的值。*/
        private var indexList:IndexBuffer3D;
        private var vertexes:VertexBuffer3D;

        private var projectionerspectiveMatrix3D = new PerspectiveMatrix3D();
        private var model:Matrix3D = new Matrix3D();
        private var view:Matrix3D = new Matrix3D();
        private var finalTransform:Matrix3D = new Matrix3D();

        //用于旋转立方体
        private const pivot:Vector3D = new Vector3D();

        private const VERTEX_SHADER:String =
            "m44 op, va0, vc0    \n" +    // 4x4 矩阵变换 //3d转2d坐标
            "mov v0, va1"; //移动颜色信息到v0

        private const FRAGMENT_SHADER:String =
            "mov oc, v0"; //设置输出颜色值从三个三角形顶点插值

        private var vertexAssembly:AGALMiniAssembler = new AGALMiniAssembler();
        private var fragmentAssembly:AGALMiniAssembler = new AGALMiniAssembler();
        private var programPairrogram3D;

        public function Context3DExample()
        {
            this.stage.scaleMode = StageScaleMode.NO_SCALE;
            this.stage.align = StageAlign.TOP_LEFT;
            //this.stage.nativeWindow.activate(); //AIR only

            stage3D = this.stage.stage3Ds[0];
            stage3D.x = 10;
            stage3D.y = 10;

            //添加注册事件
            stage3D.addEventListener( Event.CONTEXT3D_CREATE, contextCreated );
            stage3D.addEventListener( ErrorEvent.ERROR, contextCreationError );
            stage3D.requestContext3D( Context3DRenderMode.AUTO );

            //编译着色器
            vertexAssembly.assemble( Context3DProgramType.VERTEX, VERTEX_SHADER, false );
            fragmentAssembly.assemble( Context3DProgramType.FRAGMENT, FRAGMENT_SHADER, false );            
        }

        //注,context3DCreate事件可以发生在任何时间,例如,当由另一个进程的硬件资源
        private function contextCreated( event:Event ):void
        {
                renderContext = Stage3D( event.target ).context3D;
                trace( "3D driver: " + renderContext.driverInfo );
                setupscene();
        }

        private function setupScene():void
        {
            renderContext.enableErrorChecking = true; //可以减缓渲染 - 开发/测试时开启
            renderContext.configureBackBuffer( viewWidth, viewHeight, 2, false );
                        //显示模式,可以多试试选项
            renderContext.setCulling( Context3DTriangleFace.BACK );

            //索引列表 三角形-正方体
            var triangles:Vector.<uint> = Vector.<uint>( [
                2,1,0, //前面
                3,2,0,
                4,7,5, //底面
                7,6,5,
                8,11,9, //后面
                9,11,10,
                12,15,13, //上面
                13,15,14,
                16,19,17, //左面
                17,19,18,
                20,23,21, //右面
                21,23,22
            ] );
            indexList = renderContext.createIndexBuffer( triangles.length );
            indexList.uploadFromVector( triangles, 0, triangles.length );

            //Create vertexes - cube faces do not share vertexes
            const dataPerVertex:int = 6;
            var vertexData:Vector.<Number> = Vector.<Number>(
                [
                    // x,y,z r,g,b format
                                        //补充一句:4行代表4个点,你可以尝试改变其中的数值,来进一步发现与理解
                    0,0,0, 1,0,0, //front face
                    0,1,0, 1,0,0,
                    1,1,0, 1,0,0,
                    1,0,0, 1,0,0,

                    0,0,0, 0,1,0, //bottom face
                    1,0,0, 0,1,0,
                    1,0,1, 0,1,0,
                    0,0,1, 0,1,0,

                    0,0,1, 1,0,0, //back face
                    1,0,1, 1,0,0,
                    1,1,1, 1,0,0,
                    0,1,1, 1,0,0,

                    0,1,1, 0,1,0, //top face
                    1,1,1, 0,1,0,
                    1,1,0, 0,1,0,
                    0,1,0, 0,1,0,

                    0,1,1, 0,0,1, //left face
                    0,1,0, 0,0,1,
                    0,0,0, 0,0,1,
                    0,0,1, 0,0,1,

                    1,1,0, 0,0,1, //right face
                    1,1,1, 0,0,1,
                    1,0,1, 0,0,1,
                    1,0,0, 0,0,1
                ]
            );
            vertexes = renderContext.createVertexBuffer( vertexData.length/dataPerVertex, dataPerVertex );
            vertexes.uploadFromVector( vertexData, 0, vertexData.length/dataPerVertex );

            //为顶点程序输出顶点数据
            renderContext.setVertexBufferAt( 0, vertexes, 0, Context3DVertexBufferFormat.FLOAT_3 ); //va0 is position
            renderContext.setVertexBufferAt( 1, vertexes, 3, Context3DVertexBufferFormat.FLOAT_3 ); //va1 is color

            //上载并渲染
            programPair = renderContext.createProgram();
            programPair.upload( vertexAssembly.agalcode, fragmentAssembly.agalcode );
            renderContext.setProgram( programPair );

            //3d变换
            projection.perspectiveFieldOfViewRH( fov, viewWidth/viewHeight, zNear, zFar );            
            view.appendTranslation( 0, 0, -2 );    //摄像机距离
            model.appendTranslation( -.5, -.5, -.5 ); //正方体位置
            this.stage.addEventListener( Event.ENTER_FRAME, render );
        }

        private function render( event:Event ):void
        {

            model.appendRotation( .5, Vector3D.Z_AXIS, pivot );
            model.appendRotation( .5, Vector3D.Y_AXIS, pivot );
            model.appendRotation( .5, Vector3D.X_AXIS, pivot );

            //编译变换
            finalTransform.identity();
            finalTransform.append( model );
            finalTransform.append( view );
            finalTransform.append( projection );

            //上传3D矩阵对应AGAL中的vc0
            renderContext.setProgramConstantsFromMatrix( Context3DProgramType.VERTEX, 0, finalTransform, true );

            //背景色
            renderContext.clear( .3,.3,.3 );

            //上传三角顶点索引,起点为0,画12个三角形
            renderContext.drawTriangles( indexList, 0, 12 );


            renderContext.present();
        }

        private function contextCreationError( error:ErrorEvent ):void
        {
            trace( error.errorID + ": " + error.text );
        }
    }
}


分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

0

主题

1

听众

2458

积分

中级设计师

Rank: 5Rank: 5

纳金币
0
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

沙发
发表于 2014-3-26 20:41:15 |只看该作者
Thanks for sharing !
回复

使用道具 举报

0

主题

2

听众

3238

积分

中级设计师

Rank: 5Rank: 5

纳金币
0
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2014-4-30 09:02:19 |只看该作者
感谢分享!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-9-20 14:42 , Processed in 0.094919 second(s), 26 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部