Layercolor of cocos2dx engine 12-opengles Rendering

Source: Internet
Author: User

In the previous microblog, we talked about how to prepare shader for OpenGL rendering of the cocos2dx engine. In this blog, we will use layercolor to describe the rendering process of OpenGL.

 

1. Create a layercolor object

Add the layercolor element to the game:

autolayerColor = LayerColor::create(Color4B(255, 0, 0, 255), 100, 100);layerColor->setPosition(100,100);this->addChild(layerColor);

The following is the layercolor: Create method:

LayerColor* LayerColor::create(const Color4B& color, GLfloat width, GLfloat height){    LayerColor * layer = new LayerColor();    if( layer &&layer->initWithColor(color,width,height)) {        layer->autorelease();        return layer;    }    CC_SAFE_DELETE(layer);    return nullptr;}

1. Use the new operator to create a new layercolor object.

2. Use the initwithcolor method to initialize the new layercolor object.

3. After layercolor is created and initialized, it is automatically heated to memory management.

 

In the layercolor: initwithcolor method:

boolLayerColor::initWithColor(const Color4B& color, GLfloat w, GLfloat h){    if (Layer::init()){        _blendFunc =BlendFunc::ALPHA_NON_PREMULTIPLIED;        _displayedColor.r = _realColor.r =color.r;        _displayedColor.g = _realColor.g =color.g;        _displayedColor.b = _realColor.b =color.b;        _displayedOpacity = _realOpacity =color.a;        for (size_t i = 0;i<sizeof(_squareVertices) / sizeof( _squareVertices[0]); i++ )        {            _squareVertices[i].x = 0.0f;            _squareVertices[i].y = 0.0f;        }         updateColor();        setContentSize(Size(w, h));        setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_COLOR_NO_MVP));        return true;    }    return false;}

1. Call the layer: Init () method. The main function of this method is to set the default size. In fact, the layercolor size will be reset below.

2. Set the mixed mode to _ blendfunc = blendfunc: alpha_non_premultiplied.

3. Set the color of the four vertices.

4. Set the coordinates of the four vertices and the layer size.

5. Set the glprogramstate corresponding to the shader program used for layercolor rendering.

Layercolor is actually a quadrilateral. OpenGL will render layercolor in a quadrilateral mode. Therefore, you need to set the vertex coordinates and color of the Quadrilateral. All glprogramstates will be kept in glprogramstatecache: _ glprogramstates, when you obtain the glprogramstate for the first time, a new glprogramstate object is created and inserted into glprogramstatecache: _ glprogramstates.

 

2. layercolor Rendering

First, let's take a look at the function calling process of the game:

Application::run(){    ……DisplayLinkDirector::mainLoop()    ……}DisplayLinkDirector::mainLoop(){    ……Director::drawScene()…………}Director::drawScene(){    ……Node::visit(…)    ……Renderer::render()……}Node::visit(…){    ……    LayerColor::draw(…)……}

Layercolor: Draw (...) The method is as follows:

voidLayerColor::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags){    _customCommand.init(_globalZOrder);    _customCommand.func =CC_CALLBACK_0(LayerColor::onDraw, this, transform, flags);   renderer->addCommand(&_customCommand);       for(int i = 0; i < 4; ++i)    {        Vec4 pos;        pos.x = _squareVertices[i].x; pos.y =_squareVertices[i].y; pos.z = _positionZ;        pos.w = 1;       _modelViewTransform.transformVector(&pos);        _noMVPVertices[i] =Vec3(pos.x,pos.y,pos.z)/pos.w;    }}

1. initialize the _ mmcommand object. _ customcommand is a rendering command.

2. Set the callback function of _ customcommand to layercolor: ondraw.

3. Add the rendering instruction _ customcommand of layercolor to the rendering queue.

4. Convert the four vertices through the model view matrix.

 

Renderer: addcommand (...) The method is as follows:

voidRenderer::addCommand(RenderCommand* command){    int renderQueue =_commandGroupStack.top();    addCommand(command, renderQueue);}voidRenderer::addCommand(RenderCommand* command, int renderQueue){    _renderGroups[renderQueue].push_back(command);}

1. Obtain the _ commandgroupstack stack. In fact, _ commandgroupstack stores the position number of the _ rendergroups array.

2. Add the new rendering command to the _ rendergroups [renderqueue] stack.

 

Renderer: render () method:

voidRenderer::render(){    _isRendering = true;       if (_glViewAssigned)    {        _drawnBatches = _drawnVertices = 0;        for (auto &renderqueue : _renderGroups){            renderqueue.sort();        }        visitRenderQueue(_renderGroups[0]);        flush();    }    clean();    _isRendering = false;}

1. Set _ isrendering whether to render the frame to true.

2. Traverse _ rendergroups and sort renderqueue

3. In fact, only one rendering set exists in _ rendergroups.

4. Refresh parameters in OpenGL

5. Enable _ rendergroups to all commandclean

 

Renderqueue: Sort () Rendering command sorting method:

voidRenderQueue::sort(){      std::sort(std::begin(_queueNegZ),std::end(_queueNegZ), compareRenderCommand);    std::sort(std::begin(_queuePosZ), std::end(_queuePosZ),compareRenderCommand);}staticbool compareRenderCommand(RenderCommand* a, RenderCommand* b){    return a->getGlobalOrder() < b->getGlobalOrder();}

1. Sort the set of commands whose element zcoordinates are less than 0 in descending order.

2. Sort the set of commands whose element zcoordinates are greater than 0 in descending order.

 

Renderer: visitrenderqueue method:

voidRenderer::visitRenderQueue(const RenderQueue& queue){    ssize_t size = queue.size();       for (ssize_t index = 0; index < size; ++index){        auto command = queue[index];        auto commandType = command->getType();        if(RenderCommand::Type::QUAD_COMMAND ==commandType) {           ……        }else if(RenderCommand::Type::GROUP_COMMAND== commandType) {            ……        }else if(RenderCommand::Type::CUSTOM_COMMAND== commandType) {            ……            }else if(RenderCommand::Type::BATCH_COMMAND ==commandType) {            ……        }else if (RenderCommand::Type::MESH_COMMAND== commandType) {            ……      }    }}

1. Get the length of renderqueue

2. traverse the renderqueue list and process different rendering commands respectively.

3. When the rendering commad type is quad_command

4. When the rendering commad type is group_command

5. When the rendering commad type is custom_command

6. When the rendering commad type is batch_command

7. When the rendering commad type is mesh_command

Due to the limited space, the specific process of each rendering will be discussed later. Since layercolor uses customcommand, the following will analyze the specific Rendering Method of customcommand.

elseif(RenderCommand::Type::CUSTOM_COMMAND == commandType){    flush();    auto cmd = static_cast<CustomCommand*>(command);    cmd->execute();}

1. Update OpenGL parameters. The operations to be performed before each rendering are used to set OpenGL parameters to the default state.

2. Force the conversion type and execute the rendering command.

voidCustomCommand::execute(){    if(func) {        func();    }}

Determines whether func is empty. If func is not empty, execute this method. func is a callback function that is specified when layercolor is added, for example, _ customcommand. func = cc_callback_0 (layercolor: ondraw, this, transform, flags)

 

The real rendering part of layercolor:

voidLayerColor::onDraw(const Mat4& transform, uint32_t flags){    getGLProgram()->use();    getGLProgram()->setUniformsForBuiltins(transform); GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POSITION| GL::VERTEX_ATTRIB_FLAG_COLOR );     glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION,3, GL_FLOAT, GL_FALSE, 0, _noMVPVertices);    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR,4, GL_FLOAT, GL_FALSE, 0, _squareColors);     GL::blendFunc( _blendFunc.src, _blendFunc.dst);    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);    CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,4);}

1. Use the corresponding shader Program

2. Set the corresponding uniforms Matrix

3. Enabling vertex array and color array functions in OpenGL

4. Set the four vertices and colors of the Quadrilateral.

5. Set the hybrid mode

6. Draw a quadrilateral using gldrawarrays

Layercolor is actually a color quadrilateral. To render layercolor, you only need to draw a color quadrilateral in the correct position. cocos2dx uses OpenGL ES (different Windows platforms) for rendering ), there is no method for drawing a quadrilateral directly in OpenGL ES. Therefore, you need to draw a quadrilateral using the method of drawing a triangle, such as gldrawarrays (gl_triangle_strip, 0, 4;

Layercolor of cocos2dx engine 12-opengles Rendering

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.