[cocos2d-x]深刻--幾個表明性的類

摘要: 此文對cocos2d-x引擎中最具表明性,最能體現框架結構的幾個類作了簡單的介紹, 包括Director,Application, Renderer, EventDispatcher, Scheduler. 對於這些類, 也只對關係主要流程的方法作了介紹, 略過了容錯代碼和其它細節. 主要目的是讓你們快速的對cocos2d-x引擎有一個全面籠統的認識, 也方便快速定位問題.html



GLView

cocos2d-xopenGL的封裝. 不一樣平臺下, openGL有一些差異.node

openGL

一段簡單的例子

如下內容引用自Introduction to OpenGL. 須要更具體的介紹也可參考這個連接.api

#include <whateverYouNeed.h> main() { InitializeAWindowPlease(); glClearColor (0.0, 0.0, 0.0, 0.0); glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0, 1.0, 1.0); glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); glBegin(GL_POLYGON); glVertex3f (0.25, 0.25, 0.0); glVertex3f (0.75, 0.25, 0.0); glVertex3f (0.75, 0.75, 0.0); glVertex3f (0.25, 0.75, 0.0); glEnd(); glFlush(); UpdateTheWindowAndCheckForEvents(); }

OpenGL Command Syntax

  • OpenGL commands use the prefix gl and initial capital letters for each word making up the command name
  • some seemingly extraneous letters appended to some command names (for example, the 3f in glColor3f() and glVertex3f())

OpenGL as a State Machine

OpenGL is a state machine. You put it into various states (or modes) that then remain in effect until you change them.app

Application

主要方法:

virtual const char * getCurrentLanguage(); virtual Platform getTargetPlatform(); virtual void setAnimationInterval(double interval); int run();//啓動主循環

run()函數

int Application::run() { ... while(!glview->windowShouldClose()) { QueryPerformanceCounter(&nNow); if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart) { nLast.QuadPart = nNow.QuadPart; director->mainLoop(); //Director進行這一幀的渲染 glview->pollEvents(); // This function processes only those events that have already been received and then returns immediately. } else { Sleep(0); } } ... return true; }

Director

主要函數預覽

//openGL Matrix Operate void pushMatrix(MATRIX_STACK_TYPE type); void popMatrix(MATRIX_STACK_TYPE type); void loadIdentityMatrix(MATRIX_STACK_TYPE type); void loadMatrix(MATRIX_STACK_TYPE type, const Mat4& mat); void multiplyMatrix(MATRIX_STACK_TYPE type, const Mat4& mat); Mat4 getMatrix(MATRIX_STACK_TYPE type); void resetMatrixStack(); //View Data inline double getAnimationInterval(); inline bool isDisplayStats(); inline GLView* getOpenGLView(); inline Projection getProjection(); Size getVisibleSize() const; Vec2 getVisibleOrigin() const; Vec2 convertToGL(const Vec2& point); Vec2 convertToUI(const Vec2& point); float getZEye() const; // Scene 場景管理 inline Scene* getRunningScene(); void runWithScene(Scene *scene); void pushScene(Scene *scene); // 控制繪製的暫停和恢復 void end(); void pause(); void resume(); //繪製圖形(界面展現最重要的函數) void drawScene(); //Getter and Setter Scheduler* getScheduler() const { return _scheduler; } void setScheduler(Scheduler* scheduler); ActionManager* getActionManager() const { return _actionManager; } void setActionManager(ActionManager* actionManager); EventDispatcher* getEventDispatcher() const { return _eventDispatcher; } void setEventDispatcher(EventDispatcher* dispatcher); Renderer* getRenderer() const { return _renderer; }

drawScene(): 主要繪製函數

// Draw the Scene void Director::drawScene() { ... if (! _paused) { _scheduler->update(_deltaTime); //Scheduler 定時器 更新 _eventDispatcher->dispatchEvent(_eventAfterUpdate); //Dispatcher 拋發事件. } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClear if (_nextScene) //取得下一個將要顯示的Scene. { setNextScene(); } pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); //將上一次繪製的Context放到堆棧 // draw the scene if (_runningScene) { _runningScene->visit(_renderer, Mat4::IDENTITY, false); _eventDispatcher->dispatchEvent(_eventAfterVisit); } _renderer->render(); //渲染 _eventDispatcher->dispatchEvent(_eventAfterDraw); popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); //返回到上一次繪製時的狀態. // swap buffers if (_openGLView) { _openGLView->swapBuffers(); //把上面渲染的結果顯示到屏幕 } ... }

Node::visit() 函數

預覽

Node::visit() 的主要功能就是框架

  1. 調用全部孩子的visit函數
  2. 調用self->draw()函數
void Node::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags) { // quick return if not visible. children won't be drawn. if (!_visible) { return; } uint32_t flags = processParentFlags(parentTransform, parentFlags); // IMPORTANT: // To ease the migration to v3.0, we still support the Mat4 stack, // but it is deprecated and your code should not rely on it Director* director = Director::getInstance(); director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform); int i = 0; if(!_children.empty()) { sortAllChildren(); // draw children zOrder < 0 for( ; i < _children.size(); i++ ) { auto node = _children.at(i); if ( node && node->_localZOrder < 0 ) node->visit(renderer, _modelViewTransform, flags); else break; } // self draw this->draw(renderer, _modelViewTransform, flags); for(auto it=_children.cbegin()+i; it != _children.cend(); ++it) (*it)->visit(renderer, _modelViewTransform, flags); } else { this->draw(renderer, _modelViewTransform, flags); } director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); }

Node::draw()

由於Node是全部可顯示對象的父類, 沒有任何顯示內容, 因此draw函數爲空.
這裏咱們以Sprite::draw函數爲例簡單介紹下draw的做用.ide

void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) { // Don't do calculate the culling if the transform was not updated _insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds; if(_insideBounds) { _quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform); renderer->addCommand(&_quadCommand); } }

咱們看到, Sprite::draw函數主要實現了[添加一個QuadCommandRender中去]的功能.
再看看Label的繪製函數.函數

Label::draw

void Label::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) { // Don't do calculate the culling if the transform was not updated _insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds; if(_insideBounds) { _customCommand.init(_globalZOrder); _customCommand.func = CC_CALLBACK_0(Label::onDraw, this, transform, flags); renderer->addCommand(&_customCommand); } }

其實, 跟Sprite::draw也差很少. 關鍵在於這個RenderCommand怎麼構造和執行的.oop

Renderer 渲染器

主要函數預覽

 void initGLView(); /** Adds a `RenderComamnd` into the renderer */ void addCommand(RenderCommand* command); /** Adds a `RenderComamnd` into the renderer specifying a particular render queue ID */ void addCommand(RenderCommand* command, int renderQueue); /** Pushes a group into the render queue */ void pushGroup(int renderQueueID); /** Pops a group from the render queue */ void popGroup(); /** Creates a render queue and returns its Id */ int createRenderQueue(); /** Renders into the GLView all the queued `RenderCommand` objects */ void render();

可見它主要由兩個功能:ui

  1. ReanderCommand進行排序和分類管理
  2. 進行渲染:render()

渲染函數Renderer::render()

void Renderer::render() { ... if (_glViewAssigned) { ... //排列渲染隊列 for (auto &renderqueue : _renderGroups) { renderqueue.sort(); } //進行渲染 visitRenderQueue(_renderGroups[0]); ... } ... }

Renderer::visitRenderQueue

按照順序執行全部的 RenderCommandthis

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::QUAD_COMMAND == commandType) { auto cmd = static_cast<QuadCommand*>(command); //Batch quads if(_numQuads + cmd->getQuadCount() > VBO_SIZE) { drawBatchedQuads(); } _batchedQuadCommands.push_back(cmd); memcpy(_quads + _numQuads, cmd->getQuads(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); convertToWorldCoordinates(_quads + _numQuads, cmd->getQuadCount(), cmd->getModelView()); _numQuads += cmd->getQuadCount(); } else if(RenderCommand::Type::GROUP_COMMAND == commandType) { flush(); int renderQueueID = ((GroupCommand*) command)->getRenderQueueID(); visitRenderQueue(_renderGroups[renderQueueID]); } else if(RenderCommand::Type::CUSTOM_COMMAND == commandType) { ... } ... } }

openGL VAO, VBO 介紹.

GLSL渲染語言入門與VBO、VAO使用:繪製一個三角形
OpenGL 4.0 VAO VBO 理解

Schelduler介紹

Scheldulercocos2d-x中實現延遲調用,定時調用時最重要的功能. 相似於其餘語言中的Timer
他最核心的函數就是:

void schedule(const ccSchedulerFunc& callback, void *target, float interval, unsigned int repeat, float delay, bool paused, const std::string& key);

用來啓動一個定時操做: 在延遲delay時間後, 每隔repeat時間, 調用一次callback. target用來標記這個操做屬於誰, 方便管理, 好比在析構的時候調用void unschedule(void *target)便可移除當前對象的全部定時操做.

Schelduler的其它大部分方法, 要麼是它的衍生, 爲了減小調用參數; 要麼是對定時操做的控制, 好比暫停, 恢復, 移除等. 若是隻對想對框架的各個模塊有大概的瞭解, 能夠不作深刻.

EventDispatcher

(後續添加)

Written with StackEdit.

相關文章
相關標籤/搜索