博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)Stage3D程序的基本步骤
阅读量:4676 次
发布时间:2019-06-09

本文共 25859 字,大约阅读时间需要 86 分钟。

原文:http://www.flashache.com/2012/10/31/stage3d-program-basic-steps/   作者:flashche

本月24号《flash开发者大会》,我选择了《AGAL程序设计》这么一个比较难讲的主题。这么一个相对比较小众的主题,在开发者大会这种需要顾虑到所有人的一个场合下讲,如何选择切入点是很重要的。说起来要跑通一个基础的Stage3D的程序,有很多步骤,就就比较难解释了,短短的40分钟要让全场大部分人都理解可以说是基本不可能,所以肯定不可能详细阐述这块的细节。当然,如果真能做到这点的话那就更棒了。所以决定在这整理一下完成一个Stage3D项目的基本开发流程,方便大家参考。附上的参考也是非常好的学习资料哦,:-)

flash开发者大会:

参考资料:

Christer Kaitila, 《Adobe Flash 11 Stage3D(Molehill) Game Programming》, PACKT publishing
Norbz’s Dev Blog, “Stage3D / AGAL from scratch”,
7yue,“深入Stage3D”,

因为比较详细,而且为了便于理解,所以这篇文章会比较长,不过主要是重复代码,所以不用担心,不会花费太长时间。

1、创建基础类

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贴图。尽请期待。

转载于:https://www.cnblogs.com/hisiqi/archive/2013/03/07/2948743.html

你可能感兴趣的文章
【SPL标准库专题(10)】SPL Exceptions
查看>>
《Python从入门基础到实践》
查看>>
【读入优化】
查看>>
python-网络编程urllib模块
查看>>
0029 Java学习笔记-面向对象-枚举类
查看>>
CGRectGet *** 获取控件坐标的方法
查看>>
SQL的主键和外键约束
查看>>
Bookmarklet
查看>>
c++primer 第l六章编程练习答案
查看>>
上海秋季HCC小记
查看>>
Illustrator 上色
查看>>
truncate表恢复
查看>>
this关键字的使用
查看>>
Console.Read()、Console.ReadLine()、Console.ReadKey()
查看>>
ecere 编译过程中遇到的问题
查看>>
Cyclone V 与 Avalon-MM资料整理——DE1-SOC学习笔记(1)
查看>>
异常:This application has no explicit mapping for /error, so you are seeing this as a fallback.
查看>>
Flask-SQLAlchemy
查看>>
C# - Generics
查看>>
.NET LINQ 转换数据类型
查看>>