cocos2dx 渲染任意形状贴图

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,

                          constcocos2d::CCPoint *uvs,

                          intverCnt,

                          constint *indices);

    

   //重载父类draw

    void draw();

    

private:

   //初始化顶点信息

    bool initWithUV(const cocos2d::CCPoint *uvs,

                 constint *indices,

                 intverCnt);

    

   //计算中点

    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 namespacecocos2d;


cPolySprite*cPolySprite::create(constchar *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();

       returnfalse;

   }

    

   //贴图大小

   CCSize rc =m_pobTexture->getContentSize();

    

   for(inti = 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(inti = 0; i <(verCnt-2)*3; ++i)

      indices_[i] = indices[i];

    

   memset(colors_, 255, sizeof(unsigned char)*verCnt*4);

    

   verCnt_ = verCnt;

    

   translate(getCenter());

    

   return true;

}


//计算中点

CCPointcPolySprite::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(inti = 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

   }

    

   returnccp((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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值