cocos2d-x中并没有直接绘制扇形的方法,只能够自己在底层封装。方法有两种:
一、使用CCDrawingPrimitives绘制
1、在CCDrawingPrimitives.h中声明函数:
/********************************************************画扇形****/
void drawSolidFan( const Vec2& center, float radius, float from,float angle, unsigned int segments, float scaleX, float scaleY);
void drawSolidFan( const Vec2& center, float radius, float from,float angle, unsigned int segments);
/*****************************************************************/
/********************************************************画扇形****/
void drawSolidFan( const Vec2& center, float radius, float from, float angle, unsigned int segments, float scaleX, float scaleY)
{
lazy_init();
const float coef = (float)angle/segments;
GLfloat *vertices = (GLfloat*)calloc( sizeof(GLfloat)*2*(segments+2), 1);
if( ! vertices )
return;
vertices[0]=center.x;
vertices[1]=center.y;
for(unsigned int i = 0;i <= segments; i++) {
float rads = i*coef;
GLfloat j = radius * cosf(from+rads) * scaleX + center.x;
GLfloat k = radius * sinf(from+rads) * scaleY + center.y;
vertices[(i+1)*2] = j;
vertices[(i+1)*2+1] = k;
}
s_shader->use();
s_shader->setUniformsForBuiltins();
s_shader->setUniformLocationWith4fv(s_colorLocation, (GLfloat*) &s_color.r, 1);
GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POSITION );
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, (GLsizei) segments+2);
::free(vertices);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,segments+2);
}
void drawSolidFan( const Vec2& center, float radius, float from,float angle, unsigned int segments)
{
drawSolidFan(center, radius,from, angle, segments, 1.0f, 1.0f);
}
/*****************************************************************/
二、使用DrawNode绘制
1、在DrawNode.h中声明函数:
/********************************************************画扇形****/
void drawSolidFan(const Vec2& center, float radius, float from,float angle, unsigned int segments, float scaleX, float scaleY, const Color4F& color);
void drawSolidFan(const Vec2& center, float radius, float from,float angle, unsigned int segments, const Color4F& color);
/*****************************************************************/
/********************************************************画扇形****/
void DrawNode::drawSolidFan(const Vec2& center, float radius, float from,float angle, unsigned int segments, float scaleX, float scaleY, const Color4F& color){
const float coef = (float)angle/segments;
Vec2 *vertices = new (std::nothrow) Vec2[segments];
if( ! vertices )
return;
vertices[0]=center;
for(unsigned int i = 0;i < segments-1; i++)
{
float rads = i*coef;
GLfloat j = radius * cosf(rads + from) * scaleX + center.x;
GLfloat k = radius * sinf(rads + from) * scaleY + center.y;
vertices[i+1].x = j;
vertices[i+1].y = k;
}
drawSolidPoly(vertices, segments, color);
CC_SAFE_DELETE_ARRAY(vertices);
}
void DrawNode::drawSolidFan(const Vec2& center, float radius, float from,float angle, unsigned int segments, const Color4F& color){
drawSolidFan(center, radius,from, angle, segments, 1.0f, 1.0f, color);
}
/*****************************************************************/
那么这两种方法怎么用呢?
1、HelloWorldScene.h
class HelloWorld : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
virtual void draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t flags) override;
// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);
protected:
void onDraw(const cocos2d::Mat4& transform, uint32_t flags);
cocos2d::CustomCommand _customCommand;
};
bool HelloWorld::init()
{
//
// 1. super init first
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
auto draw=DrawNode::create();
this->addChild(draw,10);
draw->drawSolidFan(VisibleRect::center()+Vec2(100, 0), 50, CC_DEGREES_TO_RADIANS(120), CC_DEGREES_TO_RADIANS(270), 1890, Color4F(0.0, 1.0, 0.0, 1.0));
return true;
}
void HelloWorld::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(HelloWorld::onDraw, this, transform, flags);
renderer->addCommand(&_customCommand);
}
void HelloWorld::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();
glLineWidth(16);
DrawPrimitives::setDrawColor4B(0, 255, 0, 255);
DrawPrimitives::drawSolidFan( VisibleRect::center()-Vec2(100, 0), 50, CC_DEGREES_TO_RADIANS(120),CC_DEGREES_TO_RADIANS(270), 1890);
CHECK_GL_ERROR_DEBUG();
//end draw
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}
class VisibleRect
{
public:
static cocos2d::Rect getVisibleRect();
static cocos2d::Vec2 left();
static cocos2d::Vec2 right();
static cocos2d::Vec2 top();
static cocos2d::Vec2 bottom();
static cocos2d::Vec2 center();
static cocos2d::Vec2 leftTop();
static cocos2d::Vec2 rightTop();
static cocos2d::Vec2 leftBottom();
static cocos2d::Vec2 rightBottom();
private:
static void lazyInit();
static cocos2d::Rect s_visibleRect;
};
Rect VisibleRect::s_visibleRect;
void VisibleRect::lazyInit()
{
// no lazy init
// Useful if we change the resolution in runtime
s_visibleRect = Director::getInstance()->getOpenGLView()->getVisibleRect();
}
Rect VisibleRect::getVisibleRect()
{
lazyInit();
return s_visibleRect;
}
Vec2 VisibleRect::left()
{
lazyInit();
return Vec2(s_visibleRect.origin.x, s_visibleRect.origin.y+s_visibleRect.size.height/2);
}
Vec2 VisibleRect::right()
{
lazyInit();
return Vec2(s_visibleRect.origin.x+s_visibleRect.size.width, s_visibleRect.origin.y+s_visibleRect.size.height/2);
}
Vec2 VisibleRect::top()
{
lazyInit();
return Vec2(s_visibleRect.origin.x+s_visibleRect.size.width/2, s_visibleRect.origin.y+s_visibleRect.size.height);
}
Vec2 VisibleRect::bottom()
{
lazyInit();
return Vec2(s_visibleRect.origin.x+s_visibleRect.size.width/2, s_visibleRect.origin.y);
}
Vec2 VisibleRect::center()
{
lazyInit();
return Vec2(s_visibleRect.origin.x+s_visibleRect.size.width/2, s_visibleRect.origin.y+s_visibleRect.size.height/2);
}
Vec2 VisibleRect::leftTop()
{
lazyInit();
return Vec2(s_visibleRect.origin.x, s_visibleRect.origin.y+s_visibleRect.size.height);
}
Vec2 VisibleRect::rightTop()
{
lazyInit();
return Vec2(s_visibleRect.origin.x+s_visibleRect.size.width, s_visibleRect.origin.y+s_visibleRect.size.height);
}
Vec2 VisibleRect::leftBottom()
{
lazyInit();
return s_visibleRect.origin;
}
Vec2 VisibleRect::rightBottom()
{
lazyInit();
return Vec2(s_visibleRect.origin.x+s_visibleRect.size.width, s_visibleRect.origin.y);
}