Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
823 lines (772 sloc) 29.7 KB
//
// ofxPSBlend.h
//
// Created by Akira Hayasaka on 5/14/12.
// Copyright (c) 2012 ゚・:,。゚・:,。★゚・:,。゚・:,。☆゚・:,。゚・:,。★゚・:,。゚・:,。☆. All rights reserved.
//
#pragma once
#include "ofMain.h"
#define STRINGIFY(x) #x
static string psBlendFragShaderGL2 = "#version 120\n \
#extension GL_ARB_texture_rectangle : enable\n \
\
#define BlendLinearDodgef BlendAddf\n \
#define BlendLinearBurnf BlendSubstractf\n \
#define BlendAddf(base, blend) min(base + blend, 1.0)\n \
#define BlendSubstractf(base, blend) max(base + blend - 1.0, 0.0)\n \
#define BlendLightenf(base, blend) max(blend, base)\n \
#define BlendDarkenf(base, blend) min(blend, base)\n \
#define BlendLinearLightf(base, blend) (blend < 0.5 ? BlendLinearBurnf(base, (2.0 * blend)) : BlendLinearDodgef(base, (2.0 * (blend - 0.5))))\n \
#define BlendScreenf(base, blend) (1.0 - ((1.0 - base) * (1.0 - blend)))\n \
#define BlendOverlayf(base, blend) (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)))\n \
#define BlendSoftLightf(base, blend) ((blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend)))\n \
#define BlendColorDodgef(base, blend) ((blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0))\n \
#define BlendColorBurnf(base, blend) ((blend == 0.0) ? blend : max((1.0 - ((1.0 - base) / blend)), 0.0))\n \
#define BlendVividLightf(base, blend) ((blend < 0.5) ? BlendColorBurnf(base, (2.0 * blend)) : BlendColorDodgef(base, (2.0 * (blend - 0.5))))\n \
#define BlendPinLightf(base, blend) ((blend < 0.5) ? BlendDarkenf(base, (2.0 * blend)) : BlendLightenf(base, (2.0 *(blend - 0.5))))\n \
#define BlendHardMixf(base, blend) ((BlendVividLightf(base, blend) < 0.5) ? 0.0 : 1.0)\n \
#define BlendReflectf(base, blend) ((blend == 1.0) ? blend : min(base * base / (1.0 - blend), 1.0))\n \
#define Blend(base, blend, funcf) vec3(funcf(base.r, blend.r), funcf(base.g, blend.g), funcf(base.b, blend.b))\n \
#define BlendLightenBlendLightenf\n \
#define BlendDarkenBlendDarkenf\n \
#define BlendNormal(base, blend) (blend)\n \
#define BlendMultiply(base, blend) (base * blend)\n \
#define BlendAverage(base, blend) ((base + blend) / 2.0)\n \
#define BlendAdd(base, blend) min(base + blend, vec3(1.0))\n \
#define BlendSubstract(base, blend) max(base + blend - vec3(1.0), vec3(0.0))\n \
#define BlendDifference(base, blend) abs(base - blend)\n \
#define BlendNegation(base, blend) (vec3(1.0) - abs(vec3(1.0) - base - blend))\n \
#define BlendExclusion(base, blend) (base + blend - 2.0 * base * blend)\n \
#define BlendScreen(base, blend) Blend(base, blend, BlendScreenf)\n \
#define BlendOverlay(base, blend) Blend(base, blend, BlendOverlayf)\n \
#define BlendSoftLight(base, blend) Blend(base, blend, BlendSoftLightf)\n \
#define BlendHardLight(base, blend) BlendOverlay(blend, base)\n \
#define BlendColorDodge(base, blend) Blend(base, blend, BlendColorDodgef)\n \
#define BlendColorBurn(base, blend) Blend(base, blend, BlendColorBurnf)\n \
#define BlendLinearDodgeBlendAdd\n \
#define BlendLinearBurnBlendSubstract\n \
#define BlendLinearLight(base, blend) Blend(base, blend, BlendLinearLightf)\n \
#define BlendVividLight(base, blend) Blend(base, blend, BlendVividLightf)\n \
#define BlendPinLight(base, blend) Blend(base, blend, BlendPinLightf)\n \
#define BlendHardMix(base, blend) Blend(base, blend, BlendHardMixf)\n \
#define BlendReflect(base, blend) Blend(base, blend, BlendReflectf)\n \
#define BlendGlow(base, blend) BlendReflect(blend, base)\n \
#define BlendPhoenix(base, blend) (min(base, blend) - max(base, blend) + vec3(1.0))\n \
#define BlendOpacity(base, blend, F, O) (F(base, blend) * O + blend * (1.0 - O))\n \
#define GammaCorrection(color, gamma)pow(color, 1.0 / gamma)\n \
#define LevelsControlInputRange(color, minInput, maxInput)min(max(color - vec3(minInput), vec3(0.0)) / (vec3(maxInput) - vec3(minInput)), vec3(1.0))\n \
#define LevelsControlInput(color, minInput, gamma, maxInput)GammaCorrection(LevelsControlInputRange(color, minInput, maxInput), gamma)\n \
#define LevelsControlOutputRange(color, minOutput, maxOutput) mix(vec3(minOutput), vec3(maxOutput), color)\n \
#define LevelsControl(color, minInput, gamma, maxInput, minOutput, maxOutput) LevelsControlOutputRange(LevelsControlInput(color, minInput, gamma, maxInput), minOutput, maxOutput)\n" STRINGIFY(
vec4 Desaturate(vec3 color, float Desaturation)
{
vec3 grayXfer = vec3(0.3, 0.59, 0.11);
vec3 gray = vec3(dot(grayXfer, color));
return vec4(mix(color, gray, Desaturation), 1.0);
}
vec3 RGBToHSL(vec3 color)
{
vec3 hsl;
float fmin = min(min(color.r, color.g), color.b);
float fmax = max(max(color.r, color.g), color.b);
float delta = fmax - fmin;
hsl.z = (fmax + fmin) / 2.0;
if (delta == 0.0)
{
hsl.x = 0.0;
hsl.y = 0.0;
}
else
{
if (hsl.z < 0.5)
hsl.y = delta / (fmax + fmin);
else
hsl.y = delta / (2.0 - fmax - fmin);
float deltaR = (((fmax - color.r) / 6.0) + (delta / 2.0)) / delta;
float deltaG = (((fmax - color.g) / 6.0) + (delta / 2.0)) / delta;
float deltaB = (((fmax - color.b) / 6.0) + (delta / 2.0)) / delta;
if (color.r == fmax )
hsl.x = deltaB - deltaG;
else if (color.g == fmax)
hsl.x = (1.0 / 3.0) + deltaR - deltaB;
else if (color.b == fmax)
hsl.x = (2.0 / 3.0) + deltaG - deltaR;
if (hsl.x < 0.0)
hsl.x += 1.0;
else if (hsl.x > 1.0)
hsl.x -= 1.0;
}
return hsl;
}
float HueToRGB(float f1, float f2, float hue)
{
if (hue < 0.0)
hue += 1.0;
else if (hue > 1.0)
hue -= 1.0;
float res;
if ((6.0 * hue) < 1.0)
res = f1 + (f2 - f1) * 6.0 * hue;
else if ((2.0 * hue) < 1.0)
res = f2;
else if ((3.0 * hue) < 2.0)
res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0;
else
res = f1;
return res;
}
vec3 HSLToRGB(vec3 hsl)
{
vec3 rgb;
if (hsl.y == 0.0)
rgb = vec3(hsl.z);
else
{
float f2;
if (hsl.z < 0.5)
f2 = hsl.z * (1.0 + hsl.y);
else
f2 = (hsl.z + hsl.y) - (hsl.y * hsl.z);
float f1 = 2.0 * hsl.z - f2;
rgb.r = HueToRGB(f1, f2, hsl.x + (1.0/3.0));
rgb.g = HueToRGB(f1, f2, hsl.x);
rgb.b= HueToRGB(f1, f2, hsl.x - (1.0/3.0));
}
return rgb;
}
vec3 ContrastSaturationBrightness(vec3 color, float brt, float sat, float con)
{
const float AvgLumR = 0.5;
const float AvgLumG = 0.5;
const float AvgLumB = 0.5;
const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
vec3 brtColor = color * brt;
vec3 intensity = vec3(dot(brtColor, LumCoeff));
vec3 satColor = mix(intensity, brtColor, sat);
vec3 conColor = mix(AvgLumin, satColor, con);
return conColor;
}
vec3 BlendHue(vec3 base, vec3 blend)
{
vec3 baseHSL = RGBToHSL(base);
return HSLToRGB(vec3(RGBToHSL(blend).r, baseHSL.g, baseHSL.b));
}
vec3 BlendSaturation(vec3 base, vec3 blend)
{
vec3 baseHSL = RGBToHSL(base);
return HSLToRGB(vec3(baseHSL.r, RGBToHSL(blend).g, baseHSL.b));
}
vec3 BlendColor(vec3 base, vec3 blend)
{
vec3 blendHSL = RGBToHSL(blend);
return HSLToRGB(vec3(blendHSL.r, blendHSL.g, RGBToHSL(base).b));
}
vec3 BlendLuminosity(vec3 base, vec3 blend)
{
vec3 baseHSL = RGBToHSL(base);
return HSLToRGB(vec3(baseHSL.r, baseHSL.g, RGBToHSL(blend).b));
}
uniform sampler2DRect base;
uniform sampler2DRect blendTgt;
uniform int mode;
void main()
{
vec4 baseCol = texture2DRect(base, gl_TexCoord[0].st);
vec4 blendCol = texture2DRect(blendTgt, gl_TexCoord[0].st);
vec3 result;
if (mode == 0)
{
result = BlendNormal(baseCol.rgb, blendCol.rgb);
}
else if (mode == 1)
{
result = BlendMultiply(baseCol.rgb, blendCol.rgb);
}
else if (mode == 2)
{
result = BlendAverage(baseCol.rgb, blendCol.rgb);
}
else if (mode == 3)
{
result = BlendAdd(baseCol.rgb, blendCol.rgb);
}
else if (mode == 4)
{
result = BlendSubstract(baseCol.rgb, blendCol.rgb);
}
else if (mode == 5)
{
result = BlendDifference(baseCol.rgb, blendCol.rgb);
}
else if (mode == 6)
{
result = BlendNegation(baseCol.rgb, blendCol.rgb);
}
else if (mode == 7)
{
result = BlendExclusion(baseCol.rgb, blendCol.rgb);
}
else if (mode == 8)
{
result = BlendScreen(baseCol.rgb, blendCol.rgb);
}
else if (mode == 9)
{
result = BlendOverlay(baseCol.rgb, blendCol.rgb);
}
else if (mode == 10)
{
result = BlendSoftLight(baseCol.rgb, blendCol.rgb);
}
else if (mode == 11)
{
result = BlendHardLight(baseCol.rgb, blendCol.rgb);
}
else if (mode == 12)
{
result = BlendColorDodge(baseCol.rgb, blendCol.rgb);
}
else if (mode == 13)
{
result = BlendColorBurn(baseCol.rgb, blendCol.rgb);
}
else if (mode == 14)
{
result = BlendLinearLight(baseCol.rgb, blendCol.rgb);
}
else if (mode == 15)
{
result = BlendVividLight(baseCol.rgb, blendCol.rgb);
}
else if (mode == 16)
{
result = BlendPinLight(baseCol.rgb, blendCol.rgb);
}
else if (mode == 17)
{
result = BlendHardMix(baseCol.rgb, blendCol.rgb);
}
else if (mode == 18)
{
result = BlendReflect(baseCol.rgb, blendCol.rgb);
}
else if (mode == 19)
{
result = BlendGlow(baseCol.rgb, blendCol.rgb);
}
else if (mode == 20)
{
result = BlendPhoenix(baseCol.rgb, blendCol.rgb);
}
else if (mode == 21)
{
result = BlendHue(baseCol.rgb, blendCol.rgb);
}
else if (mode == 22)
{
result = BlendSaturation(baseCol.rgb, blendCol.rgb);
}
else if (mode == 23)
{
result = BlendColor(baseCol.rgb, blendCol.rgb);
}
else if (mode == 24)
{
result = BlendLuminosity(baseCol.rgb, blendCol.rgb);
}
else
{
result = BlendNormal(baseCol.rgb, blendCol.rgb);
}
if (blendCol.a <= 0.0)
{
gl_FragColor = vec4(0.0,0.0,0.0,0.0);
}
else
{
gl_FragColor = vec4(result, 1.0);
}
}
);
static string psBlendVertShaderGL3 = "#version 150\n" STRINGIFY(
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 textureMatrix;
uniform mat4 modelViewProjectionMatrix;
in vec4 position;
in vec2 texcoord;
in vec4 color;
in vec3 normal;
out vec2 texCoordVarying;
void main()
{
texCoordVarying = texcoord;
gl_Position = modelViewProjectionMatrix * position;
}
);
static string psBlendFragShaderGL3 = "#version 150\n \
\
#define BlendLinearDodgef BlendAddf\n \
#define BlendLinearBurnf BlendSubstractf\n \
#define BlendAddf(base, blend) min(base + blend, 1.0)\n \
#define BlendSubstractf(base, blend) max(base + blend - 1.0, 0.0)\n \
#define BlendLightenf(base, blend) max(blend, base)\n \
#define BlendDarkenf(base, blend) min(blend, base)\n \
#define BlendLinearLightf(base, blend) (blend < 0.5 ? BlendLinearBurnf(base, (2.0 * blend)) : BlendLinearDodgef(base, (2.0 * (blend - 0.5))))\n \
#define BlendScreenf(base, blend) (1.0 - ((1.0 - base) * (1.0 - blend)))\n \
#define BlendOverlayf(base, blend) (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)))\n \
#define BlendSoftLightf(base, blend) ((blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend)))\n \
#define BlendColorDodgef(base, blend) ((blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0))\n \
#define BlendColorBurnf(base, blend) ((blend == 0.0) ? blend : max((1.0 - ((1.0 - base) / blend)), 0.0))\n \
#define BlendVividLightf(base, blend) ((blend < 0.5) ? BlendColorBurnf(base, (2.0 * blend)) : BlendColorDodgef(base, (2.0 * (blend - 0.5))))\n \
#define BlendPinLightf(base, blend) ((blend < 0.5) ? BlendDarkenf(base, (2.0 * blend)) : BlendLightenf(base, (2.0 *(blend - 0.5))))\n \
#define BlendHardMixf(base, blend) ((BlendVividLightf(base, blend) < 0.5) ? 0.0 : 1.0)\n \
#define BlendReflectf(base, blend) ((blend == 1.0) ? blend : min(base * base / (1.0 - blend), 1.0))\n \
#define Blend(base, blend, funcf) vec3(funcf(base.r, blend.r), funcf(base.g, blend.g), funcf(base.b, blend.b))\n \
#define BlendLightenBlendLightenf\n \
#define BlendDarkenBlendDarkenf\n \
#define BlendNormal(base, blend) (blend)\n \
#define BlendMultiply(base, blend) (base * blend)\n \
#define BlendAverage(base, blend) ((base + blend) / 2.0)\n \
#define BlendAdd(base, blend) min(base + blend, vec3(1.0))\n \
#define BlendSubstract(base, blend) max(base + blend - vec3(1.0), vec3(0.0))\n \
#define BlendDifference(base, blend) abs(base - blend)\n \
#define BlendNegation(base, blend) (vec3(1.0) - abs(vec3(1.0) - base - blend))\n \
#define BlendExclusion(base, blend) (base + blend - 2.0 * base * blend)\n \
#define BlendScreen(base, blend) Blend(base, blend, BlendScreenf)\n \
#define BlendOverlay(base, blend) Blend(base, blend, BlendOverlayf)\n \
#define BlendSoftLight(base, blend) Blend(base, blend, BlendSoftLightf)\n \
#define BlendHardLight(base, blend) BlendOverlay(blend, base)\n \
#define BlendColorDodge(base, blend) Blend(base, blend, BlendColorDodgef)\n \
#define BlendColorBurn(base, blend) Blend(base, blend, BlendColorBurnf)\n \
#define BlendLinearDodgeBlendAdd\n \
#define BlendLinearBurnBlendSubstract\n \
#define BlendLinearLight(base, blend) Blend(base, blend, BlendLinearLightf)\n \
#define BlendVividLight(base, blend) Blend(base, blend, BlendVividLightf)\n \
#define BlendPinLight(base, blend) Blend(base, blend, BlendPinLightf)\n \
#define BlendHardMix(base, blend) Blend(base, blend, BlendHardMixf)\n \
#define BlendReflect(base, blend) Blend(base, blend, BlendReflectf)\n \
#define BlendGlow(base, blend) BlendReflect(blend, base)\n \
#define BlendPhoenix(base, blend) (min(base, blend) - max(base, blend) + vec3(1.0))\n \
#define BlendOpacity(base, blend, F, O) (F(base, blend) * O + blend * (1.0 - O))\n \
#define GammaCorrection(color, gamma)pow(color, 1.0 / gamma)\n \
#define LevelsControlInputRange(color, minInput, maxInput)min(max(color - vec3(minInput), vec3(0.0)) / (vec3(maxInput) - vec3(minInput)), vec3(1.0))\n \
#define LevelsControlInput(color, minInput, gamma, maxInput)GammaCorrection(LevelsControlInputRange(color, minInput, maxInput), gamma)\n \
#define LevelsControlOutputRange(color, minOutput, maxOutput) mix(vec3(minOutput), vec3(maxOutput), color)\n \
#define LevelsControl(color, minInput, gamma, maxInput, minOutput, maxOutput) LevelsControlOutputRange(LevelsControlInput(color, minInput, gamma, maxInput), minOutput, maxOutput)\n" STRINGIFY(
vec4 Desaturate(vec3 color, float Desaturation)
{
vec3 grayXfer = vec3(0.3, 0.59, 0.11);
vec3 gray = vec3(dot(grayXfer, color));
return vec4(mix(color, gray, Desaturation), 1.0);
}
vec3 RGBToHSL(vec3 color)
{
vec3 hsl;
float fmin = min(min(color.r, color.g), color.b);
float fmax = max(max(color.r, color.g), color.b);
float delta = fmax - fmin;
hsl.z = (fmax + fmin) / 2.0;
if (delta == 0.0)
{
hsl.x = 0.0;
hsl.y = 0.0;
}
else
{
if (hsl.z < 0.5)
hsl.y = delta / (fmax + fmin);
else
hsl.y = delta / (2.0 - fmax - fmin);
float deltaR = (((fmax - color.r) / 6.0) + (delta / 2.0)) / delta;
float deltaG = (((fmax - color.g) / 6.0) + (delta / 2.0)) / delta;
float deltaB = (((fmax - color.b) / 6.0) + (delta / 2.0)) / delta;
if (color.r == fmax )
hsl.x = deltaB - deltaG;
else if (color.g == fmax)
hsl.x = (1.0 / 3.0) + deltaR - deltaB;
else if (color.b == fmax)
hsl.x = (2.0 / 3.0) + deltaG - deltaR;
if (hsl.x < 0.0)
hsl.x += 1.0;
else if (hsl.x > 1.0)
hsl.x -= 1.0;
}
return hsl;
}
float HueToRGB(float f1, float f2, float hue)
{
if (hue < 0.0)
hue += 1.0;
else if (hue > 1.0)
hue -= 1.0;
float res;
if ((6.0 * hue) < 1.0)
res = f1 + (f2 - f1) * 6.0 * hue;
else if ((2.0 * hue) < 1.0)
res = f2;
else if ((3.0 * hue) < 2.0)
res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0;
else
res = f1;
return res;
}
vec3 HSLToRGB(vec3 hsl)
{
vec3 rgb;
if (hsl.y == 0.0)
rgb = vec3(hsl.z);
else
{
float f2;
if (hsl.z < 0.5)
f2 = hsl.z * (1.0 + hsl.y);
else
f2 = (hsl.z + hsl.y) - (hsl.y * hsl.z);
float f1 = 2.0 * hsl.z - f2;
rgb.r = HueToRGB(f1, f2, hsl.x + (1.0/3.0));
rgb.g = HueToRGB(f1, f2, hsl.x);
rgb.b= HueToRGB(f1, f2, hsl.x - (1.0/3.0));
}
return rgb;
}
vec3 ContrastSaturationBrightness(vec3 color, float brt, float sat, float con)
{
const float AvgLumR = 0.5;
const float AvgLumG = 0.5;
const float AvgLumB = 0.5;
const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
vec3 brtColor = color * brt;
vec3 intensity = vec3(dot(brtColor, LumCoeff));
vec3 satColor = mix(intensity, brtColor, sat);
vec3 conColor = mix(AvgLumin, satColor, con);
return conColor;
}
vec3 BlendHue(vec3 base, vec3 blend)
{
vec3 baseHSL = RGBToHSL(base);
return HSLToRGB(vec3(RGBToHSL(blend).r, baseHSL.g, baseHSL.b));
}
vec3 BlendSaturation(vec3 base, vec3 blend)
{
vec3 baseHSL = RGBToHSL(base);
return HSLToRGB(vec3(baseHSL.r, RGBToHSL(blend).g, baseHSL.b));
}
vec3 BlendColor(vec3 base, vec3 blend)
{
vec3 blendHSL = RGBToHSL(blend);
return HSLToRGB(vec3(blendHSL.r, blendHSL.g, RGBToHSL(base).b));
}
vec3 BlendLuminosity(vec3 base, vec3 blend)
{
vec3 baseHSL = RGBToHSL(base);
return HSLToRGB(vec3(baseHSL.r, baseHSL.g, RGBToHSL(blend).b));
}
in vec2 texCoordVarying;
uniform sampler2DRect base;
uniform sampler2DRect blendTgt;
uniform int mode;
out vec4 fragColor;
void main()
{
vec4 baseCol = texture(base, texCoordVarying.st);
vec4 blendCol = texture(blendTgt, texCoordVarying.st);
vec3 result;
if (mode == 0)
{
result = BlendNormal(baseCol.rgb, blendCol.rgb);
}
else if (mode == 1)
{
result = BlendMultiply(baseCol.rgb, blendCol.rgb);
}
else if (mode == 2)
{
result = BlendAverage(baseCol.rgb, blendCol.rgb);
}
else if (mode == 3)
{
result = BlendAdd(baseCol.rgb, blendCol.rgb);
}
else if (mode == 4)
{
result = BlendSubstract(baseCol.rgb, blendCol.rgb);
}
else if (mode == 5)
{
result = BlendDifference(baseCol.rgb, blendCol.rgb);
}
else if (mode == 6)
{
result = BlendNegation(baseCol.rgb, blendCol.rgb);
}
else if (mode == 7)
{
result = BlendExclusion(baseCol.rgb, blendCol.rgb);
}
else if (mode == 8)
{
result = BlendScreen(baseCol.rgb, blendCol.rgb);
}
else if (mode == 9)
{
result = BlendOverlay(baseCol.rgb, blendCol.rgb);
}
else if (mode == 10)
{
result = BlendSoftLight(baseCol.rgb, blendCol.rgb);
}
else if (mode == 11)
{
result = BlendHardLight(baseCol.rgb, blendCol.rgb);
}
else if (mode == 12)
{
result = BlendColorDodge(baseCol.rgb, blendCol.rgb);
}
else if (mode == 13)
{
result = BlendColorBurn(baseCol.rgb, blendCol.rgb);
}
else if (mode == 14)
{
result = BlendLinearLight(baseCol.rgb, blendCol.rgb);
}
else if (mode == 15)
{
result = BlendVividLight(baseCol.rgb, blendCol.rgb);
}
else if (mode == 16)
{
result = BlendPinLight(baseCol.rgb, blendCol.rgb);
}
else if (mode == 17)
{
result = BlendHardMix(baseCol.rgb, blendCol.rgb);
}
else if (mode == 18)
{
result = BlendReflect(baseCol.rgb, blendCol.rgb);
}
else if (mode == 19)
{
result = BlendGlow(baseCol.rgb, blendCol.rgb);
}
else if (mode == 20)
{
result = BlendPhoenix(baseCol.rgb, blendCol.rgb);
}
else if (mode == 21)
{
result = BlendHue(baseCol.rgb, blendCol.rgb);
}
else if (mode == 22)
{
result = BlendSaturation(baseCol.rgb, blendCol.rgb);
}
else if (mode == 23)
{
result = BlendColor(baseCol.rgb, blendCol.rgb);
}
else if (mode == 24)
{
result = BlendLuminosity(baseCol.rgb, blendCol.rgb);
}
else
{
result = BlendNormal(baseCol.rgb, blendCol.rgb);
}
if (blendCol.a <= 0.0)
{
fragColor = vec4(0.0,0.0,0.0,0.0);
}
else
{
fragColor = vec4(result, 1.0);
}
}
);
class ofxPSBlend
{
public:
void setup(int width, int height)
{
base.allocate(width, height, GL_RGBA, ofFbo::maxSamples());
quad.getVertices().resize(4);
quad.getTexCoords().resize(4);
quad.setMode(OF_PRIMITIVE_TRIANGLE_FAN);
this->width = width;
this->height = height;
loadShader();
}
void allocate(int width, int height)
{
base.allocate(width, height, GL_RGBA, ofFbo::maxSamples());
quad.getVertices().resize(4);
quad.getTexCoords().resize(4);
quad.setMode(OF_PRIMITIVE_TRIANGLE_FAN);
this->width = width;
this->height = height;
}
void loadShader()
{
if (ofIsGLProgrammableRenderer())
{
psBlendShader.setupShaderFromSource(GL_VERTEX_SHADER, psBlendVertShaderGL3);
psBlendShader.setupShaderFromSource(GL_FRAGMENT_SHADER, psBlendFragShaderGL3);
psBlendShader.bindDefaults();
}
else
{
psBlendShader.setupShaderFromSource(GL_FRAGMENT_SHADER, psBlendFragShaderGL2);
}
psBlendShader.linkProgram();
}
void begin()
{
ofPushStyle();
ofPushMatrix();
base.begin();
ofClear(0);
}
void end()
{
base.end();
ofPopStyle();
ofPopMatrix();
}
void draw(ofTexture& blendTgt, int blendMode = 0)
{
psBlendShader.begin();
psBlendShader.setUniformTexture("base", base, 1);
psBlendShader.setUniformTexture("blendTgt", blendTgt, 2);
psBlendShader.setUniform1i("mode", blendMode);
drawPlane(width, height);
psBlendShader.end();
}
string getBlendMode(int blendMode)
{
string blendName = "no such blend hiii";
if (blendMode == 0)
{
blendName = "BlendNormal";
}
else if (blendMode == 1)
{
blendName = "BlendMultiply";
}
else if (blendMode == 2)
{
blendName = "BlendAverage";
}
else if (blendMode == 3)
{
blendName = "BlendAdd";
}
else if (blendMode == 4)
{
blendName = "BlendSubstract";
}
else if (blendMode == 5)
{
blendName = "BlendDifference";
}
else if (blendMode == 6)
{
blendName = "BlendNegation";
}
else if (blendMode == 7)
{
blendName = "BlendExclusion";
}
else if (blendMode == 8)
{
blendName = "BlendScreen";
}
else if (blendMode == 9)
{
blendName = "BlendOverlay";
}
else if (blendMode == 10)
{
blendName = "BlendSoftLight";
}
else if (blendMode == 11)
{
blendName = "BlendHardLight";
}
else if (blendMode == 12)
{
blendName = "BlendColorDodge";
}
else if (blendMode == 13)
{
blendName = "BlendColorBurn";
}
else if (blendMode == 14)
{
blendName = "BlendLinearLight";
}
else if (blendMode == 15)
{
blendName = "BlendVividLight";
}
else if (blendMode == 16)
{
blendName = "BlendPinLight";
}
else if (blendMode == 17)
{
blendName = "BlendHardMix";
}
else if (blendMode == 18)
{
blendName = "BlendReflect";
}
else if (blendMode == 19)
{
blendName = "BlendGlow";
}
else if (blendMode == 20)
{
blendName = "BlendPhoenix";
}
else if (blendMode == 21)
{
blendName = "BlendHue";
}
else if (blendMode == 22)
{
blendName = "BlendSaturation";
}
else if (blendMode == 23)
{
blendName = "BlendColor";
}
else if (blendMode == 24)
{
blendName = "BlendLuminosity";
}
return blendName;
}
protected: // Dragon!
void drawPlane(float _width, float _height)
{
quad.setVertex(0, ofVec3f(0,0,0));
quad.setVertex(1, ofVec3f(_width,0,0));
quad.setVertex(2, ofVec3f(_width,_height,0));
quad.setVertex(3, ofVec3f(0,_height,0));
quad.setTexCoord(0, ofVec2f(0,0));
quad.setTexCoord(1, ofVec2f(_width,0));
quad.setTexCoord(2, ofVec2f(_width,_height));
quad.setTexCoord(3, ofVec2f(0,_height));
quad.draw();
}
ofFbo base;
ofShader psBlendShader;
float width;
float height;
ofVboMesh quad;
};