摘要: 此文对cocos2d-x
引擎中最具表明性,最能体现框架结构的几个类作了简单的介绍, 包括Director
,Application
, Renderer
, EventDispatcher
, Scheduler
. 对于这些类, 也只对关系主要流程的方法作了介绍, 略过了容错代码和其它细节. 主要目的是让你们快速的对cocos2d-x
引擎有一个全面笼统的认识, 也方便快速定位问题.html
cocos2d-x
对openGL
的封装. 不一样平台下, openGL
有一些差异.node
如下内容引用自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(); }
gl
and initial capital letters for each word making up the command name 3f
in glColor3f()
and glVertex3f()
)OpenGL is a state machine. You put it into various states (or modes) that then remain in effect until you change them.app
virtual const char * getCurrentLanguage(); virtual Platform getTargetPlatform(); virtual void setAnimationInterval(double interval); int 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; }
//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; }
// 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() 的主要功能就是框架
visit
函数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
函数为空.
这里咱们以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
函数主要实现了[添加一个QuadCommand
到Render
中去]的功能.
再看看Label
的绘制函数.函数
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
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
ReanderCommand
进行排序和分类管理render()
void Renderer::render() { ... if (_glViewAssigned) { ... //排列渲染队列 for (auto &renderqueue : _renderGroups) { renderqueue.sort(); } //进行渲染 visitRenderQueue(_renderGroups[0]); ... } ... }
按照顺序执行全部的 RenderCommand
this
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) { ... } ... } }
GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形
OpenGL 4.0 VAO VBO 理解
Schelduler
是cocos2d-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
的其它大部分方法, 要么是它的衍生, 为了减小调用参数; 要么是对定时操做
的控制, 好比暂停, 恢复, 移除等. 若是只对想对框架的各个模块有大概的了解, 能够不作深刻.
(后续添加)
Written with StackEdit.