Renders an object built by revolving a spline around the y-axis.
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 <cmath>
namespace oglplus {
class VaseVertShader
{
public:
VaseVertShader(void)
ObjectDesc("Vase vertex"),
"uniform vec3 LightPosition;"
"uniform vec3 CameraPosition;"
"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
"in vec4 Position;"
"in vec3 Normal;"
"in vec3 TexCoord;"
"out vec3 vertNormal;"
"out vec3 vertLightDir;"
"out vec3 vertLightRefl;"
"out vec3 vertViewDir;"
"out vec2 vertTexCoord;"
"out float vertShadow;"
"void main(void)"
"{"
" gl_Position = ModelMatrix* Position;"
" vertNormal = mat3(ModelMatrix)*Normal;"
" vertLightDir = normalize(LightPosition - gl_Position.xyz);"
" vertLightRefl = reflect(-vertLightDir, vertNormal);"
" vertViewDir = normalize(CameraPosition - gl_Position.xyz);"
" gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
" vertTexCoord = TexCoord.xy;"
" vertShadow = TexCoord.z;"
"}")
)
{ }
};
class VaseFragShader
{
public:
VaseFragShader(void)
ObjectDesc("Vase fragment"),
"uniform sampler2D VaseTex;"
"in vec3 vertNormal;"
"in vec3 vertLightDir;"
"in vec3 vertLightRefl;"
"in vec3 vertViewDir;"
"in vec2 vertTexCoord;"
"in float vertShadow;"
"out vec3 fragColor;"
"void main(void)"
"{"
" float Ambient = 0.2 + 0.3 * vertShadow;"
" float Diffuse = max(dot("
" normalize(vertNormal),"
" normalize(vertLightDir)"
" )+0.1, 0.0) * vertShadow;"
" float Specular = pow(clamp(dot("
" normalize(vertViewDir),"
" normalize(vertLightRefl)"
" ), 0.0, 1.0), 32.0) * vertShadow;"
" const vec3 LightColor = vec3(1.0, 1.0, 1.0);"
" vec3 Texel = texture(VaseTex, vertTexCoord).rgb;"
" fragColor = "
" (Ambient + Diffuse)*Texel +"
" Specular * LightColor;"
"}")
)
{ }
};
{
private:
{
Program prog(ObjectDesc(
"Vase program"));
prog << VaseVertShader() << VaseFragShader();
prog.Link().Use();
return prog;
}
const Program& prog(
void)
const {
return *
this; }
public:
ProgramUniform<Mat4f> projection_matrix, camera_matrix, model_matrix;
ProgramUniform<Vec3f> camera_position, light_position;
ProgramUniformSampler vase_tex;
VaseProgram(void)
, projection_matrix(prog(), "ProjectionMatrix")
, camera_matrix(prog(), "CameraMatrix")
, model_matrix(prog(), "ModelMatrix")
, camera_position(prog(), "CameraPosition")
, light_position(prog(), "LightPosition")
, vase_tex(prog(), "VaseTex")
{ }
};
class VaseExample : public Example
{
private:
Context gl;
VaseProgram vase_prog;
shapes::ShapeWrapper vase;
public:
VaseExample(void)
: vase(
List(
"Position")(
"Normal")(
"TexCoord").Get(),
shapes::RevolveY<GLfloat>(
36,
BezierCurves<Vec3f, GLfloat, 3>(
ListOf<Vec3f>
(
Vec3f( 0.00, 0.00, 0.00))
(
Vec3f( 0.20, 0.00, 0.00))
(
Vec3f( 0.40, 0.00, 0.00))
(
Vec3f( 0.80, 0.00, 0.00))
(
Vec3f( 1.45, 0.00, 0.00))
(
Vec3f( 1.45, 0.40, 0.00))
(
Vec3f( 1.40, 0.80, 0.00))
(
Vec3f( 1.35, 1.20, 0.00))
(
Vec3f( 1.20, 1.30, 0.00))
(
Vec3f( 1.00, 1.50, 0.00))
(
Vec3f( 0.80, 1.70, 0.00))
(
Vec3f( 0.80, 2.20, 0.00))
(
Vec3f( 0.90, 2.50, 0.00))
(
Vec3f( 1.00, 2.80, 0.00))
(
Vec3f( 0.98, 2.88, 0.00))
(
Vec3f( 1.05, 2.90, 0.00))
(
Vec3f( 1.12, 2.92, 0.00))
(
Vec3f( 1.09, 2.96, 0.00))
(
Vec3f( 1.05, 2.99, 0.00))
(
Vec3f( 1.01, 3.02, 0.00))
(
Vec3f( 0.96, 2.99, 0.00))
(
Vec3f( 0.93, 2.90, 0.00))
(
Vec3f( 0.90, 2.81, 0.00))
(
Vec3f( 0.88, 2.70, 0.00))
(
Vec3f( 0.82, 2.50, 0.00))
(
Vec3f( 0.74, 2.30, 0.00))
(
Vec3f( 0.70, 1.70, 0.00))
(
Vec3f( 0.88, 1.50, 0.00))
(
Vec3f( 1.06, 1.30, 0.00))
(
Vec3f( 1.25, 1.20, 0.00))
(
Vec3f( 1.30, 0.80, 0.00))
(
Vec3f( 1.35, 0.40, 0.00))
(
Vec3f( 1.35, 0.10, 0.00))
(
Vec3f( 0.80, 0.10, 0.00))
(
Vec3f( 0.40, 0.10, 0.00))
(
Vec3f( 0.25, 0.10, 0.00))
(
Vec3f( 0.00, 0.10, 0.00))
.Get()
).Approximate(8),
std::vector<Vec3f>(),
BezierCurves<Vec3f, GLfloat, 3>(
ListOf<Vec3f>
(
Vec3f( 5.00,-2.00, 1.00))
(
Vec3f( 5.00,-1.67, 1.00))
(
Vec3f( 5.00,-1.33, 1.00))
(
Vec3f( 5.00,-1.00, 1.00))
(
Vec3f( 5.00,-0.67, 1.00))
(
Vec3f( 5.00,-0.33, 1.00))
(
Vec3f( 5.00, 0.00, 1.00))
(
Vec3f( 5.00, 0.20, 1.00))
(
Vec3f( 5.00, 0.40, 1.00))
(
Vec3f( 5.00, 0.60, 1.00))
(
Vec3f( 5.00, 0.80, 1.00))
(
Vec3f( 5.00, 1.00, 1.00))
(
Vec3f( 5.00, 1.15, 1.00))
(
Vec3f( 5.00, 1.30, 1.00))
(
Vec3f( 5.00, 1.45, 0.40))
(
Vec3f( 5.00, 1.60, 0.60))
(
Vec3f( 5.00, 1.75, 1.00))
(
Vec3f( 5.00, 1.90, 1.00))
(
Vec3f( 5.00, 2.10, 1.00))
(
Vec3f( 5.00, 2.20, 1.00))
(
Vec3f( 5.00, 2.35, 1.00))
(
Vec3f( 5.00, 2.50, 1.00))
(
Vec3f( 5.00, 2.65, 1.00))
(
Vec3f( 5.00, 2.80, 1.00))
(
Vec3f( 5.00, 2.95, 1.00))
(
Vec3f( 5.00, 3.10, 0.90))
(
Vec3f( 5.00, 3.25, 0.50))
(
Vec3f( 5.00, 3.40, 0.10))
(
Vec3f( 5.00, 3.55, 0.00))
(
Vec3f( 5.00, 3.70, 0.00))
(
Vec3f( 5.00, 3.95, 0.00))
(
Vec3f( 5.00, 4.10, 0.00))
(
Vec3f( 5.00, 4.30, 0.00))
(
Vec3f( 5.00, 4.50, 0.10))
(
Vec3f( 5.00, 4.70, 0.15))
(
Vec3f( 5.00, 4.90, 0.20))
(
Vec3f( 5.00, 5.00, 0.30))
.Get()
).Approximate(8)
),
vase_prog
)
{
{
GLuint tex_side = 512;
auto image = images::NewtonFractal(
tex_side, tex_side,
images::NewtonFractal::X4Minus1(),
[](double x) -> double
{
}
);
gl.Bound(Texture::Target::_2D, vase_tex)
.Image2D(image)
.GenerateMipmap()
.BorderColor(
Vec4f(0.8f, 0.8f, 1.0f, 1.0f))
}
vase_prog.vase_tex = 0;
vase_prog.light_position.Set(4.0f, 4.0f, -8.0f);
gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
gl.ClearDepth(1.0f);
}
void Reshape(GLuint width, GLuint height)
{
gl.Viewport(width, height);
Degrees(60),
double(width)/height,
1, 30
);
}
{
gl.Clear().ColorBuffer().DepthBuffer();
Degrees(
SineWave(time / 20.0) * 30 + 35)
);
vase_prog.camera_matrix = camera;
vase_prog.camera_position = camera.Position();
vase_prog.model_matrix =
vase.Draw();
}
{
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 VaseExample);
}
}