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.3 ,
0 , 1 ,
0 , 0 ,
0 ,
0.3 , 0 ,
0 , 1 ,
0 , 0.3 , - 0.3 ,
0 , 0 ,
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.3 ,
0 , 1 ,
0 , 0 ,
0 ,
0.3 , 0 ,
0 , 1 ,
0 , 0.3 , - 0.3 ,
0 , 0 ,
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.3 ,
0 , 1 ,
0 , 0 ,
0 ,
0.3 , 0 ,
0 , 1 ,
0 , 0.3 , - 0.3 ,
0 , 0 ,
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.3 ,
0 , 1 ,
0 , 0 ,
0 ,
0.3 , 0 ,
0 , 1 ,
0 , 0.3 , - 0.3 ,
0 , 0 ,
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.3 ,
0 , 1 ,
0 , 0 ,
0 ,
0.3 , 0 ,
0 , 1 ,
0 , 0.3 , - 0.3 ,
0 , 0 ,
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.3 ,
0 , 1 ,
0 , 0 ,
0 ,
0.3 , 0 ,
0 , 1 ,
0 , 0.3 , - 0.3 ,
0 , 0 ,
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.3 ,
0 , 1 ,
0 , 0 ,
0 ,
0.3 , 0 ,
0 , 1 ,
0 , 0.3 , - 0.3 ,
0 , 0 ,
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.3 ,
0 , 1 ,
0 , 0 ,
0 ,
0.3 , 0 ,
0 , 1 ,
0 , 0.3 , - 0.3 ,
0 , 0 ,
0 , 1 ]);
_meshInexData = Vector.< uint >([
0 ,
1 , 2 ]);
}
}
} |
最终结果:
虽然只是一个三角,但是这正是stage3d底层开发的一个开端,虽然步骤看上去很多,而且不同的情况下这些步骤的细节会有所调整,但是掌握好这个demo才能继续接下来的内容。下一篇文章我将继续Stage3D的底层开发,使用uv贴图。尽请期待。