最近在看《Real Time 3D Terrain Engines Using C++And DirectX 9》,不过是看网上翻译的版本叫《实时地形引擎》 , 看英文实在蛋疼,还好有翻译版的,要多多感谢承天一大哥!这本书讲解了地形制作的一些技术,更吸引人的是实现了一个小型的渲染引擎,对于我这样的游戏引擎初学者很适合。gaia正是书中构建的引擎的名字。这里来写写一些简单的分析,作为学习笔记。
(一) 资源管理
1、 data_pool.h
cPoolGroup : 模板类,池组,顾名思义,就是装载一组数据的对象
template <
class
T>
class
cPoolGroup
{
public
:
cPoolGroup(uint16 maxCount);
~cPoolGroup(){};
void
create();
void
destroy();
uint16 addMember(
const
T& member);
uint16 nextMember();
void
release(uint16 index);
uint16 totalOpen()
const
;
uint16 totalUsed()
const
;
uint16 firstOpen()
const
;
bool
isOpen(uint16 index)
const
;
T& member(uint16 index);
const
T& member(uint16 index)
const
;
T* memberPtr(uint16 index);
const
T* memberPtr(uint16 index)
const
;
private
:
uint16 m_totalOpen;
uint16 m_firstOpen;
uint16 m_maxCount;
uint16* m_nextOpenList;
T* m_memberList;
//
数据对象链表
};
cDataPoolInterface :数据池接口,抽象类
class
cDataPoolInterface
{
public
:
typedef
void
(*MEMBER_CALLBACK)(cDataPoolInterface* pPool, cPoolHandle handle,
void
* member);
cDataPoolInterface():m_initialized(
false
){};
virtual
~cDataPoolInterface(){};
virtual
void
initialize(uint16 growSize)=
0
;;
virtual
void
destroy()=
0
;;
virtual
void
clear()=
0
;
virtual
cPoolHandle nextHandle()=
0
;
virtual
void
release(cPoolHandle* pHandle)=
0
;
virtual
void
forEach(MEMBER_CALLBACK function)=
0
;
virtual
void
* getGenericPtr(cPoolHandle index)=
0
;
bool
isInitialized()
const
{
return
m_initialized;}
protected
:
bool
m_initialized;
};
cDataPool
:模板类,继承自
cDataPoolInterface
,数据池,它包括了若干个
cPoolGroup
template <
class
T>
class
cDataPool :
public
cDataPoolInterface
{
public
:
//
Data Types & Constants...
typedef T DATA_TYPE;
typedef cPoolGroup<T> MemberGroup;
typedef std::list<MemberGroup*> MemberGroupList;
typedef cDataPoolInterface::MEMBER_CALLBACK MEMBER_CALLBACK;
//
Creators...
cDataPool();
~cDataPool();
void
initialize(uint16 growSize);
void
destroy();
const
T&
operator
[](cPoolHandle handle)
const
{
return
get
(handle);}
T&
operator
[](cPoolHandle handle) {
return
get
(handle);}
//
Mutators...
cPoolHandle add(
const
T& member);
void
clear();
cPoolHandle nextHandle();
void
release(cPoolHandle* pHandle);
void
forEach(MEMBER_CALLBACK function);
//
Accessors...
bool
isHandleValid(cPoolHandle index)
const
;
const
T&
get
(cPoolHandle index)
const
;
T* getPtr(cPoolHandle index);
void
* getGenericPtr(cPoolHandle index);
uint16 totalMembers()
const
{
return
m_totalMembers;}
uint16 totalOpen()
const
{
return
m_totalOpen;}
uint16 totalUsed()
const
{
return
m_totalMembers-m_totalOpen;}
private
:
//
Private Data...
MemberGroupList m_groupList;
//
cPoolGroup链表
uint16 m_totalMembers;
uint16 m_totalOpen;
uint16 m_groupCount;
uint32 m_indexMask;
int
m_indexShift;
//
Private Functions...
explicit
cDataPool(
const
cDataPool& Src);
cDataPool&
operator
=(
const
cDataPool& Src);
cPoolGroup<T>* addGroup();
cPoolGroup<T>* findOpenGroup(unsigned* groupNumber);
cPoolGroup<T>* getGroup(unsigned index);
const
cPoolGroup<T>* getGroup(unsigned index)
const
;
int
getGroupNumber(cPoolHandle handle)
const
;
int
getItemIndex(cPoolHandle handle)
const
;
cPoolHandle buildHandle(
int
group,
int
index)
const
;
};
2、 resource_pool.h
cResourcePoolInterface :资源池接口,抽象类
class
cResourcePoolInterface
{
public
:
union FILE_EXTENSION
{
char
ext[
4
];
uint32 fourcc;
};
typedef std::map<cString, cPoolHandle> NAME_LOOKUP_MAP;
cResourcePoolInterface();
virtual
~cResourcePoolInterface(){};
//
these functions must be proviided in the derived class (cResourceType)
virtual
void
initialize(uint16 growSize)=
0
;
virtual
void
destroy()=
0
;
virtual
bool
isInitialized()
const
=
0
;
virtual
void
destroyAll()=
0
;
virtual
void
disableAll()=
0
;
virtual
void
restoreAll()=
0
;
virtual
void
clean()=
0
;
cResourcePoolItem* createResource(
const
cString& resourceName);
cResourcePoolItem* loadResource(
const
cString& filename);
cResourcePoolItem* getResource(cPoolHandle handle);
cResourcePoolItem* findResource(
const
cString& Name);
void
destroyResource(cResourcePoolItem* pResource);
bool
saveResource(cResourcePoolItem* pResource);
cPoolHandle findResourceHandle(
const
cString& Name);
const
cString* findResourceName(cPoolHandle handle)
const
;
void
setResourceName(cPoolHandle handle,
const
tchar* name);
void
registerResourcePool(cResourceCode code);
void
unregisterResourcePool();
cResourceCode registrationCode()
const
;
protected
:
cResourceCode m_registrationCode;
NAME_LOOKUP_MAP m_nameMap;
private
:
//
Private Functions...
virtual
cPoolHandle internalCreateResource(
const
cString& resourceName)=
0
;
virtual
void
internalDestroyResource(cPoolHandle handle)=
0
;
virtual
cResourcePoolItem* internalGetResource(cPoolHandle handle)=
0
;
};
cResourcePool:模板类,资源池,继承自cResourcePoolInterface,成员中有一个DataPool可以看做是DataPool的扩充。
template <
class
T>
class
cResourcePool :
public
cResourcePoolInterface
{
public
:
typedef T DataType;
typedef cDataPool<T> DataPool;
//
Creators...
cResourcePool(){};
~cResourcePool(){};
//
Base Class Overrides...
void
initialize(uint16 growSize);
void
destroy();
bool
isInitialized()
const
;
void
destroyAll();
void
disableAll();
void
restoreAll();
void
clean();
//
delete items no longer referenced
DataType* createResource(
const
cString& resourceName);
DataType* loadResource(
const
cString& filename);
DataType* getResource(cPoolHandle handle);
DataType* findResource(
const
cString& Name);
//
static data pool callbacks
static
void
callbackDestroy(cDataPoolInterface* pPool, cPoolHandle handle,
void
* resource);
static
void
callbackRestore(cDataPoolInterface* pPool, cPoolHandle handle,
void
* resource);
static
void
callbackDisable(cDataPoolInterface* pPool, cPoolHandle handle,
void
* resource);
static
void
callbackClean(cDataPoolInterface* pPool, cPoolHandle handle,
void
* resource);
private
:
//
Data...
DataPool m_dataPool;
//
Private Functions...
cPoolHandle internalCreateResource(
const
cString& resourceName);
void
internalDestroyResource(cPoolHandle handle);
cResourcePoolItem* internalGetResource(cPoolHandle handle);
//
Nonexistant Functions...
cResourcePool(
const
cResourcePool& Src);
cResourcePool&
operator
=(
const
cResourcePool& Src);
};
cResourcePoolItem :资源池对象继承自 cReferenceCounter
关于 cReferenceCounter 上一段英文:
/* cResourcePoolItem
------------------------------------------------------------------------------------------
A cResourcePoolItem is a simple base class for a shared resource such as a texture,
animation or vertex buffer.
Note that cResourcePoolItem is derived from cReferenceCounter. The cResourcePoolManager uses
the value of the cReferenceCounter to decide when objects are no longer in use and can
be destroyed during the cResourcePoolManager::clean() function. This means the application
must update the reference count of the cResourcePoolItem whenever links between objects
are created or removed between objects. The cReferenceCounter base class provides the
functionality to manipulate the reference count.
------------------------------------------------------------------------------------------
*/
class
cResourcePoolItem :
public
cReferenceCounter
{
public
:
//
Data Types & Constants...
enum
{
nCreated=
0
,
//
the resource has been created
nLoaded,
//
the resource is filled with data and ready for use
nDisabled,
//
the resource is currently disabled for use
nAltered,
//
the resource has been altered since loaded
nTotalResourceFlags
};
//
Creators...
cResourcePoolItem();
virtual
~cResourcePoolItem();
//
User Functions
//
These function prototypes are to be used by resources that use volatile or system-specific resources.
//
Examples would be video-memory resident textures or hardware vertex buffers.
virtual
bool
createResource()=
0
;
//
innitialize the resource (called once)
virtual
bool
destroyResource()=
0
;
//
destroy the resource
virtual
bool
disableResource()=
0
;
//
purge the resource from volatile memory
virtual
bool
restoreResource()=
0
;
//
restore the resource to volatile memory
virtual
bool
loadResource(
const
tchar* filename=
0
)=
0
;
//
load the resource from a file (or NULL to use the resource name)
virtual
bool
saveResource(
const
tchar* filename=
0
)=
0
;
//
save the resource to a file (or NULL to use the resource name)
//
Accessors...
cResourceCode resourceCode()
const
;
cResourcePoolInterface* resourcePool()
const
;
cPoolHandle resourceHandle()
const
;
u32Flags resourceFlags()
const
;
bool
isResourceCreated()
const
;
bool
isResourceDisabled()
const
;
bool
isResourceLoaded()
const
;
const
cString* findResourceName()
const
;
void
setResourceName(
const
tchar* name);
void
setAlteredFlag(
bool
onOff);
bool
alteredFlag()
const
;
//
mimic COM interfaces
virtual
int32 Release();
protected
:
//
only derrived classes are permitted to modify internal members
void
setResourceCode(cResourceCode code);
void
setResourcePool(cResourcePoolInterface* interfaePtr);
void
setResourceHandle(cPoolHandle handle);
void
setResourceFlag(
int
flagBit,
bool
Setting);
void
notifyCreated();
void
notifyDisabled();
void
notifyLoaded();
void
notifyUnloaded();
void
notifyRestored();
void
notifyDestroyed();
void
notifySaved();
private
:
//
Data...
cResourceCode m_resourceCode;
cResourcePoolInterface* m_resourcePool;
cPoolHandle m_resourceHandle;
u32Flags m_resourceFlags;
//
Private Functions...
//
Nonexistant Functions...
cResourcePoolItem(
const
cResourcePoolItem& Src);
cResourcePoolItem&
operator
=(
const
cResourcePoolItem& Src);
friend cResourcePoolInterface;
};
cReferenceCounter:。。(我没太理解它的作用,望大虾指点。。)
/* cReferenceCounter
-----------------------------------------------------------------
A cReferenceCounter is a base class which allows the program
to count open instances.
-----------------------------------------------------------------
*/
class
cReferenceCounter
{
public
:
//
Construction and Destruction...
cReferenceCounter()
{
m_nReferenceCount =
0
;
}
cReferenceCounter(
const
cReferenceCounter& Src)
{
//
Reference counts are tied to a specific instance
//
i.e. they are never copied
m_nReferenceCount =
0
;
}
virtual
~cReferenceCounter()
{
//
assert if this object is still in use
assert(m_nReferenceCount ==
0
);
}
//
Operators...
cReferenceCounter&
operator
=(
const
cReferenceCounter& Src)
{
//
this function is provided in order to allow
//
derived classes to provide copy operators.
//
the reference count itself is never copied.
return
*
this
;
}
//
Mutators...
virtual
int32 AddRef()
{
assert(m_nReferenceCount != MAX_INT32);
++m_nReferenceCount;
return
(m_nReferenceCount);
};
virtual
int32 Release()
{
assert(m_nReferenceCount >
0
);
--m_nReferenceCount;
return
(m_nReferenceCount);
}
//
Accessors...
int32 referenceCount()
const
{
return
m_nReferenceCount;}
private
:
//
the internal reference count, stored in 32bits
int32 m_nReferenceCount;
};
cResourcePoolManager :单件类,资源管理器,负责申请资源池,找到资源等资源管理功能。
class
cResourcePoolManager :
public
cSingleton<cResourcePoolManager>
{
public
:
typedef std::map<cResourceCode, cResourcePoolInterface*> ResourcePoolTypeMap;
typedef std::list<cResourcePoolInterface*> ResourcePoolFamilyList;
//
Creators...
cResourcePoolManager();
~cResourcePoolManager(){};
//
registration of resource manager interfaces
void
registerResourcePool(cResourceCode code, cResourcePoolInterface* pInterface);
cResourcePoolInterface* unregisterResourcePool(cResourceCode code);
//
operations for all resource types
void
destroyAll();
void
disableAll();
void
restoreAll();
void
clean();
//
delete items no longer referenced
//
operations on specific resource types
void
destroyResourceFamily(
int
family);
void
disableResourceFamily(
int
family);
void
restoreResourceFamily(
int
family);
void
cleanResourceFamily(
int
family);
void
destroyResourceType(cResourceCode code);
void
disableResourceType(cResourceCode code);
void
restoreResourceType(cResourceCode code);
void
cleanResourceType(cResourceCode code);
cResourcePoolInterface* findResourcePool(cResourceCode code)
const
;
cPoolHandle findResourceHandle(cResourceCode code,
const
cString& Name)
const
;
cResourcePoolItem* findResource(cResourceCode code,
const
cString& Name)
const
;
cResourcePoolItem* findResource(cResourceCode code, cPoolHandle handle)
const
;
private
:
ResourcePoolFamilyList m_resourceFamilyList[k_nTotalResourceFamilies];
ResourcePoolTypeMap m_resourceTypeMap;
};
引擎中所有的资源都派生自 cResourcePoolItem ,也可以说是对 D3D 资源类的封装。例如: texture.h 里的 cTexture:
class
cTexture :
public
cResourcePoolItem
{
public
:
//
Data Types & Constants...
enum
eTextureFlags
{
k_cubeMap=
0
,
k_dynamicTexture,
k_renderTarget,
k_paletized,
k_mipMaps,
};
enum
eForcedFormatFlags
{
k_forceMipLevels=
0
,
k_forceFormat,
k_forceSize,
};
//
Creators...
cTexture();
~cTexture();
//
base resource overrides
bool
createResource();
//
innitialize the resource (called once)
bool
destroyResource();
//
destroy the resource
bool
disableResource();
//
purge the resource from volatile memory
bool
restoreResource();
//
prepare the resource for use (create any volatile memory objects needed)
bool
loadResource(
const
tchar* filename=
0
);
//
load the resource from a file (or NULL to use the resource name)
bool
saveResource(
const
tchar* filename=
0
);
//
save the resource to a file (or NULL to use the resource name)
bool
createTexture(uint32 width, uint32 height, uint32 mipLevels, uint32 usage, D3DFORMAT Format, D3DPOOL pool);
bool
createCubeTexture(uint32 size, uint32 mipLevels, uint32 usage, D3DFORMAT Format, D3DPOOL pool);
void
generateMidpointNoise(
float
falloff);
void
generatePerlinNoise(
float
scale,
int
octaves,
float
falloff);
bool
generateNormalMap(LPDIRECT3DTEXTURE9 heightMap, uint32 channel, uint32 flags,
float
amplitude);
bool
generateNormalizationCubeMap();
bool
maskWithImage(cImage* pImage);
void
releaseTexture();
bool
convertToNormalMap(
uint32 channel,
uint32 flags,
float
amplitude);
//
Accessors...
LPDIRECT3DTEXTURE9 getTexture()
const
;
bool
uploadImage(
const
cImage* pImage,
bool
copyAll =
true
);
bool
uploadCubeFace(
const
cImage* pImage, D3DCUBEMAP_FACES face,
bool
copyAll =
true
);
uint32 width()
const
{
return
m_width;}
uint32 height()
const
{
return
m_height;}
uint32 mipLevels()
const
{
return
m_mipLevels;}
uint32 d3dUsage()
const
{
return
m_d3dUsage;}
D3DFORMAT d3dFormat()
const
{
return
m_d3dFormat;}
D3DPOOL d3dPool()
const
{
return
m_d3dPool;}
bool
getSurfaceLevel(
int
level, LPDIRECT3DSURFACE9* ppSurface);
private
:
//
Data...
uint32 m_width;
uint32 m_height;
uint32 m_mipLevels;
uint32 m_d3dUsage;
D3DFORMAT m_d3dFormat;
D3DPOOL m_d3dPool;
DWORD m_d3dFilter;
DWORD m_d3dMipFilter;
D3DCOLOR m_d3dColorKey;
D3DXIMAGE_INFO m_d3dImageInfo;
PALETTEENTRY* m_pPalette;
LPDIRECT3DTEXTURE9 m_pTexture;
LPDIRECT3DCUBETEXTURE9 m_pCubeTexture;
bool
loadFromResourceFile(cFile& InputFile);
bool
configureImageSettings();
bool
checkTextureRequirements();
bool
checkCubeTextureRequirements();
bool
loadTextureFromImageFile(
const
tchar* filename);
bool
loadTextureFromMemory(uint8* memory, uint32 size);
bool
loadCubeTextureFromImageFile(
const
tchar* filename);
bool
loadCubeTextureFromMemory(uint8* memory, uint32 size);
//
Nonexistant Functions...
cTexture(
const
cTexture& Src);
cTexture&
operator
=(
const
cTexture& Src);
};
typedef cResourcePool<cTexture> cTextureManager;
此外还有 vertex_buffer.h 中的 cVertexBuffer 和 model_resource.h 中的 cModelResource
P56 有资源的使用示例
类关系图:
由 cResourcePoolManager 统一管理。
书的第四章gaia引擎总览有提到资源管理相关的内容,但是并没用对源码进行过多的解释,这部分还是要自己硬着头皮看啊。。。
不过看了这些基本理解了资源管理的原理和整个模块的结构,受益匪浅。。
3D游戏引擎编程

