关于stage3D中的图片纹理数据:
1、stage3D实际处理的是Texture数据类型的纹理,这是一种压缩纹理,上传到GPU后直接使用的。
2、你可以通过BitmapData方式转化为Texture,使用Context3DTextureFormat.BGRA方式创建纹理,并用uploadFromBitmapData上传,这需要消耗一些性能,不过只要转化一次即可不用每帧渲染时都转化。
3、你可以通过ATF文件以字节流的方式读取,使用Context3DTextureFormat.COMPRESSED方式创建纹理,并用uploadCompressedTextureFromByteArray上传,这不用再次压缩了效率更高。
4、无论你用哪种方式上传,要确保图片宽高是2的n次方,你可以拉伸图片或者只是填充画布至那个宽高(拉伸的话当然就可能出现模糊之类的问题)。
5、mipmap是指纹理资源里面就有多个更小的纹理,比如正常的为128x128 那么它还有64x64 32x32 16x16 8x8 4x4 2x2 1x1 的版本,为了在远处看起来没那么锯齿感以及牺牲一点点空间来换取时间(就是处理起来更快一些),你可以找到相关ATF文件用flashplayer打开看看。
6、BitmapData转Texture(带有mipmap方式)
/**
* 将bitmapData处理成mipmap格式的Texture
* @param dest 目标Texture
* @param src 源图片数据
*
*/
public function uploadTextureWithMipmaps(
dest:Texture, src:BitmapData):void
{
var ws:int = src.width;
var hs:int = src.height;
var level:int = 0;
var tmp:BitmapData;
var transform:Matrix = new Matrix();
var tmp2:BitmapData;
tmp = new BitmapData( src.width, src.height, true, 0x00000000);
while ( ws >= 1 && hs >= 1 )
{
tmp.draw(src, transform, null, null, null, true);
dest.uploadFromBitmapData(tmp, level);
transform.scale(0.5, 0.5);
level++;
ws >>= 1;
hs >>= 1;
if (hs && ws)
{
tmp.dispose();
tmp = new BitmapData(ws, hs, true, 0x00000000);
}
}
tmp.dispose();
}
7、纹理的坐标系并不是三维空间点的坐标系,而是从上至下的,参照2D。
8、关于使用纹理
// ---- 以下初始化时处理即可 ----
// 一个纹理源要有一个Texture,你可以把它认为是3D版的BitmapData
private var tex:Texture;
// 比如通过BitmapData转化为Texture(wallBmp是256*256的)
tex = context3d.createTexture(wallBmp.width,wallBmp.height,Context3DTextureFormat.BGRA,false);
tex.uploadFromBitmapData(wallBmp.bitmapData);
// ---- 以下要在实时渲染时要更改状态机将当前的纹理放到某通道中以便使用 ----
// -- 设置状态机使用的纹理到当前的fs0通道,在片段着色器代码中使用的
context3d.setTextureAt(0,tex);
// ---- 片段着色器代码 ----
"tex ft0, v2, fs0 <2d,linear,repeat,nomip>\n"+ //临时变量 ft0 = v2(UV坐标点)和图片纹理作用的颜色点
"mov oc, ft0\n" // 直接输出颜色点 ft0