Copyright 2008-2014 Matus Chochlik. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <cstdlib>
#include <ctime>
namespace oglplus {
class TexProgram
{
private:
{
vs.Source(
"#version 330\n"
"uniform vec2 Offset;"
"uniform float Scale;"
"in vec4 Position;"
"out vec2 vertTexCoord;"
"void main(void)"
"{"
" gl_Position = Position;"
" vertTexCoord = Scale * (0.5*Position.xy + Offset);"
"}"
).Compile();
fs.Source(
"#version 330\n"
"uniform float Scale;"
"uniform sampler2D Tex;"
"in vec2 vertTexCoord;"
"out vec3 fragColor;"
"const vec2 offs[9] = vec2[9]("
" vec2(-1,-1),"
" vec2(-1, 0),"
" vec2(-1, 1),"
" vec2( 0,-1),"
" vec2( 0, 0),"
" vec2( 0, 1),"
" vec2( 1,-1),"
" vec2( 1, 0),"
" vec2( 1, 1) "
");"
"float dist(vec2 tc, vec2 ofs)"
"{"
" vec2 cc = floor(tc+ofs);"
" vec2 cp = texture(Tex, cc/textureSize(Tex, 0)).xy;"
" return distance(tc, cc+cp);"
"}"
"vec3 point_color(vec2 tc, vec2 ofs)"
"{"
" vec2 cc = floor(tc+ofs);"
" return texture(Tex, cc/textureSize(Tex, 0)).rgb;"
"}"
"vec3 voronoi(vec2 tc)"
"{"
" float md = 2.0;"
" int mc = 9;"
" for(int c=0; c<9; ++c)"
" {"
" float d = dist(tc, offs[c]);"
" if(md > d)"
" {"
" md = d;"
" mc = c;"
" }"
" }"
" return mix("
" point_color(tc, offs[mc])*mix(1.4, 0.5, md),"
" vec3(0, 0, 0),"
" pow(exp(1-md*512/Scale), 2.0)"
" );"
"}"
"void main(void)"
"{"
" fragColor = voronoi(vertTexCoord);"
"}"
).Compile();
prog << vs << fs;
prog.Link().Use();
return std::move(prog);
}
{
return *this;
}
public:
Uniform<Vec2f> offset;
Uniform<float> scale;
TexProgram(void)
, offset(self(), "Offset")
, scale(self(), "Scale")
{
UniformSampler(self(), "Tex").Set(0);
}
};
class VoronoiExample
: public Example
{
private:
Context gl;
TexProgram prog;
shapes::ShapeWrapper screen;
public:
VoronoiExample(void)
: gl()
, prog()
{
std::srand(std::time(0));
<< images::RandomRGBUByte(256, 256);
}
void Reshape(GLuint width, GLuint height)
{
gl.Viewport(width, height);
}
{
float o = 2;
float s = 24;
prog.scale.Set(s + 1 +
SineWave(time / 19.0)*s);
screen.Draw();
}
{
return time < 60.0;
}
};
void setupExample(ExampleParams& ){ }
std::unique_ptr<ExampleThread> makeExampleThread(
Example& ,
unsigned ,
const ExampleParams&
){ return std::unique_ptr<ExampleThread>(); }
std::unique_ptr<Example> makeExample(const ExampleParams& )
{
return std::unique_ptr<Example>(new VoronoiExample);
}
}