11.1 使用DrawingPrimitives接口绘制图元
11.1.1 如何绘制图元
Cocos2d-x的CCDrawingPrimitives.h中封装了大量的图元绘制接口,但要使用它们却不那么轻松,这些接口都是直接调用OpenGL的方法进行绘制,如图11-1是cpp-tests示例中的draw primitives示例,该示例演示了如何用图元绘制接口。
图11-1 draw primitives示例
在Cocos2d-x中,需要遵循规则才能正确地将图元渲染到屏幕上,不能直接使用这些渲染接口,而是需要实现一个自定义的Node,将Node添加到场景中,在Node的draw()方法中调用这些接口进行绘制。
如果不在Node的draw()方法中进行绘制,而在其他地方进行绘制,例如在update回调中绘制,则是无法渲染到屏幕上的,因为Cocos2d-x在Director的drawScene()方法中会渲染,执行的流程是update更新(这里包含了所有的Schedule、Action)、clear清除屏幕、draw绘制、swapbuffer刷新缓冲区。所以任何在update或schedule中的渲染行为,都将会被clear操作清除掉。
接下来了解一下使用DrawingPrimitives的正确步骤。
(1)定义一个继承于Node的类,并重写其draw()方法。
(2)在draw()方法中添加一条Custom渲染命令到renderer中。
(3)在真正的绘制函数中压入模型视图矩阵,执行绘制,绘制完成后弹出模型视图矩阵。
在cpp-tests中的DrawPrimitivesTest示例演示了以上步骤。以下是该示例的关键代码。
void DrawPrimitivesTest::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) { _customCommand.init(_globalZOrder); _customCommand.func = CC_CALLBACK_0(DrawPrimitivesTest::onDraw, this, transform, flags); renderer->addCommand(&_customCommand); } void DrawPrimitivesTest::onDraw(const Mat4 &transform, uint32_t flags) { Director* director = Director::getInstance(); director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform); //执行绘制 CHECK_GL_ERROR_DEBUG(); DrawPrimitives::drawLine( VisibleRect::leftBottom(), VisibleRect::rightTop() ); CHECK_GL_ERROR_DEBUG(); director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); }
11.1.2 半透明效果
当希望在图元渲染中,开启半透明的效果时(默认透明通道是失效的),需要手动开启颜色混合,然后在绘制图元的时候指定Alpha通道。
GL::blendFunc( m_sBlendFunc.src, m_sBlendFunc.dst ); glLineWidth( 2.0f ); DrawPrimitives::setDrawColor4B(1.0f,0.8f,0.0f, 0.5f); DrawPrimitives::DrawLine( ccp(100.0f, 100.0f), ccp(200.0f,200.0f));
11.1.3 抗锯齿
在绘制图元的时候可以发现很明显的锯齿,如果希望图元变得平滑一些,可以在绘制的时候手动开启OpenGL的抗锯齿功能,针对不同图元类型的绘制,需要设置不同的抗锯齿选项。首先需要用glEnable()函数开启对应的抗锯齿功能。
glEnable(GL_POINT_SMOOTH); //对点进行抗锯齿优化 glEnable(GL_LINE_SMOOTH); //对线条进行抗锯齿优化 glEnable(GL_POLYGON_SMOOTH); //对多边形渲染进行抗锯齿优化
接下来用glHint()函数设置抗锯齿的质量,glHint()函数有两个参数,第一个是需要对哪种抗锯齿类型进行设置,也就是对上面3种类型的其中一种,第二个参数是抗锯齿的质量。
glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE); //默认 glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST); //速度优先 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); //画质优先