Skip to content

Instantly share code, notes, and snippets.

@PoisonousJohn
Last active December 11, 2015 06:59
Show Gist options
  • Save PoisonousJohn/4563296 to your computer and use it in GitHub Desktop.
Save PoisonousJohn/4563296 to your computer and use it in GitHub Desktop.
Hue shader
//
// Created by JohnPoison <[email protected]> on 1/17/13.
#import <Foundation/Foundation.h>
#import "CCSprite.h"
@interface CCSpriteHue : CCSprite {
GLint _hueShiftUniform;
GLint _lightnessUniform;
}
@property (nonatomic, assign) GLfloat hue;
@property (nonatomic, assign) GLfloat lightness;
- (void) initHueShader;
@end
//
// Created by JohnPoison <[email protected]> on 1/17/13.
#import "CCSpriteHue.h"
#import "CCGLProgram.h"
#import "ccShaders.h"
#import "CCFileUtils.h"
#import "ccDeprecated.h"
@implementation CCSpriteHue
@synthesize hue=_hue, lightness=_lightness;
- (void)setHue:(GLfloat)hue {
if (_hueShiftUniform != 0) {
NSLog(@"hue changed to: %f", hue);
_hue = hue;
glUniform1f(_hueShiftUniform, hue);
}
}
- (void)setLightness:(GLfloat)lightness {
if (_lightnessUniform != 0) {
NSLog(@"lightness changed to: %f", lightness);
_lightness = lightness;
glUniform1f(_lightnessUniform, _lightness);
}
}
- (void)initHueShader {
const GLchar * fragmentSource = (GLchar*) [[NSString stringWithContentsOfFile:[[CCFileUtils sharedFileUtils] fullPathFromRelativePath:@"Hue.fsh.glsl"] encoding:NSUTF8StringEncoding error:nil] UTF8String];
self.shaderProgram = [[[CCGLProgram alloc] initWithVertexShaderByteArray:ccPositionTextureA8Color_vert
fragmentShaderByteArray:fragmentSource] autorelease];
[self.shaderProgram addAttribute:kCCAttributeNamePosition index:kCCVertexAttrib_Position];
[self.shaderProgram addAttribute:kCCAttributeNameTexCoord index:kCCVertexAttrib_TexCoords];
[self.shaderProgram link];
[self.shaderProgram updateUniforms];
[self.shaderProgram use];
_hueShiftUniform = glGetUniformLocation(self.shaderProgram->program_, "u_hueShift");
_lightnessUniform = glGetUniformLocation(self.shaderProgram->program_, "u_V");
//setting default values
self.hue = 0.0;
self.lightness = 1.0;
}
#pragma mark CCSprite - draw
-(void) draw
{
// self.lightness += 1;
// NSLog(@"draw");
CC_PROFILER_START_CATEGORY(kCCProfilerCategorySprite, @"CCSprite - draw");
NSAssert(!batchNode_, @"If CCSprite is being rendered by CCSpriteBatchNode, CCSprite#draw SHOULD NOT be called");
CC_NODE_DRAW_SETUP();
ccGLBlendFunc( blendFunc_.src, blendFunc_.dst );
ccGLBindTexture2D( [texture_ name] );
//
// Attributes
//
ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex );
#define kQuadSize sizeof(quad_.bl)
long offset = (long)&quad_;
// vertex
NSInteger diff = offsetof( ccV3F_C4B_T2F, vertices);
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));
// texCoods
diff = offsetof( ccV3F_C4B_T2F, texCoords);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));
// color
diff = offsetof( ccV3F_C4B_T2F, colors);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
CHECK_GL_ERROR_DEBUG();
#if CC_SPRITE_DEBUG_DRAW == 1
// draw bounding box
CGPoint vertices[4]={
ccp(quad_.tl.vertices.x,quad_.tl.vertices.y),
ccp(quad_.bl.vertices.x,quad_.bl.vertices.y),
ccp(quad_.br.vertices.x,quad_.br.vertices.y),
ccp(quad_.tr.vertices.x,quad_.tr.vertices.y),
};
ccDrawPoly(vertices, 4, YES);
#elif CC_SPRITE_DEBUG_DRAW == 2
// draw texture box
CGSize s = self.textureRect.size;
CGPoint offsetPix = self.offsetPosition;
CGPoint vertices[4] = {
ccp(offsetPix.x,offsetPix.y), ccp(offsetPix.x+s.width,offsetPix.y),
ccp(offsetPix.x+s.width,offsetPix.y+s.height), ccp(offsetPix.x,offsetPix.y+s.height)
};
ccDrawPoly(vertices, 4, YES);
#endif // CC_SPRITE_DEBUG_DRAW
CC_INCREMENT_GL_DRAWS(1);
CC_PROFILER_STOP_CATEGORY(kCCProfilerCategorySprite, @"CCSprite - draw");
}
@end
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
uniform mat4 u_MVPMatrix;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = u_MVPMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
...
CCSpriteHue *hue = [CCSpriteHue spriteWithFile: @"Icon.png"];
hue.position = ccp(150, 100);
[hue initHueShader];
hue.hue = 2.5;
hue.lightness = 0.8;
[self addChild: hue z: 1000];
...
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D u_texture;
uniform float u_hueShift;
uniform float u_V;
void main ()
{
vec3 inColor = texture2D(u_texture, v_texCoord).rgb;
float u_VSU = cos(u_hueShift);
float u_VSW = sin(u_hueShift);
vec3 ret;
ret.r = (.299*u_V+.701*u_VSU+.168*u_VSW)*inColor.r
+ (.587*u_V-.587*u_VSU+.330*u_VSW)*inColor.g
+ (.114*u_V-.114*u_VSU-.497*u_VSW)*inColor.b;
ret.g = (.299*u_V-.299*u_VSU-.328*u_VSW)*inColor.r
+ (.587*u_V+.413*u_VSU+.035*u_VSW)*inColor.g
+ (.114*u_V-.114*u_VSU+.292*u_VSW)*inColor.b;
ret.b = (.299*u_V-.3*u_VSU+1.25*u_VSW)*inColor.r
+ (.587*u_V-.588*u_VSU-1.05*u_VSW)*inColor.g
+ (.114*u_V+.886*u_VSU-.203*u_VSW)*inColor.b;
float alpha = texture2D(u_texture, v_texCoord).a;
gl_FragColor = vec4(ret,alpha);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment