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


  • 博客: http://www.cnblogs.com/jhzhu
  • 邮箱: jhzhuustc@gmail.com
  • 作者: 知明所以
  • 时间: 2014-07-21

  • GLView

    • openGL

      • 一段简单的例子
      • OpenGL Command Syntax
      • OpenGL as a State Machine
  • Application
    • 主要方法:
    • run()函数
  • Director
    • 主要函数预览
    • drawScene(): 主要绘制函数
  • Node::visit() 函数
    • 预览
    • Node::draw()
    • Label::draw
  • Renderer 渲染器
    • 主要函数预览
    • 渲染函数Renderer::render()
    • Renderer::visitRenderQueue
    • openGL VAO, VBO 介绍.
  • Schelduler介绍
  • EventDispatcher

GLView

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

openGL

一段简单的例子

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

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

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 Operatevoid 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 Datainline 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 SetterScheduler* 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);         //glClearif (_nextScene)                                             //取得下一个将要显示的Scene.{setNextScene();}pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);      //将上一次绘制的Context放到堆栈// draw the sceneif (_runningScene){_runningScene->visit(_renderer, Mat4::IDENTITY, false);_eventDispatcher->dispatchEvent(_eventAfterVisit);}_renderer->render();                                        //渲染_eventDispatcher->dispatchEvent(_eventAfterDraw);popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);       //返回到上一次绘制时的状态.// swap buffersif (_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 itDirector* 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 < 0for( ; i < _children.size(); i++ ){auto node = _children.at(i);if ( node && node->_localZOrder < 0 )node->visit(renderer, _modelViewTransform, flags);elsebreak;}// self drawthis->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的作用.

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怎么构造和执行的.

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();

可见它主要由两个功能:

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

渲染函数Renderer::render()

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

Renderer::visitRenderQueue

按照顺序执行所有的 RenderCommand

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 quadsif(_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.

转载于:https://www.cnblogs.com/jhzhu/p/3859964.html

[cocos2d-x]深入--几个代表性的类相关推荐

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

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

  2. 添加类iOS cocos2d 2游戏开发实战(第3版)

    这两天一直在学习添加类之类的问题,现在正好有机会和大家讨论一下. 第1章 简介 1 1.1 第3版中的新增内容 2 1.2 选择ios版cocos2d的来由 3 1.2.1 收费 3 1.2.2 开源 ...

  3. cocos2D(四)---- CCSprite

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

  4. 初探使用iOS 7 Sprite Kit与Cocos2d开发游戏的对比(一家之言)

    初探使用iOS 7 Sprite Kit与Cocos2d开发游戏的对比 初探使用iOS 7 Sprite Kit与Cocos2d开发游戏的对比 发布于:2013-07-18 11:00阅读数:1984 ...

  5. Cocos2d使用TexturePacker工具打包生成plist和pvr.ccz文件方法总结

    我们用TexturePacker工具打包生成了plist和pvr.ccz文件,那么下一步,我们就该获取plist中的信息了. Cocos2d中SpriteFrameCache通常用来处理plist文件 ...

  6. iOS cocos2d 2游戏开发实战(第3版)

    <iOS cocos2d 2游戏开发实战(第3版)> 基本信息 原书名:Learn cocos2d 2: Game Development for iOS 作者: (美)Steffen I ...

  7. Cocos2d游戏开发学习记录——4.开发《植物大战僵尸》

    文章目录 1.植物大战僵尸 2.开发前导 3.载入页面 4.菜单页面 & 预备战斗页面 5.植物准备页面 6.正式战斗页面 7.战斗逻辑 8.向日葵逻辑 9.进度条逻辑 10.音乐逻辑 11. ...

  8. 初探使用iOS 7 Sprite Kit与Cocos2d开发游戏的对比

    前言 iOS7 beta发布后,大部分开发者和用户的注意力都集中在了iOS 7的全新UI交互设计界面上.一直负责硬件工业设计的Jony Ive首次全面负责苹果的软件和硬件设计工作,自然要把他自己的设计 ...

  9. cocos2d中的Color3B、Color4B、Color4F的使用

    首先给出cocos2d标准库中的三个类的构造函数和定义,他们也是可以互相转换的    cocos2d中表示颜色有三种对象: Color3B 用三个 0-255 的整数描述颜色. Color4B 用四个 ...

最新文章

  1. OKR落地,实践经验总结两个点比较重要
  2. python 字符串部分总结
  3. php增删改查心得体会,php增删改查入门示例
  4. vb.net 功能f8键事件_笔记本电脑功能键介绍
  5. 对话高博(一)| 机器码、Pascal,以及计算机学习的分形
  6. 太阳能发电板的规格尺寸_新疆深山藏着一个村庄,至今未通水电,村民买太阳能板自行发电...
  7. 简单分析ComponentScan
  8. springboot 整合 kafka demo 顺便看一下源码
  9. html代码大全贴音乐,网页音乐代码大全
  10. 爪哇国新游记之二十六----迷宫寻路
  11. APUE读书笔记-04文件和目录(5)
  12. matlab 连通域数量,【Matlab】找到矩阵中每个连通域的最小值
  13. windwo下载完nvm无法执行node
  14. mysql 嵌套查询优化_MySQL——优化嵌套查询和分页查询
  15. 基于X86汇编语言的简易打字游戏实现
  16. ldc java_java – LDC指令代码的负值是什么意思?
  17. HDOJ 5296 Annoying problem LCA+数据结构
  18. 【PC工具】压缩包密码破解工具,暴力破解压缩包密码,zip密码获取
  19. 简单暴力的排序方式:直接排序
  20. 助力武汉抗击疫情,湖北科研资料共享

热门文章

  1. LeetCode Search a 2D Matrix
  2. 在线文本行固定长度填充工具
  3. RelativeLayout addRule踩坑之旅
  4. jetty服务器原理与maven集成
  5. qml demo分析(clocks-时钟)
  6. shell截取字符串的8种方法
  7. Shell Curses 函数库
  8. 如何解决 FrameBuffer console (vc)自动关闭显示
  9. LVS-DR负载均衡-02
  10. redis解决了分布式系统的session一致性问题