蔡军生先生第二人生的源码分析(四十九)接收服务器回应的纹理图片数据
2008-05-17 16:30
477 查看
上面已经介绍怎么样接收纹理图片头的数据,但真正的图片数据是怎么样传送回来的呢?
#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来解码。这样就完成了从服务器下载纹理图片的任务。
#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来解码。这样就完成了从服务器下载纹理图片的任务。
相关文章推荐
- 蔡军生先生第二人生的源码分析(四十八)接收服务器回应的纹理图片头数据
- 第二人生的源码分析(四十九)接收服务器回应的纹理图片数据
- 第二人生的源码分析(四十九)接收服务器回应的纹理图片数据
- 第二人生的源码分析(四十八)接收服务器回应的纹理图片头数据
- 第二人生的源码分析(四十八)接收服务器回应的纹理图片头数据
- 第二人生的源码分析(四十八)接收服务器回应的纹理图片头数据
- 蔡军生先生第二人生的源码分析(四十六)获取纹理图片的线程
- 蔡军生先生第二人生的源码分析(四十七)发送下载纹理图片请求
- 蔡军生先生第二人生的源码分析(五十)纹理图片的格式之引用类
- 蔡军生先生第二人生的源码分析(五十一)纹理图片的格式之LLImageBase类
- 蔡军生先生第二人生的源码分析(五十二) 纹理图片的格式之LLImageFormatted类
- 蔡军生先生第二人生的源码分析(三十)UDP接收数据和Windows网络关闭
- 蔡军生先生第二人生的源码分析(五十三) 纹理图片的格式之LLImageJ2C类
- 蔡军生先生第二人生的源码分析(三十一)接收数据的流量控制
- 蔡军生先生第二人生的源码分析(五十四)纹理图片的格式之LLImageTGA类
- 蔡军生先生第二人生的源码分析(三十一)接收数据的流量控制
- 蔡军生先生第二人生的源码分析(二十八)UDP发送数据的可靠性控制
- 蔡军生先生第二人生的源码分析(十七)人物Mesh数据显示的实现
- 蔡军生先生第二人生的源码分析(二十五)人物行走与服务器同步
- 蔡军生先生第二人生的源码分析(十八)人物纹理显示的实现