日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[转贴]Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程

發(fā)布時(shí)間:2023/12/13 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转贴]Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

看了opengles有一段時(shí)間了,算是了解了一下下。然后,就在基本要決定還是回歸cocos2dx 3.2的,看了這篇好文章,欣喜轉(zhuǎn)之~?

推薦看原帖:?Cocos2d-x3.2與OpenGL渲染總結(jié)(一)Cocos2d-x3.2的渲染流程

最近幾天,我都在學(xué)習(xí)如何在Cocos2d-x 3.2中使用OpenGL來實(shí)現(xiàn)對(duì)圖形的渲染。在網(wǎng)上也看到了很多好的文章,在這些文章基礎(chǔ)上做了這次的我個(gè)人認(rèn)為比較完整的總結(jié)。當(dāng)你了解了Cocos2d-x 3.2中對(duì)圖形渲染的流程,你就會(huì)覺得要學(xué)會(huì)寫自己的shader才是最重要的。

?

第一、渲染流程從2.x到3.x的變化

在2.x中,渲染過程是通過遞歸渲染樹(Rendering tree)這種圖關(guān)系來渲染關(guān)系圖。遞歸調(diào)用visit()函數(shù),并且在visit()函數(shù)中調(diào)用該節(jié)點(diǎn)的draw函數(shù)渲染各個(gè)節(jié)點(diǎn),此時(shí)draw函數(shù)的作用是直接調(diào)用OpenGL代碼進(jìn)行圖形的渲染。由于visit()和draw函數(shù)都是虛函數(shù),所以要注意執(zhí)行時(shí)的多態(tài)。那么我們來看看2.x版本中CCSprite的draw函數(shù),如代碼1。

代碼1:

1 //這是cocos2d-2.0-x-2.0.4版本的CCSprite的draw函數(shù) 2 void CCSprite::draw(void) 3 { 4 CC_PROFILER_START_CATEGORY(kCCProfilerCategorySprite, "CCSprite - draw"); 5 CCAssert(!m_pobBatchNode, "If CCSprite is being rendered by CCSpriteBatchNode, CCSprite#draw SHOULD NOT be called"); 6 CC_NODE_DRAW_SETUP(); 7 ccGLBlendFunc( m_sBlendFunc.src, m_sBlendFunc.dst ); 8 if (m_pobTexture != NULL) 9 { 10 ccGLBindTexture2D( m_pobTexture->getName() ); 11 } 12 else 13 { 14 ccGLBindTexture2D(0); 15 } 16 // 17 // Attributes 18 // 19 ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex ); 20 #define kQuadSize sizeof(m_sQuad.bl) 21 long offset = (long)&m_sQuad; 22 // vertex 23 int diff = offsetof( ccV3F_C4B_T2F, vertices); 24 glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); 25 // texCoods 26 diff = offsetof( ccV3F_C4B_T2F, texCoords); 27 glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); 28 // color 29 diff = offsetof( ccV3F_C4B_T2F, colors); 30 glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); 31 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 32 CHECK_GL_ERROR_DEBUG(); 33 #if CC_SPRITE_DEBUG_DRAW == 1 34 // draw bounding box 35 CCPoint vertices[4]={ 36 ccp(m_sQuad.tl.vertices.x,m_sQuad.tl.vertices.y), 37 ccp(m_sQuad.bl.vertices.x,m_sQuad.bl.vertices.y), 38 ccp(m_sQuad.br.vertices.x,m_sQuad.br.vertices.y), 39 ccp(m_sQuad.tr.vertices.x,m_sQuad.tr.vertices.y), 40 }; 41 ccDrawPoly(vertices, 4, true); 42 #elif CC_SPRITE_DEBUG_DRAW == 2 43 // draw texture box 44 CCSize s = this->getTextureRect().size; 45 CCPoint offsetPix = this->getOffsetPosition(); 46 CCPoint vertices[4] = { 47 ccp(offsetPix.x,offsetPix.y), ccp(offsetPix.x+s.width,offsetPix.y), 48 ccp(offsetPix.x+s.width,offsetPix.y+s.height), ccp(offsetPix.x,offsetPix.y+s.height) 49 }; 50 ccDrawPoly(vertices, 4, true); 51 #endif // CC_SPRITE_DEBUG_DRAW 52 53 CC_INCREMENT_GL_DRAWS(1); 54 55 CC_PROFILER_STOP_CATEGORY(kCCProfilerCategorySprite, "CCSprite - draw"); 56 }

?那么我們也看看3.x中Sprite的draw函數(shù),如代碼2

? ? ? 代碼2:

1 void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) 2 { 3 // Don't do calculate the culling if the transform was not updated 4 _insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds; 5 if(_insideBounds) 6 { 7 _quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform); 8 renderer->addCommand(&_quadCommand); 9 #if CC_SPRITE_DEBUG_DRAW 10 _customDebugDrawCommand.init(_globalZOrder); 11 _customDebugDrawCommand.func = CC_CALLBACK_0(Sprite::drawDebugData, this); 12 renderer->addCommand(&_customDebugDrawCommand); 13 #endif //CC_SPRITE_DEBUG_DRAW 14 } 15 }

從代碼1和代碼2的對(duì)比中,我們很容易就發(fā)現(xiàn)2.x版本中的draw函數(shù)直接調(diào)用OpengGL代碼進(jìn)行圖形渲染,而3.x版本中draw的作用是把RenderCommand添加到CommandQueue中,至于這樣做的好處是,實(shí)際的渲染API進(jìn)入其中一個(gè)與顯卡直接交流的有獨(dú)立線程的RenderQueue。

??? 從Cocos2d-x3.0開始,Cocos2d-x引入了新的渲染流程,它不像2.x版本直接在每一個(gè)node中的draw函數(shù)中直接調(diào)用OpenGL代碼進(jìn)行圖形渲染,而是通過各種RenderCommand封裝起來,然后添加到一個(gè)CommandQueue隊(duì)列里面去,而現(xiàn)在draw函數(shù)的作用就是在此函數(shù)中設(shè)置好相對(duì)應(yīng)的RenderCommand參數(shù),然后把此RenderCommand添加到CommandQueue中。最后在每一幀結(jié)束時(shí)調(diào)用renderer函數(shù)進(jìn)行渲染,在renderer函數(shù)中會(huì)根據(jù)ID對(duì)RenderCommand進(jìn)行排序,然后才進(jìn)行渲染。

?? 下面我們來看看圖1、圖2,這兩個(gè)圖形象地表現(xiàn)了Cocos2d-x3.x下RenderCommand的封裝與傳遞與及RenderCommand的排序。

??? 圖1:

??????

?

? ? 圖2:

???????

?????上面所說的各個(gè)方面都有點(diǎn)零碎,下面就對(duì)渲染的整個(gè)流程來一個(gè)從頭到尾的梳理吧。下面是針對(duì)3.2版本的,對(duì)于2.x版本的梳理不做梳理,因?yàn)槲矣玫氖?.2版本。

  首先,我們Cocos2d-x的執(zhí)行是通過Application::run()來開始的,如代碼3,此代碼目錄中在xx\cocos2d\cocos\platform\對(duì)應(yīng)平臺(tái)的目錄下,這是與多平臺(tái)實(shí)現(xiàn)有關(guān)的類,關(guān)于如何實(shí)現(xiàn)多平臺(tái)的編譯,你可以參考《Cocos2d-x3.2源碼分析(一)類FileUtils--實(shí)現(xiàn)把資源放在Resources文件目錄下達(dá)到多平臺(tái)的引用》中我對(duì)平臺(tái)編譯的分析。以防篇幅過長,只截取了重要部分,如需詳解,可以直接查看源碼。

代碼3:

1 int Application::run() 2 { 3 ... 4 director->mainLoop(); 5 ... 6  }

從代碼3中,它明顯的啟發(fā)著我們要繼續(xù)追尋Director::mainLoop()函數(shù)。在Director中mainLoop()為純函數(shù),此子類DisplayLinkDirector才有其實(shí)現(xiàn),如代碼4。

代碼4:

1 void DisplayLinkDirector::mainLoop() 2 { 3 //只有一種情況會(huì)調(diào)用到這里來,就是導(dǎo)演類調(diào)用end函數(shù) 4 if (_purgeDirectorInNextLoop) 5 { 6 _purgeDirectorInNextLoop = false; 7 //清除導(dǎo)演類 8 purgeDirector(); 9 } 10 else if (! _invalid) 11 { //繪制 12 drawScene(); 13 //清除當(dāng)前內(nèi)存池中對(duì)象,即池中每一個(gè)對(duì)象--_referenceCount 14 PoolManager::getInstance()->getCurrentPool()->clear(); 15 } 16 }

mainLoop是主線程調(diào)用的循環(huán),其中drawScene()是繪制函數(shù),接著我們繼續(xù)追尋它的代碼,如代碼5。

代碼5:

1 void Director::drawScene() 2 { 3 //計(jì)算間隔時(shí)間 4 calculateDeltaTime(); 5 6 //忽略該幀如果時(shí)間間隔接近0 7 if(_deltaTime < FLT_EPSILON) 8 { 9 return; 10 } 11 12 if (_openGLView) 13 { 14 _openGLView->pollInputEvents(); 15 } 16 17 //tick before glClear: issue #533 18 if (! _paused) 19 { 20 _scheduler->update(_deltaTime); 21 _eventDispatcher->dispatchEvent(_eventAfterUpdate); 22 } 23 24 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 25 26 /* to avoid flickr, nextScene MUST be here: after tick and before draw. 27 XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */ 28 if (_nextScene) 29 { 30 setNextScene(); 31 } 32 33 pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 34 35 // draw the scene 36 if (_runningScene) 37 { 38 _runningScene->visit(_renderer, Mat4::IDENTITY, false); 39 _eventDispatcher->dispatchEvent(_eventAfterVisit); 40 } 41 42 // draw the notifications node 43 if (_notificationNode) 44 { 45 _notificationNode->visit(_renderer, Mat4::IDENTITY, false); 46 } 47 48 if (_displayStats) 49 { 50 showStats(); 51 } 52 53 _renderer->render(); 54 _eventDispatcher->dispatchEvent(_eventAfterDraw); 55 56 popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 57 58 _totalFrames++; 59 60 // swap buffers 61 if (_openGLView) 62 { 63 _openGLView->swapBuffers(); 64 } 65 66 if (_displayStats) 67 { 68 calculateMPF(); 69 } 70 }

從代碼5中,我們看見visit()和render()函數(shù)的調(diào)用。其中visit()函數(shù)會(huì)調(diào)用draw()函數(shù)來向RenderQueue中添加RenderCommand,那么就繼續(xù)追尋visit()的代碼,如代碼6。

代碼6:

1 void Node::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags) 2 { 3 // quick return if not visible. children won't be drawn. 4 if (!_visible) 5 { 6 return; 7 } 8 9 uint32_t flags = processParentFlags(parentTransform, parentFlags); 10 11 // IMPORTANT: 12 // To ease the migration to v3.0, we still support the Mat4 stack, 13 // but it is deprecated and your code should not rely on it 14 Director* director = Director::getInstance(); 15 director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 16 director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform); 17 int i = 0; 18 if(!_children.empty()) 19 { 20 sortAllChildren(); 21 // draw children zOrder < 0 22 for( ; i < _children.size(); i++ ) 23 { 24 auto node = _children.at(i); 25 26 if ( node && node->_localZOrder < 0 ) 27 node->visit(renderer, _modelViewTransform, flags); 28 else 29 break; 30 } 31 // self draw 32 this->draw(renderer, _modelViewTransform, flags); 33 34 for(auto it=_children.cbegin()+i; it != _children.cend(); ++it) 35 (*it)->visit(renderer, _modelViewTransform, flags); 36 } 37 else 38 { 39 this->draw(renderer, _modelViewTransform, flags); 40 } 41 42 director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 43 44 // FIX ME: Why need to set _orderOfArrival to 0?? 45 // Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920 46 // reset for next frame 47 // _orderOfArrival = 0; 48 }

從代碼6中,我們可以看到“ auto node = _children.at(i);和node->visit(renderer, _modelViewTransform, flags);”,這段代碼的意思是先獲取子節(jié)點(diǎn),然后遞歸調(diào)用節(jié)點(diǎn)的visit()函數(shù),到了沒有子節(jié)點(diǎn)的節(jié)點(diǎn),開始調(diào)用draw()函數(shù)。那么我們看看draw()函數(shù)代碼,如代碼7。

代碼7:

?1 void Node::draw(Renderer* renderer, const Mat4 &transform, uint32_t flags) ?{ ?}?

好吧,從代碼7中,我們看到Node的draw什么都沒有做,是我們找錯(cuò)地方?原來draw()是虛函數(shù),所以它執(zhí)行時(shí)執(zhí)行的是該字節(jié)類的draw()函數(shù)。確實(shí)是我們找錯(cuò)地方了。那么我們分別看DrawNode::draw()、Sprite::draw()。

代碼8:

1 void DrawNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) 2 { 3 _customCommand.init(_globalZOrder); 4 _customCommand.func = CC_CALLBACK_0(DrawNode::onDraw, this, transform, flags); 5 renderer->addCommand(&_customCommand); 6 } 7 8 void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) 9 { 10 // Don't do calculate the culling if the transform was not updated 11 _insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds; 12 13 if(_insideBounds) 14 { 15 _quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform); 16 renderer->addCommand(&_quadCommand); 17 #if CC_SPRITE_DEBUG_DRAW 18 _customDebugDrawCommand.init(_globalZOrder); 19 _customDebugDrawCommand.func = CC_CALLBACK_0(Sprite::drawDebugData, this); 20 renderer->addCommand(&_customDebugDrawCommand); 21 #endif //CC_SPRITE_DEBUG_DRAW 22 } 23 }

?從代碼8中,我們可以看到在draw()函數(shù)向RenderQueue中添加RenderCommand,當(dāng)然有的類的draw()不是向RenderQueue中添加RenderCommand,而是直接使用OpenGL的API直接進(jìn)行渲染,或者做一些其他的事情。

??? 那么當(dāng)draw()都遞歸調(diào)用完了,我們來看看最后進(jìn)行渲染的Renderer::render() 函數(shù),如代碼9。

??? 代碼9:

1 void Renderer::render() 2 { 3 //Uncomment this once everything is rendered by new renderer 4 //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 5 6 //TODO setup camera or MVP 7 _isRendering = true; 8 9 if (_glViewAssigned) 10 { 11 // cleanup 12 _drawnBatches = _drawnVertices = 0; 13 14 //Process render commands 15 //1. Sort render commands based on ID 16 for (auto &renderqueue : _renderGroups) 17 { 18 renderqueue.sort(); 19 } 20 visitRenderQueue(_renderGroups[0]); 21 flush(); 22 } 23 clean(); 24 _isRendering = false; 25 }

從代碼9中,我們看到“renderqueue.sort()",這是之前所說的對(duì)命令先排序,然后才進(jìn)行渲染,“visitRenderQueue( _renderGroups[0])”就是來進(jìn)行渲染的。那么我們接著看看void Renderer::visitRenderQueue(const RenderQueue& queue)的代碼,如代碼10。

代碼10:

1 void Renderer::visitRenderQueue(const RenderQueue& queue) 2 { 3 ssize_t size = queue.size(); 4 5 for (ssize_t index = 0; index < size; ++index) 6 { 7 auto command = queue[index]; 8 auto commandType = command->getType(); 9 if(RenderCommand::Type::QUAD_COMMAND == commandType) 10 { 11 flush3D(); 12 auto cmd = static_cast<QuadCommand*>(command); 13 //Batch quads 14 if(_numQuads + cmd->getQuadCount() > VBO_SIZE) 15 { 16 CCASSERT(cmd->getQuadCount()>= 0 && cmd->getQuadCount() < VBO_SIZE, "VBO is not big enough for quad data, please break the quad data down or use customized render command"); 17 18 //Draw batched quads if VBO is full 19 drawBatchedQuads(); 20 } 21 22 _batchedQuadCommands.push_back(cmd); 23 24 memcpy(_quads + _numQuads, cmd->getQuads(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); 25 convertToWorldCoordinates(_quads + _numQuads, cmd->getQuadCount(), cmd->getModelView()); 26 27 _numQuads += cmd->getQuadCount(); 28 29 } 30 else if(RenderCommand::Type::GROUP_COMMAND == commandType) 31 { 32 flush(); 33 int renderQueueID = ((GroupCommand*) command)->getRenderQueueID(); 34 visitRenderQueue(_renderGroups[renderQueueID]); 35 } 36 else if(RenderCommand::Type::CUSTOM_COMMAND == commandType) 37 { 38 flush(); 39 auto cmd = static_cast<CustomCommand*>(command); 40 cmd->execute(); 41 } 42 else if(RenderCommand::Type::BATCH_COMMAND == commandType) 43 { 44 flush(); 45 auto cmd = static_cast<BatchCommand*>(command); 46 cmd->execute(); 47 } 48 else if (RenderCommand::Type::MESH_COMMAND == commandType) 49 { 50 flush2D(); 51 auto cmd = static_cast<MeshCommand*>(command); 52 if (_lastBatchedMeshCommand == nullptr || _lastBatchedMeshCommand->getMaterialID() != cmd->getMaterialID()) 53 { 54 flush3D(); 55 cmd->preBatchDraw(); 56 cmd->batchDraw(); 57 _lastBatchedMeshCommand = cmd; 58 } 59 else 60 { 61 cmd->batchDraw(); 62 } 63 } 64 else 65 { 66 CCLOGERROR("Unknown commands in renderQueue"); 67 } 68 } 69 }

從代碼10中,我們看到RenderCommand類型有QUAD_COMMAND,CUSTOM_COMMAND,BATCH_COMMAND,GROUP_COMMAND,MESH_COMMAND五種,這些類型的講解在下一節(jié)。

從代碼10中,好像沒有與OpenGL相關(guān)的代碼,有點(diǎn)囧。其實(shí)這OpenGL的API調(diào)用是在Renderer::drawBatchedQuads()、BatchCommand::execute()中。在代碼10中,我們也看到在QUAD_COMMAND類型中調(diào)用了drawBatchedQuads(),如代碼11。在CUSTOM_COMMAND中調(diào)用了CustomCommand::execute(),如代碼12。在BATCH_COMMAND中調(diào)用了BatchCommand::execute(),如代碼13。在MESH_COMMAND類型中調(diào)用了MeshCommand::preBatchDraw()和MeshCommand::batchDraw()。至于GROUP_COMMAND類型,就遞歸它組里的成員。

代碼11:

1 void Renderer::drawBatchedQuads() 2 { 3 //TODO we can improve the draw performance by insert material switching command before hand. 4 5 int quadsToDraw = 0; 6 int startQuad = 0; 7 8 //Upload buffer to VBO 9 if(_numQuads <= 0 || _batchedQuadCommands.empty()) 10 { 11 return; 12 } 13 14 if (Configuration::getInstance()->supportsShareableVAO()) 15 { 16 //Set VBO data 17 glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); 18 19 // option 1: subdata 20 // glBufferSubData(GL_ARRAY_BUFFER, sizeof(_quads[0])*start, sizeof(_quads[0]) * n , &_quads[start] ); 21 22 // option 2: data 23 // glBufferData(GL_ARRAY_BUFFER, sizeof(quads_[0]) * (n-start), &quads_[start], GL_DYNAMIC_DRAW); 24 25 // option 3: orphaning + glMapBuffer 26 glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * (_numQuads), nullptr, GL_DYNAMIC_DRAW); 27 void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); 28 memcpy(buf, _quads, sizeof(_quads[0])* (_numQuads)); 29 glUnmapBuffer(GL_ARRAY_BUFFER); 30 31 glBindBuffer(GL_ARRAY_BUFFER, 0); 32 33 //Bind VAO 34 GL::bindVAO(_quadVAO); 35 } 36 else 37 { 38 #define kQuadSize sizeof(_quads[0].bl) 39 glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); 40 41 glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * _numQuads , _quads, GL_DYNAMIC_DRAW); 42 43 GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); 44 45 // vertices 46 glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, vertices)); 47 48 // colors 49 glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, colors)); 50 51 // tex coords 52 glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, texCoords)); 53 54 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); 55 } 56 57 //Start drawing verties in batch 58 for(const auto& cmd : _batchedQuadCommands) 59 { 60 auto newMaterialID = cmd->getMaterialID(); 61 if(_lastMaterialID != newMaterialID || newMaterialID == QuadCommand::MATERIAL_ID_DO_NOT_BATCH) 62 { 63 //Draw quads 64 if(quadsToDraw > 0) 65 { 66 glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); 67 _drawnBatches++; 68 _drawnVertices += quadsToDraw*6; 69 70 startQuad += quadsToDraw; 71 quadsToDraw = 0; 72 } 73 74 //Use new material 75 cmd->useMaterial(); 76 _lastMaterialID = newMaterialID; 77 } 78 79 quadsToDraw += cmd->getQuadCount(); 80 } 81 82 //Draw any remaining quad 83 if(quadsToDraw > 0) 84 { 85 glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); 86 _drawnBatches++; 87 _drawnVertices += quadsToDraw*6; 88 } 89 90 if (Configuration::getInstance()->supportsShareableVAO()) 91 { 92 //Unbind VAO 93 GL::bindVAO(0); 94 } 95 else 96 { 97 glBindBuffer(GL_ARRAY_BUFFER, 0); 98 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 99 } 100 101 _batchedQuadCommands.clear(); 102 _numQuads = 0; 103 }

代碼12:

1 void CustomCommand::execute() 2 { 3 if(func) 4 { 5 func(); 6 } 7 }

代碼13:

1 void BatchCommand::execute() 2 { 3 // Set material 4 _shader->use(); 5 _shader->setUniformsForBuiltins(_mv); 6 GL::bindTexture2D(_textureID); 7 GL::blendFunc(_blendType.src, _blendType.dst); 8 9 // Draw 10 _textureAtlas->drawQuads(); 11 }

從代碼11、代碼12、代碼13中,我們都看到了這些函數(shù)中對(duì)OpenGl的API調(diào)用來進(jìn)行渲染。其中特別提醒一下,在CustomCommand::execute()中直接調(diào)用的函數(shù)是我們?cè)O(shè)置的回調(diào)函數(shù)。在這個(gè)函數(shù)中,我們可以自己使用OpenGL的API進(jìn)行圖形的渲染。這就在第三節(jié)中講如何在Cocos2d-x中自己設(shè)置渲染功能中向_customCommand添加的函數(shù)。在這里我先給出簡便的方式,_customCommand.func = CC_CALLBACK_0(HelloWorld::onDraw, this)。

?

以上就是把一個(gè)完整的渲染的流程都梳理了一片,下面我給出了流程圖,如圖3。

圖3:

第二、RenderCommand的類型

這里的類型講解主要參考這篇文章中關(guān)于RenderComman的類型講解。

  • QUAD_COMMAND:QuadCommand類繪制精靈等。所有繪制圖片的命令都會(huì)調(diào)用到這里,處理這個(gè)類型命令的代碼就是繪制貼圖的openGL代碼,下一篇文章會(huì)詳細(xì)介紹這部分代碼。

  • CUSTOM_COMMAND:CustomCommand類自定義繪制,自己定義繪制函數(shù),在調(diào)用繪制時(shí)只需調(diào)用已經(jīng)傳進(jìn)來的回調(diào)函數(shù)就可以,裁剪節(jié)點(diǎn),繪制圖形節(jié)點(diǎn)都采用這個(gè)繪制,把繪制函數(shù)定義在自己的類里。這種類型的繪制命令不會(huì)在處理命令的時(shí)候調(diào)用任何一句openGL代碼,而是調(diào)用你寫好并設(shè)置給func的繪制函數(shù),后續(xù)文章會(huì)介紹引擎中的所有自定義繪制,并自己實(shí)現(xiàn)一個(gè)自定義的繪制。

  • BATCH_COMMAND:BatchCommand類批處理繪制,批處理精靈和粒子。其實(shí)它類似于自定義繪制,也不會(huì)再render函數(shù)中出現(xiàn)任何一句openGL函數(shù),它調(diào)用一個(gè)固定的函數(shù),這個(gè)函數(shù)會(huì)在下一篇文章中介紹。

  • GROUP_COMMAND:GroupCommand類繪制組,一個(gè)節(jié)點(diǎn)包括兩個(gè)以上繪制命令的時(shí)候,把這個(gè)繪制命令存儲(chǔ)到另外一個(gè)_renderGroups中的元素中,并把這個(gè)元素的指針作為一個(gè)節(jié)點(diǎn)存儲(chǔ)到_renderGroups[0]中。

?

第三、如何在Cocos2d-x中自己設(shè)置渲染功能

1.第一種方法針對(duì)的是整個(gè)圖層的渲染

重寫visit()函數(shù),并且在visit()函數(shù)中直接向CommandQueue添加CustomCommand,設(shè)置好回調(diào)函數(shù),這個(gè)比較直接,如代碼14,代碼14是子龍山人基于Cocos2d-x學(xué)習(xí)OpenGL ES 2.0系列文章的第一篇中的部分代碼。或者重寫draw()函數(shù),并且在draw()函數(shù)中向CommandQueue添加CustomCommand,設(shè)置好回調(diào)函數(shù),這個(gè)就比較按照正規(guī)的流程走。

代碼14:

1 void HelloWorld::visit(cocos2d::Renderer *renderer, const Mat4 &transform, bool transformUpdated) 2 { 3 Layer::draw(renderer, transform, transformUpdated); 4 5 //send custom command to tell the renderer to call opengl commands 6 _customCommand.init(_globalZOrder); 7 _customCommand.func = CC_CALLBACK_0(HelloWorld::onDraw, this); 8 renderer->addCommand(&_customCommand); 9 10 11 } 12 void HelloWorld::onDraw() 13 { 14 //question1: why the triangle goes to the up side 15 //如果使用對(duì)等矩陣,則三角形繪制會(huì)在最前面 16 Director::getInstance()->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 17 Director::getInstance()->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 18 Director::getInstance()->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); 19 Director::getInstance()->loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); 20 21 &nbsp;auto glProgram = getGLProgram(); 22 23 glProgram->use(); 24 25 //set uniform values, the order of the line is very important 26 glProgram->setUniformsForBuiltins(); 27 auto size = Director::getInstance()->getWinSize(); 28 29 //use vao 30 glBindVertexArray(vao); 31 32 GLuint uColorLocation = glGetUniformLocation(glProgram->getProgram(), "u_color"); 33 34 float uColor[] = {1.0, 1.0, 1.0, 1.0}; 35 glUniform4fv(uColorLocation,1, uColor); 36 // glDrawArrays(GL_TRIANGLES, 0, 6); 37 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE,(GLvoid*)0); 38 glBindVertexArray(0); 39 CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 6); 40 CHECK_GL_ERROR_DEBUG(); 41 Director::getInstance()->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); 42 Director::getInstance()->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); 43 44 }

從代碼14中,我們看到重寫visit()函數(shù),在visit()函數(shù)中直接向RenderQueue添加RenderCommand,即“renderer->addCommand(&_customCommand);”,由于此RenderCommand類型為CustomCommand,所以要添加處理圖形渲染的回調(diào)函數(shù),即“_customCommand.func = CC_CALLBACK_0(HelloWorld::onDraw, this);”,這行代碼就是添加回調(diào)函數(shù)的,onDraw()函數(shù)中調(diào)用OpengGL的API渲染圖形。關(guān)于func是如何被調(diào)用,可以參考上面的代碼12上下文的分析。

?

2.第二種方法針對(duì)個(gè)別精靈

有時(shí)候,我們只要對(duì)個(gè)別精靈進(jìn)行特效的處理,這個(gè)精靈需要使用我們自己編寫的Shader,而圖層其他的元素按默認(rèn)處理就行了。這時(shí)候就需要第二種方法了。設(shè)置好Shader,向精靈添加Shader,最后在重寫draw函數(shù),在draw函數(shù)中進(jìn)行特效的處理,如代碼15,代碼15是《捕魚達(dá)人3》教程第二節(jié)的代碼。

代碼15:

1 bool FishLayer::init() 2 { 3 ...省略了不相關(guān)的代碼。 4 // 將vsh與fsh裝配成一個(gè)完整的Shader文件。 5 auto glprogram = GLProgram::createWithFilenames("UVAnimation.vsh", "UVAnimation.fsh"); 6 // 由Shader文件創(chuàng)建這個(gè)Shader 7 auto glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram); 8 // 給精靈設(shè)置所用的Shader 9 m_Sprite->setGLProgramState(glprogramstate); 10 11 //創(chuàng)建海龜所用的貼圖。 12 auto textrue1 = Director::getInstance()->getTextureCache()->addImage("tortoise.png"); 13 //將貼圖設(shè)置給Shader中的變量值u_texture1 14 glprogramstate->setUniformTexture("u_texture1", textrue1); 15 //創(chuàng)建波光貼圖。 16 auto textrue2 = Director::getInstance()->getTextureCache()->addImage("caustics.png"); 17 //將貼圖設(shè)置給Shader中的變量值u_lightTexture 18 glprogramstate->setUniformTexture("u_lightTexture", textrue2); 19 20 //注意,對(duì)于波光貼圖,我們希望它在進(jìn)行UV動(dòng)畫時(shí)能產(chǎn)生四方連續(xù)效果,必須設(shè)置它的紋理UV尋址方式為GL_REPEAT。 21 Texture2D::TexParams tRepeatParams; 22 tRepeatParams.magFilter = GL_LINEAR_MIPMAP_LINEAR; 23 tRepeatParams.minFilter = GL_LINEAR; 24 tRepeatParams.wrapS = GL_REPEAT; 25 tRepeatParams.wrapT = GL_REPEAT; 26 textrue2->setTexParameters(tRepeatParams); 27 //在這里,我們?cè)O(shè)置一個(gè)波光的顏色,這里設(shè)置為白色。 28 Vec4 tLightColor(1.0,1.0,1.0,1.0); 29 glprogramstate->setUniformVec4("v_LightColor",tLightColor); 30 //下面這一段,是為了將我們自定義的Shader與我們的模型頂點(diǎn)組織方式進(jìn)行匹配。模型的頂點(diǎn)數(shù)據(jù)一般包括位置,法線,色彩,紋理,以及骨骼綁定信息。而Shader需要將內(nèi)部相應(yīng)的頂點(diǎn)屬性通道與模型相應(yīng)的頂點(diǎn)屬性數(shù)據(jù)進(jìn)行綁定才能正確顯示出頂點(diǎn)。 31 long offset = 0; 32 auto attributeCount = m_Sprite->getMesh()->getMeshVertexAttribCount(); 33 for (auto k = 0; k < attributeCount; k++) { 34 auto meshattribute = m_Sprite->getMesh()->getMeshVertexAttribute(k); 35 glprogramstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib], 36 meshattribute.size, 37 meshattribute.type, 38 GL_FALSE, 39 m_Sprite->getMesh()->getVertexSizeInBytes(), 40 (GLvoid*)offset); 41 offset += meshattribute.attribSizeBytes; 42 } 43 44 //uv滾動(dòng)初始值設(shè)為0 45 m_LightAni.x = m_LightAni.y = 0; 46 return true; 47 } 48 49 void FishLayer::draw(Renderer* renderer, const Mat4 &transform, uint32_t flags) 50 { 51 if(m_Sprite) 52 { 53 //烏龜從右向左移動(dòng),移出屏幕后就回到最右邊 54 auto s = Director::getInstance()->getWinSize(); 55 m_Sprite->setPositionX(m_Sprite->getPositionX()-1); 56 if(m_Sprite->getPositionX() < -100) 57 { 58 m_Sprite->setPositionX(s.width + 10); 59 } 60 61 auto glprogramstate = m_Sprite->getGLProgramState(); 62 if(glprogramstate) 63 { 64 m_LightAni.x += 0.01; 65 if(m_LightAni.x > 1.0) 66 { 67 m_LightAni.x-= 1.0; 68 } 69 m_LightAni.y += 0.01; 70 if(m_LightAni.y > 1.0) 71 { 72 m_LightAni.y-= 1.0; 73 } 74 glprogramstate->setUniformVec2("v_animLight",m_LightAni); 75 } 76 } 77 Node::draw(renderer,transform,flags); 78 }

從代碼15中,我們可以看到先使用OpengGL的API創(chuàng)建自己的Shader,然后再把m_sprite的Shader設(shè)置為自己的Shader即“m_Sprite->setGLProgramState(glprogramstate);”,這是給精靈設(shè)置所用的Shader,這就是針對(duì)個(gè)別的精靈,而不是整個(gè)圖層。接著在draw()中,如果精靈已生成,每次調(diào)用draw()函數(shù)都改變Shader中參數(shù),以達(dá)到特別的效果。

以上都是我通過閱讀別人的代碼總結(jié)的方法,有其他的在Cocos2d-x中自己設(shè)置渲染功能的方法,可以一起溝通。

來源網(wǎng)址:http://blog.csdn.net/cbbbc/article/details/39449945

?

轉(zhuǎn)載于:https://www.cnblogs.com/slysky/p/3988430.html

總結(jié)

以上是生活随笔為你收集整理的[转贴]Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

66av99精品福利视频在线 | 天天操狠狠操 | 日韩精品一区二区三区不卡 | 亚洲国产精品成人av | 五月天久久综合网 | 精品久久久久久久久久久院品网 | 99视频在线观看一区三区 | wwwwww色| 美女视频永久黄网站免费观看国产 | 韩国av一区 | 九九精品视频在线 | 伊色综合久久之综合久久 | 97av视频在线观看 | 三级免费黄 | 久操操| 欧美疯狂性受xxxxx另类 | 人人操日日干 | 免费观看一级特黄欧美大片 | 国产高清在线观看av | 国产一区二区免费看 | 97精品国产一二三产区 | 超级碰99 | 操操操com | 九九在线免费视频 | www久久久| 亚洲精品tv久久久久久久久久 | 亚洲成aⅴ人片久久青草影院 | 操操操操网 | 人人藻人人澡人人爽 | 中文字幕乱码视频 | 国产黄色精品 | 五月婷婷综合在线 | 亚洲精品中文字幕在线 | 色婷婷免费视频 | 日韩草比| 国产精品com | 免费一级片在线观看 | 国产精品视频地址 | 娇妻呻吟一区二区三区 | 日韩国产精品毛片 | 免费视频97 | 国产五月婷 | 九九热在线视频免费观看 | 亚洲伦理精品 | 色999五月色 | 欧美一级片在线播放 | 国产美女主播精品一区二区三区 | 日韩激情久久 | 天天综合成人网 | 三级动图 | 国产精品第一视频 | 精品国产乱码久久 | 成人一区影院 | 六月丁香在线视频 | 国产精品爽爽久久久久久蜜臀 | 丁香九月激情 | 国产精品久久久久一区二区 | 999久久精品 | av三级在线看 | 免费观看国产精品 | 日韩欧美一区二区三区黑寡妇 | 婷婷深爱网 | 国产精品一区在线播放 | 又黄又爽免费视频 | 99国产一区二区三精品乱码 | 在线视频91| 亚洲清纯国产 | 午夜av在线 | 最新日本中文字幕 | 五月婷网站| 亚洲精品视频中文字幕 | 欧美黄网站 | 国产精品福利在线 | 精品免费观看视频 | 一区二区三区四区影院 | 久久免费电影网 | 一级欧美黄 | 99久久精品国产一区二区成人 | 亚洲在线国产 | 色资源二区在线视频 | 国产亚洲aⅴaaaaaa毛片 | 久久撸在线视频 | www.狠狠操.com| 国产免费一区二区三区最新 | 欧美韩国日本在线观看 | 免费看污片 | 丁香花在线观看免费完整版视频 | 高清久久久久久 | 国产精品96久久久久久吹潮 | 国产免费作爱视频 | 久久免费在线观看 | 免费的国产精品 | 综合色中文 | 久 久久影院| 日韩免费视频一区二区 | 中文字幕欧美三区 | 91传媒免费观看 | 97色在线视频 | 色综合久久五月 | 国产香蕉97碰碰碰视频在线观看 | ,午夜性刺激免费看视频 | 91色偷偷 | 狠狠狠狠狠狠天天爱 | 国产精品一区二区三区99 | 麻豆视频入口 | 久草网在线 | 在线亚洲高清视频 | 国产露脸91国语对白 | 欧美日韩免费在线视频 | 欧美日韩高清一区二区 国产亚洲免费看 | 久草在线免费新视频 | 久久er99热精品一区二区 | a成人v | 成人av一区二区在线观看 | 久久99精品久久久久久 | 日韩三级在线 | 日韩中文字幕第一页 | 手机看片久久 | 久久爱导航 | 亚洲日本va在线观看 | 91视频这里只有精品 | 久久国产成人午夜av影院宅 | 91九色精品| 激情五月在线观看 | 9热精品 | www.久久91| 九九热99视频| 国产精品久久久久aaaa九色 | 亚洲国产精品视频在线观看 | 国产精品99久久久久久久久久久久 | av福利在线| 日韩伦理一区二区三区av在线 | 亚洲一区视频在线播放 | 色91在线 | 国产一区网 | 国产精品高清av | 日韩精品欧美专区 | 亚洲理论影院 | 黄色精品在线看 | 色狠狠干 | 中文字幕欧美日韩va免费视频 | 免费精品视频在线 | 欧洲色吧 | 天天爱天天操天天爽 | 国产一级片在线播放 | 欧美大香线蕉线伊人久久 | 色婷婷久久一区二区 | 午夜精品久久久久久久99 | 亚洲理论片在线观看 | 午夜国产福利在线 | 免费在线观看污 | 国产欧美在线一区二区三区 | av免费观看网站 | www.国产视频 | www.av中文字幕.com | 五月天最新网址 | 伊人色**天天综合婷婷 | 国产小视频在线免费观看 | 五月亚洲综合 | 国产一级片免费观看 | 久久久天天操 | 99热在线国产 | 91麻豆看国产在线紧急地址 | 久久精品一二三区白丝高潮 | 国产精品免费人成网站 | 中文字幕在线观看免费高清完整版 | 日韩高清在线一区二区 | 久久在线观看 | 国产欧美精品一区aⅴ影院 99视频国产精品免费观看 | 黄色一级在线免费观看 | 久久免费看a级毛毛片 | 最近中文字幕完整视频高清1 | www.黄色网.com | 毛片激情永久免费 | 国产一区二区在线免费播放 | 91激情视频在线播放 | 日韩在线视频国产 | 国语对白少妇爽91 | 久久免费黄色网址 | 免费看成人片 | 国产小视频在线看 | 91看片淫黄大片一级在线观看 | 99re久久资源最新地址 | 日本韩国精品在线 | 日韩一级黄色大片 | 免费a网址| 久久毛片网站 | 97成人在线观看视频 | 免费成人在线观看视频 | 国产日产在线观看 | 国产精品二区三区 | 国产男女爽爽爽免费视频 | 国产精品久久久影视 | 日本高清免费中文字幕 | 婷婷色社区 | 91麻豆免费版| 日日操夜| 久久成人一区 | 国产成人av网站 | 色综合久久88色综合天天 | 2024av| 色综合色综合色综合 | 久久久精品成人 | 最新中文字幕在线播放 | 国产亚洲精品久久久久秋 | 亚洲国产精品久久久久 | 日韩av三区| 日韩欧美成人网 | 91污污视频在线观看 | 超碰人人射 | 国产男男gay做爰 | 青青河边草免费直播 | 免费www视频| av天天澡天天爽天天av | 久久久久伊人 | 日韩国产欧美在线播放 | 免费日韩 | 国产一区二区三区在线 | 热九九精品 | 91精品免费 | 看av免费网站 | 亚洲专区路线二 | 国产精品久久精品国产 | 涩五月婷婷 | 精品国产一区二区三区久久 | 97天天综合网 | 在线免费观看黄网站 | 日韩激情久久 | 日韩在线观看小视频 | 日韩视频三区 | av短片在线观看 | 日韩中文字幕一区 | 国产中的精品av小宝探花 | 九九热在线播放 | 在线成人小视频 | 成人黄色短片 | 欧美激情视频在线观看免费 | 91传媒免费在线观看 | 一区二区三区四区影院 | 日本三级吹潮在线 | 国产精品大全 | 国产精品成人免费一区久久羞羞 | 久草在线电影网 | 久久人人爽人人爽人人片av免费 | 人人超碰在线 | 奇米网网址 | 亚洲精品久久久久58 | 久草在线网址 | 精品国产自在精品国产精野外直播 | 久久精品视频2 | 亚洲精品国偷拍自产在线观看蜜桃 | 亚洲无线视频 | 成人久久久久久久久久 | 人人澡人人模 | 欧美aa一级片 | 网站在线观看你们懂的 | av在线亚洲天堂 | 少妇搡bbbb搡bbb搡忠贞 | 丝袜av一区 | 夜夜夜精品 | 中文字幕 国产 一区 | 国产一区二区三区四区在线 | 国产精品人人做人人爽人人添 | 97国产大学生情侣酒店的特点 | 国产伦理久久精品久久久久_ | 国产午夜精品免费一区二区三区视频 | 亚洲男男gaygayxxxgv | 午夜av在线播放 | 亚洲乱亚洲乱亚洲 | 手机看片中文字幕 | av丝袜美腿 | 久久精品国产精品亚洲 | 91传媒视频在线观看 | 天天色天天搞 | 中文字幕高清免费日韩视频在线 | 日韩av在线影视 | 欧美激情在线网站 | 天天干天天天 | 日p在线观看 | 国产综合小视频 | 久久99国产精品久久99 | 最新日本中文字幕 | 美国三级黄色大片 | 午夜精品一区二区三区在线视频 | 久久手机视频 | 91精品国产亚洲 | 国产一区欧美在线 | 国产日韩在线播放 | 久久曰视频 | 黄色av电影在线观看 | 国产一及片 | 2019中文最近的2019中文在线 | 久草视频99 | 蜜臀久久99精品久久久无需会员 | 欧美成年网站 | 久久久久国产精品一区 | 国产一区二区综合 | 久久婷婷色综合 | 久久视频免费观看 | 国产在线观看你懂的 | 97国产在线视频 | 欧美色操 | 国产一级黄色av | 久久久久亚洲国产 | 亚洲精品动漫在线 | 天天色天天 | 国产精品高清免费在线观看 | 国产99精品在线观看 | 亚洲国产精品久久久久婷婷884 | 97精品伊人 | 久草com | av电影在线观看完整版一区二区 | 偷拍区另类综合在线 | 国产精品自产拍在线观看桃花 | 久久在线免费视频 | 日韩三级视频在线看 | 亚洲国产成人在线观看 | 久久尤物电影视频在线观看 | va视频在线观看 | 激情电影影院 | 18国产精品福利片久久婷 | 国产精品久久久久久久久大全 | www婷婷| 99热这里只有精品久久 | 色婷婷97 | 五月婷婷狠狠 | 在线观看久 | 久草在线高清 | 最新国产在线视频 | 亚洲精品中文字幕在线观看 | 国产精品精品视频 | 在线观看你懂的网站 | 精品五月天 | 日韩欧美高清在线 | 欧美精品免费在线观看 | 国产传媒中文字幕 | 国内少妇自拍视频一区 | 国产婷婷vvvv激情久 | 在线亚洲免费视频 | 911国产在线观看 | 91九色蝌蚪国产 | 成人毛片a | 免费看一级黄色 | 国产精品一区二区av日韩在线 | 亚州国产精品视频 | 黄色日视频 | av高清一区| 久久久久久免费毛片精品 | 狠狠操影视 | 久视频在线播放 | 免费在线观看成人av | 丁香电影小说免费视频观看 | 中文字幕在线看视频 | 综合精品在线 | 欧美一区三区四区 | 最近中文字幕高清字幕在线视频 | 91亚色视频在线观看 | 黄色软件视频大全免费下载 | 91免费观看国产 | 偷拍福利视频一区二区三区 | 91在线中文字幕 | 亚洲国内精品在线 | 福利视频导航网址 | 色综合久久88色综合天天 | 日韩欧美精品免费 | 欧美怡红院视频 | 亚洲精品www久久久久久 | 丁香婷婷激情国产高清秒播 | 久久99热精品这里久久精品 | 一区三区在线欧 | 久久乐九色婷婷综合色狠狠182 | 9999亚洲 | 亚洲欧美视频网站 | 国产精品丝袜久久久久久久不卡 | 懂色av懂色av粉嫩av分享吧 | 亚洲丝袜一区二区 | 国产 视频 久久 | 久草在线视频首页 | 国产精品美女久久久久久网站 | 午夜色场 | 毛片99| av+在线播放在线播放 | avwww在线| 色婷婷丁香 | 人人草在线观看 | 黄色电影在线免费观看 | 日日骑 | 97电影在线看视频 | 国产精品视频全国免费观看 | 亚洲理论电影 | 久草视频在线资源站 | 天天操天天操天天操天天操天天操天天操 | 亚洲在线视频免费观看 | 亚洲精品视频大全 | 天天操夜夜爱 | 激情网第四色 | 成人a毛片| 久久精品网址 | 国产一区二区精品 | www.日本色 | 日本中文字幕在线免费观看 | 91国内产香蕉 | 国产一区二区中文字幕 | www色| 亚洲国产美女精品久久久久∴ | 久草视频免费观 | 日韩在线观看av | 九九热免费观看 | 免费在线观看成人小视频 | 日韩r级电影在线观看 | 亚州精品天堂中文字幕 | wwwwww黄| 激情五月婷婷综合网 | 97超碰在线免费 | 欧美韩国日本在线观看 | 久久久久久久久久久久av | 国产精品综合av一区二区国产馆 | 成人av网页| 91最新视频 | 免费亚洲视频 | 亚洲国产精品激情在线观看 | www天天干 | 最近最新中文字幕视频 | 992tv在线成人免费观看 | 精品国产伦一区二区三区免费 | 天天天综合 | av资源在线看 | 国产精品久久久久aaaa | 日韩三区在线 | 午夜在线日韩 | www色网站| 国产精品成人一区二区 | 亚洲激情一区二区三区 | 一区二区三区精品在线视频 | 国产免费高清 | 在线观看岛国av | 国产亚洲一区二区在线观看 | 黄网av在线| 伊人干综合 | 综合色综合 | 国产成人99久久亚洲综合精品 | 国产精品福利在线播放 | 天天射天天艹 | 日韩精品一区在线观看 | 国产精品白丝av | 狠狠干网址 | 在线观看精品一区 | 亚洲全部视频 | www亚洲一区 | 五月天狠狠操 | 国产成人一区二区三区在线观看 | 天天操天天干天天操天天干 | 中文字幕在线观看完整版电影 | 国产精品嫩草影院99网站 | 午夜视频免费在线观看 | .精品久久久麻豆国产精品 亚洲va欧美 | 色综合久久久久综合 | 伊人在线视频 | 国产九九在线 | 日韩精品播放 | 久久久久久久久久久久亚洲 | 99精品乱码国产在线观看 | 精品一区在线看 | 久久99精品热在线观看 | 中文字幕高清 | 亚洲精品字幕在线观看 | 亚洲精品一区二区三区在线观看 | 狠狠色丁香婷婷综合久小说久 | 天天操天天怕 | 在线韩国电影免费观影完整版 | 亚洲激情综合网 | 久久国产精品一区二区三区四区 | 中文字幕在线观看免费高清完整版 | 亚洲精品av中文字幕在线在线 | 欧美另类69| 97av影院| 人人插人人草 | 亚洲国产小视频在线观看 | 国产一区网 | 欧美久久久久久久久久久久久 | 精品在线你懂的 | 国内视频在线观看 | 日韩网站在线观看 | 国产精品一区二区美女视频免费看 | 美腿丝袜一区二区三区 | 日本午夜免费福利视频 | 最新中文字幕在线资源 | 91精品久久久久久久久 | 欧美日韩精品久久久 | 日韩在线在线 | 美女黄色网在线播放 | 亚洲天天干| 国产精品大片免费观看 | 欧美91在线| 97超碰影视 | 最近中文字幕高清字幕免费mv | 久久久免费视频播放 | 成人影片在线免费观看 | 欧美电影在线观看 | 不卡电影免费在线播放一区 | 岛国av在线不卡 | 国产在线国偷精品产拍 | 成年人网站免费在线观看 | 欧美日韩中文字幕视频 | 久操视频在线播放 | wwwwww黄 | 日韩免费视频线观看 | 婷婷资源站 | www.久久免费 | 97av视频在线观看 | 久久一区二区三区超碰国产精品 | 欧美日韩精品综合 | 精品网站999www | 日韩一区二区三免费高清在线观看 | 久草在线最新视频 | 中文字幕999 | 特级毛片在线 | 亚洲高清av在线 | 亚洲精品欧洲精品 | 亚洲综合小说电影qvod | 欧美成人猛片 | 中文字幕一区二区三区四区久久 | 日韩欧美网址 | 亚洲国产精品成人女人久久 | 欧美精品乱码久久久久久按摩 | 麻豆影视在线免费观看 | 免费视频你懂的 | 欧美日韩精品区 | 国产亚洲免费观看 | 波多野结衣综合网 | 精品福利av | 国内精品99 | 美女免费视频一区 | 国产91在线观看 | 亚洲精品久久久久中文字幕二区 | 午夜三级影院 | 欧美午夜久久久 | 91麻豆免费看 | 96亚洲精品久久 | 国产欧美日韩精品一区二区免费 | 国产精品女人网站 | 深夜免费福利在线 | 日韩久久午夜一级啪啪 | 国产精品久久久久久久久久久久冷 | 狠狠网站 | 欧美日韩伦理一区 | 国产精品久久久久四虎 | 500部大龄熟乱视频使用方法 | 亚洲精品456在线播放乱码 | 一区二区三区免费在线观看 | 婷婷伊人综合亚洲综合网 | 久久久久久麻豆 | 激情小说网站亚洲综合网 | 国产网红在线 | 亚洲精品观看 | 精品一区免费 | 中文字幕第一页在线播放 | 正在播放国产一区二区 | 香蕉视频网址 | 久久综合久久综合久久综合 | 国产精选在线 | 久久热亚洲 | 亚洲伊人色| 日韩成人精品在线观看 | 一区二区三区精品在线 | 日韩videos | 国产精品福利在线 | 亚洲精品中文字幕视频 | 99c视频高清免费观看 | 国产精品美女久久久久久网站 | 美女黄频在线观看 | 99久久激情 | 日韩三级免费观看 | 精品网站999www | 色多视频在线观看 | 精品国产福利在线 | 久艹视频在线观看 | 五月婷婷免费 | 五月婷婷激情六月 | 92国产精品久久久久首页 | 在线成人小视频 | 欧美日本不卡 | 国产精品门事件 | 黄色99视频 | 永久精品视频 | 日韩精品一区二区三区水蜜桃 | 国产一区二区三区四区在线 | 在线午夜电影神马影院 | 国产视频一区精品 | 亚洲精品视频大全 | 中文字幕免费不卡视频 | 欧美一二三区播放 | 一区精品在线 | 日本黄色免费看 | 日韩素人在线观看 | 国产成人av片 | 久久99热国产 | 狠狠的日日 | 波多野结衣视频网址 | 国产精品 999 | 国产成人一区二 | 国产手机在线精品 | 欧美极品一区二区三区 | 成人av在线网址 | 国产在线精品观看 | 日韩av不卡在线观看 | 91传媒91久久久 | 成人av中文字幕 | 天天草天天干天天 | 一级理论片在线观看 | 亚洲人片在线观看 | 久久久免费网站 | 久久涩视频 | 国产精品自在线拍国产 | 久久久久亚洲天堂 | 国产视频1区2区3区 久久夜视频 | 亚洲欧洲精品一区二区精品久久久 | 久久久午夜精品福利内容 | 欧美a级在线播放 | 日韩欧美观看 | 亚洲国产成人在线播放 | 亚洲a成人v | 亚洲高清在线观看视频 | 激情视频国产 | 在线一级片 | 日日噜噜噜噜夜夜爽亚洲精品 | 天堂在线成人 | 日韩免费看 | 粉嫩av一区二区三区四区 | 日日麻批40分钟视频免费观看 | 天天鲁天天干天天射 | 91麻豆精品国产91久久久久久久久 | www久| 国产精品96久久久久久吹潮 | 四虎小视频 | wwwww.国产| 国产精彩视频一区 | 亚洲成人精品久久 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 国产精品99久久久久久人免费 | 国产精品自产拍在线观看桃花 | 九九热只有精品 | 日日久视频 | 韩日电影在线 | 久久精品4 | 国产综合视频在线观看 | 国际精品网| 国产精品成久久久久三级 | 特级毛片在线 | 日韩国产高清在线 | 最近最新最好看中文视频 | 亚洲精品一区二区三区新线路 | 超碰人人在 | 999久久国产精品免费观看网站 | 国产 欧美 日本 | 91视频在线免费观看 | 91人人澡 | 日韩高清免费在线观看 | 色噜噜日韩精品欧美一区二区 | 开心激情五月婷婷 | 婷婷av电影 | 免费一级特黄录像 | 999久久a精品合区久久久 | 国产一区久久久 | 久草影视在线观看 | 天天综合久久综合 | 免费黄色激情视频 | 亚洲国产精品一区二区尤物区 | 在线观看免费av片 | 久草在线视频网站 | 中文字幕免费不卡视频 | 91精品久久久久久久久久入口 | 免费观看的黄色片 | 丁香婷婷社区 | 国内一级片在线观看 | 波多野结衣在线中文字幕 | 97精品国产97久久久久久粉红 | 91完整版在线观看 | 亚洲网站在线 | 免费99精品国产自在在线 | 中文字幕在线视频免费播放 | 色爽网站| 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 成人久久18免费网站麻豆 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 免费手机黄色网址 | 色婷婷国产精品 | 五月婷婷色 | 久久久精品99 | 国产区精品在线 | 亚洲激情 在线 | 国产成人久久精品亚洲 | 日韩在线观看视频免费 | 亚洲免费观看在线视频 | 一区二区免费不卡在线 | av福利在线看 | 欧美视频日韩视频 | 国产色视频一区 | 99久久久久久久久久 | 日韩大片免费观看 | 午夜精品福利一区二区三区蜜桃 | 日韩在线免费小视频 | 国产欧美在线一区 | 欧美日韩亚洲在线观看 | 国产又黄又爽无遮挡 | 中文字幕免费高清av | 91麻豆精品国产自产在线 | 91视频com | 97电影网手机版 | 成全免费观看视频 | 欧美日韩一区二区三区视频 | 狠狠干在线 | 精品久久久久久综合日本 | 国产女人40精品一区毛片视频 | 色婷久久 | www.狠狠色.com | 在线观看精品黄av片免费 | 9999精品免费视频 | 麻豆国产露脸在线观看 | 欧美精品国产综合久久 | 国产一级片直播 | 黄色影院在线观看 | 亚洲精品乱码久久久久久久久久 | 色天天天 | 中文字幕精品一区二区三区电影 | 成人黄色在线视频 | 国产精品久久 | 久久字幕精品一区 | 国产在线观看黄 | 亚洲精品美女久久17c | 久久免费成人精品视频 | 中文字幕有码在线观看 | 天天综合天天做天天综合 | 国产精品久久久久久久久久免费 | 激情综合网天天干 | 亚洲少妇激情 | 亚洲视频456 | www黄色大片 | 1024手机基地在线观看 | 国产涩涩在线观看 | 国产无套精品久久久久久 | 深爱激情综合网 | 丁香视频免费观看 | 在线免费中文字幕 | 国内免费的中文字幕 | 免费福利片 | 国语精品久久 | 不卡的av| 亚洲国产精彩中文乱码av | 国产偷国产偷亚洲清高 | 国产特黄色片 | 九精品 | 国产91区| 韩国在线一区 | 麻豆国产精品va在线观看不卡 | 在线免费视频 你懂得 | 免费色视频在线 | 午夜美女福利 | 国产在线久草 | 中文字幕国语官网在线视频 | 操天天操| 青青视频一区 | 欧美韩国日本在线观看 | 天天碰天天操视频 | 一区二区三区四区五区在线视频 | 夜夜躁天天躁很躁波 | 成年人免费在线看 | 99精品国产99久久久久久福利 | 九七人人干 | 久久99久久99精品免费看小说 | 天天操天天能 | 中文字幕一二三区 | 成人免费在线视频 | 欧美日韩视频免费 | 久久高清免费观看 | 公开超碰在线 | www.97视频| 国产不卡视频在线 | 亚洲国产精品久久久久久 | 超碰在97| 精品9999| 久久精品一区二区三区四区 | 国产美女在线观看 | 国产成人亚洲在线观看 | 丁香影院在线 | 婷婷射五月 | 狠狠狠狠狠狠 | 欧美日韩久久久 | 国产精品久久久久久欧美 | 日韩精品播放 | 粉嫩av一区二区三区入口 | 日韩视频免费在线观看 | 欧美日韩国产精品一区二区三区 | 欧美久久久久久久久久久久 | 成人免费视频观看 | 69av视频在线观看 | av成人动漫 | 成年人看片 | 中文字幕在线观看完整版 | 国产中文欧美日韩在线 | 亚洲精品免费在线观看视频 | 毛片无卡免费无播放器 | 91视频免费国产 | 久久精品国产免费看久久精品 | 国产精品69久久久久 | 三级黄色片子 | 麻豆免费看片 | 狠狠色伊人亚洲综合成人 | 亚洲另类视频在线观看 | 国产精品成人自产拍在线观看 | 久久精品一区二区三区国产主播 | 草久中文字幕 | 亚洲欧美日韩国产一区二区 | www.国产在线视频 | 99成人免费视频 | 成人亚洲免费 | 久久久高清免费视频 | 在线观看国产www | 亚洲免费av在线 | 久久99九九99精品 | 亚洲理论在线观看电影 | 久久精品日本啪啪涩涩 | 成人精品福利 | 国产精品免费久久 | 成人精品视频久久久久 | 日韩一区二区免费视频 | 中文字幕在线久一本久 | 久久久久久久久久久高潮一区二区 | 99精品在线看 | 在线91色 | 日韩午夜在线观看 | 激情综合啪啪 | 中国美女一级看片 | 国产xxxx | 国产精品一区二区在线观看 | 午夜精品一区二区三区四区 | 97夜夜澡人人双人人人喊 | 日产乱码一二三区别免费 | 成年美女黄网站色大片免费看 | 天天操夜夜操天天射 | 91在线免费播放 | 国产成人在线免费观看 | av网址在线播放 | 欧美爽爽爽 | 亚洲日本一区二区在线 | 香蕉久久久久久久 | 超碰人人干人人 | 国产精品永久免费在线 | 日日夜夜网 | 中文不卡视频 | 91色在线观看 | 免费一级特黄毛大片 | 成年人免费看片 | 亚洲丝袜一区二区 | 夜夜骑天天操 | 99久久国产免费,99久久国产免费大片 | 天天操天天射天天操 | 欧美精品九九99久久 | 最新亚洲视频 | 久久久资源 | 日韩电影在线视频 | 久久久久久久久久国产精品 | 久久久久久久久久久成人 | 久久视频在线看 | 国产大片免费久久 | 欧美性久久久久久 | 国产一二三四在线视频 | а天堂中文最新一区二区三区 | 婷婷在线免费视频 | 日批网站免费观看 | 亚洲精品在线观 | 久久久成人精品 | 狠狠狠色丁香综合久久天下网 | 国产精品区在线观看 | 99精品欧美一区二区三区黑人哦 | 在线国产精品一区 | 国产91在线看 | 久久精品99国产精品日本 | 免费看成年人 | 99久久99视频 | 国产成人精品亚洲精品 | 天天插狠狠插 | 日韩av在线免费播放 | 久久在视频 | 九九热国产视频 | 欧美一级欧美一级 | 国产成人精品一区二区三区福利 | 亚洲综合成人专区片 | 激情在线免费视频 | 国产精品入口久久 | 久草视频免费观 | 久久国产精品一国产精品 | 超碰免费公开 | 午夜性生活 | 欧美狠狠色 | 在线一级片| 丁香花在线观看视频在线 | 国产专区在线播放 | 国产精品ⅴa有声小说 | 欧美最猛性xxx | 狠狠精品 | 欧美性色19p | 国产精华国产精品 | 天天爱天天操天天爽 | 国产网站av | 欧美一级性生活 | 国产资源在线视频 | 欧美va天堂va视频va在线 | 在线观看亚洲a | 二区三区毛片 | 亚洲激色 | 超碰在线人人97 | 国产精品激情 | 国产成人精品一区二区在线观看 | 超碰在线公开 | 日韩av一区二区三区 | 少妇bbb | 一级一片免费看 | 激情 一区二区 | 国产小视频在线免费观看视频 | 怡红院久久 | 视频国产一区二区三区 | 五月天色丁香 | 国产一区二区久久久 | 日韩精品一区在线播放 | 99热这里只有精品1 av中文字幕日韩 | 在线天堂中文www视软件 | 人人干网 | 成人黄性视频 | 麻豆影视在线免费观看 | 一区二区在线电影 | 久久免费视频4 | 亚洲免费小视频 | 国产正在播放 | 欧美另类xxxx | 中文字幕av专区 | 免费视频一级片 | 久草免费福利在线观看 | 久久久久成人精品 | 天天操天天操天天操 | 国模精品一区二区三区 | 中文字幕影片免费在线观看 | 特级毛片在线观看 | 又黄又爽又刺激视频 | 国产97视频在线 | 狠狠色婷婷丁香六月 | 日韩手机在线观看 | 91av综合| 久久国产高清 | 免费试看一区 | 中文永久免费观看 | 久久精品电影院 | 91污在线| 久久久久久久久久伊人 | 激情av网| a黄色| 久久韩国免费视频 | 久久艹在线观看 | 亚洲天堂在线观看完整版 | 欧美视频18 | 啪啪小视频网站 | 在线观看日韩精品 | 九九在线视频 | 天天射,天天干 | 天天爽夜夜爽精品视频婷婷 | 久久在线播放 | 中文字幕免费高清 | 青青草国产在线 | 久久视频这里有久久精品视频11 | 91视频91色 | 中文字幕 国产专区 | 高清不卡毛片 | 人人搞人人爽 | 国产网站av| 日韩视频免费在线 | 看片的网址| 久久久精品亚洲 | 日韩av一区在线观看 | 午夜国产福利在线观看 | 久久一久久 | 久久免费毛片视频 | av中文字幕日韩 | 夜夜躁天天躁很躁波 | 91亚洲国产成人久久精品网站 | 超碰97在线看 | 在线视频观看国产 | 中文字幕免费观看全部电影 | 亚洲日b视频 | 亚洲综合在线五月 | 日韩久久精品一区二区三区下载 | 日本免费久久高清视频 | 欧美一区视频 | 天天天干夜夜夜操 | 精品96久久久久久中文字幕无 | 天天综合91| a在线v| 日韩 精品 一区 国产 麻豆 | 亚洲自拍偷拍色图 |