纹理图片对于3D程序来说比较重要的数据,如果没有纹理图片,就没有亮丽的外表,就没有丰富多彩的世界。在第二人生里,纹理图片不是随着程序一起发布的,而是不断地从服务器上下载的,这点是不像其它游戏,把所有图片全部预先下载好。下面就来分析一下纹理下载线程的工作过程。
先从程序:
LLAppViewer::getTextureFetch()->createRequest(getID(),getTargetHost(), decode_priority, w, h, c, desired_discard, needsAux())
里调用createRequest函数来创建一个纹理图片下载。然后就在纹理下载线程里调用LLTextureFetch::update函数来更新这个请求,这时就启动纹理线程LLTextureFetch来获取纹理图片,而线程类LLTextureFetch是继承LLWorkerThread线程类的,因此这也是调用工作线程来运行。
如果从网络下载一个纹理图片,又是怎么执行的呢?先看下面的代码:
#001 void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
#002 {
#003
if (mRequestMap.find(worker->mID) != mRequestMap.end())
#004
{
#005
// only add to the queue if in the request map
#006
// i.e. a delete has not been requested
#007
mNetworkQueue.insert(worker->mID);
#008
}
#009
for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
#010
iter1 != mCancelQueue.end(); ++iter1)
#011
{
#012
iter1->second.erase(worker->mID);
#013
}
#014 }
上面的代码就是把这个纹理图片添加网络下载队列mNetworkQueue,然后再由网络层向服务器发送下载图片的请求。
#001 S32 LLTextureFetch::update(U32 max_time_ms)
#002 {
#003
S32 res;
#004
res = LLWorkerThread::update(max_time_ms);
#005
#006
const F32 REQUEST_TIME = 1.f;
#007
#008
// Periodically, gather the list of textures that need data from the network
#009
// And send the requests out to the simulators
#010
if (mNetworkTimer.getElapsedTimeF32() >= REQUEST_TIME)
#011
{
#012
mNetworkTimer.reset();
#013
sendRequestListToSimulators();
#014
}
#015
#016
return res;
#017 }
上面这段代码就是不断地把向网络请求下载纹理的ID向服务器发送,主要是通过函数sendRequestListToSimulators来实现的,这个函数的代码比较长,下次再分析它。