flash 3d flash3d 研究所 pv3d 共享资源  | 经典范例  | 视频教程  | 友情链接  | 联系我们
登陆 | 注册  flash 3d 研究所
讨论区





最近更新:
● payday loan阁下在教程区里 回复“《pv3d, sandy, away3d...”(05:56:23)
● bad credit payday loan阁下在教程区里 回复“《超简易papervision3D基础 ...”(05:56:13)
● payday loan阁下在教程区里 回复“《超简易papervision3D基础 ...”(05:56:12)
浏览主题:重贴图问题

重贴图问题
Bruce Lau (2009-03-22 14:44:45)

我想为场景中的一个实体换贴图,现在有个方法是使用BitmapFileMaterial类变换贴图的URL,然后进行载入
但是这种方法的缺点是由于图像资源在硬盘上,所以载入速度比较慢。因此我想把所有我想用的图片资源一次性的载入内存,然后再读取进行更换
我的问题是载入后的图像数据怎样提取呢,比如我用URL可以直接使用 var fileMat:BitmapFileMaterial = new BitmapFileMaterial(“URL”);
可图像数据怎样得到BitmapFileMaterial类的fileMat呢?

PV中的Sphere = new Sphere({material:fileMat,radius:600,segmentsH:40, segmentsW:40,pushback:true})第一个参数用到了这个类的一个对象,我现在想把我所有想用的图像资源一次性的载入内存,用Array进行存储,可是我找不到BitmapFileMaterial类对象的数据区,把Array中的数据替换进来,我应该怎样做呢?
或者有没有更好的方法可以支持快速的换图呢?(PS.由于需要更换的图片的数量很大,把所有图片载入到库里不是一个好办法,而且灵活性也不好)


flash 3d 研究所 DDM君
(2009-03-22 15:48:07)
BitmapFileMaterial本来就是个图方便的类,建议少用。
推荐用BitmapMaterial,它可以使用的参数是bitmapData,可以用先读取外补贴图为bitmapData(flash说明文档有具体操作说明),然后再用这个bitmapData建立bitmapMaterial,这样就没有现场读取的尴尬了。
要更换也很容易把所有的bitmapData,push进数组中
然后用shpere.material.bitmap=数组[i]
就可以解决了

希望这些能帮到您~


flash 3d 研究所 Bruce Lau
(2009-03-22 15:53:20)
十分感谢,我觉得非常可行!

flash 3d 研究所 DDM君
(2009-03-22 21:04:23)
呵呵,能解决就好,加油哦~

flash 3d 研究所 Bruce Lau
(2009-03-23 10:19:22)
出现了一些问题,得到的图像是NULL,不知道是为什么,调试了很长时间还是不好用
var imageArray:Array=new Array();
var bmp:Bitmap;
for(i=1;i<=55;++i)
{      
var request:URLRequest=new URLRequest(URL(里面有i作为地址变量));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loader.load(request);
addChild(loader);
imageArray.push(bmp.bitmapData);
     }

function completeHandler(event:Event){
  var loader:Loader=Loader(event.target.loader);
  bmp=Bitmap(loader.content);
}
使用上面的方法不知道为什么bmp的值为NULL

但是在function里面如果使用了bmpData.draw(bmp)就可以显示,但是问题是用draw需要设定图像的大小,2880*2880这个范围对我的要求来说不能满足,所以请教一下,我的前面的方法出了什么问题呢?

flash 3d 研究所 Bruce Lau
(2009-03-23 10:21:45)
PS. loader 在最前面已经定义了,循环体里面的loader是有定义的

flash 3d 研究所 DDM君
(2009-03-23 10:55:12)
push显然必须在确认读取以后嘛,呵呵,也就是在completeHandler才能push,不然push的肯定是‘空’

flash 3d 研究所 Bruce Lau
(2009-03-23 11:36:57)
function completeHandler(event:Event){
var loader:Loader=Loader(event.target.loader);
bmp=Bitmap(loader.content);
imageArray.push(bmp.bitmapData);
}
这样吗?这样还是NULL啊。。。

flash 3d 研究所 DDM君
(2009-03-23 12:17:17)
一定要2880以上??2880在网络传输来说已经属于不着编辑的巨大了,试试256*256这种小的,先把具体是不是这个问题排除先呢?

flash 3d 研究所 Bruce Lau
(2009-03-23 13:05:43)
恩,在前面定义一个
var bmpData:BmpData=new BmpData(width,heigth);
然后在function中写入:
bmpData.draw(bmp)

图像可以被载入进来,但是不写draw就进不来,这是什么原因呢

flash 3d 研究所 DDM君
(2009-03-23 13:42:36)
因为不draw就不是‘深度复制’,也就是其实一直push了n次的同一个东西
具体关于‘深度复制’可以去百度查查

flash 3d 研究所 Bruce Lau
(2009-03-23 13:55:30)
谢谢您的提示,我去查一下!

flash 3d 研究所
(2009-03-23 14:59:03)
换成一个DAE对象,该这么办呢?
var material:BitmapFileMaterial=new BitmapFileMaterial(e.currentTarget.selectedItem.url, true);
intro.model.load(url.text,new MaterialsList({ all :material}));
我现在还是只有这样重新加载模型

flash 3d 研究所
(2009-03-23 15:19:42)
貌似基本三维体可以 .material.bitmap=XXX

flash 3d 研究所 DDM君
(2009-03-23 16:19:54)
是呀

flash 3d 研究所
(2009-03-23 16:42:01)
但是DAE对象,该这么办呢?
重新加载模型啊?

flash 3d 研究所 DDM君
(2009-03-23 17:03:39)
下面这贴有讲,呵呵~
http://www.flab3d.com/topicview.html?top=DDM+%E5%90%9B+DAE%E5%AF%B9%E8%B1%A1%E7%9A%84%E8%B4%B4%E5%9B%BE%E6%80%8E%E4%B9%88%E5%88%87%E6%8D%A2%EF%BC%9F


flash 3d 研究所 Bruce Lau
(2009-03-23 21:50:00)
经过一番调试,把问题定位在loader上了,发现loader.content为空,代码前面贴过了,这里再把相关部分贴下:
var request:URLRequest=new URLRequest(URL(里面有i作为地址变量));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loader.load(request);

function completeHandler(event:Event){
var loader:Loader=Loader(event.target.loader);
bmp=Bitmap(loader.content);
}
请问,设置***************************的作用是什么呢?为什么会出现load.content为null这样的现象呢?并且在调试中发现在function中设置断点,程序运行后并不进入断点这又是为什么呢?(PS. 我算是一个初学者,发问之前书和网页都查过一些了,可是比较糊涂。我知道这个似乎不属于3D范畴,是AS的知识,但是还是希望得到您的帮助,谢谢)


flash 3d 研究所 Bruce Lau
(2009-03-23 21:51:14)
***************************=***************************
不知道为什么会出现上面的情况,呵呵

flash 3d 研究所 Bruce Lau
(2009-03-23 21:52:04)
Listener=***************************


flash 3d 研究所 fur3
(2009-03-23 22:34:26)
*************************** 是什么呀?bruce你好无厘头,真幽默啊,哈哈哈>_<

下面这两句是等价的,这里写错了event.target.loader
bmp=Bitmap(loader.content)
bmp=Bitmap(event.target.content)



flash 3d 研究所 Bruce Lau
(2009-03-24 16:30:16)
谢谢fur君的提示,已经有一些进展了!

flash 3d 研究所 fur3
(2009-03-24 16:31:23)
不错!

flash 3d 研究所 Bruce Lau
(2009-03-25 10:23:26)
又出现了新的问题了。。

由于采用一般的Loader方法载入图像数据比较麻烦,所以我采用了BulkLoader类库,进行多幅图像的加载

private var newLoader:BulkLoader= new BulkLoader("main");
  for(i=1;i<=N;++i) newLoader.add("a\\"+i+".jpg");

  newLoader.addEventListener(BulkLoader.COMPLETE,completeHandler);
  newLoader.start();

private function completeHandler(event:Event):void {
     for(i=1;i<=N;++i)
     {
           var bmp:Bitmap = newLoader.getBitmap("a\\"+i+".jpg");
           imageArray.push(bmp.bitmapData);
     }
}
可是当N很小的时候加载的速度还比较快,可是我想加载几千甚至几万幅图像的时候,等待的时间超过15秒,程序就不能运行了
另外,我想在一个球体上贴图,采用方向键控制换图:
private function onKeyDown(event:KeyboardEvent):void
{
switch(event.keyCode)
{
  case VK_UP:
++num;
var fileMat:BitmapMaterial = new BitmapMaterial(imageArray[num]);
globe= new Sphere({material:fileMat,radius:600,segmentsH:40, segmentsW:40,pushback:true});
globe.bothsides = true;
view.scene.addChild(globe);
view.render();
break;
default:break;
}            
}
可是,更换图像时出现了图像数据块的错位。不知道是为什么

所以,不知道能不能对这种加载图像的方法进行改进,或者有更好的方法来加载大批量的图像数据,用于快速更换?

flash 3d 研究所 fur3
(2009-03-25 11:04:07)
试试
材质的.precise=true和.smooth=true
如果图片每张不一样大会被压缩

一次读几万张图怎么可能啊。只有分批读取,比如一次读1-50张,浏览到第40张时,再动态读取下一组

flash 3d 研究所 Bruce Lau
(2009-03-25 14:51:48)
谢谢fur君的回答!我觉这个办法挺好的。可是我又有了一个想法,如果采用流媒体的话,数据载入的速度会不会快一些呢?

具体来说就是可以通过把大量的图片数据编码成H.264格式,进行传输,在Flash这边进行解码,可以得到数据,然后显示,这样的话效果会不会好些呢?

如果这样的话就需要在Flash平台下做视频解码,我想到了两个方案
1,有没有用as3写好的针对H.264编码格式的解码库函数?如果有的话可以直接使用(刚才我搜了一下,好像没搜到)

2,如果as3里没有这样现成库的话,通过现在网络上有现成的FFMPEG库(它的代码是用C写的,在VC平台下可以编译)dll文件,在Flash这边调用dll,来实现对h.264编码的解码(具体怎样操作我也不太懂)

不知道是否可行,具体应该怎样操作呢?

flash 3d 研究所 fur3
(2009-03-25 15:10:17)
=____=看昏了,不大懂这些编码问题,编码问题一般都直接使用别人写的(如果没有就比较残念=_____=....)

把图片弄成.flv大概可以,画质差一点。总之尽量避免一次读取n大的一个文件。

我们研究所有自制的可以动态生成mc动画的类,不过这个对你要的功能没什么关系,呵呵

为什么一定要非常清晰的上万张图片呢?(我电脑里都还没有那么多图片呢)

flash 3d 研究所 Bruce Lau
(2009-03-25 16:10:41)
恩,是项目需要,呵呵。

那么在Flash中调用dll 应该怎样去做呢,可不可以调用静态链接库.lib呢?

flash 3d 研究所 fur3
(2009-03-25 16:13:01)
我不懂C呢,ddm和kevin同志比较懂,不过他不常来

flash 3d 研究所 Bruce Lau
(2009-03-25 16:27:48)
呵呵,辛苦fur君多日的耐心解答,我去google上找找答案^_^

flash 3d 研究所 fur3
(2009-03-25 16:44:14)
好的,bruce lee的兄弟,哈哈~

flash 3d 研究所 Bruce Lau
(2009-03-25 22:26:18)
fur君,还有问题,继续麻烦你,嘿嘿
我的imageArray里面存了3张图像,将imageArray[0]贴到球面上显示结果正常, 然后通过方向键换图成imageArray[1],结果发现第二幅图像没有替换第一幅,而是共同存在,一块一块的像马赛克一样;再按方向键换imageArray[2]发现,三幅图像的部分都有。
for(i=1;i<=3;++i)
{      
     newLoader.add("a\\"+i+".jpg");
}
newLoader.addEventListener(BulkLoader.COMPLETE,completeHandler);
newLoader.start();

private function completeHandler(event:Event):void {

     for(i=1;i<=3;++i)
     {
           var bmp:Bitmap = newLoader.getBitmap("a\\"+i+".jpg");
           imageArray[.push(bmp.bitmapData);
     }
     
var fileMat1:BitmapMaterial= new BitmapMaterial(imageArray[0]);
globe= new Sphere({material:fileMat1,radius:600,segmentsH:40, segmentsW:40,pushback:true});
globe.bothsides = true;
view.scene.addChild(globe);
view.render();
}

private function onKeyDown(event:KeyboardEvent):void
{
switch(event.keyCode)
{
case 38:
++num;
var fileMat2:BitmapMaterial= new BitmapMaterial(imageArray[num]);
globe= new Sphere({material:fileMat2,radius:600,segmentsH:40, segmentsW:40,pushback:true});

globe.bothsides = true;
view.scene.addChild(globe);
view.render();
break;

default:break;
}
           
}
里面载入图像我用的是BulkLoader


flash 3d 研究所 fur3
(2009-03-25 23:18:14)
因为你每次都新建了一个球,当然会重在一起
替换的时候直接
globe.material.bitmap=imageArray[num];
就可以了

flash 3d 研究所 Bruce Lau
(2009-03-25 23:47:24)
哈哈,感谢fur君啊,问题解决啦!!

赞一个!

flash 3d 研究所 fur3
(2009-03-26 10:36:22)
不错不错哈兄弟!

评论人:
邮   箱: (填入邮箱,博客地址均可)

内   容: (广告和垃圾内容可能会被删除,望理解)
链接地址

验证码:(为防止机器人骚扰,请麻烦输入验证码^_^)
  

(目前需登陆方可发表)


不想添加了