//
// cPolySprite.h
// cardmap
//
// Created by sunny on 12-12-4.
//
//
#ifndef __cardmap__cPolySprite__
#define __cardmap__cPolySprite__
#include "cocos2d.h"
//多边形精灵
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);
//重载父类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_;
};
#endif
//
// cPolySprite.cpp
// cardmap
//
// Created by sunny on 12-12-4.
//
//
#include "cPolySprite.h"
#include "cocos2d.h"
using namespace cocos2d;
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()
{
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);
有点笨拙,但是还能用,需要注意的地方就是坐标系,纹理坐标左上角为原点,屏幕坐标左下角是原点。
渲染了个四边形贴图: