摘要: 此文对cocos2d-x引擎中最具代表性,最能体现框架结构的几个类做了简单的介绍, 包括Director,Application, Renderer, EventDispatcher, Scheduler. 对于这些类, 也只对关系主要流程的方法做了介绍, 略过了容错代码和其它细节. 主要目的是让大家快速的对cocos2d-x引擎有一个全面笼统的认识, 也方便快速定位问题.



GLView

cocos2d-xopenGL的封装. 不同平台下, openGL有一些差别.

openGL

一段简单的例子

以下内容引用自Introduction to OpenGL. 需要更具体的介绍也可参考这个链接.

  1. #include <whateverYouNeed.h>
  2. main() {
  3. InitializeAWindowPlease();
  4. glClearColor (0.0, 0.0, 0.0, 0.0);
  5. glClear (GL_COLOR_BUFFER_BIT);
  6. glColor3f (1.0, 1.0, 1.0);
  7. glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
  8. glBegin(GL_POLYGON);
  9. glVertex3f (0.25, 0.25, 0.0);
  10. glVertex3f (0.75, 0.25, 0.0);
  11. glVertex3f (0.75, 0.75, 0.0);
  12. glVertex3f (0.25, 0.75, 0.0);
  13. glEnd();
  14. glFlush();
  15. UpdateTheWindowAndCheckForEvents();
  16. }

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.

Application

主要方法:

  1. virtual const char * getCurrentLanguage();
  2. virtual Platform getTargetPlatform();
  3. virtual void setAnimationInterval(double interval);
  4. int run();//启动主循环

run()函数

  1. int Application::run()
  2. {
  3. ...
  4. while(!glview->windowShouldClose())
  5. {
  6. QueryPerformanceCounter(&nNow);
  7. if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart)
  8. {
  9. nLast.QuadPart = nNow.QuadPart;
  10. director->mainLoop(); //Director进行这一帧的渲染
  11. glview->pollEvents(); // This function processes only those events that have already been received and then returns immediately.
  12. }
  13. else
  14. {
  15. Sleep(0);
  16. }
  17. }
  18. ...
  19. return true;
  20. }

Director

主要函数预览

  1. //openGL Matrix Operate
  2. void pushMatrix(MATRIX_STACK_TYPE type);
  3. void popMatrix(MATRIX_STACK_TYPE type);
  4. void loadIdentityMatrix(MATRIX_STACK_TYPE type);
  5. void loadMatrix(MATRIX_STACK_TYPE type, const Mat4& mat);
  6. void multiplyMatrix(MATRIX_STACK_TYPE type, const Mat4& mat);
  7. Mat4 getMatrix(MATRIX_STACK_TYPE type);
  8. void resetMatrixStack();
  9. //View Data
  10. inline double getAnimationInterval();
  11. inline bool isDisplayStats();
  12. inline GLView* getOpenGLView();
  13. inline Projection getProjection();
  14. Size getVisibleSize() const;
  15. Vec2 getVisibleOrigin() const;
  16. Vec2 convertToGL(const Vec2& point);
  17. Vec2 convertToUI(const Vec2& point);
  18. float getZEye() const;
  19. // Scene 场景管理
  20. inline Scene* getRunningScene();
  21. void runWithScene(Scene *scene);
  22. void pushScene(Scene *scene);
  23. // 控制绘制的暂停和恢复
  24. void end();
  25. void pause();
  26. void resume();
  27. //绘制图形(界面展示最重要的函数)
  28. void drawScene();
  29. //Getter and Setter
  30. Scheduler* getScheduler() const { return _scheduler; }
  31. void setScheduler(Scheduler* scheduler);
  32. ActionManager* getActionManager() const { return _actionManager; }
  33. void setActionManager(ActionManager* actionManager);
  34. EventDispatcher* getEventDispatcher() const { return _eventDispatcher; }
  35. void setEventDispatcher(EventDispatcher* dispatcher);
  36. Renderer* getRenderer() const { return _renderer; }

drawScene(): 主要绘制函数

  1. // Draw the Scene
  2. void Director::drawScene()
  3. {
  4. ...
  5. if (! _paused)
  6. {
  7. _scheduler->update(_deltaTime); //Scheduler 定时器 更新
  8. _eventDispatcher->dispatchEvent(_eventAfterUpdate); //Dispatcher 抛发事件.
  9. }
  10. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClear
  11. if (_nextScene) //取得下一个将要显示的Scene.
  12. {
  13. setNextScene();
  14. }
  15. pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); //将上一次绘制的Context放到堆栈
  16. // draw the scene
  17. if (_runningScene)
  18. {
  19. _runningScene->visit(_renderer, Mat4::IDENTITY, false);
  20. _eventDispatcher->dispatchEvent(_eventAfterVisit);
  21. }
  22. _renderer->render(); //渲染
  23. _eventDispatcher->dispatchEvent(_eventAfterDraw);
  24. popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); //返回到上一次绘制时的状态.
  25. // swap buffers
  26. if (_openGLView)
  27. {
  28. _openGLView->swapBuffers(); //把上面渲染的结果显示到屏幕
  29. }
  30. ...
  31. }

Node::visit() 函数

预览

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

  1. 调用所有孩子的visit函数
  2. 调用self->draw()函数
  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. uint32_t flags = processParentFlags(parentTransform, parentFlags);
  9. // IMPORTANT:
  10. // To ease the migration to v3.0, we still support the Mat4 stack,
  11. // but it is deprecated and your code should not rely on it
  12. Director* director = Director::getInstance();
  13. director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
  14. director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
  15. int i = 0;
  16. if(!_children.empty())
  17. {
  18. sortAllChildren();
  19. // draw children zOrder < 0
  20. for( ; i < _children.size(); i++ )
  21. {
  22. auto node = _children.at(i);
  23. if ( node && node->_localZOrder < 0 )
  24. node->visit(renderer, _modelViewTransform, flags);
  25. else
  26. break;
  27. }
  28. // self draw
  29. this->draw(renderer, _modelViewTransform, flags);
  30. for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
  31. (*it)->visit(renderer, _modelViewTransform, flags);
  32. }
  33. else
  34. {
  35. this->draw(renderer, _modelViewTransform, flags);
  36. }
  37. director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
  38. }

Node::draw()

因为Node是所有可显示对象的父类, 没有任何显示内容, 所以draw函数为空.

这里我们以Sprite::draw函数为例简单介绍下draw的作用.

  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. }
  10. }

我们看到, Sprite::draw函数主要实现了[添加一个QuadCommandRender中去]的功能.

再看看Label的绘制函数.

Label::draw

  1. void Label::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. _customCommand.init(_globalZOrder);
  7. _customCommand.func = CC_CALLBACK_0(Label::onDraw, this, transform, flags);
  8. renderer->addCommand(&_customCommand);
  9. }
  10. }

其实, 跟Sprite::draw也差不多. 关键在于这个RenderCommand怎么构造和执行的.

Renderer 渲染器

主要函数预览

  1. void initGLView();
  2. /** Adds a `RenderComamnd` into the renderer */
  3. void addCommand(RenderCommand* command);
  4. /** Adds a `RenderComamnd` into the renderer specifying a particular render queue ID */
  5. void addCommand(RenderCommand* command, int renderQueue);
  6. /** Pushes a group into the render queue */
  7. void pushGroup(int renderQueueID);
  8. /** Pops a group from the render queue */
  9. void popGroup();
  10. /** Creates a render queue and returns its Id */
  11. int createRenderQueue();
  12. /** Renders into the GLView all the queued `RenderCommand` objects */
  13. void render();

可见它主要由两个功能:

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

渲染函数Renderer::render()

  1. void Renderer::render()
  2. {
  3. ...
  4. if (_glViewAssigned)
  5. {
  6. ...
  7. //排列渲染队列
  8. for (auto &renderqueue : _renderGroups)
  9. {
  10. renderqueue.sort();
  11. }
  12. //进行渲染
  13. visitRenderQueue(_renderGroups[0]);
  14. ...
  15. }
  16. ...
  17. }

Renderer::visitRenderQueue

按照顺序执行所有的 RenderCommand

  1. void Renderer::visitRenderQueue(const RenderQueue& queue)
  2. {
  3. ssize_t size = queue.size();
  4. for (ssize_t index = 0; index < size; ++index)
  5. {
  6. auto command = queue[index];
  7. auto commandType = command->getType();
  8. if(RenderCommand::Type::QUAD_COMMAND == commandType)
  9. {
  10. auto cmd = static_cast<QuadCommand*>(command);
  11. //Batch quads
  12. if(_numQuads + cmd->getQuadCount() > VBO_SIZE)
  13. {
  14. drawBatchedQuads();
  15. }
  16. _batchedQuadCommands.push_back(cmd);
  17. memcpy(_quads + _numQuads, cmd->getQuads(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount());
  18. convertToWorldCoordinates(_quads + _numQuads, cmd->getQuadCount(), cmd->getModelView());
  19. _numQuads += cmd->getQuadCount();
  20. }
  21. else if(RenderCommand::Type::GROUP_COMMAND == commandType)
  22. {
  23. flush();
  24. int renderQueueID = ((GroupCommand*) command)->getRenderQueueID();
  25. visitRenderQueue(_renderGroups[renderQueueID]);
  26. }
  27. else if(RenderCommand::Type::CUSTOM_COMMAND == commandType)
  28. {
  29. ...
  30. }
  31. ...
  32. }
  33. }

openGL VAO, VBO 介绍.

GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形

OpenGL 4.0 VAO VBO 理解

Schelduler介绍

Scheldulercocos2d-x中实现延迟调用,定时调用时最重要的功能. 类似于其他语言中的Timer

他最核心的函数就是:

  1. 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.

[cocos2d-x]深入--几个代表性的类的更多相关文章

  1. [cocos2d-x]深入--几个代表性的类 (续)

    摘要: 此文对cocos2d-x引擎中最具代表性,最能体现框架结构的几个类做了简单的介绍, 包括Director,Application, Renderer, EventDispatcher, Sch ...

  2. Cocos2d 3.0继承自Sprite的类在addChild后出现故障

    当继承自Sprite的类被addChild到其它的Node里后出现例如以下图问题,说明没有调用父类Sprite::init()的方法.由于父类Sprite里的_textureAtlas须要初始化为nu ...

  3. Cocos2d-x——CocosBuilder官方帮助文档翻译1 使用自定义类

    原创:请注明转载! 在Cocos2d-x中使用CocosBuilder 使用自定义类 CocosBuilder的使用方法是通过自定义类.在CocosBuilder中选中一个对象并在属性栏中输入自定义类 ...

  4. cocos2d-x实战 C++卷 学习笔记--第4章 字符串 __String类

    前言: <cocos2d-x实战C++卷>学习笔记.(cocos2d-x 是3.0版本) 介绍 cocos2d-x 通用的字符串类  __String . 使用cocos2d::__Str ...

  5. cocos2D(四)---- CCSprite

    在介绍CCSprite之前,先要理解游戏开发中的一个核心概念:精灵.精灵也称为游戏对象,它能够用来表示游戏中的不论什么物体,比方敌人.子弹.甚至是一个背景图片.一段文字.CCSprite能够说是在co ...

  6. [cocos2dx笔记013]一个使用CCRenderTexture创建动态纹理显示数字的类

    用CCLabelTTF显示的数字不好看.于是就想到用图片来代理.眼下网上的实现都是把每一个数字做一个CCSprite组合的方式. 可是我想.动态生成纹理的方式.没有就仅仅好自己手动写一个. 头文件 # ...

  7. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

  8. cocos2d-x 2.0 序列帧动画 深入分析

    转自:http://blog.csdn.net/honghaier/article/details/8222401 序列帧动画主要有几个类: CCSpriteFrame:精灵帧信息,序列帧动画是依靠多 ...

  9. Darwin Streaming Server 简介

    Darwin Streaming Server     概要 Darwin Streaming Server简称DSS.DSS是Apple公司提供的开源实时流媒体播放服务器程序.整个程序使用C++编写 ...

随机推荐

  1. CSS3背景温故

    1.背景的五种基本属性background-color(背景颜色)background-image(背景图片)background-repeat(背景图片展示方式)background-attachm ...

  2. 【web前端优化之图片模糊到清晰】看我QQ空间如何显示相片

    前言 此篇文章估计不会太长,有移除首页的风险,但是老夫(称老夫是因为我们真正的叶小钗其实都100多岁啦)是不会怕滴.所以,我来了哟! 题外话:今天我们一起还看了一道前端的面试题,而后我本来还想多找几道 ...

  3. JavaScript学习10 JS数据类型、强制类型转换和对象属性

    JavaScript学习10 JS数据类型.强制类型转换和对象属性 JavaScript数据类型 JavaScript中有五种原始数据类型:Undefined.Null.Boolean.Number以 ...

  4. Ida双开定位android so文件

    Ida双开定位的意思是先用ida静态分析so文件,然后再开一个ida动态调试so文件.因为在动态调试中ida并不会对整个动态加载的so文件进行详细的分析,所以很多函数并无法识别出来.比如静态分析中有很 ...

  5. RxJava 和 RxAndroid 二(操作符的使用)

    前言:对Rx不了解的朋友可以先看我的第一篇博文 RxJava 和 RxAndroid 一 (基础),是对Rxjava的基本介绍 1.merge操作符,合并观察对象 List<String> ...

  6. Java中的查找算法之顺序查找(Sequential Search)

    Java中的查找算法之顺序查找(Sequential Search) 神话丿小王子的博客主页 a) 原理:顺序查找就是按顺序从头到尾依次往下查找,找到数据,则提前结束查找,找不到便一直查找下去,直到数 ...

  7. NSArray与NSMutableArray 数组与可变数组

    1.NSArray 是一个父类,NSMUtableArray是其子类,他们构成了OC的数组.2.NSArray的创建NSArray * array = [[NSArray alloc]initWith ...

  8. iOS 学习 - 9.Block 入门

    来自李明杰的视频. block 用来保存一段代码 block 的标志:^ block  跟函数很像: 1).可以保存代码  2).有返回值  3). 有形参 temp1:没有返回值.没有形参的 blo ...

  9. 1.8 基础知识——GP2.7 识别和卷入干系人(Stakeholder) & GP2.9 质量保证(QA)

    GP2.7 识别和卷入干系人(Stakeholder) GP2.7 Identify and involve the relevant stakeholders of XXX process as p ...

  10. yii2 输出xml格式数据

    作者:白狼 出处:http://www.manks.top/yii2_xml_response.html.html本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文 ...