Cocos2d-x 3.x 的精灵修改色相(Hue)
来源:互联网 发布:下列属于软件特性 编辑:程序博客网 时间:2024/04/28 13:21
Cocos2d-x 3.x 的精灵修改色相(Hue)
原文链接 : http://www.cocoachina.com/bbs/read.php?tid=282479
首先是shader文件
hueChange.fsh
varying vec2 v_texCoord;uniform mat3 u_hue;uniform float u_alpha;void main(){ vec4 pixColor = texture2D(CC_Texture0, v_texCoord); vec3 rgbColor ; rgbColor = u_hue * pixColor.rgb; gl_FragColor = vec4(rgbColor.r,rgbColor.g,rgbColor.b, pixColor.a * u_alpha);}
hueChange.vsh
attribute vec4 a_position;attribute vec2 a_texCoord;attribute vec4 a_color;varying vec2 v_texCoord;void main(){ gl_Position = CC_PMatrix * a_position; v_texCoord = a_texCoord;}
CCSpriteWithHue.h
#ifndef __SnippetsProject__CCSpriteWithHue__#define __SnippetsProject__CCSpriteWithHue__#include "cocos2d.h"USING_NS_CC;class CCSpriteWithHue :public Sprite { private://variable GLint m_hueLocation; GLint m_alphaLocation; protected://variable public://variable CC_SYNTHESIZE_READONLY(GLfloat, m_hue, Hue); private://method protected://method virtual void setupDefaultSettings(); virtual void getUniformLocations(); virtual void updateColorMatrix(); virtual void updateAlpha(); virtual GLfloat alpha(); virtual void updateColor(); virtual bool initWithTexture(Texture2D *texture, const Rect& rect, bool rotated); virtual void initShader(); public://method CCSpriteWithHue(); virtual ~CCSpriteWithHue(); static CCSpriteWithHue* create(const std::string& filename); virtual void setHue(GLfloat _hue); };
CCSpriteWithHue.cpp
#include "CCSpriteWithHue.h"void xRotateMat(float mat[3][3], float rs, float rc);void yRotateMat(float mat[3][3], float rs, float rc);void zRotateMat(float mat[3][3], float rs, float rc);void matrixMult(float a[3][3], float b[3][3], float c[3][3]);void hueMatrix(GLfloat mat[3][3], float angle);void premultiplyAlpha(GLfloat mat[3][3], float alpha);CCSpriteWithHue::CCSpriteWithHue(){ }CCSpriteWithHue::~CCSpriteWithHue(){ }CCSpriteWithHue* CCSpriteWithHue::create(const std::string& filename){ CCSpriteWithHue *sprite = new (std::nothrow) CCSpriteWithHue(); if (sprite && sprite->initWithFile(filename)) { sprite->autorelease(); return sprite; } CC_SAFE_DELETE(sprite); return nullptr;}bool CCSpriteWithHue::initWithTexture(Texture2D *texture, const Rect& rect, bool rotated){ if (!Sprite::initWithTexture(texture, rect, rotated)) { return false; } this->setupDefaultSettings(); this->initShader(); return true;}void CCSpriteWithHue::setupDefaultSettings(){ this->m_hue = 0.0;}void CCSpriteWithHue::initShader(){ GLProgram * p = new GLProgram(); this->setGLProgram(p); p->release(); p->initWithFilenames("hueChange.vsh", "hueChange.fsh"); p->link(); p->updateUniforms(); this->getUniformLocations(); this->updateColor();}void CCSpriteWithHue::getUniformLocations(){ m_hueLocation = glGetUniformLocation(this->getGLProgram()->getProgram(), "u_hue"); m_alphaLocation = glGetUniformLocation(this->getGLProgram()->getProgram(), "u_alpha");}void CCSpriteWithHue::updateColorMatrix(){ this->getGLProgram()->use(); GLfloat mat[3][3]; memset(mat, 0, sizeof(GLfloat)*9); hueMatrix(mat, m_hue); premultiplyAlpha(mat, this->alpha()); glUniformMatrix3fv(m_hueLocation, 1, GL_FALSE, (GLfloat *)&mat);}void CCSpriteWithHue::updateAlpha(){ this->getGLProgram()->use(); glUniform1f(m_alphaLocation, this->alpha());}GLfloat CCSpriteWithHue::alpha(){ return _displayedOpacity / 255.0f;}void CCSpriteWithHue::setHue(GLfloat _hue){ m_hue = _hue; this->updateColorMatrix();}void CCSpriteWithHue::updateColor(){ Sprite::updateColor(); this->updateColorMatrix(); this->updateAlpha();}#pragma mark -void xRotateMat(float mat[3][3], float rs, float rc){ mat[0][0] = 1.0; mat[0][1] = 0.0; mat[0][2] = 0.0; mat[1][0] = 0.0; mat[1][1] = rc; mat[1][2] = rs; mat[2][0] = 0.0; mat[2][1] = -rs; mat[2][2] = rc;}void yRotateMat(float mat[3][3], float rs, float rc){ mat[0][0] = rc; mat[0][1] = 0.0; mat[0][2] = -rs; mat[1][0] = 0.0; mat[1][1] = 1.0; mat[1][2] = 0.0; mat[2][0] = rs; mat[2][1] = 0.0; mat[2][2] = rc;}void zRotateMat(float mat[3][3], float rs, float rc){ mat[0][0] = rc; mat[0][1] = rs; mat[0][2] = 0.0; mat[1][0] = -rs; mat[1][1] = rc; mat[1][2] = 0.0; mat[2][0] = 0.0; mat[2][1] = 0.0; mat[2][2] = 1.0;}void matrixMult(float a[3][3], float b[3][3], float c[3][3]){ int x, y; float temp[3][3]; for(y=0; y<3; y++) { for(x=0; x<3; x++) { temp[y][x] = b[y][0] * a[0][x] + b[y][1] * a[1][x] + b[y][2] * a[2][x]; } } for(y=0; y<3; y++) { for(x=0; x<3; x++) { c[y][x] = temp[y][x]; } }}void hueMatrix(GLfloat mat[3][3], float angle){#define SQRT_2 sqrt(2.0)#define SQRT_3 sqrt(3.0) float mag, rot[3][3]; float xrs, xrc; float yrs, yrc; float zrs, zrc; // Rotate the grey vector into positive Z mag = SQRT_2; xrs = 1.0/mag; xrc = 1.0/mag; xRotateMat(mat, xrs, xrc); mag = SQRT_3; yrs = -1.0/mag; yrc = SQRT_2/mag; yRotateMat(rot, yrs, yrc); matrixMult(rot, mat, mat); // Rotate the hue zrs = sin(angle); zrc = cos(angle); zRotateMat(rot, zrs, zrc); matrixMult(rot, mat, mat); // Rotate the grey vector back into place yRotateMat(rot, -yrs, yrc); matrixMult(rot, mat, mat); xRotateMat(rot, -xrs, xrc); matrixMult(rot, mat, mat);}void premultiplyAlpha(GLfloat mat[3][3], float alpha){ for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { mat[i][j] *= alpha; } }}
使用实例
CCSpriteWithHue *hueSprite = CCSpriteWithHue::create("HelloWorld.png");hueSprite->setHue(1.6);//值在 0 ~ 2 Pi 之间hueSprite->setPosition(visibleSize.width / 2, visibleSize.height / 2);this->addChild(hueSprite);
运行效果
setHue(1.6):
setHue(2.6):
setHue(3.6):
0 0
- Cocos2d-x 3.x 的精灵修改色相(Hue)
- 在 cocos2d-x 3.x中使用shader实现精灵色相(Hue)的修改
- Cocos2d-X的精灵
- Cocos2D-X shader(四) 利用shader改变图片色相(Hue)
- Cocos2D-X shader(四) 利用shader改变图片色相(Hue)
- cocos2d-x精灵的动作
- cocos2d-x精灵的旋转
- cocos2d-x精灵的跳跃
- cocos2d-x --- 创建精灵的方法(3.x)
- cocos2d-x 2.x 精灵的创建
- cocos2d-x(精灵类)
- cocos2d-x创建精灵
- Cocos2d-x精灵创建
- Cocos2d-x 精灵贴图
- Cocos2d-x 精灵移动
- cocos2d-x创建精灵
- cocos2d-x之精灵
- cocos2d-x中的精灵
- Java序列化和反序列化小记
- Jmeter之JDBC Request使用方法(oracle)
- 解决电脑自动开机问题
- 最小生成树~prim
- Yii2 mongodb – 关于mongoid的使用
- Cocos2d-x 3.x 的精灵修改色相(Hue)
- SDUT2139图结构练习——BFS——从起始点到目标点的最短步数
- android源码学习
- 【Android】Android Studio中使用OpenCV将彩图转换成灰度图
- 大文件断点续传
- Yii2 关闭和打开csrf 验证
- window安装redis
- web容器中的类加载机制
- Yii2 如何设置首页