void Renderer::visitTransparentRenderQueue(const TransparentRenderQueue& queue) { // do not batch for transparent objects ssize_t size = queue.size(); _batchedCommands.clear(); _filledVertex = 0; _filledIndex = 0; for (ssize_t index = 0; index < size; ++index) { auto command = queue[index]; auto commandType = command->getType(); if( RenderCommand::Type::TRIANGLES_COMMAND == commandType) { auto cmd = static_cast<TrianglesCommand*>(command); _batchedCommands.push_back(cmd); fillVerticesAndIndices(cmd); drawBatchedTriangles(); } else if(RenderCommand::Type::QUAD_COMMAND == commandType) { auto cmd = static_cast<QuadCommand*>(command); _batchQuadCommands.push_back(cmd); fillQuads(cmd); drawBatchedQuads(); } else if(RenderCommand::Type::GROUP_COMMAND == commandType) { int renderQueueID = (static_cast<GroupCommand*>(command))->getRenderQueueID(); visitRenderQueue(_renderGroups[renderQueueID]); } else if(RenderCommand::Type::CUSTOM_COMMAND == commandType) { auto cmd = static_cast<CustomCommand*>(command); cmd->execute(); } else if(RenderCommand::Type::BATCH_COMMAND == commandType) { auto cmd = static_cast<BatchCommand*>(command); cmd->execute(); } else if(RenderCommand::Type::PRIMITIVE_COMMAND == commandType) { auto cmd = static_cast<PrimitiveCommand*>(command); cmd->execute(); } else if (RenderCommand::Type::MESH_COMMAND == commandType) { auto cmd = static_cast<MeshCommand*>(command); cmd->execute(); } else { CCLOGERROR("Unknown commands in renderQueue"); } } }
void Renderer::processRenderCommand(RenderCommand* command) { auto commandType = command->getType(); if( RenderCommand::Type::TRIANGLES_COMMAND == commandType) { //Draw if we have batched other commands which are not triangle command flush3D(); flushQuads(); //Process triangle command auto cmd = static_cast<TrianglesCommand*>(command); //Draw batched Triangles if necessary if(cmd->isSkipBatching() || _filledVertex + cmd->getVertexCount() > VBO_SIZE || _filledIndex + cmd->getIndexCount() > INDEX_VBO_SIZE) { CCASSERT(cmd->getVertexCount()>= 0 && cmd->getVertexCount() < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command"); CCASSERT(cmd->getIndexCount()>= 0 && cmd->getIndexCount() < INDEX_VBO_SIZE, "VBO for index is not big enough, please break the data down or use customized render command"); //Draw batched Triangles if VBO is full drawBatchedTriangles(); } //Batch Triangles _batchedCommands.push_back(cmd); fillVerticesAndIndices(cmd); if(cmd->isSkipBatching()) { drawBatchedTriangles(); } } else if ( RenderCommand::Type::QUAD_COMMAND == commandType ) { //Draw if we have batched other commands which are not quad command flush3D(); flushTriangles(); //Process quad command auto cmd = static_cast<QuadCommand*>(command); //Draw batched quads if necessary if(cmd->isSkipBatching()|| (_numberQuads + cmd->getQuadCount()) * 4 > VBO_SIZE ) { CCASSERT(cmd->getQuadCount()>= 0 && cmd->getQuadCount() * 4 < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command"); //Draw batched quads if VBO is full drawBatchedQuads(); } //Batch Quads _batchQuadCommands.push_back(cmd); fillQuads(cmd); if(cmd->isSkipBatching()) { drawBatchedQuads(); } } else if (RenderCommand::Type::MESH_COMMAND == commandType) { flush2D(); auto cmd = static_cast<MeshCommand*>(command); if (cmd->isSkipBatching() || _lastBatchedMeshCommand == nullptr || _lastBatchedMeshCommand->getMaterialID() != cmd->getMaterialID()) { flush3D(); if(cmd->isSkipBatching()) { // XXX: execute() will call bind() and unbind() // but unbind() shouldn't be call if the next command is a MESH_COMMAND with Material. // Once most of cocos2d-x moves to Pass/StateBlock, only bind() should be used. cmd->execute(); } else { cmd->preBatchDraw(); cmd->batchDraw(); _lastBatchedMeshCommand = cmd; } } else { cmd->batchDraw(); } } else if(RenderCommand::Type::GROUP_COMMAND == commandType) { flush(); int renderQueueID = ((GroupCommand*) command)->getRenderQueueID(); visitRenderQueue(_renderGroups[renderQueueID]); } else if(RenderCommand::Type::CUSTOM_COMMAND == commandType) { flush(); auto cmd = static_cast<CustomCommand*>(command); cmd->execute(); } else if(RenderCommand::Type::BATCH_COMMAND == commandType) { flush(); auto cmd = static_cast<BatchCommand*>(command); cmd->execute(); } else if(RenderCommand::Type::PRIMITIVE_COMMAND == commandType) { flush(); auto cmd = static_cast<PrimitiveCommand*>(command); cmd->execute(); } else { CCLOGERROR("Unknown commands in renderQueue"); } }
void Renderer::processRenderCommand(RenderCommand* command) { auto commandType = command->getType(); if( RenderCommand::Type::TRIANGLES_COMMAND == commandType) { //Draw if we have batched other commands which are not triangle command flush3D(); flushQuads(); //Process triangle command auto cmd = static_cast<TrianglesCommand*>(command); //Draw batched Triangles if necessary if(cmd->isSkipBatching() || _filledVertex + cmd->getVertexCount() > VBO_SIZE || _filledIndex + cmd->getIndexCount() > INDEX_VBO_SIZE) { CCASSERT(cmd->getVertexCount()>= 0 && cmd->getVertexCount() < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command"); CCASSERT(cmd->getIndexCount()>= 0 && cmd->getIndexCount() < INDEX_VBO_SIZE, "VBO for index is not big enough, please break the data down or use customized render command"); //Draw batched Triangles if VBO is full drawBatchedTriangles(); } //Batch Triangles _batchedCommands.push_back(cmd); fillVerticesAndIndices(cmd); if(cmd->isSkipBatching()) { drawBatchedTriangles(); } } else if ( RenderCommand::Type::QUAD_COMMAND == commandType ) { //Draw if we have batched other commands which are not quad command flush3D(); flushTriangles(); //Process quad command auto cmd = static_cast<QuadCommand*>(command); //Draw batched quads if necessary if(cmd->isSkipBatching()|| (_numberQuads + cmd->getQuadCount()) * 4 > VBO_SIZE ) { CCASSERT(cmd->getQuadCount()>= 0 && cmd->getQuadCount() * 4 < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command"); //Draw batched quads if VBO is full drawBatchedQuads(); } //Batch Quads _batchQuadCommands.push_back(cmd); fillQuads(cmd); if(cmd->isSkipBatching()) { drawBatchedQuads(); } } else if (RenderCommand::Type::MESH_COMMAND == commandType) { flush2D(); auto cmd = static_cast<MeshCommand*>(command); if (cmd->isSkipBatching() || _lastBatchedMeshCommand == nullptr || _lastBatchedMeshCommand->getMaterialID() != cmd->getMaterialID()) { flush3D(); if(cmd->isSkipBatching()) { cmd->execute(); } else { cmd->preBatchDraw(); cmd->batchDraw(); _lastBatchedMeshCommand = cmd; } } else { cmd->batchDraw(); } } else if(RenderCommand::Type::GROUP_COMMAND == commandType) { flush(); int renderQueueID = ((GroupCommand*) command)->getRenderQueueID(); visitRenderQueue(_renderGroups[renderQueueID]); } else if(RenderCommand::Type::CUSTOM_COMMAND == commandType) { flush(); auto cmd = static_cast<CustomCommand*>(command); cmd->execute(); } else if(RenderCommand::Type::BATCH_COMMAND == commandType) { flush(); auto cmd = static_cast<BatchCommand*>(command); cmd->execute(); } else if(RenderCommand::Type::BEGIN_SCISSOR_COMMAND == commandType) { flush(); command->execute<BeginScissorCommand>(); } else if(RenderCommand::Type::END_SCISSOR_COMMAND == commandType) { flush(); command->execute<EndScissorCommand>(); } else if(RenderCommand::Type::BEGIN_STENCIL_COMMAND == commandType) { flush(); command->execute<BeginStencilCommand>(); } else if(RenderCommand::Type::AFTER_STENCIL_COMMAND == commandType) { flush(); command->execute<AfterStencilCommand>(); } else if(RenderCommand::Type::END_STENCIL_COMMAND == commandType) { flush(); command->execute<EndStencilCommand>(); } else { CCLOGERROR("Unknown commands in renderQueue"); } }
void Renderer::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::TRIANGLES_COMMAND == commandType) { flush3D(); if(_numberQuads > 0) { drawBatchedQuads(); _lastMaterialID = 0; } auto cmd = static_cast<TrianglesCommand*>(command); //Batch Triangles if( _filledVertex + cmd->getVertexCount() > VBO_SIZE || _filledIndex + cmd->getIndexCount() > INDEX_VBO_SIZE) { CCASSERT(cmd->getVertexCount()>= 0 && cmd->getVertexCount() < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command"); CCASSERT(cmd->getIndexCount()>= 0 && cmd->getIndexCount() < INDEX_VBO_SIZE, "VBO for index is not big enough, please break the data down or use customized render command"); //Draw batched Triangles if VBO is full drawBatchedTriangles(); } _batchedCommands.push_back(cmd); fillVerticesAndIndices(cmd); } else if ( RenderCommand::Type::QUAD_COMMAND == commandType ) { flush3D(); if(_filledIndex > 0) { drawBatchedTriangles(); _lastMaterialID = 0; } auto cmd = static_cast<QuadCommand*>(command); //Batch quads if( (_numberQuads + cmd->getQuadCount()) * 4 > VBO_SIZE ) { CCASSERT(cmd->getQuadCount()>= 0 && cmd->getQuadCount() * 4 < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command"); //Draw batched quads if VBO is full drawBatchedQuads(); } _batchQuadCommands.push_back(cmd); fillQuads(cmd); } else if(RenderCommand::Type::GROUP_COMMAND == commandType) { flush(); int renderQueueID = ((GroupCommand*) command)->getRenderQueueID(); visitRenderQueue(_renderGroups[renderQueueID]); } else if(RenderCommand::Type::CUSTOM_COMMAND == commandType) { flush(); auto cmd = static_cast<CustomCommand*>(command); cmd->execute(); } else if(RenderCommand::Type::BATCH_COMMAND == commandType) { flush(); auto cmd = static_cast<BatchCommand*>(command); cmd->execute(); } else if(RenderCommand::Type::PRIMITIVE_COMMAND == commandType) { flush(); auto cmd = static_cast<PrimitiveCommand*>(command); cmd->execute(); } else if (RenderCommand::Type::MESH_COMMAND == commandType) { flush2D(); auto cmd = static_cast<MeshCommand*>(command); if (_lastBatchedMeshCommand == nullptr || _lastBatchedMeshCommand->getMaterialID() != cmd->getMaterialID()) { flush3D(); cmd->preBatchDraw(); cmd->batchDraw(); _lastBatchedMeshCommand = cmd; } else { cmd->batchDraw(); } } else { CCLOGERROR("Unknown commands in renderQueue"); } } }