您的位置:首页 > 其它

蔡军生先生第二人生的源码分析(五十)纹理图片的格式之引用类

2008-06-01 14:08 441 查看
从前面已经看到可以从服务器下载纹理图片,那么下载这些纹理图片,又是什么样的格式呢?在第二人生里,主要有三种格式:JPEG2000、TGA、RAW。虽然对应只有三种格式,但OpenGL里只能使用RAW的格式作为纹理,而JPEG2000和TGA并不能直接作纹理数据使用,因而就需要对这两种格式进行转换和管理。下面就来了解这方面的内容,看看第二人生里是怎么样把JPEG2000和TGA转换为可以使用的纹理格式的。

纹理图片的格式类的继承关系如下:
class LLThreadSafeRefCount
class LLImageBase : public LLThreadSafeRefCount
class LLImageFormatted : public LLImageBase
class LLImageJ2C : public LLImageFormatted
class LLImageTGA : public LLImageFormatted
从上面的继承关系,可以看到LLThreadSafeRefCount类是基类,主要用来作接口的引用计数。现在就先从这个类开始分析,再一个一个派生类进行具体的分析。
LLThreadSafeRefCount类的代码如下:
#001 class LLThreadSafeRefCount
#002 {
#003 public:

创建线程互斥对象。
#004 static void initClass(); // creates sMutex
#005 static void cleanupClass(); // destroys sMutex
#006
#007 private:

保存线程互斥对象。
#008 static LLMutex* sMutex;
#009

下面声明这个类不能实现类拷贝。
#010 private:
#011 LLThreadSafeRefCount(const LLThreadSafeRefCount&); // not implemented
#012 LLThreadSafeRefCount&operator=(const LLThreadSafeRefCount&); // not implemented
#013
#014 protected:
#015 virtual ~LLThreadSafeRefCount(); // use unref()
#016
#017 public:
#018 LLThreadSafeRefCount();
#019

下面是增加这个接口的引用计数。
#020 void ref()
#021 {
#022 if (sMutex) sMutex->lock();
#023 mRef++;
#024 if (sMutex) sMutex->unlock();
#025 }
#026

下面是减少这个接口的引用计数,当引用计数为0时,就删除这个整个类对象,达到释放内存的目的,这跟COM的引用计数是一样的。
#027 S32 unref()
#028 {
#029 llassert(mRef >= 1);
#030 if (sMutex) sMutex->lock();
#031 S32 res = --mRef;
#032 if (sMutex) sMutex->unlock();
#033 if (0 == res)
#034 {
#035 delete this;
#036 return 0;
#037 }
#038 return res;
#039 }

这里是获取引用计数,一般用来判断是否可以在容器里删除类对象。
#040 S32 getNumRefs() const
#041 {
#042 return mRef;
#043 }
#044
#045 private:
#046 S32 mRef;
#047 };

LLThreadSafeRefCount类是跟COM调用的对象引用计数是一样的,都是实现对象生命周期的管理,这种方法在C++是最常用、最简单的管理方法。如果在C++里不使用这种方法管理,在多线程里动态地共享对象就会有问题。比如A线程创建了一个对象OBJ,把这个对象OBJ传送给B线程和C线程,B线程和C线程谁最后做完工作就把对象OBJ删除,由于B线程和C线程之间不会有同步关系,谁最后做完工作是没有确定的,因此删除对象OBJ也是不确定的,如果采用引用计数,就解决这个问题,不用关心谁最后做完工作,这就是引用计数的方便之处。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐