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 CubeVertShader
{
public:
CubeVertShader(void)
ObjectDesc("Cube vertex"),
"#version 400\n"
"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;"
"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;"
"}"
)
{ }
};
class CubeFragShader
{
public:
CubeFragShader(void)
ObjectDesc("Cube fragment"),
"#version 400\n"
"subroutine vec3 pixelColorFuncType(vec2 TexCoord);"
"subroutine vec3 pixelLightFuncType("
" vec3 Color, "
" float Ambient, "
" float Diffuse, "
" float Specular"
");"
"uniform vec3 Color1, Color2;"
"uniform vec2 TexScale;"
"uniform float SpecularFactor;"
"uniform sampler2D CubeTex;"
"subroutine uniform pixelColorFuncType pixelColorFunc;"
"subroutine uniform pixelLightFuncType pixelLightFunc;"
"in vec3 vertNormal;"
"in vec3 vertLightDir;"
"in vec3 vertLightRefl;"
"in vec3 vertViewDir;"
"in vec2 vertTexCoord;"
"out vec3 fragColor;"
"const vec3 LightColor = vec3(1.0, 1.0, 1.0);"
"subroutine(pixelLightFuncType)"
"vec3 shiny("
" vec3 Color, "
" float Ambient, "
" float Diffuse, "
" float Specular"
")"
"{"
" return (Ambient+Diffuse)*Color +"
" Specular * LightColor;"
"}"
"subroutine(pixelLightFuncType)"
"vec3 dull("
" vec3 Color, "
" float Ambient, "
" float Diffuse, "
" float Specular"
")"
"{"
" return (Ambient+Diffuse*0.9)*Color +"
" Specular*0.1 * LightColor;"
"}"
"subroutine(pixelColorFuncType)"
"vec3 checker(vec2 TexCoord)"
"{"
" float a = ("
" int(TexCoord.x)%2+"
" int(TexCoord.y)%2 "
" )%2;"
" return mix(Color1, Color2, a);"
"}"
"subroutine(pixelColorFuncType)"
"vec3 strips(vec2 TexCoord)"
"{"
" float a = int(TexCoord.x+TexCoord.y)%2;"
" return mix(Color1, Color2, a);"
"}"
"subroutine(pixelColorFuncType)"
"vec3 spiral(vec2 TexCoord)"
"{"
" vec2 center = (TexCoord - vec2(0.5, 0.5)) * 16.0;"
" float l = length(center);"
" float t = atan(center.y, center.x)/(2.0*asin(1.0));"
" float m = int(l+t) % 2;"
" return mix(Color1, Color2, m);"
"}"
"subroutine(pixelColorFuncType)"
"vec3 textureRGB(vec2 TexCoord)"
"{"
" return texture(CubeTex, TexCoord).rgb;"
"}"
"subroutine(pixelColorFuncType)"
"vec3 textureBGR(vec2 TexCoord)"
"{"
" return texture(CubeTex, TexCoord).bgr;"
"}"
"void main(void)"
"{"
" float Ambient = 0.5;"
" float Diffuse = max(dot("
" normalize(vertNormal),"
" normalize(vertLightDir)"
" )+0.1, 0.0);"
" float Specular = pow(clamp(dot("
" normalize(vertViewDir),"
" normalize(vertLightRefl)"
" ), 0.0, 1.0), SpecularFactor);"
" fragColor = pixelLightFunc("
" pixelColorFunc(vertTexCoord * TexScale),"
" Ambient, "
" Diffuse, "
" Specular "
" );"
"}"
)
{ }
};
{
private:
{
Program prog(ObjectDesc(
"Cube program"));
prog.AttachShader(CubeVertShader());
prog.AttachShader(CubeFragShader());
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;
ProgramUniform<Vec3f> color_1, color_2;
ProgramUniform<Vec2f> tex_scale;
ProgramUniform<GLfloat> specular_factor;
ProgramUniformSampler cube_tex;
Subroutine checker, strips, spiral, texture_rgb, texture_bgr;
UniformSubroutines frag_subroutines;
UniformSubroutines::Preset frag_shiny_checker;
UniformSubroutines::Preset frag_shiny_texture;
UniformSubroutines::Preset frag_shiny_strips;
UniformSubroutines::Preset frag_shiny_spiral;
CubeProgram(void)
, projection_matrix(prog(), "ProjectionMatrix")
, camera_matrix(prog(), "CameraMatrix")
, model_matrix(prog(), "ModelMatrix")
, camera_position(prog(), "CameraPosition")
, light_position(prog(), "LightPosition")
, color_1(prog(), "Color1")
, color_2(prog(), "Color2")
, tex_scale(prog(), "TexScale")
, specular_factor(prog(), "SpecularFactor")
, cube_tex(prog(), "CubeTex")
, frag_shiny_checker(
frag_subroutines
.Assign(pixel_light_func, shiny)
.Assign(pixel_color_func, checker)
.Save()
), frag_shiny_texture(
frag_subroutines
.Assign(pixel_color_func, texture_rgb)
.Save()
), frag_shiny_strips(
frag_subroutines
.Assign(pixel_color_func, strips)
.Save()
), frag_shiny_spiral(
frag_subroutines
.Assign(pixel_color_func, spiral)
.Save()
)
{ }
};
class CubeExample : public Example
{
private:
Context gl;
CubeProgram cube_prog;
shapes::ShapeWrapper cube;
public:
CubeExample(void)
: cube(
List(
"Position")(
"Normal")(
"TexCoord").Get(),
shapes::Cube(),
cube_prog
)
{
{
GLuint tex_side = 512;
auto image = images::NewtonFractal(
tex_side, tex_side,
images::NewtonFractal::X4Minus1(),
images::NewtonFractal::DefaultMixer()
);
gl.Bound(Texture::Target::_2D, cube_tex)
.Image2D(image)
.GenerateMipmap()
.BorderColor(
Vec4f(0.8f, 0.8f, 1.0f, 1.0f))
}
cube_prog.cube_tex = 0;
cube_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, 25
);
}
{
gl.Clear().ColorBuffer().DepthBuffer();
Degrees(
SineWave(time / 20.0) * 30 + 35)
);
cube_prog.camera_matrix = camera;
cube_prog.camera_position = camera.Position();
cube_prog.frag_subroutines.Apply(cube_prog.frag_shiny_checker);
cube_prog.specular_factor = 32;
cube_prog.color_1 =
Vec3f(0.9, 0.8, 0.7);
cube_prog.color_2 =
Vec3f(0.3, 0.4, 0.5);
cube_prog.tex_scale =
Vec2f(4, 4);
cube_prog.model_matrix =
cube.Draw();
cube_prog.frag_subroutines.Apply(cube_prog.frag_shiny_texture);
cube_prog.specular_factor = 16;
cube_prog.tex_scale =
Vec2f(1, 1);
cube_prog.model_matrix =
cube.Draw();
cube_prog.frag_subroutines.Apply(cube_prog.frag_shiny_strips);
cube_prog.specular_factor = 32;
cube_prog.color_1 =
Vec3f(0.9, 0.9, 0.1);
cube_prog.color_2 =
Vec3f(0.1, 0.1, 0.1);
cube_prog.tex_scale =
Vec2f(16, 16);
cube_prog.model_matrix =
cube.Draw();
cube_prog.frag_subroutines.Apply(cube_prog.frag_shiny_spiral);
cube_prog.specular_factor = 24;
cube_prog.color_1 =
Vec3f(0.9, 0.9, 0.9);
cube_prog.color_2 =
Vec3f(0.4, 0.9, 0.4);
cube_prog.tex_scale =
Vec2f(1, 1);
cube_prog.model_matrix =
cube.Draw();
cube_prog.frag_subroutines
.Assign(
cube_prog.pixel_light_func,
cube_prog.dull
).Assign(
cube_prog.pixel_color_func,
cube_prog.strips
).Apply();
cube_prog.specular_factor = 32;
cube_prog.color_2 =
Vec3f(1.0, 1.0, 1.0);
cube_prog.color_1 =
Vec3f(0.9, 0.2, 0.2);
cube_prog.tex_scale =
Vec2f(8, 6);
cube_prog.model_matrix =
cube.Draw();
cube_prog.frag_subroutines
.Assign(
cube_prog.pixel_color_func,
cube_prog.texture_bgr
).Apply();
cube_prog.tex_scale =
Vec2f(1, 1);
cube_prog.model_matrix =
cube.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 CubeExample);
}
}