cocos2d-x 中自己写的draw函数会自己调用的
要把画画的代码放到draw里面不然画不出来的
比如说:将画一条直线放到下面这函数是画不出来的
bool HelloWorld::init(){。。。。。。
ccDrawLine( ccp(0, 0), ccp(s.width, s.height) );
CHECK_GL_ERROR_DEBUG();。。。。。。
}
#include “TowerPosEditorLayer.h”
TowerPosEditorLayer::TowerPosEditorLayer(){
m_iCurLevel = 1;
}TowerPosEditorLayer::~TowerPosEditorLayer(){
}
bool TowerPosEditorLayer::init(){
if (!Layer::init()){
return false;
}auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = \[\](Touch* touch, Event* event){ return true; }; listener->onTouchEnded = \[&\](Touch* touch, Event* event){ Point pos = Director::getInstance()->convertToGL(touch->getLocationInView()); editTowerPos(pos); }; _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); return true;
}
void TowerPosEditorLayer::editTowerPos(Point pos){
PosBase* existPos = findExistTowerPos(pos);
if (existPos != NULL){
deleteTowerPos(existPos);
}
else {
createTowerPos(pos);
}
}PosBase* TowerPosEditorLayer::findExistTowerPos(Point pos){
for (auto basePos : m_towerPosList){
if (basePos->isClickMe(pos)){
return basePos;
}
}
return NULL;
}void TowerPosEditorLayer::createTowerPos(Point pos){
TowerPos* tPos = TowerPos::create(pos, true);
this->addChild(tPos, 10);
m_towerPosList.pushBack(tPos);
}void TowerPosEditorLayer::deleteTowerPos(PosBase* existPos){
this->removeChild(existPos);
m_towerPosList.eraseObject(existPos);
}void TowerPosEditorLayer::deleteAllPos(){
this->removeAllChildrenWithCleanup(true);
m_towerPosList.clear();
}而放到draw函数就能画出来,也不需要调用
void HelloWorld::draw(){
ccDrawLine( ccp(0, 0), ccp(s.width, s.height) );
CHECK_GL_ERROR_DEBUG();}
转:3.0之前是visit后就draw,而draw是真正的OpenGL操作。也就是说,每访问一个对象,先计算节点的渲染数据,然后马上渲染。因为节点是按树形结构组织的,如果两个父节点p1和p2的深度分别是10和20,c1是p1的子节点,其深度是30,c2是p2的子节点,其深度是5。则渲染顺序是p1、c1、c2、p2。 3.0也是在visit后就draw,但是draw并不进行OpenGL操作。3.0抽象了一个RenderCommand,在draw的时候其实是生成一个渲染命令,渲染命令其实就是对渲染所需要的数据的封装。RenderCommand作为基类,只包含了两个成员,一个是命令类型\_type,这个很必要,正是靠这个来获取子类对象的具体类型的,这里没有用运行时类型,应该是考虑到效率;另一个是z深度\_globalOrder,这个也很必要,渲染的时候必然要对节点排序,而z序是唯一的依据。 3.0包含了以下几个RenderCommand的子类: 1,CustomCommand: 顾名思义,是客户自定义的。它没有过多的数据,只有一个std::function<>类型成员func,这个是在节点draw创建CustomCommand的时候传入的参数,而在真正渲染的时候调用的正是这个函数。比如Label,它的draw函数体为: void Label::draw() { \_customCommand.init(\_globalOrder); \_customCommand.func=CC\_CALLBACK_0(Label::onDraw, this,transform,transformUpdated); render->addCommand(&_customCommand); } 可见,真正的渲染是在onDraw回调函数中。onDraw的操作和此前版本的draw函数相差不大,都是设置混合方式,使用GLProgram,更新shader的变换矩阵等shader所用到的uniform变量,更新子节点位置(注:因为是批量渲染,这个和此前的CCSpriteBatchNode很相近),调用TextureAtlas::drawQuads(); 使用CustomCommand还有Layer,LableAtlas,LabelBMFont,此外还有RenderTexture,这个比较特殊,下面会说。 注:估计作者是对所有不太好抽象的渲染节点,就干脆做了一个CustomCommand。 #include "TowerPos.h" TowerPos::TowerPos(){ m_pos = Point(0, 0); m_isDebug = false; } TowerPos::~TowerPos(){ } //要画的东西丢给draw,draw会调用onDraw来绘制,该函数会自动被调用 //renderer渲染器, draw函数固定重写,决定画啥的还是onDraw void TowerPos::draw(Renderer* renderer, const kmMat4 &transform, bool transformUpdate){ if (m_isDebug){ \_customCommand.init(\_globalZOrder); \_customCommand.func = CC\_CALLBACK_0(TowerPos::onDraw, this, transform, transformUpdate); renderer->addCommand(&_customCommand); } } void TowerPos::onDraw(const kmMat4 &transform, bool transformUpdate){ //开始绘制 kmGLPushMatrix(); kmGLLoadMatrix(&transform); //笔刷厚度 glLineWidth(5.0f); Point srcPos = Point(m\_pos.x - RADIUS, m\_pos.y + RADIUS); Point destPos = Point(m\_pos.x + RADIUS, m\_pos.y - RADIUS); //这函数负责各种画图 DrawPrimitives::drawRect(srcPos, destPos); glLineWidth(1); kmGLPopMatrix();//结束绘制 } bool TowerPos::isClickMe(Point pos){ Point srcPos = Point(m\_pos.x - RADIUS, m\_pos.y + RADIUS); Point destPos = Point(m\_pos.x + RADIUS, m\_pos.y - RADIUS); if (pos.x >= srcPos.x && pos.x <= destPos.x && pos.y <= srcPos.y && pos.y >= destPos.y){ return true; } return false; } TowerPos* TowerPos::create(Point pos){ TowerPos* tPos = new TowerPos(); if (tPos && tPos->init(pos)){ tPos->autorelease(); } else { CC\_SAFE\_DELETE(tPos); } return tPos; } TowerPos* TowerPos::create(Point pos, bool isDebug){ TowerPos* tPos = new TowerPos(); if (tPos && tPos->init(pos, isDebug)){ tPos->autorelease(); } else { CC\_SAFE\_DELETE(tPos); } return tPos; } bool TowerPos::init(Point pos){ bool bRet = false; do { CC\_BREAK\_IF(!PosBase::init(pos)); bRet = true; } while (0); return bRet; } bool TowerPos::init(Point pos, bool isDebug){ bool bRet = false; do { CC\_BREAK\_IF(!PosBase::init(pos, isDebug)); bRet = true; } while (0); return bRet; }