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

从前面已经看到可以从服务器下载纹理图片,那么下载这些纹理图片,又是什么样的格式呢?在第二人生里,主要有三种格式: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也是不确定的,如果采用引用计数,就解决这个问题,不用关心谁最后做完工作,这就是引用计数的方便之处。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

caimouse

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

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

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

打赏作者

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

抵扣说明:

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

余额充值