【转】cocos2d-x游戏开发(十四)用shader使图片背景透明
转自:http://blog.csdn.net/dawn_moon/article/details/8631783
好吧,终于抽时间写这篇文章了。
手头上有很多人物行走图,技能特效图等,但这些图都有个纯黑色背景,怎么样将内容显示出来,让背景透明呢?前段时间搞了一下,感谢群里的童鞋们,提供了思路和方法。
这里用shader处理了像素,使黑色背景透明,直接上代码
ShaderSprite.h
#ifndef __TestShader__ShaderSprite__
#define __TestShader__ShaderSprite__
#include "cocos2d.h"
USING_NS_CC;
class ShaderSprite : public CCSprite {
public:
static ShaderSprite* create(const char* pszFileName);
virtual bool initWithTexture(CCTexture2D *pTexture, const CCRect& rect);
virtual void draw(void);
};
#endif /* defined(__TestShader__ShaderSprite__) */
ShaderSprite.cpp
#include "ShaderSprite.h"
static CC_DLL const GLchar *transparentshader =
#include "tansparentshader.h"
ShaderSprite* ShaderSprite::create(const char *pszFileName)
{
ShaderSprite *pRet = new ShaderSprite();
if (pRet && pRet->initWithFile(pszFileName)) {
pRet->autorelease();
return pRet;
}
else
{
delete pRet;
pRet = NULL;
return NULL;
}
}
bool ShaderSprite::initWithTexture(CCTexture2D *pTexture, const CCRect& rect)
{
do{
// CCLog("override initWithTexture!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
CC_BREAK_IF(!CCSprite::initWithTexture(pTexture, rect));
// 加载顶点着色器和片元着色器
m_pShaderProgram = new CCGLProgram();
m_pShaderProgram ->initWithVertexShaderByteArray(ccPositionTextureA8Color_vert, transparentshader);
CHECK_GL_ERROR_DEBUG();
// 启用顶点着色器的attribute变量,坐标、纹理坐标、颜色
m_pShaderProgram->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
m_pShaderProgram->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
m_pShaderProgram->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
CHECK_GL_ERROR_DEBUG();
// 自定义着色器链接
m_pShaderProgram->link();
CHECK_GL_ERROR_DEBUG();
// 设置移动、缩放、旋转矩阵
m_pShaderProgram->updateUniforms();
CHECK_GL_ERROR_DEBUG();
return true;
});
return false;
}
void ShaderSprite::draw(void)
{
// CCLog("override draw!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
CC_PROFILER_START_CATEGORY(kCCProfilerCategorySprite, "CCSprite - draw");
CCAssert(!m_pobBatchNode, "If CCSprite is being rendered by CCSpriteBatchNode, CCSprite#draw SHOULD NOT be called");
CC_NODE_DRAW_SETUP();
//
// 启用attributes变量输入,顶点坐标,纹理坐标,颜色
//
ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex );
ccGLBlendFunc(m_sBlendFunc.src, m_sBlendFunc.dst);
m_pShaderProgram->use();
m_pShaderProgram->setUniformsForBuiltins();
// 绑定纹理到纹理槽0
ccGLBindTexture2D(m_pobTexture->getName());
#define kQuadSize sizeof(m_sQuad.bl)
long offset = (long)&m_sQuad;
// vertex
int diff = offsetof( ccV3F_C4B_T2F, vertices);
glVertexAttribPointer(kCCVertexAttrib_Position, , GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));
// texCoods
diff = offsetof( ccV3F_C4B_T2F, texCoords);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, , GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));
// color
diff = offsetof( ccV3F_C4B_T2F, colors);
glVertexAttribPointer(kCCVertexAttrib_Color, , GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));
glDrawArrays(GL_TRIANGLE_STRIP, , );
CHECK_GL_ERROR_DEBUG();
CC_INCREMENT_GL_DRAWS();
CC_PROFILER_STOP_CATEGORY(kCCProfilerCategorySprite, "CCSprite - draw");
}
片段着色器代码
tansparentshader.h
" \n\
#ifdef GL_ES \n\
precision lowp float; \n\
#endif \n\
varying vec4 v_fragmentColor; \n\
varying vec2 v_texCoord; \n\
uniform sampler2D u_texture; \n\
void main() \n\
{ \n\
float ratio=0.0; \n\
vec4 texColor = texture2D(u_texture, v_texCoord); \n\
ratio = texColor[] > texColor[]?(texColor[] > texColor[] ? texColor[] : texColor[]) :(texColor[] > texColor[]? texColor[] : texColor[]); \n\
if (ratio != 0.0) \n\
{ \n\
texColor[] = texColor[] / ratio; \n\
texColor[] = texColor[] / ratio; \n\
texColor[] = texColor[] / ratio; \n\
texColor[] = ratio; \n\
} \n\
else \n\
{ \n\
texColor[] = 0.0; \n\
} \n\
gl_FragColor = v_fragmentColor*texColor; \n\
}";
注意shader编程没有隐士数据类型转换,所以都显示为float了。
然后ratio是指在rgb中找最大的,如果ratio为0直接将alpha设为0,否则alpha设为ratio,然后各rgb除以ratio,这里是为了做渐变,否则变化太生硬。
上图:


好了,上面两张图是一样的。只是屏幕背景一个是白色,一个是黑色。图片背景透明了。
【转】cocos2d-x游戏开发(十四)用shader使图片背景透明的更多相关文章
- iOS cocos2d 2游戏开发实战(第3版)书评
2013是游戏爆发的一年,手游用户也是飞速暴增.虽然自己不做游戏,但也是时刻了解手机应用开发的新动向.看到CSDN的"写书评得技术图书赢下载分"活动,就申请了一本<iOS c ...
- STC8H开发(十四): I2C驱动RX8025T高精度实时时钟芯片
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...
- python运维开发(十四)----HTML基本操作
内容目录: HTML概述 head标签 body中常用标签 css选择器 css常用属性 HTML HTML概述 HTML是英文Hyper Text Mark-up Language(超文本标记语言) ...
- Java微信公众平台开发(十四)【番外篇】--微信web开发者工具使用
转自:http://www.cuiyongzhi.com/post/58.html 为帮助开发者更方便.更安全地开发和调试基于微信的网页,微信推出了 web 开发者工具.它是一个桌面应用,通过模拟微信 ...
- cocos2d-x游戏开发(十五)游戏加载动画loading界面
个人原创,欢迎转载:http://blog.csdn.net/dawn_moon/article/details/11478885 这个资源加载的loading界面demo是在玩客网做逆转三国的时候随 ...
- cocos2d-x游戏开发(十五)游戏载入动画loading界面
这个资源载入的loading界面demo是在玩客网做逆转三国的时候随手写的,尽管我在那仅仅待了2个礼拜.可是也算參与了一个商业游戏项目了,学到不少东西.当时使用的cocos2d-x还是1.0版的,我用 ...
- cocos2d-x游戏开发(十六)帧动画
欢迎转载:http://blog.csdn.net/dawn_moon/article/details/11775745 本来想写一下帧动画的,搜了一下网上好像有一大把,就懒得写了,直接贴代码. // ...
- cocos2d-x游戏开发 跑酷(四) 关联与物理世界
原创.转载注明出处http://blog.csdn.net/dawn_moon/article/details/21451077 前面一节尽管实现了一个跑动的人物,可是他只不过一个精灵在运行一个跑动的 ...
- unity3D游戏开发十八之NGUI动画
我们先来看下帧动画,顾名思义,就是一帧帧的图片组成的动画,我们须要用到UISprite Animation组件,它的属性例如以下: Framerate:播放速率,也就是每秒钟播放的帧数 Name Pr ...
随机推荐
- c#3位一分(money)
NumberFormatInfo num = new NumberFormatInfo(); num.NumberDecimalDigits = 2; string ...
- 让<未将对象引用到实例>见鬼去吧!
未将对象引用到实例,即NullReferenceException异常,我相信这是c#编程中最常见的错误之一,至少我在做项目的过程中,有很多时候都会抛出这个异常.每当这个异常出现的时候,我都会头皮一紧 ...
- gif格式的图片不能存在与包含js目录的路径中?
如题:gif格式的图片不能存在与包含js目录的路径中?是我的设置问题?还是真不能存在于js目录中. 今天纠结了一下午,某个项目中的效果就是出不来,找了差不多两个半小时... 在D盘新建一个js和jss ...
- @Entity设置OneToMany
Hibernate设置bean映射数据库的方式有配置模式与注解模式,下面通过注解模式配置OneToMany @Entity @Table(name="csdnbbs_sys_catalog& ...
- [DP] 堆盒子问题
给一堆盒子,知道每个盒子的三围(长宽高),盒子正面朝你,不能旋转摆放,按照大的放在小的下面的原则堆起来,必须是 strictly larger,同样大小的盒子不行,问怎么样堆到最大的高度? 思路:动态 ...
- kafka.network.SocketServer分析
当Kafka启动时,会启动这个SocketServer来接收客户端的连接,处理客户端请求,发送响应. 这个类的注释说明了这个socket server的结构 /** * An NIO socket s ...
- [Firefly引擎][学习笔记三][已完结]所需模块封装
原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读: 笔记三主要就是各个模块的封装了,这里贴 ...
- HTML字符实体(Character Entities),转义字符串(Escape Sequence)
为什么要用转义字符串? HTML中<,>,&等有特殊含义(<,>,用于链接签,&用于转义),不能直接使用.这些符号是不显示在我们最终看到的网页里的,那如果我们希 ...
- 1027-Quicksum
描述 A checksum is an algorithm that scans a packet of data and returns a single number. The idea is t ...
- Android面试宝典(转)
Java知识点包括:接口与抽象的使用及区别,多线程,socket基础,集合类,也有个别公司考察定义,很无语. C/C++知识点包括:指针的移动,排序算法,链表,有时还会有二叉树的遍历或图的遍历. 1. ...