您的位置:首页 > 移动开发 > Cocos引擎

cocos2dx 渲染任意形状贴图

2016-06-17 18:41 363 查看
原文地址:http://blog.sina.com.cn/s/blog_62b2318d0101du43.html

cocos2d-x中的CCSprite职能渲染矩形,如果想随意渲染任意形状的贴图,我没找到什么现成的东西,自己扩展了一下CCSprite,如下:

//

//  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);

有点笨拙,但是还能用,需要注意的地方就是坐标系,纹理坐标左上角为原点,屏幕坐标左下角是原点。

渲染了个四边形贴图:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: