蔡军生先生第二人生的源码分析(五十)纹理图片的格式之引用类
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也是不确定的,如果采用引用计数,就解决这个问题,不用关心谁最后做完工作,这就是引用计数的方便之处。
纹理图片的格式类的继承关系如下:
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也是不确定的,如果采用引用计数,就解决这个问题,不用关心谁最后做完工作,这就是引用计数的方便之处。
相关文章推荐
- 第二人生的源码分析(五十)纹理图片的格式之引用类
- 第二人生的源码分析(五十)纹理图片的格式之引用类
- 蔡军生先生第二人生的源码分析(五十一)纹理图片的格式之LLImageBase类
- 蔡军生先生第二人生的源码分析(五十二) 纹理图片的格式之LLImageFormatted类
- 蔡军生先生第二人生的源码分析(五十三) 纹理图片的格式之LLImageJ2C类
- 蔡军生先生第二人生的源码分析(五十四)纹理图片的格式之LLImageTGA类
- 蔡军生先生第二人生的源码分析(四十七)发送下载纹理图片请求
- 蔡军生先生第二人生的源码分析(四十八)接收服务器回应的纹理图片头数据
- 蔡军生先生第二人生的源码分析(四十九)接收服务器回应的纹理图片数据
- 蔡军生先生第二人生的源码分析(四十六)获取纹理图片的线程
- 第二人生的源码分析(五十二) 纹理图片的格式之LLImageFormatted类
- 蔡军生先生第二人生的源码分析(十八)人物纹理显示的实现
- 第二人生的源码分析(五十二) 纹理图片的格式之LLImageFormatted类
- 第二人生的源码分析(五十一)纹理图片的格式之LLImageBase类
- 第二人生的源码分析(五十四)纹理图片的格式之LLImageTGA类
- 第二人生的源码分析(五十一)纹理图片的格式之LLImageBase类
- 第二人生的源码分析(五十四)纹理图片的格式之LLImageTGA类
- 第二人生的源码分析(四十九)接收服务器回应的纹理图片数据
- 蔡军生先生第二人生的源码分析(1)第一个画面
- 蔡军生先生第二人生的源码分析(9)登录界面显示