• Stage3D学习笔记(二):使用GPU绘制一个三角形


    我们需要使用到Adobe自家提供的AGALMiniAssembler代码类,可以在网下进行下载;

    关于AGAL的入门知识可以参考下面的文章:

    AGAL介绍系列文章(第一部分)
    AGAL介绍系列文章(第二部分)
    AGAL介绍系列文章(第三部分)

    最终效果如下:

    直接上代码了,亲们请查看相关的注释说明:

      1 package
      2 {
      3     import com.adobe.utils.AGALMiniAssembler;
      4     
      5     import flash.display.Sprite;
      6     import flash.display.Stage3D;
      7     import flash.display3D.Context3D;
      8     import flash.display3D.Context3DProfile;
      9     import flash.display3D.Context3DRenderMode;
     10     import flash.display3D.Context3DVertexBufferFormat;
     11     import flash.display3D.IndexBuffer3D;
     12     import flash.display3D.Program3D;
     13     import flash.display3D.VertexBuffer3D;
     14     import flash.events.ErrorEvent;
     15     import flash.events.Event;
     16     
     17     [SWF(width=800, height=600, frameRate=60)]
     18     public class DrawTriangle extends Sprite
     19     {
     20         //3D 场景对象
     21         private var _stage3D:Stage3D;
     22         //3D 上下文渲染对象
     23         private var _context3D:Context3D;
     24         
     25         //顶点缓冲数据
     26         private var _vertexBuffer:VertexBuffer3D;
     27         //索引缓冲数据
     28         private var _indexBuffer:IndexBuffer3D;
     29         
     30         //着色器对象
     31         private var _program3D:Program3D;
     32         
     33         public function DrawTriangle()
     34         {
     35             addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
     36         }
     37         
     38         private function addedToStageHandler(event:Event):void
     39         {
     40             removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
     41             
     42             //3D 场景存在, 一般存在 4 个 3D 场景对象
     43             if(stage.stage3Ds.length > 0)
     44             {
     45                 //使用最下层的 3D 场景
     46                 _stage3D = stage.stage3Ds[0];
     47                 //请求 3D 上下文渲染对象
     48                 _stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
     49                 _stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
     50                 _stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
     51             }
     52         }
     53         
     54         private function stage3DErrorHandler(event:ErrorEvent):void
     55         {
     56             trace("Context3D对象请求失败:", event.text);
     57         }
     58         
     59         private function context3DCreateHandler(event:Event):void
     60         {
     61             initContext3D();
     62             initBuffer();
     63             initProgram();
     64             
     65             //每帧进行渲染
     66             addEventListener(Event.ENTER_FRAME, render);
     67         }
     68         
     69         private function initContext3D():void
     70         {
     71             //获取 3D 渲染对象
     72             _context3D = _stage3D.context3D;
     73             //调整 3D 舞台位置
     74             _stage3D.x = 50;
     75             _stage3D.y = 50;
     76             //设置后台缓冲区
     77             _context3D.configureBackBuffer(700, 500, 2);
     78         }
     79         
     80         private function initBuffer():void
     81         {
     82             //顶点数据
     83             var vertexData:Vector.<Number> = Vector.<Number>(
     84                 [
     85                 //  x, y, z, r, g, b
     86                     0, 0, 0, 1, 0, 0,
     87                     1, 1, 0, 0, 1, 0,
     88                     1, 0, 0, 0, 0, 1
     89                 ]);
     90             
     91             //创建顶点缓冲对象, 参数设定存在几组数据和每组数据的个数
     92             _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 6, 6);
     93             //上传顶点数据到GPU, 参数设定从第几组数据开始上传和上传多少组数据
     94             _vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 6);
     95             
     96             //索引数据
     97             var indexData:Vector.<uint> = Vector.<uint>(
     98                 [
     99                     0, 1, 2
    100                 ]);
    101             
    102             //创建索引缓冲对象, 每个索引对应顶点数据中的相对应的一组数据, 
    103             //每3个索引组成一个会被绘制出来的三角形, 参数指定索引的长度
    104             _indexBuffer = _context3D.createIndexBuffer(indexData.length);
    105             //上传索引数据到GPU, 参数设定从第几个数据开始上传和上传多少个数据
    106             _indexBuffer.uploadFromVector(indexData, 0, 3);
    107         }
    108         
    109         private function initProgram():void
    110         {
    111             //顶点着色器代码, 每个上传的顶点前都会执行一次该代码
    112             var vertexArr:Array =
    113                 [
    114                     //op 代表位置输出寄存器, 无论对顶点进行多少次的运算最终都要将结果
    115                     //赋值给他, 这里我们不进行运行, 直接赋值
    116                     "mov op, va0",
    117                     //片段着色器需要用的数据要在这里通过 v0 中转一下, 因为片段着色器不
    118                     //能直接读取 va0 和 va1 的数据
    119                     "mov v0, va1"
    120                 ];
    121             
    122             //片段着色器代码, 每个可以显示的像素都会执行一次该代码
    123             var fragmentArr:Array =
    124                 [
    125                     //oc 代表颜色输出寄存器, 每个顶点的颜色数据都要赋值给他
    126                     "mov oc, v0"
    127                 ];
    128             
    129             //使用 Adobe 自己提供的编译器编译代码为程序可使用的二进制数据
    130             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    131             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    132         }
    133         
    134         private function render(event:Event):void
    135         {
    136             //清除已绘制过的 3D 图像
    137             _context3D.clear(0, 0, 0);
    138             //指定着色器代码的 va0 代表的数据段, 以一组顶点数据为基础来看
    139             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    140             //指定着色器代码的 va1 代表的数据段, 以一组顶点数据为基础来看
    141             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3);
    142             //指定当前使用的着色器对象
    143             _context3D.setProgram(_program3D);
    144             //通过顶点索引数据绘制所有的三角形
    145             _context3D.drawTriangles(_indexBuffer);
    146             //将后台缓冲的图像显示到屏幕
    147             _context3D.present();
    148         }
    149     }
    150 }
  • 相关阅读:
    datagrid在MVC中的运用05-加入时间搜索条件,枚举填充下拉框
    datagrid在MVC中的运用04-同时添加搜索和操作区域
    datagrid在MVC中的运用03-选择单行或多行
    datagrid在MVC中的运用02-结合搜索
    datagrid在MVC中的运用01-基本属性并实现分页
    Object [object Object] has no method 'live'
    AutoMapper在MVC中的运用小结
    error CS0234: 命名空间“XXX”中不存在类型或命名空间名称“UserInfoVm”(是否缺少程序集引用?)
    《黄聪:手机移动站SEO优化教程》2、PC端和手机移动端SEO优化区别
    《黄聪:手机移动站SEO优化教程》1、为什么要做手机移动端网站
  • 原文地址:https://www.cnblogs.com/hammerc/p/4058184.html
Copyright © 2020-2023  润新知