有mole2d测试项目的可以一起讨论讨论,下面是个人通过此项目得出的推断:
官方发言人已告诉我们Stage3D不属于显示对象,并不在渲染列表中。但是在显卡不兼容的情况下会被软件模拟。特别感谢野哥分析
入正题:
建议:在自己学习的过程中,人为的制造错误看提示,可以帮助理解。特别是AGAL部分
一:关于stage3D[0]
如果说我们要创建一个3D对象就需要一个上下文context3D,那么var s3d:Stage3D = stage.stage3Ds[0];开始就是在为创建舞台做准备,这里有个stage3D[0]让人很纳闷,为什么这里会从stage3D[0]来取出一个stage3D对象呢(三中解释)?本人也不从知道,后台打印和断点后发现有这么几个特点:
首先,初始长度为4,但是每个对象都没有context3D上下文,在initialize方法执行后,刚才我们取出的一个拥有了上下文。
那么我就想,经过创建和测试我推断:原有的空上下文3D容器及stage3Ds只不过是aip提供给我们的4个不同的上下文环境,用来做切换用的,也许吧…为什么一开始就有4个呢?可能是对象池的概念吧,毕竟我们自己也可以进行创建。你可以进行试验,一开始便添加一个新的stage3d对象,并引用下标4(但是程序会崩溃,如果我们引用下标4的话)。
提示:创建办法不唯一。但是大同小异
二、stage3D的初始化
很明显下面几行代码就是一种
var stage3D:Stage3D = stage.stage3Ds[0];
stage3D.addEventListener(Event.CONTEXT3D_CREATE, initialize);
stage3D.requestContext3D(Context3DRenderMode.AUTO);
stage3D.viewPort = new Rectangle(0, 0, W, H);
initialize方法监听到stage3D的上下文环境创建完成,而此stage3D请求了一个通用的(暂且这样解释)上下文环境,通过Context3DRenderMode. AUTO,而视窗定义就不说明了。
暂时由于没有API在手,分析了下这个requestContext3D,里面可以传入的阐述分别是auto与software.在不同方式下调试了一下,发现software方式就是手动设置3D为软件模拟,而auto就是官方人员介绍的优先GPU的形式。
三.操作Context3D
在初始化方法中我们发现,事件的监听目标被引用给了Main中定义的一个Context3D对象,而后面所有的操作基本都在操作这个context3D,很明显,它引用的也就是stage3Ds里面下标0的那个stage3D中的上下文,如果我们将0-3都控制成不同的图片会是怎样的结果呢?
trace(_context3D.driverInfo);驱动信息
在我的机器上是:DirectX9 Description=NVIDIA GeForce GTS 250 (Microsoft Corporation - WDDM v1.1) Driver=nvd3dum.dll Version=8000f:b2191
var vertexShader:Array =从字面意思很好理解,利用AGAL创建一个顶点渲染器,实际上这里是操作码的创建过程。详细信息见前一篇关于AGAL的介绍
[
"dp4 op.x, va0, vc0",
"dp4 op.y, va0, vc1",
"dp4 op.z, va0, vc2",
"dp4 op.w, va0, vc3",
"mov v0, va1.xyzw"
];
AGALMiniAssembler类用于将我们的指令集转换成可用的byteArray,里面规则判断有一些,自己可以研究。
var fragmentShader:Array = 像素着色器来了
关于tex的更多信息请参考前一章译文
现在可以用同样的办法分析(flash.display3D.Context3DProgramType中的两个参数了
_shaderProgram = _context3D.createProgram();方法在当前操作的上下文中创建了一个着色器任务。一个渲染任务的创建通过upload方法分别将之前创建的顶点着色器与像素着色器作为1,2参数传入。
_indexBuffer = _context3D.createIndexBuffer(6);
_indexBuffer.uploadFromVector(Vector.<uint>([0, 1, 2, 0, 2, 3]), 0, 6);
这里比较茫然,但是分析结果为定义了两个三角色6个顶点的编号
四、贴图
_texture = _context3D.createTexture(256, 256, Context3DTextureFormat.BGRA, false);
_texture.uploadFromBitmapData(bitmap.bitmapData);
//在当前上下文环境中声明一个贴图区域。并且传入贴图源,在uploadFromBitmapData中可以设置投影的密度,可以尝试修改看看,并且createTexture中传入的宽高必须是2的倍数,我们尝试更改了这两个参数,发现渲染区域为256,256,因为图片的大小,而贴图源来至我们指定的256,256这个区域(与图像同大小,如果我们设置成双倍呢?呵呵自己观察下)。
五、MoleSprite
创建对象时传入了在Main中持有的上下文对象,很明显,molesprite需要将自己维护在对应的上下文环境中,所以在创建时进行传入,这个是个人编程习惯问题。
setVertexBufferAndTexture方法传入了同一个上下文对象与之前声明的贴图。
context.setVertexBufferAt(0, _buffer, 0, Context3DVertexBufferFormat.FLOAT_2); //xy
将之前的4个顶点数据分派给顶点寄存器0,也就是va0,
setTextureAt上下文中设置纹理,用之前创建的纹理对象。
这里与AGAL方式有点混淆了,个人迷糊。
最后:enterFrame
_context3D.clear(1, 1, 1, 0);,清楚所有渲染为制定颜色,透明与清除深度。
_context3D.setProgram(_shaderProgram);这里是在设置渲染任务,有渲染任务才可以进行正常的渲染。
剩下部分就比较简单了,重新设置任务,并且调用渲染
drawTriangles便是用之前声明的_indexBuffer数据重新绘制了2个三角形..
_context3D.present();代码后执行重新渲染
总结:囫囵吞枣,个人需要找时间吸收并搞清楚它的工作原理才可以正确理解。希望有molehillAPI的同学可以分享下啊。Qq:623440028。之后会有一个附带完整说明的例子放出