对应源码位置:cocos2d-x-3.3\cocos\render*
从RenderCommand看起
class CC_DLL RenderCommand
{
public:
//以下 主要 7种
enum class Type
{
UNKNOWN_COMMAND,//这一种 就是不知道是哪一种
QUAD_COMMAND,
CUSTOM_COMMAND,
BATCH_COMMAND,
GROUP_COMMAND,
MESH_COMMAND,
PRIMITIVE_COMMAND,
TRIANGLES_COMMAND
};
/** Get Render Command Id */
inline float getGlobalOrder() const {
return _globalOrder; }
/** Returns the Command type */
inline Type getType() const {
return _type; }
//是否透明
/** Retruns whether is transparent */
inline bool isTransparent() const {
return _isTransparent; }
/** set transparent flag */
inline void setTransparent(bool isTransparent) {
_isTransparent = isTransparent; }
protected:
RenderCommand();
virtual ~RenderCommand();
void printID();
// Type used in order to avoid dynamic cast, faster
//类型
Type _type;
// commands are sort by depth
//按深度排序
float _globalOrder;
// transparent flag
bool _isTransparent;
};
QuadCommand类的实现
用来绘制一个或者多个矩形区域,简单来说 ,一个矩形区域就需要一个4个矩形顶点 一个纹理,以及一组纹理坐标。
class CC_DLL QuadCommand : public RenderCommand
{
public:
QuadCommand();
~QuadCommand();
/** Initializes the command with a globalZOrder, a texture ID, a `GLProgram`, a blending function, a pointer to quads,
* quantity of quads, and the Model View transform to be used for the quads */
void init(float globalOrder, GLuint texutreID, GLProgramState* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount,
const Mat4& mv);
void useMaterial() const;
inline uint32_t getMaterialID() const {
return _materialID; }
inline GLuint getTextureID() const {
return _textureID; }
inline V3F_C4B_T2F_Quad* getQuads() const {
return _quads; }
inline ssize_t getQuadCount() const {
return _quadsCount; }
inline GLProgramState* getGLProgramState() const {
return _glProgramState; }
inline BlendFunc getBlendType() const {
return _blendType; }
inline const Mat4& getModelView() const {
return _mv; }
protected:
void generateMaterialID();
//就是 材质的id 就是根据id相同的渲染命令 把他合并成一个批次 这就是所谓的 自动批处理。
uint32_t _materialID;
GLuint _textureID;
//程序状态
GLProgramState* _glProgramState;
//混合方式 就是alpha怎么占比的计算方式
BlendFunc _blendType;
//这个 结构体一点都不吓人
//就是 顶点使用3个float 颜色 用4个字节 纹理坐标 用2个float
V3F_C4B_T2F_Quad* _quads;
ssize_t _quadsCount;
Mat4 _mv;
};
//可以看到这个 MaterialID 使用的是 根据
// glProgram, (int)_textureID, (int)_blendType.src, (int)_blendType.dst
//生成 一个hash值 如果 这四个相同了 就可以合并成一个批次。合理
void QuadCommand::generateMaterialID()
{
if(_glProgramState->getUniformCount() > 0)
{
_materialID = Renderer::MATERIAL_ID_DO_NOT_BATCH;
}
else
{
int glProgram = (int)_glProgramState->getGLProgram()->getProgram();
int intArray[4] = {
glProgram, (int)_textureID, (int)_blendType.src, (int)_blendType.dst};
_materialID = XXH32((const void*)intArray, sizeof(intArray), 0);
}
}
//这里就是我们熟悉的 openGL部分。
void QuadCommand::useMaterial() const
{
//Set texture
GL::bindTexture2D(_textureID);
//set blend mode
GL::blendFunc(_blendType.src, _blendType.dst);
_glProgramState->apply(_mv);
}
PrimitiveCommand 类的实现
class CC_DLL PrimitiveCommand : public RenderCommand
{
public:
PrimitiveCommand();
~PrimitiveCommand();
void init(float globalOrder, GLuint textureID, GLProgramState* glProgramState, BlendFunc blendType, Primitive* primitive,const Mat4& mv);
inline uint32_t getMaterialID() const {
return _materialID; }
inline GLuint getTextureID() const {
return _textureID; }
inline GLProgramState* getGLProgramState() const {
return _glProgramState; }
inline BlendFunc getBlendType() const {
return _blendType; }
inline const Mat4& getModelView() const {
return _mv; }
//另外实现执行
void execute() const;
protected:
//除了 图元本身 其他的都与前面大同小异
uint32_t _materialID;
GLuint _textureID;
GLProgramState* _glProgramState;
BlendFunc _blendType;
Primitive* _primitive;
Mat4 _mv;
};
void PrimitiveCommand::execute() const
{
//Set texture
GL::bindTexture2D(_textureID);
//set blend mode
GL::blendFunc(_blendType.src, _blendType.dst);
_glProgramState->apply(_mv);
//图元自身的绘制 后面详细说明
_primitive->draw();
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,_primitive->getCount());
}
CustomCommand类的实现
用户自定义的绘制命令 就写在这里
class CC_DLL CustomCommand : public RenderCommand
{
public:
CustomCommand();
~CustomCommand();
public:
//留一个属性 用于渲染命令的排序
void init(float depth);
void execute();
inline bool isTranslucent() {
return true; }
std::function<void()> func;
protected:
};
//唯一一个重要函数
void CustomCommand::execute()
{
//其实就是 执行用户自定义的回调
if(func)
{
func();
}
}
BatchCommand类的实现
用于绘制 TextureAtlas
class CC_DLL BatchCommand : public RenderCommand
{
public:
BatchCommand();
~BatchCommand();
void init(float depth, GLProgram* shader, BlendFunc blendType, TextureAtlas *textureAtlas, const Mat4& modelViewTransform);
void execute();
protected:
//Material
int32_t _materialID;
GLuint _textureID;
GLProgram* _shader;
BlendFunc _blendType;
TextureAtlas *_textureAtlas;
// ModelView transform
Mat4 _mv;
};
//唯一一个重要的函数
void BatchCommand::execute()
{
// Set material
_shader->use();
_shader->setUniformsForBuiltins(_mv);
GL::bindTexture2D(_textureID);
GL::blendFunc(_blendType.src, _blendType.dst);
//核心在于 _textureAtlas的绘制方式 后面具体分析
// Draw
_textureAtlas->drawQuads();
}
TrianglesCommand类的实现
class CC_DLL TrianglesCommand : public RenderCommand
{
public:
//这里 就是 我们熟悉的 定义一系列三角形要的数据
struct Triangles
{
//多个顶点 后传到VBO
V3F_C4B_T2F* verts;
//定义 索引数据 后传到 EBO或者叫IBO
unsigned short* indices;
ssize_t vertCount;
ssize_t indexCount;
};
TrianglesCommand();
~TrianglesCommand();
/** Initializes the command with a globalZOrder, a texture ID, a `GLProgram`, a blending function, a pointer to triangles,
* quantity of quads, and the Model View transform to be used for the quads */
void init(float globalOrder, GLuint textureID, GLProgramState* glProgramState, BlendFunc blendType, const Triangles& triangles,const Mat4& mv);
void useMaterial() const;
inline uint32_t getMaterialID() const {
return _materialID; }
inline GLuint getTextureID() const {
return _textureID; }
inline const Triangles& getTriangles() const {
return _triangles; }
inline ssize_t getVertexCount() const {
return _triangles.vertCount; }
inline ssize_t getIndexCount() const {
return _triangles.indexCount; }
inline const V3F_C4B_T2F* getVertices() const {
return _triangles.verts; }
inline const unsigned short* getIndices() const {
return _triangles.indices; }
inline GLProgramState* getGLProgramState() const {<