TextureAtlas的主要作用是保存了一张纹理以及一批Quad矩形顶点数据,然后一个gl draw call中,将这些顶点数据全部绘制,这些quad数据是可以动态改变的。这其实就是批量绘制(batch drawing)的基础。
一、数据结构
class CC_DLL TextureAtlas : public Ref
{
protected:
GLushort* _indices; // 顶点索引
GLuint _VAOname; // VAO
GLuint _buffersVBO[2]; //0: vertex 1: indices
bool _dirty; // indicates whether or not the array buffer of the VBO needs to be updated
ssize_t _totalQuads; // 矩形数量,一般就是一个quad一个sprite
ssize_t _capacity; // 在不触发内存重新分配的情况下,最多能有几个quad
Texture2D* _texture; // 使用到的纹理
V3F_C4B_T2F_Quad* _quads; // 矩形顶点数据数组,一个或多个quad
// 一个quad 4个顶点,构成两个三角形,每个顶点的数据如下:
// 顶点坐标:V3F,3个float(x、y、z)
// 颜色数据:C4B,4个byte(r、g、b、a)
// 纹理坐标;T2F,2个float(u,v)
#if CC_ENABLE_CACHE_TEXTURE_DATA
EventListenerCustom* _rendererRecreatedListener;
#endif
};
二、创建
class CC_DLL TextureAtlas : public Ref
{
public:
// file: texutre的image file path
// capacity: 预计最多会有几个quad,避免频繁的内存重分配
static TextureAtlas* create(const std::string& file , ssize_t capacity);
static TextureAtlas* createWithTexture(Texture2D *texture, ssize_t capacity);
}
三、绘制
class CC_DLL TextureAtlas : public Ref
{
// 绘制从0 ~ n-1的quad,n<=capacity
void drawNumberOfQuads(ssize_t n);
// 绘制从start ~ n + start-1的quad,n + start-1 <= capacity
void drawNumberOfQuads(ssize_t n, ssize_t start);
// 绘制所有quad
void drawQuads();
}
四、更新quad顶点数据
class CC_DLL TextureAtlas : public Ref
{
public:
// ********************************************************
// ****************** 改
// ********************************************************
void setQuads(V3F_C4B_T2F_Quad* quads);
void updateQuad(V3F_C4B_T2F_Quad* quad, ssize_t index);
// Moves an amount of quads from oldIndex at newIndex.
void moveQuadsFromIndex(ssize_t oldIndex, ssize_t amount, ssize_t newIndex);
// Moves quads from index till totalQuads to the newIndex.Used internally by ParticleBatchNode.
// This method doesn't enlarge the array if newIndex + quads to be moved > capacity.
void moveQuadsFromIndex(ssize_t index, ssize_t newIndex);
// fill an amout of empty quads at index. Used internally by ParticleBatchNode.
void fillWithEmptyQuadsFromIndex(ssize_t index, ssize_t amount);
// ********************************************************
// ****************** 插
// ********************************************************
void insertQuad(V3F_C4B_T2F_Quad* quad, ssize_t index);
// 在index开始,插入amount个quad,数据在quads中。
void insertQuads(V3F_C4B_T2F_Quad* quads, ssize_t index, ssize_t amount);
// 将fromIndex的quad插入到newIndex位置
void insertQuadFromIndex(ssize_t fromIndex, ssize_t newIndex);
// ********************************************************
// ****************** 删
// ********************************************************
void removeQuadAtIndex(ssize_t index);
void removeQuadsAtIndex(ssize_t index, ssize_t amount);
// 数组的内的数据不会变动,仅仅是标记有用元素为0个。
void removeAllQuads();
}