对应源码位置:cocos2d-x-3.3\cocos\render*
从 RenderQueue说起
//渲染 队列
class RenderQueue {
public:
void push_back(RenderCommand* command);
ssize_t size() const;
//按照 z值进行排序
void sort();
RenderCommand* operator[](ssize_t index) const;
void clear();
protected:
//用于存储 渲染命令的 三个队列
std::vector<RenderCommand*> _queueNegZ;
std::vector<RenderCommand*> _queue0;
std::vector<RenderCommand*> _queuePosZ;
};
//用于存储 渲染有透明性质的对象命令
//render queue for transparency object, NOTE that the _globalOrder of RenderCommand is the distance to the camera when added to the transparent queue
class TransparentRenderQueue {
public:
void push_back(RenderCommand* command);
ssize_t size() const
{
return _queueCmd.size();
}
void sort();
RenderCommand* operator[](ssize_t index) const;
void clear();
protected:
std::vector<RenderCommand*> _queueCmd;
};
//整个渲染队列作为 一个元素
struct RenderStackElement
{
int renderQueueID;
ssize_t currentIndex;
};
详细分析 Renderer类
下面是 Renderer
的主要数据部分,后面详细介绍它的函数及实现。
class CC_DLL Renderer
{
public:
//VBO的属性数量
static const int VBO_SIZE = 65536;
//索引buffer数据量
static const int INDEX_VBO_SIZE = VBO_SIZE * 6 / 4;
static const int BATCH_QUADCOMMAND_RESEVER_SIZE = 64;
static const int MATERIAL_ID_DO_NOT_BATCH = 0;
Renderer();
~Renderer();
//保存 各个GroupId的堆栈 注意是 栈的数据结构
std::stack<int> _commandGroupStack;
//渲染队列的队列
std::vector<RenderQueue> _renderGroups;
//透明对象渲染的处理队列
TransparentRenderQueue _transparentRenderGroups; //transparency objects
//最近一次 使用的 材质的ID
uint32_t _lastMaterialID;
MeshCommand* _lastBatchedMeshCommand;
//批次 处理的 三角形 和 四边形绘制命令
std::vector<TrianglesCommand*> _batchedCommands;
std::vector<QuadCommand*> _batchQuadCommands;
//for TrianglesCommand
V3F_C4B_T2F _verts[VBO_SIZE];
GLushort _indices[INDEX_VBO_SIZE];
GLuint _buffersVAO;
GLuint _buffersVBO[2]; //0: vertex 1: indices
//这一次 填充的数据 数目
//分别是 顶点数 以及 索引数目
int _filledVertex;
int _filledIndex;
//for QuadCommand
V3F_C4B_T2F _quadVerts[VBO_SIZE];
GLushort _quadIndices[INDEX_VBO_SIZE];
GLuint _quadVAO;
GLuint _quadbuffersVBO[2]; //0: vertex 1: indices
//四边形 数目
int _numberQuads;
bool _glViewAssigned;
// stats
ssize_t _drawnBatches;
ssize_t _drawnVertices;
//the flag for checking whether renderer is rendering
bool _isRendering;
GroupCommandManager* _groupCommandManager;
};
下面开始具体函数的 分析。
//构造函数
Renderer::Renderer()
:_lastMaterialID(0)
,_lastBatchedMeshCommand(nullptr)
,_filledVertex(0)
,_filledIndex(0)
,_numberQuads(0)
,_glViewAssigned(false)
,_isRendering(false)
#if CC_ENABLE_CACHE_TEXTURE_DATA
,_cacheTextureListener(nullptr)
#endif
{
//GroupCommandManager这个类 主要是为 GroupCommand类 分配和管理 RenderQueue
_groupCommandManager = new (std::nothrow) GroupCommandManager();
//先将 默认渲染队列 入栈
_commandGroupStack.push(DEFAULT_RENDER_QUEUE);
RenderQueue defaultRenderQueue;
//默认的渲染队列 位于首部
_renderGroups.push_back(defaultRenderQueue);
_batchedCommands.reserve(BATCH_QUADCOMMAND_RESEVER_SIZE);
}
void Renderer::initGLView()
{
#if CC_ENABLE_CACHE_TEXTURE_DATA
_cacheTextureListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom* event){
/** listen the event that renderer was recreated on Android/WP8 */
this->setupBuffer();
});
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_cacheTextureListener, -1);
#endif
//setup index data for quads
//很容易 理解 一个四边形 其实就是 就是由两个三角形
//逆时针 编号为 0 1 3 2
//那么 可以到的 0 1 2 3 2 1这样的索引顺序
for( int i=0; i < VBO_SIZE/4; i++)
{
_quadIndices[i*6+0] = (GLushort) (i*4+0);
_quadIndices[i*6+1] = (GLushort) (i*4+1);
_quadIndices[i*6+2] = (GLushort) (i*4+2);
_quadIndices[i*6+3] = (GLushort) (i*4+3);
_quadIndices[i*6+4] = (GLushort) (i*4+2);
_quadIndices[i*6+5] = (GLushort) (i*4+1);
}
//见下面 具体分析 这里是建立buffer对象
setupBuffer();
_glViewAssigned = true;
}
void Renderer::setupBuffer()
{
//看是否支持 VAO
if(Configuration::getInstance()->supportsShareableVAO())
{
setupVBOAndVAO();
}
else
{
setupVBO();
}
}
void Renderer::setupVBOAndVAO()
{
//generate vbo and vao for trianglesCommand
//先生成 三角形的VAO
glGenVertexArrays(1, &_buffersVAO);
GL::bindVAO(_buffersVAO);
//生成两个buffer 对象 分别为 VBO IBO
glGenBuffers(2, &_buffersVBO[0]);
//传输 整个数据块
glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(_verts[0]) * VBO_SIZE, _verts, GL_DYNAMIC_DRAW);
// vertices 配置 顶点数据的位置
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid*) offsetof( V3F_C4B_T2F, vertices));
// colors 配置 颜色数据的位置