第二人生的源码分析(四十九)接收服务器回应的纹理图片数据

上面已经介绍怎么样接收纹理图片头的数据,但真正的图片数据是怎么样传送回来的呢?
#001 // static
#002 void LLViewerImageList::receiveImagePacket(LLMessageSystem *msg, void **user_data)
#003 {
#004       LLMemType mt1(LLMemType::MTYPE_APPFMTIMAGE);
#005       LLFastTimer t(LLFastTimer::FTM_PROCESS_IMAGES);
#006      
#007       // Receives image packet, copy into image object,
#008       // checks if all packets received, decompresses if so.
#009      
#010       LLUUID id;
#011       U16 packet_num;
#012      
#013       char ip_string[256];
 
把二进制的IP地址转换为字符串的方式。
#014       u32_to_ip_string(msg->getSenderIP(),ip_string);
#015      
 
查看这个消息是否压缩,如果压缩就有不同的数据大小。
#016       if (msg->getReceiveCompressedSize())
#017       {
#018              gImageList.sTextureBits += msg->getReceiveCompressedSize() * 8;
#019       }
#020       else
#021       {
#022              gImageList.sTextureBits += msg->getReceiveSize() * 8;
#023       }
#024       gImageList.sTexturePackets++;
#025      
 
获取图片的ID。
#026       //llprintline("Start decode, image header...");
#027       msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
#028       msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num);
 
获取这次传送图片数据的大小。
#029       S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data);
#030      
#031       if (!data_size)
#032       {
#033              return;
#034       }
#035       if (data_size < 0)
#036       {
#037              // msg->getSizeFast() is probably trying to tell us there
#038              // was an error.
#039              llerrs << "image data chunk size was negative: "
#040              << data_size << llendl;
#041              return;
#042       }
#043       if (data_size > MTUBYTES)
#044       {
#045              llerrs << "image data chunk too large: " << data_size << " bytes" << llendl;
#046              return;
#047       }
 
创建保存数据的缓冲区。
#048       U8 *data = new U8[data_size];
 
从消息里获取图片数据。
#049       msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
#050      
 
取得管理这个图片ID的对象。
#051       LLViewerImage *image = gImageList.getImage(id);
#052       if (!image)
#053       {
#054              delete [] data;
#055              return;
#056       }
 
更新发送定时器。
#057       image->mLastPacketTimer.reset();
 
把数据放到解码线程里。
#058       bool res = LLAppViewer::getTextureFetch()->receiveImagePacket(msg->getSender(), id, packet_num, data_size, data);
#059       if (!res)
#060       {
#061              delete[] data;
#062       }
#063 }
 
通过上面函数的接收到数据,并放到解码线程里准备解码,然后生成原始的纹理图片。通过LLTextureFetchWorker::insertPacket函数来保存数据到图片数据管理器里,由于不断地以分包数据的方式从服务器下载图片,然后再通过函数LLTextureFetchWorker::processSimulatorPackets来组成图片,并测试它是否全部下载了所有数据。如果下载完成,就可通过函数LLTextureFetchWorker::decodeImage来解码。这样就完成了从服务器下载纹理图片的任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值