7.【cocos2d-x 源码分析】:渲染部分的详细分析(中)

本文深入剖析cocos2d-x 3.3版本的渲染部分,从RenderCommand出发,详细讲解QuadCommand、PrimitiveCommand、CustomCommand、BatchCommand、TrianglesCommand及GroupCommand的实现,探讨OpenGL原理在其中的应用,并对Primitive和GLProgramState进行深入分析,揭示渲染流程的关键细节。
摘要由CSDN通过智能技术生成
对应源码位置: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 {<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值