[cocos2d-x]深入--几个代表性的类
摘要: 此文对cocos2d-x引擎中最具代表性,最能体现框架结构的几个类做了简单的介绍, 包括Director,Application, Renderer, EventDispatcher, Scheduler. 对于这些类, 也只对关系主要流程的方法做了介绍, 略过了容错代码和其它细节. 主要目的是让大家快速的对cocos2d-x引擎有一个全面笼统的认识, 也方便快速定位问题.
- 博客: http://www.cnblogs.com/jhzhu
- 邮箱: jhzhuustc@gmail.com
- 作者: 知明所以
- 时间: 2014-07-21
GLView
cocos2d-x对openGL的封装. 不同平台下, 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
gland initial capital letters for each word making up the command name - some seemingly extraneous letters appended to some command names (for example, the
3finglColor3f()andglVertex3f())
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 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() 的主要功能就是
- 调用所有孩子的
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()
因为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函数主要实现了[添加一个QuadCommand到Render中去]的功能.
再看看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();
可见它主要由两个功能:
- 对
ReanderCommand进行排序和分类管理 - 进行渲染:
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 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介绍
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的其它大部分方法, 要么是它的衍生, 为了减少调用参数; 要么是对定时操作的控制, 比如暂停, 恢复, 移除等. 如果只对想对框架的各个模块有大概的了解, 可以不做深入.
EventDispatcher
(后续添加)
Written with StackEdit.
[cocos2d-x]深入--几个代表性的类的更多相关文章
- [cocos2d-x]深入--几个代表性的类 (续)
摘要: 此文对cocos2d-x引擎中最具代表性,最能体现框架结构的几个类做了简单的介绍, 包括Director,Application, Renderer, EventDispatcher, Sch ...
- Cocos2d 3.0继承自Sprite的类在addChild后出现故障
当继承自Sprite的类被addChild到其它的Node里后出现例如以下图问题,说明没有调用父类Sprite::init()的方法.由于父类Sprite里的_textureAtlas须要初始化为nu ...
- Cocos2d-x——CocosBuilder官方帮助文档翻译1 使用自定义类
原创:请注明转载! 在Cocos2d-x中使用CocosBuilder 使用自定义类 CocosBuilder的使用方法是通过自定义类.在CocosBuilder中选中一个对象并在属性栏中输入自定义类 ...
- cocos2d-x实战 C++卷 学习笔记--第4章 字符串 __String类
前言: <cocos2d-x实战C++卷>学习笔记.(cocos2d-x 是3.0版本) 介绍 cocos2d-x 通用的字符串类 __String . 使用cocos2d::__Str ...
- cocos2D(四)---- CCSprite
在介绍CCSprite之前,先要理解游戏开发中的一个核心概念:精灵.精灵也称为游戏对象,它能够用来表示游戏中的不论什么物体,比方敌人.子弹.甚至是一个背景图片.一段文字.CCSprite能够说是在co ...
- [cocos2dx笔记013]一个使用CCRenderTexture创建动态纹理显示数字的类
用CCLabelTTF显示的数字不好看.于是就想到用图片来代理.眼下网上的实现都是把每一个数字做一个CCSprite组合的方式. 可是我想.动态生成纹理的方式.没有就仅仅好自己手动写一个. 头文件 # ...
- Java类的继承与多态特性-入门笔记
相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...
- cocos2d-x 2.0 序列帧动画 深入分析
转自:http://blog.csdn.net/honghaier/article/details/8222401 序列帧动画主要有几个类: CCSpriteFrame:精灵帧信息,序列帧动画是依靠多 ...
- Darwin Streaming Server 简介
Darwin Streaming Server 概要 Darwin Streaming Server简称DSS.DSS是Apple公司提供的开源实时流媒体播放服务器程序.整个程序使用C++编写 ...
随机推荐
- 类似 Dribbble 下载按钮的 SVG 弹性动画进度条
Codrops 发布了一个如何创建一个基于弹性效果的 SVG 加载进度条教程,基于 SVG 和 TweenMax 实现.按钮开始的时候是一个带有箭头的图标,一旦它被点击,动画成一个有趣的小金属丝和一个 ...
- css样式 --- CSS hack
前端样式,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我们会极不情愿的使用这个不太友好的方式来达到大家要求的页面表现.我个人是不太推荐使用hack的,要知道一 ...
- Sap 常用Function 说明
函数名 描述 SD_VBAP_READ_WITH_VBELN 根据销售订单读取表vbap中的信息EDIT_LINES 把READ_TEXT返回的LINES中的行按照TDFORMAT=“*”重新组织VI ...
- Kali Linux (XFce版本)安装后的一些设置
kali Linux的主版本自带的是Gnome桌面环境,安装后使用效率太低,不知道是不是我机器配置低的原因, 在虚拟机里运行起来太慢.卡.丑啦....所以以前都一直都在用Backbox Linux,并 ...
- C语言一级指针与二级指针
指针的概念 指针就是地址, 利用这个地址可以找到指定的数据 指针就是地址, 那么在使用的时候, 常常会简单的说 指针变量为指针 指针变量就是存储地址的变量 int *p1;// 申请了一个变量, 即在 ...
- Android高级模糊技术[转]
今天我们来更深入了解一下Android开发上的模糊技术.我读过几篇有关的文章,也在StackOverFlow上看过一些相关教程的帖子,所以我想在这里总结一下学到的东西. 为什么学习这个模糊技术? 现在 ...
- 浏览器判断是否安装APP
浏览器判断是否安装APP http://blog.csdn.net/henrywulibin/article/details/52087041 从浏览器中打开我们的应用 http://blog.csd ...
- 操作系统开发系列—4.LDT
一直以来,我们把所有的段描述符都放在GDT中,而不管它属于内核还是用户程序,为了有效地在任务之间实施隔离,处理器建议每个任务都应当具有自己的描述符表,称为局部描述符表LDT,并且把专属于自己的那些段放 ...
- CoreGraphics相关方法
// 将view转为image(不经常用到的功能)(摘自SCCatWaitingHUD) - (UIImage *)convertViewToImage { CGSize s = self.bound ...
- 【代码笔记】iOS-两个滚动条,上下都能滑动
一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...