cocos2dx源码分析:渲染指令BatchCommand

来源:互联网 发布:json是什么文件 编辑:程序博客网 时间:2024/04/29 23:40

BatchCommand是批次渲染指令,一次可以渲染多个三角形(GL_TRIANGLES),目前仅被粒子系统使用(ParticleBatchNode)
初始化参数

float globalOrder, 全局zorder,决定渲染属性GLProgram* shader, 着色程序BlendFunc blendType, 混合函数TextureAtlas *textureAtlas, 需要渲染的三角形数据const Mat4& modelViewTransform, 坐标转换矩阵uint32_t flags,标志位

BatchCommand初始化时,保存了初始化参数

void BatchCommand::init(float globalOrder, GLProgram* shader, BlendFunc blendType, TextureAtlas *textureAtlas, const Mat4& modelViewTransform, uint32_t flags){    CCASSERT(shader, "shader cannot be null");    CCASSERT(textureAtlas, "textureAtlas cannot be null");    RenderCommand::init(globalOrder, modelViewTransform, flags);    _textureID = textureAtlas->getTexture()->getName();    _blendType = blendType;    _shader = shader;    _textureAtlas = textureAtlas;    _mv = modelViewTransform;}

在处理BatchCommand时,是通过_textureAtlas->drawQuads()进行绘制的

void BatchCommand::execute(){    /*设置着色器脚本和纹理*/    // Set material    _shader->use();    _shader->setUniformsForBuiltins(_mv);    GL::bindTexture2D(_textureID);    GL::blendFunc(_blendType.src, _blendType.dst);    // Draw    _textureAtlas->drawQuads();}

最后通过drawNumberOfQuads进行渲染操作

void TextureAtlas::drawQuads(){    this->drawNumberOfQuads(_totalQuads, 0);}void TextureAtlas::drawNumberOfQuads(ssize_t numberOfQuads, ssize_t start){    CCASSERT(numberOfQuads>=0 && start>=0, "numberOfQuads and start must be >= 0");    if(!numberOfQuads)        return;    /*绑定纹理*/    GL::bindTexture2D(_texture->getName());    /*是否使用vao进行不同处理,vao是渲染优化,opengles2.0不支持,3.0支持*/    if (Configuration::getInstance()->supportsShareableVAO())    {        //        // Using VBO and VAO        //        // FIXME:: update is done in draw... perhaps it should be done in a timer        if (_dirty)         {            /*渲染数据更新*/            glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);            // option 1: subdata//            glBufferSubData(GL_ARRAY_BUFFER, sizeof(_quads[0])*start, sizeof(_quads[0]) * n , &_quads[start] );            // option 2: data//            glBufferData(GL_ARRAY_BUFFER, sizeof(quads_[0]) * (n-start), &quads_[start], GL_DYNAMIC_DRAW);            // option 3: orphaning + glMapBuffer            glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * _capacity, nullptr, GL_DYNAMIC_DRAW);            void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);            memcpy(buf, _quads, sizeof(_quads[0])* _totalQuads);            glUnmapBuffer(GL_ARRAY_BUFFER);            glBindBuffer(GL_ARRAY_BUFFER, 0);            _dirty = false;        }        GL::bindVAO(_VAOname);#if CC_REBIND_INDICES_BUFFER        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);#endif        /*绘制三角形*/        glDrawElements(GL_TRIANGLES, (GLsizei) numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0])) );        GL::bindVAO(0);#if CC_REBIND_INDICES_BUFFER        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);#endif//    glBindVertexArray(0);    }    else    {        //        // Using VBO without VAO        //        /*渲染数据更新*/#define kQuadSize sizeof(_quads[0].bl)        glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);        // FIXME:: update is done in draw... perhaps it should be done in a timer        if (_dirty)         {            glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(_quads[0]) * _totalQuads , &_quads[0] );            _dirty = false;        }        GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);        // vertices        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, vertices));        // colors        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, colors));        // tex coords        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, texCoords));        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);        /*绘制三角形*/        glDrawElements(GL_TRIANGLES, (GLsizei)numberOfQuads*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0])));        glBindBuffer(GL_ARRAY_BUFFER, 0);        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);    }    CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,numberOfQuads*6);    CHECK_GL_ERROR_DEBUG();}
0 0
原创粉丝点击