class cPolySprite : public cocos2d::CCSprite { public: cPolySprite() : vertexs_(NULL), uvs_(NULL), indices_(NULL), verCnt_(0) {} virtual ~cPolySprite(); static cPolySprite* create(const char *pFile,const cocos2d::CCPoint *uvs,int verCnt,const int *indices); static cPolySprite* create(CCTexture2D* texture,const CCPoint* uvs,int verCnt,const int* indices); //重载父类draw void draw(); private: //初始化顶点信息 bool initWithUV(const cocos2d::CCPoint *uvs, const int *indices, int verCnt); //计算中点 cocos2d::CCPoint getCenter(); void translate(const cocos2d::CCPoint&); void drawPoly(); void releasePoly(); private: //多边形顶点 cocos2d::ccVertex2F *vertexs_; //定点纹理坐标 cocos2d::ccVertex2F *uvs_; //三角形索引 unsigned short *indices_; //顶点颜色 unsigned char *colors_; //顶点数目 int verCnt_; };
#include "cPolySprite.h" cPolySprite* cPolySprite::create(const char *pFile,const cocos2d::CCPoint *uvs,int verCnt,const int *indices) { cPolySprite *pobSprite = new cPolySprite(); //创建精灵 if (pobSprite && pobSprite->initWithFile(pFile) && pobSprite->initWithUV(uvs, indices, verCnt)) { pobSprite->autorelease(); return pobSprite; } CC_SAFE_DELETE(pobSprite); return false; } cPolySprite* cPolySprite::create(CCTexture2D* pTexture,const CCPoint* uvs,int verCnt,const int* indices) { cPolySprite *pobSprite = new cPolySprite(); CCRect rect = CCRectZero; rect.size = pTexture->getContentSize(); if (pobSprite && pobSprite->initWithTexture(pTexture, rect) && pobSprite->initWithUV(uvs, indices, verCnt)) { pobSprite->autorelease(); return pobSprite; } CC_SAFE_DELETE(pobSprite); return false; } cPolySprite::~cPolySprite() { releasePoly(); } //初始化顶点信息 bool cPolySprite::initWithUV(const cocos2d::CCPoint *uvs,const int *indices,int verCnt) { //内存分配 vertexs_ = new ccVertex2F[verCnt]; uvs_ = new ccVertex2F[verCnt]; indices_ = new unsigned short[( verCnt - 2 ) * 3]; colors_ = new unsigned char[ verCnt * 4 ]; //失败处理 if(!vertexs_ || !uvs_ || !indices_ || !colors_) { releasePoly(); return false; } //贴图大小 CCSize rc = m_pobTexture->getContentSize(); for(int i = 0; i < verCnt; ++i) { //根据纹理坐标以及纹理大小计算顶点坐标 vertexs_[i].x = uvs[i].x * rc.width; //cocos2dx纹理坐标以左上角为原点 vertexs_[i].y = (1.0 - uvs[i].y)*rc.height; uvs_[i].x = uvs[i].x; uvs_[i].y = uvs[i].y; } for(int i = 0; i < (verCnt-2)*3; ++i) indices_[i] = indices[i]; memset(colors_, 255, sizeof(unsigned char)*verCnt*4); verCnt_ = verCnt; translate(getCenter()); return true; } //计算中点 CCPoint cPolySprite::getCenter() { if(!vertexs_) return ccp(0,0); float minx = vertexs_[0].x, maxx = vertexs_[0].x, miny = vertexs_[0].y, maxy = vertexs_[0].y; //计算所有顶点坐标的中心点坐标 for(int i = 0; i < verCnt_; ++i) { minx = minx>vertexs_[i].x?vertexs_[i].x:minx; maxx = maxx; miny = miny>vertexs_[i].y?vertexs_[i].y:miny; maxy = maxy; } return ccp((minx+maxx)*0.5, (miny+maxy)*0.5); } void cPolySprite::translate(const cocos2d::CCPoint& pos) { //设置锚点 CCSize rc = m_pobTexture->getContentSize(); setAnchorPoint(ccp(pos.x/rc.width, pos.y/rc.height)); } void cPolySprite::drawPoly() { CC_NODE_DRAW_SETUP(); ccGLBlendFunc( m_sBlendFunc.src, m_sBlendFunc.dst ); if (m_pobTexture != NULL) { ccGLBindTexture2D( m_pobTexture->getName() ); } else { ccGLBindTexture2D(0); } ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex); //顶点,纹理,颜色 glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertexs_); glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, uvs_); glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, colors_); //根据索引draw三角形 glDrawElements(GL_TRIANGLES, (verCnt_-2)*3, GL_UNSIGNED_SHORT, indices_); CC_INCREMENT_GL_DRAWS(1); } void cPolySprite::releasePoly() { CC_SAFE_DELETE(vertexs_); CC_SAFE_DELETE(uvs_); CC_SAFE_DELETE(indices_); CC_SAFE_DELETE(colors_); } void cPolySprite::draw(void) { drawPoly(); }
使用方式:
//示例 //CCPoint p[] = {ccp(0, 1.0), ccp(0.3, 0.3), ccp(0.4, 0.4), ccp(0.4, 0.2)}; //int index[] = {0, 1, 3, 0, 2, 3}; //cPolySprite *csp = cPolySprite::create("HelloWorld.png", p, 4, index);
http://blog.sina.com.cn/s/blog_62b2318d0101du43.html