Stage3D程序的基本步骤

本文介绍了Stage3D底层开发三角渲染的步骤,包括创建基础类、请求Context3D对象、设置显示缓冲区、初始化模型数据、创建缓冲并上传数据、编译顶点和片段着色器、创建Program3D实例、设置Shader数据、设置当前程序及渲染等,掌握此demo是后续开发基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、创建基础类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
  
    [SWF(width="600",height="400",frameRate="60")]
    public class Stage3DBasic extends Sprite
    {
        public function Stage3DBasic()
        {
            if(stage != null) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
  
        private function init(e:Event = null):void
        {
            if(hasEventListener(Event.ADDED_TO_STAGE))
                removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
        }
    }
}

为Stage3D设置这3个Frame rate,20/30/60

2、请求Context3D对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.events.Event;
  
    [SWF(width="600",height="400",frameRate="60")]
    public class Stage3DBasic extends Sprite
    {
        private var _view_width:Number;
        private var _view_height:Number;
  
        private var _renderContext:Context3D;
  
        public function Stage3DBasic()
        {
            if(stage != null) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
  
        private function init(e:Event = null):void
        {
            if(hasEventListener(Event.ADDED_TO_STAGE))
                removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
  
            _view_width = stage.stageWidth;
            _view_height = stage.stageHeight;
  
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
            stage.stage3Ds[0].requestContext3D();
        }
  
        private function onContext3DCreate(e:Event):void
        {
            _renderContext = stage.stage3Ds[0].context3D;
        }
    }
}

3、设置Context3D Display Buffer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.events.Event;
  
    [SWF(width="600",height="400",frameRate="60")]
    public class Stage3DBasic extends Sprite
    {
        private var _view_width:Number;
        private var _view_height:Number;
  
        private var _renderContext:Context3D;
  
        public function Stage3DBasic()
        {
            if(stage != null) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
  
        private function init(e:Event = null):void
        {
            if(hasEventListener(Event.ADDED_TO_STAGE))
                removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
  
            _view_width = stage.stageWidth;
            _view_height = stage.stageHeight;
  
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
            stage.stage3Ds[0].requestContext3D();
        }
  
        private function onContext3DCreate(e:Event):void
        {
            _renderContext = stage.stage3Ds[0].context3D;
            _renderContext.configureBackBuffer(_view_width, _view_height, 0, true);
        }
    }
}

4、初始化模型数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.events.Event;
  
    [SWF(width="600",height="400",frameRate="60")]
    public class Stage3DBasic extends Sprite
    {
        private var _view_width:Number;
        private var _view_height:Number;
  
        private var _renderContext:Context3D;
  
        private var _meshVertexData:Vector.<Number>;
        private var _meshInexData:Vector.<uint>;
  
        public function Stage3DBasic()
        {
            if(stage != null) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
  
        private function init(e:Event = null):void
        {
            if(hasEventListener(Event.ADDED_TO_STAGE))
                removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
  
            _view_width = stage.stageWidth;
            _view_height = stage.stageHeight;
  
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
            stage.stage3Ds[0].requestContext3D();
        }
  
        private function onContext3DCreate(e:Event):void
        {
            _renderContext = stage.stage3Ds[0].context3D;
            _renderContext.configureBackBuffer(_view_width, _view_height, 0, true);
  
            initData();
        }
  
        private function initData():void
        {
            _meshVertexData = Vector.<Number>([
                    //X,  Y,     Z,  r, g, b
                    -0.3, -0.301, 0, 0,
                    0,    0.3,   00, 1, 0,
                    0.3, -0.3,   00, 0, 1
                ]);
            _meshInexData = Vector.<uint>([
                    0, 1, 2
                ]);
        }
    }
}

为了简单起见,定义的是一个三角形,可以看到两个数据,一个是meshVertexData,定义了每个定点的位置,和颜色值,一共三个点,每个点包含了6个数据,分别是x, y, z和r, g, b。meshVertexData包含了三个这样的数据。然后是meshIndexData,定义了链接这些定点的顺序,0, 1, 2,即按照顺序链接这三个定点,有点像小时候玩的连线游戏,是不是很简单就能理解了 :D

5、创建顶点缓冲和索引缓冲,并上传数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
  
    [SWF(width="600",height="400",frameRate="60")]
    public class Stage3DBasic extends Sprite
    {
        private var _view_width:Number;
        private var _view_height:Number;
  
        private var _renderContext:Context3D;
  
        private var _meshVertexData:Vector.<Number>;
        private var _meshInexData:Vector.<uint>;
  
        private var _vertexBuffer:VertexBuffer3D;
        private var _indexBuffer:IndexBuffer3D;
  
        public function Stage3DBasic()
        {
            if(stage != null) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
  
        private function init(e:Event = null):void
        {
            if(hasEventListener(Event.ADDED_TO_STAGE))
                removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
  
            _view_width = stage.stageWidth;
            _view_height = stage.stageHeight;
  
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
            stage.stage3Ds[0].requestContext3D();
        }
  
        private function onContext3DCreate(e:Event):void
        {
            _renderContext = stage.stage3Ds[0].context3D;
            _renderContext.configureBackBuffer(_view_width, _view_height, 0, true);
  
            initData();
  
            _vertexBuffer = _renderContext.createVertexBuffer(_meshVertexData.length / 6, 6);
            _vertexBuffer.uploadFromVector(_meshVertexData, 0, _meshVertexData.length / 6);
  
            _indexBuffer = _renderContext.createIndexBuffer(_meshInexData.length);
            _indexBuffer.uploadFromVector(_meshInexData, 0, _meshInexData.length);
        }
  
        private function initData():void
        {
            _meshVertexData = Vector.<Number>([
                    //X,  Y,     Z,  r, g, b
                    -0.3, -0.301, 0, 0,
                    0,    0.3,   00, 1, 0,
                    0.3, -0.3,   00, 0, 1
                ]);
            _meshInexData = Vector.<uint>([
                    0, 1, 2
                ]);
        }
    }
}

createVertexBuffer,传入的几个定点,以及每个定点包含的数据量。根据现有demo定义的meshVertexData,一共有meshVertexData.lenght/ 6个顶点,其实也就是3个,然后每个定点包含了:x,y,z,r,g,b,6个数据。

6、编译Vertex Shader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package
{
    import com.adobe.utils.AGALMiniAssembler;
  
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.utils.ByteArray;
  
    [SWF(width="600",height="400",frameRate="60")]
    public class Stage3DBasic extends Sprite
    {
        private var _view_width:Number;
        private var _view_height:Number;
  
        private var _renderContext:Context3D;
  
        private var _meshVertexData:Vector.<Number>;
        private var _meshInexData:Vector.<uint>;
  
        private var _vertexBuffer:VertexBuffer3D;
        private var _indexBuffer:IndexBuffer3D;
  
        private var _vertexShader:ByteArray;
  
        public function Stage3DBasic()
        {
            if(stage != null) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
  
        private function init(e:Event = null):void
        {
            if(hasEventListener(Event.ADDED_TO_STAGE))
                removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
  
            _view_width = stage.stageWidth;
            _view_height = stage.stageHeight;
  
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
            stage.stage3Ds[0].requestContext3D();
        }
  
        private function onContext3DCreate(e:Event):void
        {
            _renderContext = stage.stage3Ds[0].context3D;
            _renderContext.configureBackBuffer(_view_width, _view_height, 0, true);
  
            initData();
  
            _vertexBuffer = _renderContext.createVertexBuffer(_meshVertexData.length / 6, 6);
            _vertexBuffer.uploadFromVector(_meshVertexData, 0, _meshVertexData.length / 6);
  
            _indexBuffer = _renderContext.createIndexBuffer(_meshInexData.length);
            _indexBuffer.uploadFromVector(_meshInexData, 0, _meshInexData.length);
  
            var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            _vertexShader = vertexShaderAssembler.assemble(
                    Context3DProgramType.VERTEX,
                    "mov op, va0\n" +
                    "mov v0, va1\n"
                );
        }
  
        private function initData():void
        {
            _meshVertexData = Vector.<Number>([
                    //X,  Y,     Z,  r, g, b
                    -0.3, -0.301, 0, 0,
                    0,    0.3,   00, 1, 0,
                    0.3, -0.3,   00, 0, 1
                ]);
            _meshInexData = Vector.<uint>([
                    0, 1, 2
                ]);
        }
    }
}

示例包含了两行AGAL代码,使用了同一个opcode:mov,第一行将va0(将保存位置信息)输出到op,然后第二行将保存了颜色信息的va1赋值给v0,这种寄存器保存的信息共享于vertex shader和fragment shader。

7、编译Fragment Shader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package
{
    import com.adobe.utils.AGALMiniAssembler;
  
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.utils.ByteArray;
  
    [SWF(width="600",height="400",frameRate="60")]
    public class Stage3DBasic extends Sprite
    {
        private var _view_width:Number;
        private var _view_height:Number;
  
        private var _renderContext:Context3D;
  
        private var _meshVertexData:Vector.<Number>;
        private var _meshInexData:Vector.<uint>;
  
        private var _vertexBuffer:VertexBuffer3D;
        private var _indexBuffer:IndexBuffer3D;
  
        private var _vertexShader:ByteArray;
        private var _fragmentShader:ByteArray;
  
        public function Stage3DBasic()
        {
            if(stage != null) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
  
        private function init(e:Event = null):void
        {
            if(hasEventListener(Event.ADDED_TO_STAGE))
                removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
  
            _view_width = stage.stageWidth;
            _view_height = stage.stageHeight;
  
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
            stage.stage3Ds[0].requestContext3D();
        }
  
        private function onContext3DCreate(e:Event):void
        {
            _renderContext = stage.stage3Ds[0].context3D;
            _renderContext.configureBackBuffer(_view_width, _view_height, 0, true);
  
            initData();
  
            _vertexBuffer = _renderContext.createVertexBuffer(_meshVertexData.length / 6, 6);
            _vertexBuffer.uploadFromVector(_meshVertexData, 0, _meshVertexData.length / 6);
  
            _indexBuffer = _renderContext.createIndexBuffer(_meshInexData.length);
            _indexBuffer.uploadFromVector(_meshInexData, 0, _meshInexData.length);
  
            var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            _vertexShader = vertexShaderAssembler.assemble(
                    Context3DProgramType.VERTEX,
                    "mov op, va0\n" +
                    "mov v0, va1\n"
                );
  
            var fragmentShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            _fragmentShader = fragmentShaderAssembler.assemble(
                    Context3DProgramType.FRAGMENT,
                    "mov oc, v0\n"
                );
        }
  
        private function initData():void
        {
            _meshVertexData = Vector.<Number>([
                    //X,  Y,     Z,  r, g, b
                    -0.3, -0.301, 0, 0,
                    0,    0.3,   00, 1, 0,
                    0.3, -0.3,   00, 0, 1
                ]);
            _meshInexData = Vector.<uint>([
                    0, 1, 2
                ]);
        }
    }
}

此处的fragment shader只是将v0保存的颜色信息给输出出来。

8、创建Program3D实例,并上传Shader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package
{
    import com.adobe.utils.AGALMiniAssembler;
  
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.utils.ByteArray;
  
    [SWF(width="600",height="400",frameRate="60")]
    public class Stage3DBasic extends Sprite
    {
        private var _view_width:Number;
        private var _view_height:Number;
  
        private var _renderContext:Context3D;
  
        private var _meshVertexData:Vector.<Number>;
        private var _meshInexData:Vector.<uint>;
  
        private var _vertexBuffer:VertexBuffer3D;
        private var _indexBuffer:IndexBuffer3D;
  
        private var _vertexShader:ByteArray;
        private var _fragmentShader:ByteArray;
  
        private var _shaderProgram:Program3D;
  
        public function Stage3DBasic()
        {
            if(stage != null) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
  
        private function init(e:Event = null):void
        {
            if(hasEventListener(Event.ADDED_TO_STAGE))
                removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
  
            _view_width = stage.stageWidth;
            _view_height = stage.stageHeight;
  
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
            stage.stage3Ds[0].requestContext3D();
        }
  
        private function onContext3DCreate(e:Event):void
        {
            _renderContext = stage.stage3Ds[0].context3D;
            _renderContext.configureBackBuffer(_view_width, _view_height, 0, true);
  
            initData();
  
            _vertexBuffer = _renderContext.createVertexBuffer(_meshVertexData.length / 6, 6);
            _vertexBuffer.uploadFromVector(_meshVertexData, 0, _meshVertexData.length / 6);
  
            _indexBuffer = _renderContext.createIndexBuffer(_meshInexData.length);
            _indexBuffer.uploadFromVector(_meshInexData, 0, _meshInexData.length);
  
            var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            _vertexShader = vertexShaderAssembler.assemble(
                    Context3DProgramType.VERTEX,
                    "mov op, va0\n" +
                    "mov v0, va1\n"
                );
  
            var fragmentShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            _fragmentShader = fragmentShaderAssembler.assemble(
                    Context3DProgramType.FRAGMENT,
                    "mov oc, v0\n"
                );
  
            _shaderProgram = _renderContext.createProgram();
            _shaderProgram.upload(_vertexShader, _fragmentShader);
  
        }
  
        private function initData():void
        {
            _meshVertexData = Vector.<Number>([
                    //X,  Y,     Z,  r, g, b
                    -0.3, -0.301, 0, 0,
                    0,    0.3,   00, 1, 0,
                    0.3, -0.3,   00, 0, 1
                ]);
            _meshInexData = Vector.<uint>([
                    0, 1, 2
                ]);
        }
    }
}

9、设置Shader数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package
{
    import com.adobe.utils.AGALMiniAssembler;
  
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Context3DVertexBufferFormat;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.utils.ByteArray;
  
    [SWF(width="600",height="400",frameRate="60")]
    public class Stage3DBasic extends Sprite
    {
        private var _view_width:Number;
        private var _view_height:Number;
  
        private var _renderContext:Context3D;
  
        private var _meshVertexData:Vector.<Number>;
        private var _meshInexData:Vector.<uint>;
  
        private var _vertexBuffer:VertexBuffer3D;
        private var _indexBuffer:IndexBuffer3D;
  
        private var _vertexShader:ByteArray;
        private var _fragmentShader:ByteArray;
  
        private var _shaderProgram:Program3D;
  
        public function Stage3DBasic()
        {
            if(stage != null) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
  
        private function init(e:Event = null):void
        {
            if(hasEventListener(Event.ADDED_TO_STAGE))
                removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
  
            _view_width = stage.stageWidth;
            _view_height = stage.stageHeight;
  
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
            stage.stage3Ds[0].requestContext3D();
        }
  
        private function onContext3DCreate(e:Event):void
        {
            _renderContext = stage.stage3Ds[0].context3D;
            _renderContext.configureBackBuffer(_view_width, _view_height, 0, true);
  
            initData();
  
            _vertexBuffer = _renderContext.createVertexBuffer(_meshVertexData.length / 6, 6);
            _vertexBuffer.uploadFromVector(_meshVertexData, 0, _meshVertexData.length / 6);
  
            _indexBuffer = _renderContext.createIndexBuffer(_meshInexData.length);
            _indexBuffer.uploadFromVector(_meshInexData, 0, _meshInexData.length);
  
            var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            _vertexShader = vertexShaderAssembler.assemble(
                    Context3DProgramType.VERTEX,
                    "mov op, va0\n" +
                    "mov v0, va1\n"
                );
  
            var fragmentShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            _fragmentShader = fragmentShaderAssembler.assemble(
                    Context3DProgramType.FRAGMENT,
                    "mov oc, v0\n"
                );
  
            _shaderProgram = _renderContext.createProgram();
            _shaderProgram.upload(_vertexShader, _fragmentShader);
  
            _renderContext.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
            _renderContext.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3);
        }
  
        private function initData():void
        {
            _meshVertexData = Vector.<Number>([
                    //X,  Y,     Z,  r, g, b
                    -0.3, -0.301, 0, 0,
                    0,    0.3,   00, 1, 0,
                    0.3, -0.3,   00, 0, 1
                ]);
            _meshInexData = Vector.<uint>([
                    0, 1, 2
                ]);
        }
    }
}

设置shader数据,分别设置了va0和va1。

10、设置当前的shader程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package
{
    import com.adobe.utils.AGALMiniAssembler;
  
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Context3DVertexBufferFormat;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.utils.ByteArray;
  
    [SWF(width="600",height="400",frameRate="60")]
    public class Stage3DBasic extends Sprite
    {
        private var _view_width:Number;
        private var _view_height:Number;
  
        private var _renderContext:Context3D;
  
        private var _meshVertexData:Vector.<Number>;
        private var _meshInexData:Vector.<uint>;
  
        private var _vertexBuffer:VertexBuffer3D;
        private var _indexBuffer:IndexBuffer3D;
  
        private var _vertexShader:ByteArray;
        private var _fragmentShader:ByteArray;
  
        private var _shaderProgram:Program3D;
  
        public function Stage3DBasic()
        {
            if(stage != null) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
  
        private function init(e:Event = null):void
        {
            if(hasEventListener(Event.ADDED_TO_STAGE))
                removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
  
            _view_width = stage.stageWidth;
            _view_height = stage.stageHeight;
  
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
            stage.stage3Ds[0].requestContext3D();
        }
  
        private function onContext3DCreate(e:Event):void
        {
            _renderContext = stage.stage3Ds[0].context3D;
            _renderContext.configureBackBuffer(_view_width, _view_height, 0, true);
  
            initData();
  
            _vertexBuffer = _renderContext.createVertexBuffer(_meshVertexData.length / 6, 6);
            _vertexBuffer.uploadFromVector(_meshVertexData, 0, _meshVertexData.length / 6);
  
            _indexBuffer = _renderContext.createIndexBuffer(_meshInexData.length);
            _indexBuffer.uploadFromVector(_meshInexData, 0, _meshInexData.length);
  
            var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            _vertexShader = vertexShaderAssembler.assemble(
                    Context3DProgramType.VERTEX,
                    "mov op, va0\n" +
                    "mov v0, va1\n"
                );
  
            var fragmentShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            _fragmentShader = fragmentShaderAssembler.assemble(
                    Context3DProgramType.FRAGMENT,
                    "mov oc, v0\n"
                );
  
            _shaderProgram = _renderContext.createProgram();
            _shaderProgram.upload(_vertexShader, _fragmentShader);
  
            _renderContext.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
            _renderContext.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3);
  
            _renderContext.setProgram(_shaderProgram);
        }
  
        private function initData():void
        {
            _meshVertexData = Vector.<Number>([
                    //X,  Y,     Z,  r, g, b
                    -0.3, -0.301, 0, 0,
                    0,    0.3,   00, 1, 0,
                    0.3, -0.3,   00, 0, 1
                ]);
            _meshInexData = Vector.<uint>([
                    0, 1, 2
                ]);
        }
    }
}

11、渲染

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package
{
    import com.adobe.utils.AGALMiniAssembler;
  
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Context3DVertexBufferFormat;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.utils.ByteArray;
  
    [SWF(width="600",height="400",frameRate="60")]
    public class Stage3DBasic extends Sprite
    {
        private var _view_width:Number;
        private var _view_height:Number;
  
        private var _renderContext:Context3D;
  
        private var _meshVertexData:Vector.<Number>;
        private var _meshInexData:Vector.<uint>;
  
        private var _vertexBuffer:VertexBuffer3D;
        private var _indexBuffer:IndexBuffer3D;
  
        private var _vertexShader:ByteArray;
        private var _fragmentShader:ByteArray;
  
        private var _shaderProgram:Program3D;
  
        public function Stage3DBasic()
        {
            if(stage != null) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
  
        private function init(e:Event = null):void
        {
            if(hasEventListener(Event.ADDED_TO_STAGE))
                removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
  
            _view_width = stage.stageWidth;
            _view_height = stage.stageHeight;
  
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
            stage.stage3Ds[0].requestContext3D();
        }
  
        private function onContext3DCreate(e:Event):void
        {
            _renderContext = stage.stage3Ds[0].context3D;
            _renderContext.configureBackBuffer(_view_width, _view_height, 0, true);
  
            initData();
  
            _vertexBuffer = _renderContext.createVertexBuffer(_meshVertexData.length / 6, 6);
            _vertexBuffer.uploadFromVector(_meshVertexData, 0, _meshVertexData.length / 6);
  
            _indexBuffer = _renderContext.createIndexBuffer(_meshInexData.length);
            _indexBuffer.uploadFromVector(_meshInexData, 0, _meshInexData.length);
  
            var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            _vertexShader = vertexShaderAssembler.assemble(
                    Context3DProgramType.VERTEX,
                    "mov op, va0\n" +
                    "mov v0, va1\n"
                );
  
            var fragmentShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            _fragmentShader = fragmentShaderAssembler.assemble(
                    Context3DProgramType.FRAGMENT,
                    "mov oc, v0\n"
                );
  
            _shaderProgram = _renderContext.createProgram();
            _shaderProgram.upload(_vertexShader, _fragmentShader);
  
            _renderContext.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
            _renderContext.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3);
  
            _renderContext.setProgram(_shaderProgram);
  
            addEventListener(Event.ENTER_FRAME, render);
        }
  
        private function render(e:Event):void
        {
            _renderContext.clear(0,0,0,0);
            _renderContext.drawTriangles(_indexBuffer);
            _renderContext.present();
        }
  
        private function initData():void
        {
            _meshVertexData = Vector.<Number>([
                    //X,  Y,     Z,  r, g, b
                    -0.3, -0.301, 0, 0,
                    0,    0.3,   00, 1, 0,
                    0.3, -0.3,   00, 0, 1
                ]);
            _meshInexData = Vector.<uint>([
                    0, 1, 2
                ]);
        }
    }
}

最终结果:

虽然只是一个三角,但是这正是stage3d底层开发的一个开端,虽然步骤看上去很多,而且不同的情况下这些步骤的细节会有所调整,但是掌握好这个demo才能继续接下来的内容。下一篇文章我将继续Stage3D的底层开发,使用uv贴图。尽请期待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值