Created
January 28, 2020 22:11
-
-
Save headstash/da7ed8a3092a795edc622e46874abd41 to your computer and use it in GitHub Desktop.
Waterly.cpp (FFGL 1.6)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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