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)
namespace oglplus {
class LandscapeExample : public Example
{
private:
GLuint grid_side;
shapes::Plane make_plane;
shapes::DrawingInstructions plane_instr;
Context gl;
LazyUniform<Vec3f> light_pos;
LazyUniform<Mat4f> projection_matrix, camera_matrix;
CubicBezierLoop<Vec3f, double> light_path;
public:
LandscapeExample(void)
: grid_side(128)
, make_plane(
grid_side*3, grid_side*3
), plane_instr(make_plane.Instructions())
, plane_indices(make_plane.Indices())
, light_pos(prog, "LightPos")
, projection_matrix(prog, "ProjectionMatrix")
, camera_matrix(prog, "CameraMatrix")
, light_path(
ListOf<Vec3f>
(
Vec3f(-3.0f, 2.0f, -3.5f))
(
Vec3f( 0.0f, 5.0f, 0.5f))
(
Vec3f( 3.0f, 3.0f, 3.0f))
(
Vec3f( 3.0f, 3.0f, -3.0f))
(
Vec3f( 0.0f, 5.0f, 0.5f))
(
Vec3f(-3.2f, 2.0f, 3.0f))
.Get()
)
{
vs.Source(
"#version 330\n"
"uniform mat4 ProjectionMatrix, CameraMatrix;"
"uniform sampler2D TexUnit;"
"in vec4 Position;"
"in vec2 TexCoord;"
"out vec3 vertLight;"
"out vec3 vertNormal;"
"uniform vec3 LightPos;"
"void main(void)"
"{"
" gl_Position = Position;"
" float o = 0.0;"
" float s[9];"
" int k=0;"
" for(int y=-1; y!=2; ++y)"
" for(int x=-1; x!=2; ++x)"
" {"
" s[k] = sqrt(texture("
" TexUnit, "
" TexCoord*3.0+"
" vec2(x, y)/128.0"
" ).r);"
" o += s[k++];"
" }"
" gl_Position.y += o*0.5;"
" vec3 c = vec3( 0.0, s[4], 0.0);"
" float d = 1.0/32.0;"
" vertNormal = normalize("
" cross("
" vec3( 0.0, s[1], -d) - c,"
" vec3( -d, s[3], 0.0) - c"
" )+"
" cross("
" vec3( d, s[5], 0.0) - c,"
" vec3( 0.0, s[1], -d) - c"
" )+"
" cross("
" vec3( 0.0, s[7], d) - c,"
" vec3( d, s[5], 0.0) - c"
" )+"
" cross("
" vec3( -d, s[3], 0.0) - c,"
" vec3( 0.0, s[7], d) - c"
" )"
" );"
" vertLight = LightPos - gl_Position.xyz;"
" gl_Position = "
" ProjectionMatrix *"
" CameraMatrix *"
" gl_Position;"
"}"
);
vs.Compile();
fs.Source(
"#version 330\n"
"in vec3 vertNormal;"
"in vec3 vertLight;"
"out vec4 fragColor;"
"void main(void)"
"{"
" float l = length(vertLight);"
" float d = l > 0? dot("
" normalize(vertNormal), "
" normalize(vertLight)"
" ) / l : 0.0;"
" float i = 0.1 + 1.2*max(d, 0.0) + 4.2*pow(d, 2.0);"
" fragColor = vec4(i*0.7, i*0.7, i*0.3, 1.0);"
"}"
);
fs.Compile();
prog.AttachShader(vs);
prog.AttachShader(fs);
prog.Link();
prog.Use();
plane.Bind();
{
std::vector<GLfloat> data;
GLuint n_per_vertex = make_plane.Positions(data);
attr.Setup<GLfloat>(n_per_vertex);
attr.Enable();
}
{
std::vector<GLfloat> data;
GLuint n_per_vertex = make_plane.TexCoordinates(data);
attr.Setup<GLfloat>(n_per_vertex);
attr.Enable();
}
tex.Bind(tex_tgt);
{
auto image = images::NewtonFractal(
grid_side, grid_side,
images::NewtonFractal::X3Minus1(),
images::NewtonFractal::DefaultMixer()
);
}
gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
gl.ClearDepth(1.0f);
gl.FrontFace(make_plane.FaceWinding());
}
void Reshape(GLuint width, GLuint height)
{
gl.Viewport(width, height);
prog.Use();
projection_matrix.Set(
Degrees(60),
double(width)/height,
1, 100
)
);
}
{
gl.Clear().ColorBuffer().DepthBuffer();
camera_matrix.Set(
6.5,
Degrees(time * 35),
Degrees(55 -
SineWave(time / 20.0) * 30)
)
);
light_pos.Set(light_path.Position(time / 10.0));
plane.Bind();
plane_instr.Draw(plane_indices);
}
{
return time < 30.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 LandscapeExample);
}
}