Skip to content

Instantly share code, notes, and snippets.

@headstash
Created January 28, 2020 22:11
Show Gist options
  • Save headstash/da7ed8a3092a795edc622e46874abd41 to your computer and use it in GitHub Desktop.
Save headstash/da7ed8a3092a795edc622e46874abd41 to your computer and use it in GitHub Desktop.
Waterly.cpp (FFGL 1.6)
#include "FFGL.h"
#include "FFGLLib.h"
#include "Waterly.h"
#include "../../lib/ffgl/utilities/utilities.h"
#define FFPARAM_Time (0)
#define FFPARAM_Rate (1)
#define FFPARAM_Intensity (2)
#define FFPARAM_Scale (3)
////////////////////////////////////////////////////////////////////////////////////////////////////
// Plugin information
////////////////////////////////////////////////////////////////////////////////////////////////////
static CFFGLPluginInfo PluginInfo(
Waterly::CreateInstance, // Create method
"SH01", // Plugin unique ID
"Waterly", // Plugin name
1, // API major version number
500, // API minor version number
1, // Plugin major version number
000, // Plugin minor version number
FF_EFFECT, // Plugin type
"", // Plugin description
"" // About
);
static const std::string vertexShaderCode = STRINGIFY(
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
}
);
static const std::string fragmentShaderCode = STRINGIFY(
//#define PI 3.14159265358979
uniform vec3 iResolution;
uniform sampler2D inputTexture;
uniform float Time;
uniform float Rate;
uniform float Scale;
uniform float Intensity;
float pi = 3.14159265358979;
float SCALE = 1.0;
float style = 0.0;
float input_Scale = 1.0;
vec2 direction = vec2(0.0);
vec2 position = vec2(0.0);
mat3 m = mat3(0.00, 0.80, 0.60,
-0.80, 0.36, -0.48,
-0.60, -0.48, 0.64);
float hash(float n)
{
return fract(sin(n) * 43758.5453);
}
float noise(in vec3 x)
{
vec3 p = floor(x);
vec3 f = fract(x);
f = f * f * (3.0 - 2.0 * f);
float n = p.x + p.y * 57.0 + 113.0 * p.z;
float res = mix(mix(mix(hash(n + 0.0), hash(n + 1.0), f.x),
mix(hash(n + 57.0), hash(n + 58.0), f.x), f.y),
mix(mix(hash(n + 113.0), hash(n + 114.0), f.x),
mix(hash(n + 170.0), hash(n + 171.0), f.x), f.y), f.z);
return res;
}
float fbm(vec3 p)
{
float f;
f = 0.5000 * noise(p); p = m * p * 2.02;
f += 0.2500 * noise(p); p = m * p * 2.03;
f += 0.1250 * noise(p); p = m * p * 2.01;
f += 0.0625 * noise(p);
return f;
}
// --- End of: Created by inigo quilez --------------------
float mynoise(vec3 p)
{
return mix(noise(p * Scale) * Intensity, .5 + .5 * noise(p * Scale) * Intensity, style);
}
float myfbm(vec3 p)
{
float f;
f = 0.5000 * mynoise(p); p = m * p * 2.02;
f += 0.2500 * mynoise(p); p = m * p * 2.03;
f += 0.1250 * mynoise(p); p = m * p * 2.01;
f += 0.0625 * mynoise(p); p = m * p * 2.05;
f += 0.0625 / 2. * mynoise(p); p = m * p * 2.02;
f += 0.0625 / 4. * mynoise(p);
return f;
}
float myfbm2(vec3 p)
{
float f;
f = 1. - 0.5000 * mynoise(p); p = m * p * 2.02;
f *= 1. - 0.2500 * mynoise(p); p = m * p * 2.03;
f *= 1. - 0.1250 * mynoise(p); p = m * p * 2.01;
f *= 1. - 0.0625 * mynoise(p); p = m * p * 2.05;
f *= 1. - 0.0625 / 2. * mynoise(p); p = m * p * 2.02;
f *= 1. - 0.0625 / 4. * mynoise(p);
return f;
}
mat2 rotate2d(float _angle) {
return mat2(cos(_angle), -sin(_angle),
sin(_angle), cos(_angle));
}
void main()
{
vec2 _uv = gl_FragCoord.xy / iResolution.xy;
_uv.xy += direction.xy;
_uv = rotate2d(1 * -pi) * _uv;
vec3 v;
vec3 p = 4. * vec3(_uv, 0.) + (Time * Rate) * (.1, .7, 1.2);
float x = myfbm(p);
//v = vec3(x);
v = (.5 + .5 * sin(x * vec3(30., 20., 10.) * SCALE)) / SCALE;
float g = 1.;
//g = pow(length(v),1.);
//g = .5*noise(8.*m*m*m*p)+.5; g = 2.*pow(g,3.);
v *= g;
vec3 Ti = texture(inputTexture, mod(.02 * v.xy + position.xy + _uv.xy, 1.0)).rgb;
vec3 T = Ti;
//T = Ti+(1.-Ti)*Tf;
vec3 T1;
vec3 T2;
T1 = vec3(0., 0., 0.); T1 *= .5 * (T + 1.);
T2 = vec3(1., 1., 1.); //T2 = 1.2*Ti*vec3(1.,.8,.6)-.2;
v = mix(T1, T2, T);
gl_FragColor = vec4(v, 1.0);
}
);
Waterly::Waterly()
:CFreeFrameGLPlugin(),
m_initResources(1),
m_inputTextureLocation(-1)
{
// Input properties
SetMinInputs(1);
SetMaxInputs(1);
// Parameters
SetParamInfo(FFPARAM_Time, "Time", FF_TYPE_STANDARD, 0.0f);
m_Time = 0.0f;
SetParamInfo(FFPARAM_Rate, "Rate", FF_TYPE_STANDARD, 0.5f);
m_Rate = 0.5f;
SetParamInfo(FFPARAM_Intensity, "Intensity", FF_TYPE_STANDARD, 0.5f);
m_Intensity = 0.5f;
SetParamInfo(FFPARAM_Scale, "Scale", FF_TYPE_STANDARD, 1.0f);
m_Scale = 1.0f;
}
Waterly::~Waterly()
{
}
FFResult Waterly::InitGL(const FFGLViewportStruct* vp)
{
m_initResources = 0;
//initialize gl shader
m_shader.Compile(vertexShaderCode, fragmentShaderCode);
//activate our shader
m_shader.BindShader();
//to assign values to parameters in the shader, we have to lookup
//the "location" of each value.. then call one of the glUniform* methods
//to assign a value
m_inputTextureLocation = m_shader.FindUniform("inputTexture");
m_resolutionLocation = m_shader.FindUniform("iResolution");
//the 0 means that the 'inputTexture' in
//the shader will use the texture bound to GL texture unit 0
glUniform1i(m_inputTextureLocation, 0);
m_shader.UnbindShader();
return FF_SUCCESS;
}
FFResult Waterly::DeInitGL()
{
m_shader.FreeGLResources();
return FF_SUCCESS;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Methods
////////////////////////////////////////////////////////////////////////////////////////////////////
FFResult Waterly::ProcessOpenGL(ProcessOpenGLStruct* pGL)
{
if (pGL->numInputTextures < 1)
return FF_FAIL;
if (pGL->inputTextures[0] == NULL)
return FF_FAIL;
//activate our shader
m_shader.BindShader();
FFGLTextureStruct& Texture = *(pGL->inputTextures[0]);
//get the max s,t that correspond to the
//width,height of the used portion of the allocated texture space
FFGLTexCoords maxCoords = GetMaxGLTexCoords(Texture);
//activate texture unit 1 and bind the input texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Texture.Handle);
//draw the quad that will be painted by the shader/textures
//note that we are sending texture coordinates to texture unit 1..
//the vertex shader and fragment shader refer to this when querying for
//texture coordinates of the inputTexture
glBegin(GL_QUADS);
//lower left
glMultiTexCoord2f(GL_TEXTURE0, 0, 0);
glVertex2f(-1, -1);
//upper left
glMultiTexCoord2f(GL_TEXTURE0, 0, maxCoords.t);
glVertex2f(-1, 1);
//upper right
glMultiTexCoord2f(GL_TEXTURE0, maxCoords.s, maxCoords.t);
glVertex2f(1, 1);
//lower right
glMultiTexCoord2f(GL_TEXTURE0, maxCoords.s, 0);
glVertex2f(1, -1);
glEnd();
//unbind the input texture
glBindTexture(GL_TEXTURE_2D, 0);
float vpdim[4];
glGetFloatv(GL_VIEWPORT, vpdim);
glUniform3fARB(m_resolutionLocation, vpdim[2], vpdim[3], 1.0);
//unbind the shader
m_shader.UnbindShader();
return FF_SUCCESS;
}
float Waterly::GetFloatParameter(unsigned int dwIndex)
{
float retValue = 0.0;
switch (dwIndex)
{
case FFPARAM_Time:
retValue = m_Time;
return retValue;
case FFPARAM_Rate:
retValue = m_Rate;
return retValue;
case FFPARAM_Intensity:
retValue = m_Intensity;
return retValue;
case FFPARAM_Scale:
retValue = m_Scale;
return retValue;
default:
return retValue;
}
}
FFResult Waterly::SetFloatParameter(unsigned int dwIndex, float value)
{
switch (dwIndex)
{
case FFPARAM_Time:
m_Time = value;
break;
case FFPARAM_Rate:
m_Rate = value;
break;
case FFPARAM_Intensity:
m_Intensity = value;
break;
case FFPARAM_Scale:
m_Scale = value;
break;
default:
return FF_FAIL;
}
return FF_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment