FlowMapHolder( GLuint flow_tex_size, GLuint tex_unit, const images::Image& flow_map_image ): first_tex_unit(tex_unit) , nhm(3) , height_maps(nhm, Texture::Target::_2D, first_tex_unit) , curr(0) { std::vector<GLfloat> v(flow_tex_size*flow_tex_size, 0.0f); for(GLuint i=0; i!=nhm; ++i) { height_maps[i].Image2D( 0, PixelDataInternalFormat::Red, flow_tex_size, flow_tex_size, 0, PixelDataFormat::Red, PixelDataType::Float, v.data() ); height_maps[i].MinFilter(TextureMinFilter::Linear); height_maps[i].MagFilter(TextureMagFilter::Linear); height_maps[i].WrapS(TextureWrap::ClampToBorder); height_maps[i].WrapT(TextureWrap::ClampToBorder); } Texture::Active(BumpMapUnit()); { auto bound_tex = Bind(bump_map, Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::RGBA, flow_tex_size, flow_tex_size, 0, PixelDataFormat::RGBA, PixelDataType::UnsignedByte, nullptr ); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); } Texture::Active(FlowMapUnit()); { auto bound_tex = Bind(flow_map, Texture::Target::_2D); bound_tex.Image2D(flow_map_image); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } }
FlowExample(void) : gl() , flow(images::LoadTexture("flow_map"), 1) , screen( List("Position")("TexCoord").Get(), shapes::Screen(), screen_prog ) { Texture::Active(0); { auto bound_tex = Bind(background, Texture::Target::_2D); bound_tex.Image2D(images::LoadTexture("flower_glass")); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::MirroredRepeat); bound_tex.WrapT(TextureWrap::MirroredRepeat); } screen_prog.background.Set(0); screen_prog.normal_map.Set(flow.TexUnit()); gl.ClearColor(0.4f, 0.4f, 0.4f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); }
LiquidExample(const ExampleParams& params) : liquid_prog() , grid(liquid_prog, params.quality) , grid_repeat(int(1 + params.quality*2)) { Texture::Active(1); { auto image = images::Squares(512, 512, 0.9f, 8, 8); auto bound_tex = gl.Bound(Texture::Target::CubeMap, env_map); for(int i=0; i!=6; ++i) Texture::ImageCM(i, image); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); bound_tex.SwizzleG(TextureSwizzle::Red); bound_tex.SwizzleB(TextureSwizzle::Red); } ProgramUniformSampler(liquid_prog, "EnvMap").Set(1); const Vec3f light_position(12.0, 1.0, 8.0); liquid_prog.light_position.Set(light_position); gl.ClearColor(0.7f, 0.65f, 0.55f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(FaceOrientation::CW); gl.CullFace(Face::Back); }
RippleTexHolder(GLuint ripple_tex_size, GLuint tex_unit) : first_tex_unit(tex_unit) , nhm(3) , height_maps(nhm) , curr(0) { std::vector<GLfloat> v(ripple_tex_size*ripple_tex_size, 0.0f); for(GLuint i=0; i!=nhm; ++i) { Texture::Active(first_tex_unit+i); auto bound_tex = Bind(height_maps[i], Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::Red, ripple_tex_size, ripple_tex_size, 0, PixelDataFormat::Red, PixelDataType::Float, v.data() ); bound_tex.MinFilter(TextureMinFilter::Nearest); bound_tex.MagFilter(TextureMagFilter::Nearest); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } Texture::Active(first_tex_unit+nhm); auto bound_tex = Bind(bump_map, Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::RGBA, ripple_tex_size, ripple_tex_size, 0, PixelDataFormat::RGBA, PixelDataType::UnsignedByte, nullptr ); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); }
FBTexThread(FBTexExample& example) : gl() , prog(make_prog(example)) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , shape(List("Position")("Normal")("TexCoord").Get(), shapes::TwistedTorus(), prog) , tex_side(512) , parent_ready(example.parent_ready) { example.thread_ready = &thread_ready; Uniform<Vec3f>(prog, "LightPos").Set(20.0f, 30.0f, 40.0f); Texture::Active(0); { auto bound_tex = Bind(example.tex, Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::RGBA, tex_side, tex_side, 0, PixelDataFormat::RGBA, PixelDataType::UnsignedByte, nullptr ); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } { auto bound_fbo = Bind(fbo, Framebuffer::Target::Draw); auto bound_rbo = Bind(rbo, Renderbuffer::Target::Renderbuffer); bound_rbo.Storage( PixelDataInternalFormat::DepthComponent, tex_side, tex_side ); bound_fbo.AttachTexture(FramebufferAttachment::Color, example.tex, 0); bound_fbo.AttachRenderbuffer(FramebufferAttachment::Depth, rbo); } Use(); }
LiquidExample(const ExampleParams& params) : liquid_prog() , grid(liquid_prog, params.quality) , grid_repeat(1 + params.quality*2) { Texture::Active(0); { auto image = images::NewtonFractal( 256, 256, Vec3f(0.1f, 0.1f, 0.1f), Vec3f(1.0f, 1.0f, 1.0f), Vec2f(-1.0f, -1.0f), Vec2f( 1.0f, 1.0f), images::NewtonFractal::X4Minus1(), images::NewtonFractal::DefaultMixer() ); auto bound_tex = oglplus::Context::Bound( Texture::Target::CubeMap, env_map ); for(int i=0; i!=6; ++i) Texture::ImageCM(i, image); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); } ProgramUniformSampler(liquid_prog, "EnvMap").Set(0); const Vec3f light_position(12.0, 1.0, 8.0); liquid_prog.light_position.Set(light_position); gl.ClearColor(0.7f, 0.65f, 0.55f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(FaceOrientation::CW); gl.CullFace(Face::Back); }
CubeExample(void) : cube( List("Position")("Normal")("TexCoord").Get(), shapes::Cube(), cube_prog ) { // setup the texture { GLuint tex_side = 512; auto image = images::NewtonFractal( tex_side, tex_side, Vec3f(0.2f, 0.1f, 0.4f), Vec3f(0.8f, 0.8f, 1.0f), Vec2f(-1.0f, -1.0f), Vec2f( 1.0f, 1.0f), images::NewtonFractal::X4Minus1(), images::NewtonFractal::DefaultMixer() ); auto bound_tex = Bind(cube_tex, Texture::Target::_2D); bound_tex.Image2D(image); bound_tex.GenerateMipmap(); bound_tex.BorderColor(Vec4f(0.8f, 0.8f, 1.0f, 1.0f)); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } 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); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.CullFace(Face::Back); }
EnvMap(GLuint tex_unit) : _tex_unit(tex_unit) { Texture::Active(_tex_unit); auto bound_tex = oglplus::Bind(*this, Texture::Target::CubeMap); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); Texture::Image2D( Texture::CubeMapFace(0), images::LoadTexture("cloudy_day-cm_0", false, false) ); Texture::Image2D( Texture::CubeMapFace(1), images::LoadTexture("cloudy_day-cm_1", false, false) ); Texture::Image2D( Texture::CubeMapFace(2), images::LoadTexture("cloudy_day-cm_2", false, false) ); Texture::Image2D( Texture::CubeMapFace(3), images::LoadTexture("cloudy_day-cm_3", false, false) ); Texture::Image2D( Texture::CubeMapFace(4), images::LoadTexture("cloudy_day-cm_4", false, false) ); Texture::Image2D( Texture::CubeMapFace(5), images::LoadTexture("cloudy_day-cm_5", false, false) ); }
Test01(void) { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 projectionMatrix, cameraMatrix, modelMatrix;" "in vec4 vertex;" "in vec3 normal;" "in vec3 tangent;" "in vec2 texcoord;" "out vec3 fragLight;" "out vec2 fragTex;" "out mat3 normalMatrix;" "uniform vec3 lightPos;" "void main(void)" "{" " vec3 fragNormal = (" " modelMatrix *" " vec4(normal, 0.0)" " ).xyz;" " vec3 fragTangent = (" " modelMatrix *" " vec4(tangent, 0.0)" " ).xyz;" " normalMatrix[0] = fragTangent;" " normalMatrix[1] = cross(fragNormal, fragTangent);" " normalMatrix[2] = fragNormal;" " fragLight = (" " vec4(lightPos, 0.0)-" " modelMatrix*vertex" " ).xyz;" " fragTex = texcoord;" " gl_Position = " " projectionMatrix *" " cameraMatrix *" " modelMatrix *" " vertex;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler2D colorTex, normalTex;" "in vec3 fragLight;" "in vec2 fragTex;" "in mat3 normalMatrix;" "out vec4 fragColor;" "void main(void)" "{" " float s = 5.0;" " float l = length(fragLight);" " vec3 n = texture2D(normalTex, fragTex*s).xyz;" " vec3 finalNormal = normalMatrix * n;" " float d = (l != 0.0)?" " dot(fragLight, finalNormal)/l:" " 0.0;" " float i = 0.1 + 2.5*clamp(d, 0.0, 1.0);" " vec4 t = texture2D(colorTex, fragTex*s);" " fragColor = vec4(t.rgb*i, 1.0);" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the shape vao.Bind(); { std::vector<GLfloat> data; GLuint n_per_vertex = shape.Positions(data); Bind(verts, Buffer::Target::Array).Data(data); // setup the vertex attribs array for the vertices VertexAttribArray attr(prog, "vertex"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } { std::vector<GLfloat> data; GLuint n_per_vertex = shape.Normals(data); Bind(normals, Buffer::Target::Array).Data(data); // setup the vertex attribs array for the normals VertexAttribArray attr(prog, "normal"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } { std::vector<GLfloat> data; GLuint n_per_vertex = shape.Tangents(data); Bind(tangents, Buffer::Target::Array).Data(data); VertexAttribArray attr(prog, "tangent"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // bind the VBO for the shape tex-coords { std::vector<GLfloat> data; GLuint n_per_vertex = shape.TexCoordinates(data); Bind(texcoords, Buffer::Target::Array).Data(data); // VertexAttribArray attr(prog, "texcoord"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // setup the textures { Texture::Active(0); UniformSampler(prog, "colorTex").Set(0); auto bound_tex = Bind(color_tex, Texture::Target::_2D); bound_tex.Image2D(images::LoadTexture("stones")); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } { Texture::Active(1); UniformSampler(prog, "normalTex").Set(1); auto bound_tex = Bind(normal_tex, Texture::Target::_2D); bound_tex.Image2D( images::NormalMap(images::LoadTexture("stones-hmap")) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } Uniform<Mat4f>(prog, "projectionMatrix").Set( CamMatrixf::Perspective(Degrees(24), 1.25, 1, 100) ); // VertexArray::Unbind(); gl.ClearColor(0.3f, 0.3f, 0.3f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); // gl.FrontFace(shape.FaceWinding()); gl.CullFace(Face::Back); gl.Enable(Capability::CullFace); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { namespace se = oglplus::smart_enums; // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertLight;" "out vec2 vertTexCoord;" "uniform vec3 LightPos;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " gl_Position = ModelMatrix * Position;" " vertLight = LightPos - gl_Position.xyz;" " vertTexCoord = TexCoord;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler2D TexUnit;" "in vec3 vertNormal;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(vertLight);" " float d = l > 0 ? dot(vertNormal, normalize(vertLight)) / l : 0.0;" " float i = 0.3 + 2.0*max(d, 0.0);" " vec4 t = texture(TexUnit, vertTexCoord);" " fragColor = vec4(t.rgb*i, 1.0);" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the cube cube.Bind(); verts.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(se::Array(), data); (prog|"Position").Setup(n_per_vertex, se::Float()).Enable(); } normals.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(se::Array(), data); (prog|"Normal").Setup(n_per_vertex, se::Float()).Enable(); } texcoords.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(se::Array(), data); (prog|"TexCoord").Setup(n_per_vertex, se::Float()).Enable(); } // setup the texture { auto bound_tex = Bind(tex, se::_2D()); bound_tex.Image2D(images::LoadTexture("concrete_block")); bound_tex.MinFilter(se::Linear()); bound_tex.MagFilter(se::Linear()); bound_tex.WrapS(se::Repeat()); bound_tex.WrapT(se::Repeat()); } // set the uniform values (prog/"TexUnit") = 0; (prog/"LightPos") = Vec3f(1.0f, 2.0f, 3.0f); // gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(se::DepthTest()); gl.Enable(se::CullFace()); gl.FrontFace(make_cube.FaceWinding()); }
SketchExample(void) : transf_prog() , sketch_prog() , plane( transf_prog, shapes::Plane( Vec3f(0, 0, 0), Vec3f(9, 0, 0), Vec3f(0, 0,-9), 9, 9 ) ), torus(transf_prog, shapes::WickerTorus()) , sketch_tex_layers(8) , shadow_tex_side(1024) { NoProgram().Use(); shadow_pp.Bind(); shadow_pp.UseStages(transf_prog).Vertex(); shadow_pp.UseStages(shadow_prog).Fragment(); sketch_pp.Bind(); sketch_pp.UseStages(transf_prog).Vertex(); sketch_pp.UseStages(sketch_prog).Fragment(); line_pp.Bind(); line_pp.UseStages(transf_prog).Vertex(); line_pp.UseStages(line_prog).Geometry().Fragment(); Texture::Active(0); sketch_prog.sketch_tex.Set(0); { auto bound_tex = gl.Bound(Texture::Target::_3D, sketch_texture); for(GLuint i=0; i<sketch_tex_layers; ++i) { auto image = images::BrushedMetalUByte( 512, 512, 64 + i*128, -(2+i*4), +(2+i*4), 64, 256-i*4 ); if(i == 0) { bound_tex.Image3D( 0, PixelDataInternalFormat::RGB, image.Width(), image.Height(), sketch_tex_layers, 0, image.Format(), image.Type(), nullptr ); } bound_tex.SubImage3D( 0, 0, 0, i, image.Width(), image.Height(), 1, image.Format(), image.Type(), image.RawData() ); } bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); bound_tex.WrapR(TextureWrap::ClampToEdge); } Texture::Active(1); sketch_prog.shadow_tex.Set(1); gl.Bound(Texture::Target::_2D, shadow_tex) .MinFilter(TextureMinFilter::Linear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::ClampToEdge) .WrapT(TextureWrap::ClampToEdge) .CompareMode(TextureCompareMode::CompareRefToTexture) .Image2D( 0, PixelDataInternalFormat::DepthComponent32, shadow_tex_side, shadow_tex_side, 0, PixelDataFormat::DepthComponent, PixelDataType::Float, nullptr ); gl.Bound(Framebuffer::Target::Draw, frame_shadow_fbo) .AttachTexture( FramebufferAttachment::Depth, shadow_tex, 0 ); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.DepthFunc(CompareFn::LEqual); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); gl.PolygonOffset(1.0, 1.0); gl.LineWidth(1.5); }
ReflectionExample(void) : make_plane( Vec3f(), Vec3f(3.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, -3.0f), 15, 15 ), plane_instr(make_plane.Instructions()) , plane_indices(make_plane.Indices()) , make_shape() , shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , plane_vs(ObjectDesc("Plane vertex")) , shape_vs(ObjectDesc("Shape vertex")) , plane_fs(ObjectDesc("Plane fragment")) , shape_fs(ObjectDesc("Shape fragment")) , plane_projection_matrix(plane_prog, "ProjectionMatrix") , plane_camera_matrix(plane_prog, "CameraMatrix") , plane_model_matrix(plane_prog, "ModelMatrix") , shape_projection_matrix(shape_prog, "ProjectionMatrix") , shape_camera_matrix(shape_prog, "CameraMatrix") , shape_model_matrix(shape_prog, "ModelMatrix") , width(800) , height(600) , tex_size_div(2) { plane_vs.Source( "#version 330\n" "uniform vec3 LightPosition;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "out vec3 vertLightDir;" "out vec4 vertTexCoord;" "void main(void)" "{" " gl_Position = ModelMatrix*Position;" " vertLightDir = LightPosition - gl_Position.xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" " vertTexCoord = gl_Position;" "}" ); plane_vs.Compile(); plane_fs.Source( "#version 330\n" "uniform sampler2DRect ReflectTex;" "uniform vec3 Normal;" "in vec3 vertLightDir;" "in vec4 vertTexCoord;" "out vec3 fragColor;" "const int n = 5;" "const int ns = (n*n);" "const float blur = 0.15/n;" "void main(void)" "{" " float d = dot(Normal, normalize(vertLightDir));" " float intensity = 0.5 + pow(1.4*d, 2.0);" " vec3 color = vec3(0.0, 0.0, 0.0);" " int n = 2;" " float pct = 0.5/vertTexCoord.w;" " for(int y=-n; y!=(n+1); ++y)" " for(int x=-n; x!=(n+1); ++x)" " {" " vec2 coord = vertTexCoord.xy;" " coord += vec2(blur*x, blur*y);" " coord *= pct;" " coord += vec2(0.5, 0.5);" " coord *= textureSize(ReflectTex);" " color += texture(ReflectTex, coord).rgb/ns;" " }" " fragColor = color*intensity;" "}" ); plane_fs.Compile(); plane_prog.AttachShader(plane_vs); plane_prog.AttachShader(plane_fs); plane_prog.Link(); plane_prog.Use(); Vec3f lightPos(3.0f, 0.5f, 2.0f); Uniform<Vec3f>(plane_prog, "LightPosition").Set(lightPos); Uniform<Vec3f>(plane_prog, "Normal").Set(make_plane.Normal()); plane.Bind(); plane_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_plane.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(plane_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // Texture::Active(1); { auto bound_tex = Bind(depth_tex, Texture::Target::Rectangle); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); } Texture::Active(0); ProgramUniformSampler(plane_prog, "ReflectTex").Set(0); { auto bound_tex = Bind(reflect_tex, Texture::Target::Rectangle); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); } { auto bound_fbo = Bind( fbo, Framebuffer::Target::Draw ); bound_fbo.AttachTexture( FramebufferAttachment::Color, reflect_tex, 0 ); bound_fbo.AttachTexture( FramebufferAttachment::Depth, depth_tex, 0 ); } shape_vs.Source( "#version 330\n" "uniform vec3 LightPosition;" "uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "out vec3 vertViewDir;" "out vec3 vertColor;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertLightDir = LightPosition - gl_Position.xyz;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLightRefl = reflect(" " -normalize(vertLightDir)," " normalize(vertNormal)" " );" " vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)*CameraMatrix).xyz;" " vertColor = vec3(1, 1, 1) - vertNormal;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); shape_vs.Compile(); shape_fs.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec3 vertColor;" "out vec3 fragColor;" "void main(void)" "{" " float l = length(vertLightDir);" " float d = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / l;" " float s = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 lt = vec3(1.0, 1.0, 1.0);" " fragColor = " " vertColor * 0.4 + " " (lt + vertColor)*pow(max(2.5*d, 0.0), 3) + " " lt * pow(max(s, 0.0), 64);" "}" ); shape_fs.Compile(); shape_prog.AttachShader(shape_vs); shape_prog.AttachShader(shape_fs); shape_prog.Link(); shape_prog.Use(); Uniform<Vec3f>(shape_prog, "LightPosition").Set(lightPos); shape.Bind(); shape_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(shape_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } shape_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(shape_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // gl.ClearColor(0.5f, 0.5f, 0.4f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); }
FBTexExample(void) : make_cube() , cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , make_torus(1.0, 0.5, 72, 48) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , cube_fs(ObjectDesc("Cube fragment")) , torus_fs(ObjectDesc("Torus fragment")) , torus_projection_matrix(torus_prog, "ProjectionMatrix") , torus_camera_matrix(torus_prog, "CameraMatrix") , torus_model_matrix(torus_prog, "ModelMatrix") , cube_projection_matrix(cube_prog, "ProjectionMatrix") , cube_camera_matrix(cube_prog, "CameraMatrix") , cube_model_matrix(cube_prog, "ModelMatrix") , tex_side(512) , width(tex_side) , height(tex_side) { vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertLight;" "out vec2 vertTexCoord;" "uniform vec3 LightPos;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " gl_Position = ModelMatrix * Position;" " vertLight = LightPos-gl_Position.xyz;" " vertTexCoord = TexCoord;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); vs.Compile(); cube_fs.Source( "#version 330\n" "uniform sampler2D TexUnit;" "in vec3 vertNormal;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float l = sqrt(length(vertLight));" " float d = l > 0? dot(vertNormal, normalize(vertLight)) / l : 0.0;" " float i = 0.6 + max(d, 0.0);" " fragColor = texture(TexUnit, vertTexCoord)*i;" "}" ); cube_fs.Compile(); cube_prog.AttachShader(vs); cube_prog.AttachShader(cube_fs); cube_prog.Link(); cube_prog.Use(); cube.Bind(); cube_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(cube_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } cube_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(cube_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } cube_texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(cube_prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } UniformSampler(cube_prog, "TexUnit").Set(0); Uniform<Vec3f>(cube_prog, "LightPos").Set(4.0f, 4.0f, -8.0f); torus_fs.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float d = dot(" " vertNormal, " " normalize(vertLight)" " );" " float i = (" " int(vertTexCoord.x*18) % 2+" " int(vertTexCoord.y*14) % 2" " ) % 2;" " float c = (0.4 + max(d, 0.0))*(1-i/2);" " fragColor = vec4(c, c, c, 1.0);" "}" ); torus_fs.Compile(); torus_prog.AttachShader(vs); torus_prog.AttachShader(torus_fs); torus_prog.Link(); torus_prog.Use(); torus.Bind(); torus_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(torus_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } torus_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(torus_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } torus_texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(torus_prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } Uniform<Vec3f>(torus_prog, "LightPos").Set(2.0f, 3.0f, 4.0f); { auto bound_tex = Bind(tex, Texture::Target::_2D); bound_tex.Image2D( 0, PixelDataInternalFormat::RGBA, tex_side, tex_side, 0, PixelDataFormat::RGBA, PixelDataType::UnsignedByte, nullptr ); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } { auto bound_fbo = Bind( fbo, Framebuffer::Target::Draw ); auto bound_rbo = Bind( rbo, Renderbuffer::Target::Renderbuffer ); bound_rbo.Storage( PixelDataInternalFormat::DepthComponent, tex_side, tex_side ); bound_fbo.AttachTexture( FramebufferAttachment::Color, tex, 0 ); bound_fbo.AttachRenderbuffer( FramebufferAttachment::Depth, rbo ); } gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.CullFace(Face::Back); }
CubeMapExample(void) : shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "out vec3 vertViewDir;" "out vec3 vertViewRefl;" "uniform vec3 LightPos;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLightDir = LightPos - gl_Position.xyz;" " vertLightRefl = reflect(" " -normalize(vertLightDir)," " normalize(vertNormal)" " );" " vertViewDir = (" " vec4(0.0, 0.0, 1.0, 1.0)*" " CameraMatrix" " ).xyz;" " vertViewRefl = reflect(" " normalize(vertViewDir)," " normalize(vertNormal)" " );" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform samplerCube TexUnit;" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec3 vertViewRefl;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(vertLightDir);" " float d = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / l;" " float s = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 lt = vec3(1.0, 1.0, 1.0);" " vec3 env = texture(TexUnit, vertViewRefl).rgb;" " fragColor = vec4(" " env * 0.4 + " " (lt + env) * 1.5 * max(d, 0.0) + " " lt * pow(max(s, 0.0), 64), " " 1.0" " );" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the shape shape.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Normal"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // setup the texture { GLuint tex_side = 256; auto image = images::NewtonFractal( tex_side, tex_side, Vec3f(0.3f, 0.1f, 0.2f), Vec3f(1.0f, 0.8f, 0.9f), Vec2f(-1.0f, -1.0f), Vec2f( 1.0f, 1.0f), images::NewtonFractal::X4Minus1(), images::NewtonFractal::DefaultMixer() ); auto bound_tex = Bind(tex, Texture::Target::CubeMap); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); for(int i=0; i!=6; ++i) Texture::Image2D(Texture::CubeMapFace(i), image); } // typechecked uniform with the exact sampler type // on compilers supporting strongly typed enums // you can use: //Typechecked<Uniform<SLtoCpp<SLDataType::SamplerCube>>>(prog, "TexUnit").Set(0); // without strongly typed enums you need to do: typedef SLtoCpp<OGLPLUS_CONST_ENUM_VALUE(SLDataType::SamplerCube)> GLSLsamplerCube; Typechecked<Uniform<GLSLsamplerCube>>(prog, "TexUnit").Set(0); // Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(3.0f, 5.0f, 4.0f)); // gl.ClearColor(0.2f, 0.05f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_shape.FaceWinding()); gl.CullFace(Face::Back); }
TriangleExample(void) : projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , camera_position(prog, "CameraPosition") , light_position(prog, "LightPosition") , shape( List("Position")("TexCoord").Get(), shapes::Plane( Vec3f(), Vec3f(1.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f,-1.0f), 32, 32 ) ) { VertexShader vs; vs.Source(StrLit( "#version 330\n" "in vec3 Position;" "in vec2 TexCoord;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = vec4(Position, 1.0);" " vertTexCoord = TexCoord;" "}" )).Compile(); prog.AttachShader(vs); GeometryShader gs; gs.Source(StrLit( "#version 330\n" "#extension GL_ARB_gpu_shader5 : enable\n" "layout(triangles, invocations = 7) in;" "layout(triangle_strip, max_vertices = 21) out;" "uniform mat4 ProjectionMatrix, CameraMatrix;" "mat4 Matrix = ProjectionMatrix * CameraMatrix;" "uniform vec3 CameraPosition;" "in vec2 vertTexCoord[3];" "out gl_PerVertex {" " vec4 gl_Position;" " float gl_ClipDistance[3];" "};" "flat out mat3 geomPositionFront;" "flat out mat3 geomTexCoordFront;" "flat out vec3 geomWFront;" "noperspective out vec3 geomBarycentric;" "out vec3 geomPosition;" "out vec3 geomTexCoord;" "void main(void)" "{" " vec4 world_pos[8*3];" " vec3 tex_coord[8*3];" " vec4 view_pos[8*3];" " vec3 screen_pos[8*3];" " bool front_facing[8];" " int ft = gl_InvocationID+1;" " for(int pass=0; pass!=2; ++pass)" " {" " bool first = pass == 0;" " if(((ft == 0) && first) || (((ft != 0) && !first)))" " {" " for(int v=0; v!=3; ++v)" " {" " int w = 2-v;" " world_pos[0+v] = gl_in[w].gl_Position;" " tex_coord[0+v] = vec3(vertTexCoord[w], 0.0);" " }" " }" " vec4 n = vec4(-0.15 * normalize(cross(" " gl_in[1].gl_Position.xyz-gl_in[0].gl_Position.xyz," " gl_in[2].gl_Position.xyz-gl_in[0].gl_Position.xyz " " )), 0.0);" " if(((ft == 1) && first) || (((ft != 1) && !first)))" " {" " for(int v=0; v!=3; ++v)" " {" " world_pos[3+v] = gl_in[v].gl_Position + n;" " tex_coord[3+v] = vec3(vertTexCoord[v], 1.0);" " }" " }" " for(int v=0; v!=3; ++v)" " {" " int w = (v+1)%3;" " int k = 2+2*v;" " if(((ft == k) && first) || (((ft != k) && !first)))" " {" " world_pos[6+0+v*6] = gl_in[v].gl_Position;" " tex_coord[6+0+v*6] = vec3(vertTexCoord[v], 0.0);" " world_pos[6+1+v*6] = gl_in[w].gl_Position;" " tex_coord[6+1+v*6] = vec3(vertTexCoord[w], 0.0);" " world_pos[6+2+v*6] = gl_in[v].gl_Position + n;" " tex_coord[6+2+v*6] = vec3(vertTexCoord[v], 1.0);" " }" " k = 3+2*v;" " if(((ft == k) && first) || (((ft != k) && !first)))" " {" " world_pos[6+3+v*6] = gl_in[w].gl_Position;" " tex_coord[6+3+v*6] = vec3(vertTexCoord[w], 0.0);" " world_pos[6+4+v*6] = gl_in[w].gl_Position + n;" " tex_coord[6+4+v*6] = vec3(vertTexCoord[w], 1.0);" " world_pos[6+5+v*6] = gl_in[v].gl_Position + n;" " tex_coord[6+5+v*6] = vec3(vertTexCoord[v], 1.0);" " }" " }" " for(int t=first?ft:0; t!=8; ++t)" " {" " if(!first && (t == ft)) continue;" " int o = t*3;" " for(int v=0; v!=3; ++v)" " {" " int w = o+v;" " view_pos[w] = Matrix * world_pos[w];" " screen_pos[w] = view_pos[w].xyz/view_pos[w].w;" " }" " front_facing[t] = cross(" " screen_pos[o+1]-screen_pos[o+0]," " screen_pos[o+2]-screen_pos[o+0] " " ).z < 0.0;" " if(first) break;" " }" " if(first && !front_facing[ft]) return;" " }" " int o = ft*3;" " vec4 clip_plane[3];" " for(int v=0; v!=3; ++v)" " {" " int w = (v+1)%3;" " vec3 p0 = world_pos[o+v].xyz;" " vec3 p1 = world_pos[o+w].xyz;" " vec3 p2 = CameraPosition;" " vec3 pv = normalize(cross(p1-p0, p2-p0));" " clip_plane[v] = vec4(pv, -dot(pv, p0));" " }" " vec3 lo = CameraPosition;" " vec3 p0 = world_pos[o+0].xyz;" " vec3 pu = world_pos[o+1].xyz-p0;" " vec3 pv = world_pos[o+2].xyz-p0;" " vec3 lp = lo-p0;" " float w0 = view_pos[o+0].w;" " float wu = view_pos[o+1].w-w0;" " float wv = view_pos[o+2].w-w0;" " vec3 t0 = tex_coord[o+0];" " vec3 tu = tex_coord[o+1]-t0;" " vec3 tv = tex_coord[o+2]-t0;" " for(int bt=0; bt!=8; ++bt)" " {" " int k = bt*3;" " if((ft != bt) && !front_facing[bt])" " {" " for(int v=0; v!=3; ++v)" " {" " vec3 lt = world_pos[k+v].xyz;" " mat3 im = mat3(lo-lt, pu, pv);" " vec3 ic = inverse(im)*lp;" " float s = ic.y;" " float t = ic.z;" " geomPositionFront[v] = p0+pu*s+pv*t;" " geomTexCoordFront[v] = t0+tu*s+tv*t;" " geomWFront[v] = w0+wu*s+wv*t;" " }" " for(int v=0; v!=3; ++v)" " {" " int w = k+v;" " gl_Position = view_pos[w];" " for(int c=0; c!=3; ++c)" " {" " gl_ClipDistance[c] = dot(" " clip_plane[c]," " world_pos[w]" " );" " }" " geomPosition = world_pos[w].xyz;" " geomTexCoord = tex_coord[w];" " geomBarycentric = vec3(0.0);" " geomBarycentric[v] = 1.0;" " EmitVertex();" " }" " EndPrimitive();" " }" " }" "}" )).Compile(); prog.AttachShader(gs); FragmentShader fs; fs.Source(StrLit( "#version 330\n" "uniform float Time;" "uniform sampler2D ColorMap;" "uniform sampler2D BumpMap;" "uniform vec3 LightPosition;" "flat in mat3 geomPositionFront;" "flat in mat3 geomTexCoordFront;" "flat in vec3 geomWFront;" "noperspective in vec3 geomBarycentric;" "in vec3 geomPosition;" "in vec3 geomTexCoord;" "out vec3 fragColor;" "vec3 vcdiv(vec3 a, vec3 b)" "{" " return vec3(a.x/b.x, a.y/b.y, a.z/b.z);" "}" "void main(void)" "{" " const vec3 one = vec3(1.0, 1.0, 1.0);" " vec3 bzfv = vcdiv(geomBarycentric,geomWFront);" " vec3 p0 = geomPosition;" " vec3 p1 = (geomPositionFront*bzfv)/dot(one,bzfv);" " vec3 tc0 = geomTexCoord;" " vec3 tc1 = (geomTexCoordFront*bzfv)/dot(one,bzfv);" " ivec2 ts = textureSize(BumpMap, 0);" " int mts = max(ts.x, ts.y);" " vec2 dtc = tc1.xy - tc0.xy;" " float mdtc = max(abs(dtc.x), abs(dtc.y));" " int nsam = max(min(int(mdtc*mts), mts/2), 1);" " float step = 1.0 / nsam;" " for(int s=0; s<=nsam; ++s)" " {" " vec3 tc = mix(tc1, tc0, s*step);" " vec4 bm = texture(BumpMap, tc.xy);" " if(tc.z <= bm.w)" " {" " vec3 p = mix(p1, p0, s*step);" " vec3 ldir = normalize(LightPosition - p);" " float l = max(dot(ldir, bm.xzy), 0.0)*1.3;" " fragColor = texture(ColorMap, tc.xy).rgb*l;" " return;" " }" " }" " discard;" "}" )).Compile(); prog.AttachShader(fs); prog.Link(); prog.Use(); shape.UseInProgram(prog); auto tex_image = images::LoadTexture("stones_color_hmap"); Texture::Active(0); try { UniformSampler(prog, "ColorMap").Set(0); auto bound_tex = Bind(color_tex, Texture::Target::_2D); bound_tex.Image2D(tex_image); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } catch(Error&){ } Texture::Active(1); try { UniformSampler(prog, "BumpMap").Set(1); auto bound_tex = Bind(bump_tex, Texture::Target::_2D); bound_tex.Image2D( images::NormalMap( tex_image, images::NormalMap::FromAlpha() ) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::Repeat); bound_tex.WrapT(TextureWrap::Repeat); } catch(Error&){ } gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Disable(Capability::CullFace); gl.Enable(Functionality::ClipDistance, 0); gl.Enable(Functionality::ClipDistance, 1); gl.Enable(Functionality::ClipDistance, 2); }
CloudExample(const ExampleParams& params) : sphere_instr(make_sphere.Instructions()) , sphere_indices(make_sphere.Indices()) , samples(25 + params.quality*params.quality*100) , positions(make_positions()) , sizes(make_sizes()) , cloud_tex(positions.size()) , light_path(make_light_path_cps()) { assert(positions.size() == sizes.size()); std::srand(123456); light_vs.Source( "#version 330\n" "in vec3 Position;" "uniform vec3 LightPos;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "void main(void)" "{" " float s = 0.1;" " gl_Position = " " ProjectionMatrix*" " CameraMatrix*" " vec4(Position*s + LightPos, 1.0);" "}" ).Compile(); light_fs.Source( "#version 330\n" "out vec4 fragLight;" "void main(void)" "{" " fragLight = vec4(1.0, 1.0, 1.0, 1.0);" "}" ).Compile(); light_prog << light_vs << light_fs; light_prog.Link().Use(); light.Bind(); buffer.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_sphere.Positions(data); Buffer::Data(Buffer::Target::Array, data); (light_prog|"Position").Setup(n_per_vertex, DataType::Float).Enable(); } cloud_vs.Source( "#version 330\n" "in vec4 Position;" "in float Size;" "uniform int SampleCount;" "uniform mat4 CameraMatrix;" "uniform vec4 ViewZ;" "out float vertZOffs;" "out float vertSize;" "void main(void)" "{" " float hp = (SampleCount-1) * 0.5;" " vertZOffs = (gl_InstanceID - hp)/hp;" " vertSize = Size;" " gl_Position = vec4(" " Position.xyz +" " ViewZ.xyz*vertZOffs*Size*0.5," " 1.0" " );" "}" ).Compile(); cloud_gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "in float vertZOffs[];" "in float vertSize[];" "uniform vec3 LightPos;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec4 ViewX, ViewY, ViewZ;" "out vec3 geomTexCoord;" "out vec3 geomLightDir;" "void main(void)" "{" " float zo = vertZOffs[0];" " float s = vertSize[0];" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " vec4 v = vec4(" " gl_in[0].gl_Position.xyz+" " ViewX.xyz * xo[i] * s * 0.5+" " ViewY.xyz * yo[j] * s * 0.5," " 1.0" " );" " gl_Position = ProjectionMatrix * CameraMatrix * v;" " geomLightDir = LightPos - v.xyz;" " geomTexCoord = " " vec3(0.5, 0.5, 0.5)+" " ViewX.xyz*(xo[i])*0.707+" " ViewY.xyz*(yo[j])*0.707+" " ViewZ.xyz*(zo )*0.707;" " EmitVertex();" " }" " EndPrimitive();" "}" ).Compile(); cloud_fs.Source( "#version 330\n" "uniform sampler3D CloudTex;" "in vec3 geomTexCoord;" "in vec3 geomLightDir;" "out vec4 fragColor;" "void main(void)" "{" " float d = texture(CloudTex, geomTexCoord).r;" " float o = 1.0;" " float s = 2.0/128.0;" " float r = s * 8.0;" " vec3 sampleOffs = normalize(geomLightDir) * s;" " vec3 samplePos = geomTexCoord;" " if(d > 0.01) while(o > 0.0)" " {" " if(samplePos.x<0.0 || samplePos.x>1.0)" " break;" " if(samplePos.y<0.0 || samplePos.y>1.0)" " break;" " if(samplePos.z<0.0 || samplePos.z>1.0)" " break;" " o -= texture(CloudTex, samplePos).r*r;" " samplePos += sampleOffs;" " }" " float a = 0.4 * d;" " float i = mix(0.2, 1.0, o);" " fragColor = vec4(i, i, i, a);" "}" ).Compile(); cloud_prog << cloud_vs << cloud_gs << cloud_fs; cloud_prog.Link().Use(); // bind the VAO for the clouds clouds.Bind(); // bind the VBO for the cloud positions pos_buffer.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, positions); (cloud_prog|"Position").Setup(3, DataType::Float).Enable(); } // bind the VBO for the cloud sizes size_buffer.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, sizes); (cloud_prog|"Size").Setup(1, DataType::Float).Enable(); } // set the number of samples cloud_prog/"SampleCount" = GLint(samples); Texture::Active(0); cloud_prog/"CloudTex" = 0; for(std::size_t i=0, n=positions.size(); i!=n; ++i) { auto bound_tex = Bind(cloud_tex[i], Texture::Target::_3D); bound_tex.Image3D( images::Cloud( 128, 128, 128, Vec3f(0.1f, -0.5f, 0.3f), 0.5f ) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.BorderColor(Vec4f(0.0f, 0.0f, 0.0f, 0.0f)); bound_tex.WrapS(TextureWrap::ClampToBorder); bound_tex.WrapT(TextureWrap::ClampToBorder); bound_tex.WrapR(TextureWrap::ClampToBorder); } gl.ClearColor(0.0f, 0.1f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.Disable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
WavesExample(void) : make_plane( Vec3f( 0.0f, 0.0f, 0.0f), Vec3f(100.0f, 0.0f, 0.0f), Vec3f( 0.0f, 0.0f,-100.0f), 50, 50 ), plane_instr(make_plane.PatchInstructions()) , plane_indices(make_plane.PatchIndices()) , camera_matrix(prog, "CameraMatrix") , camera_position(prog, "CameraPosition") , anim_time(prog, "Time") , prev_period(-1) { VertexShader vs(ObjectDesc("Vertex")); vs.Source(StrLit( "#version 410\n" "uniform vec3 CameraPosition;" "in vec3 Position;" "out vec3 vertPosition;" "out float vertDistance;" "void main(void)" "{" " vertPosition = Position;" " vertDistance = distance(CameraPosition, Position);" "}" )); vs.Compile(); prog.AttachShader(vs); TessControlShader cs(ObjectDesc("TessControl")); cs.Source( "#version 410\n" "layout(vertices = 3) out;" "in vec3 vertPosition[];" "in float vertDistance[];" "out vec3 tecoPosition[];" "int tessLevel(float dist)" "{" " return clamp(int(150.0 / (dist+0.1)), 1, 10);" "}" "void main(void)" "{" " tecoPosition[gl_InvocationID] =" " vertPosition[gl_InvocationID];" " if(gl_InvocationID == 0)" " {" " gl_TessLevelInner[0] = tessLevel((" " vertDistance[0]+" " vertDistance[1]+" " vertDistance[2] " " )*0.333);" " gl_TessLevelOuter[0] = tessLevel((" " vertDistance[1]+" " vertDistance[2] " " )*0.5);" " gl_TessLevelOuter[1] = tessLevel((" " vertDistance[2]+" " vertDistance[0] " " )*0.5);" " gl_TessLevelOuter[2] = tessLevel((" " vertDistance[0]+" " vertDistance[1] " " )*0.5);" " }" "}" ); cs.Compile(); prog.AttachShader(cs); TessEvaluationShader es(ObjectDesc("TessEvaluation")); es.Source( "#version 410\n" "#define MaxWaves 5\n" "layout(triangles, equal_spacing, ccw) in;" "uniform mat4 ProjectionMatrix, CameraMatrix;" "uniform vec3 LightPosition;" "uniform vec3 CameraPosition;" "uniform float Time;" "uniform int WaveCount;" "uniform vec3 WaveDirections[MaxWaves];" "uniform vec3 WaveDimensions[MaxWaves];" "in vec3 tecoPosition[];" "out vec3 teevNormal;" "out vec3 teevLightDir;" "out vec3 teevViewDir;" "out float teevDistance;" "void main(void)" "{" " const vec3 Up = vec3(0.0, 1.0, 0.0);" " vec3 Position =" " gl_TessCoord.x * tecoPosition[0]+" " gl_TessCoord.y * tecoPosition[1]+" " gl_TessCoord.z * tecoPosition[2];" " vec3 Pos = Position;" " vec3 Nml = Up;" " for(int w=0; w!=WaveCount; ++w)" " {" " vec3 Dir = WaveDirections[w];" " vec3 Dim = WaveDimensions[w];" " float Dist = dot(Position, Dir);" " float u = Dim.y*sin(Dist/Dim.x + Time*Dim.z);" " Pos += Up * u;" " float w = (Dim.y/Dim.x)*cos(Dist/Dim.x + Time*Dim.z);" " Nml -= Dir * w;" " float d = -0.125*Dim.x*sin(2.0*Dist/Dim.x + Time*Dim.z);" " Pos += Dir * d;" " }" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(Pos, 1.0);" " teevNormal = normalize(Nml);" " teevLightDir = normalize(LightPosition - Pos);" " teevViewDir = normalize(CameraPosition - Pos);" " teevDistance = distance(CameraPosition, Pos);" "}" ); es.Compile(); prog.AttachShader(es); FragmentShader fs(ObjectDesc("Fragment")); fs.Source(StrLit( "#version 410\n" "uniform samplerCube EnvMap;" "in vec3 teevNormal;" "in vec3 teevLightDir;" "in vec3 teevViewDir;" "in float teevDistance;" "out vec3 fragColor;" "void main(void)" "{" " float Dim = clamp(30.0/teevDistance, 0.0, 1.0);" " float LightRefl = dot(reflect(-teevLightDir, teevNormal), teevViewDir);" " float LightHit = dot(teevNormal, teevLightDir);" " float Diffuse = clamp(LightHit+0.1, 0.0, 1.0);" " float Specular = pow(clamp(LightRefl, 0.0, 0.91), 32);" " vec3 Environ=texture(EnvMap,reflect(-teevViewDir, teevNormal)).rgb;" " vec3 WaterColor = vec3(0.4, 0.5, 0.5);" " vec3 LightColor = vec3(1.0, 1.0, 1.0);" " vec3 FogColor = vec3(0.9, 0.9, 0.9);" " vec3 WaveColor =" " LightColor*Specular+" " WaterColor*Diffuse+" " Environ*0.02;" " fragColor = mix(WaveColor, FogColor, 1.0-Dim);" "}" )); fs.Compile(); prog.AttachShader(fs); prog.Link(); prog.Use(); plane.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_plane.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } Uniform<Vec3f>(prog, "LightPosition").Set(-100.0, 100.0, 20.0); Uniform<Vec3f> wave_directions(prog, "WaveDirections"); Uniform<Vec3f> wave_dimensions(prog, "WaveDimensions"); Uniform<GLint>(prog, "WaveCount").Set(5); wave_directions[0] = Normalized(Vec3f(1.0f, 0.0f, 1.0f)); wave_dimensions[0] = Vec3f(5.0f, 1.5f, 1.2f); wave_directions[1] = Normalized(Vec3f(1.0f, 0.0f, 0.5f)); wave_dimensions[1] = Vec3f(4.0f, 0.8f, 1.2f); wave_directions[2] = Normalized(Vec3f(1.0f, 0.0f, 0.1f)); wave_dimensions[2] = Vec3f(2.0f, 0.5f, 2.4f); wave_directions[3] = Normalized(Vec3f(1.0f, 0.0f,-0.1f)); wave_dimensions[3] = Vec3f(1.5f, 0.2f, 3.7f); wave_directions[4] = Normalized(Vec3f(1.0f, 0.0f, 0.4f)); wave_dimensions[4] = Vec3f(1.1f, 0.2f, 4.7f); Texture::Active(0); { auto image = images::Squares(512, 512, 0.9f, 16, 16); auto bound_tex = Bind(env_map, Texture::Target::CubeMap); for(int i=0; i!=6; ++i) Texture::Image2D(Texture::CubeMapFace(i), image); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); bound_tex.SwizzleG(TextureSwizzle::Red); bound_tex.SwizzleB(TextureSwizzle::Red); } UniformSampler(prog, "EnvMap").Set(0); gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); }
ShadowVolExample(const ExampleParams& params) : shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , shape_vs(ShaderType::Vertex, ObjectDesc("Shape vertex")) , depth_vs(ShaderType::Vertex, ObjectDesc("Depth vertex")) , light_vs(ShaderType::Vertex, ObjectDesc("Light vertex")) , depth_gs(ShaderType::Geometry, ObjectDesc("Depth geometry")) , light_gs(ShaderType::Geometry, ObjectDesc("Light geometry")) , shape_fs(ShaderType::Fragment, ObjectDesc("Shape fragment")) , depth_fs(ShaderType::Fragment, ObjectDesc("Depthfragment")) , light_fs(ShaderType::Fragment, ObjectDesc("Light fragment")) , shape_prog(ObjectDesc("Shape")) , depth_prog(ObjectDesc("Depth")) , light_prog(ObjectDesc("Light")) , tex_side(128) , sample_count(params.HighQuality()?1024:128) { shape_vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "out vec3 vertViewDir;" "out vec3 vertViewRefl;" "uniform vec3 LightPos;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLightDir = LightPos - gl_Position.xyz;" " vertLightRefl = reflect(" " -normalize(vertLightDir)," " normalize(vertNormal)" " );" " vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)* CameraMatrix).xyz;" " vertViewRefl = reflect(" " normalize(vertViewDir)," " normalize(vertNormal)" " );" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); shape_vs.Compile(); shape_fs.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec3 vertViewRefl;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(vertLightDir);" " float d = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / l;" " float s = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 ambi = vec3(0.6, 0.3, 0.5);" " vec3 diff = vec3(0.9, 0.7, 0.8);" " vec3 spec = vec3(1.0, 0.9, 0.95);" " fragColor = vec4(" " ambi * 0.3 + " " diff * 0.7 * max(d, 0.0) + " " spec * pow(max(s, 0.0), 64), " " 1.0" " );" "}" ); shape_fs.Compile(); shape_prog.AttachShader(shape_vs); shape_prog.AttachShader(shape_fs); shape_prog.Link(); depth_vs.Source( "#version 330\n" "uniform mat4 ModelMatrix;" "uniform vec3 LightPos;" "in vec4 Position;" "void main(void)" "{" " gl_Position = " " mat4(" " 1.0, 0.0, 0.0, -LightPos.x," " 0.0, 1.0, 0.0, -LightPos.y," " 0.0, 0.0, 1.0, -LightPos.z," " 0.0, 0.0, 0.0, 1.0" " )*" " ModelMatrix *" " mat4(" " 10.0, 0.0, 0.0, 0.0," " 0.0, 10.0, 0.0, 0.0," " 0.0, 0.0, 10.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " )*" " Position;" "}" ); depth_vs.Compile(); depth_gs.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 18) out;" "uniform mat4 ProjectionMatrix;" "const mat4 CubeFaceMatrix[6] = mat4[6](" " mat4(" " 0.0, 0.0, -1.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " -1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " 0.0, 0.0, 1.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " 1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " 1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, -1.0, 0.0," " 0.0, 1.0, 0.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " 1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, 1.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " 1.0, 0.0, 0.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " 0.0, 0.0, -1.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " -1.0, 0.0, 0.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " 0.0, 0.0, 1.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " )" ");" "void main(void)" "{" " for(gl_Layer=0; gl_Layer!=6; ++gl_Layer)" " {" " for(int i=0; i!=3; ++i)" " {" " gl_Position = " " ProjectionMatrix *" " CubeFaceMatrix[gl_Layer]*" " gl_in[i].gl_Position;" " EmitVertex();" " }" " EndPrimitive();" " }" "}" ); depth_gs.Compile(); depth_fs.Source( "#version 330\n" "void main(void)" "{" " gl_FragDepth = gl_FragCoord.z;" "}" ); depth_fs.Compile(); depth_prog.AttachShader(depth_vs); depth_prog.AttachShader(depth_gs); depth_prog.AttachShader(depth_fs); depth_prog.Link(); depth_prog.Use(); Uniform<Mat4f>(depth_prog, "ProjectionMatrix").Set( CamMatrixf::PerspectiveX( RightAngles(1.0), 1.0, 0.1, 10.0 ) ); // bind the VAO for the shape shape.Bind(); shape_positions.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribSlot location; if(VertexAttribArray::QueryCommonLocation( "Position", location, shape_prog, depth_prog )) { VertexAttribArray shape_attr(location); shape_attr.Setup(n_per_vertex, DataType::Float); shape_attr.Enable(); } else assert(!"Inconsistent 'Position' location"); } shape_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); shape_prog.Use(); VertexAttribArray attr(shape_prog, "Normal"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } light_vs.Source( "#version 330\n" "in vec3 Position;" "out float vertZOffs;" "uniform vec3 LightPos;" "uniform int SampleCount;" "void main(void)" "{" " float hp = (SampleCount-1) * 0.5;" " vertZOffs = (gl_InstanceID - hp)/hp;" " gl_Position = vec4(Position + LightPos, 1.0);" "}" ); light_vs.Compile(); light_gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "in float vertZOffs[];" "out vec4 geomPosition;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 ViewX, ViewY, ViewZ;" "uniform float LightVolSize;" "void main(void)" "{" " float zo = vertZOffs[0];" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " geomPosition = vec4(" " gl_in[0].gl_Position.xyz+" " ViewX * xo[i] * LightVolSize+" " ViewY * yo[j] * LightVolSize+" " ViewZ * zo * LightVolSize," " 1.0" " );" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " geomPosition;" " EmitVertex();" " }" " EndPrimitive();" "}" ); light_gs.Compile(); light_fs.Source( "#version 330\n" "in vec4 geomPosition;" "out vec4 fragColor;" "uniform samplerCubeShadow ShadowMap;" "uniform int SampleCount;" "uniform vec3 LightPos;" "void main(void)" "{" " vec3 LightDir = geomPosition.xyz - LightPos;" " vec4 ShadowCoord = vec4(" " normalize(LightDir)," " length(LightDir)" " );" " float s = texture(ShadowMap, ShadowCoord);" " float alpha = s / (SampleCount * pow(length(LightDir), 2));" " fragColor = vec4(1.0, 1.0, 1.0, alpha);" "}" ); light_fs.Compile(); light_prog.AttachShader(light_vs); light_prog.AttachShader(light_gs); light_prog.AttachShader(light_fs); light_prog.Link(); light_prog.Use(); // bind the VAO for the light volume light.Bind(); // bind the VBO for the light volume plane positions light_positions.Bind(Buffer::Target::Array); { GLfloat position[3] = {0.0, 0.0, 0.0}; Buffer::Data(Buffer::Target::Array, 3, position); VertexAttribArray attr(light_prog, "Position"); attr.Setup(3, DataType::Float); attr.Enable(); } Uniform<GLint>(light_prog, "SampleCount").Set(sample_count); Uniform<GLfloat>(light_prog, "LightVolSize").Set(4); UniformSampler(light_prog, "ShadowMap").Set(0); // Setup the texture and the offscreen FBO Texture::Active(0); { auto bound_tex = Bind(depth_tex, Texture::Target::CubeMap); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); bound_tex.CompareFunc(CompareFunction::LEqual); bound_tex.CompareMode( TextureCompareMode::CompareRefToTexture ); for(int i=0; i!=6; ++i) { Texture::Image2D( Texture::CubeMapFace(i), 0, PixelDataInternalFormat::DepthComponent, tex_side, tex_side, 0, PixelDataFormat::DepthComponent, PixelDataType::Float, nullptr ); } auto bound_fbo = Bind( depth_fbo, Framebuffer::Target::Draw ); bound_fbo.AttachTexture( FramebufferAttachment::Depth, depth_tex, 0 ); } // gl.ClearColor(0.2f, 0.05f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_shape.FaceWinding()); gl.CullFace(Face::Back); gl.BlendFunc(BlendFunction::SrcAlpha, BlendFunction::One); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , light_pos(prog, "LightPos") { namespace se = oglplus::smart_enums; // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec3 Tangent;" "in vec2 TexCoord;" "out vec3 vertLight;" "out vec2 vertTexCoord;" "out mat3 NormalMatrix;" "uniform vec3 LightPos;" "void main(void)" "{" " vec3 fragNormal = mat3(ModelMatrix) * Normal;" " vec3 fragTangent = mat3(ModelMatrix) * Tangent;" " NormalMatrix[0] = fragTangent;" " NormalMatrix[1] = cross(fragNormal, fragTangent);" " NormalMatrix[2] = fragNormal;" " gl_Position = ModelMatrix * Position;" " vertLight = LightPos - gl_Position.xyz;" " vertTexCoord = TexCoord;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler2D ColorTex, NormalTex;" "in mat3 NormalMatrix;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float l = dot(vertLight, vertLight);" " vec3 n = texture(NormalTex, vertTexCoord).xyz;" " vec3 finalNormal = NormalMatrix * n;" " float d = (l > 0.0) ? dot(" " normalize(vertLight), " " finalNormal" " ) / l : 0.0;" " float i = 0.2 + 4.5*max(d, 0.0);" " vec4 t = texture(ColorTex, vertTexCoord);" " fragColor = vec4(t.rgb*i, 1.0);" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the cube cube.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(se::Array(), data); VertexAttribArray attr(prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(se::Array(), data); VertexAttribArray attr(prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } tangents.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Tangents(data); Buffer::Data(se::Array(), data); VertexAttribArray attr(prog, "Tangent"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(se::Array(), data); VertexAttribArray attr(prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // setup the textures { Texture::Active(0); UniformSampler(prog, "ColorTex").Set(0); auto bound_tex = Bind(colorTex, se::_2D()); bound_tex.Image2D(images::LoadTexture("wooden_crate")); bound_tex.GenerateMipmap(); bound_tex.MinFilter(se::LinearMipmapLinear()); bound_tex.MagFilter(se::Linear()); bound_tex.WrapS(se::Repeat()); bound_tex.WrapT(se::Repeat()); } { Texture::Active(1); UniformSampler(prog, "NormalTex").Set(1); auto bound_tex = Bind(normalTex, se::_2D()); bound_tex.Image2D( images::NormalMap( images::LoadTexture("wooden_crate-hmap"), images::NormalMap::FromRed() ) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(se::LinearMipmapLinear()); bound_tex.MagFilter(se::Linear()); bound_tex.WrapS(se::Repeat()); bound_tex.WrapT(se::Repeat()); } // gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(se::DepthTest()); gl.Enable(se::CullFace()); gl.FrontFace(make_cube.FaceWinding()); }
CloudExample(void) : projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") { // Set the vertex shader source vs.Source( "#version 330\n" "in vec4 Position;" "uniform mat4 CameraMatrix;" "void main(void)" "{" " gl_Position = " " CameraMatrix *" " Position;" "}" ); // compile it vs.Compile(); // Set the geometry shader source gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 100) out;" "const int p = 25;" "const float hp = (p-1)*0.5;" "uniform vec3 LightPos;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "out vec3 geomTexCoord;" "out vec3 geomLightDir;" "void main(void)" "{" " float s = 0.6;" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " vec3 cx = vec3(" " CameraMatrix[0][0]," " CameraMatrix[1][0]," " CameraMatrix[2][0] " " );" " vec3 cy = vec3(" " CameraMatrix[0][1]," " CameraMatrix[1][1]," " CameraMatrix[2][1] " " );" " vec3 cz = vec3(" " CameraMatrix[0][2]," " CameraMatrix[1][2]," " CameraMatrix[2][2] " " );" " for(int k=0;k!=p;++k)" " {" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " float zo = ((k - hp) / hp);" " float xoffs = xo[i]*s;" " float yoffs = yo[j]*s;" " float zoffs = zo *s;" " vec4 v = vec4(" " gl_in[0].gl_Position.x+xoffs," " gl_in[0].gl_Position.y+yoffs," " gl_in[0].gl_Position.z+zoffs," " 1.0" " );" " gl_Position = ProjectionMatrix * v;" " geomLightDir = LightPos - v.xyz;" " geomTexCoord = " " vec3(0.5, 0.5, 0.5)+" " cx*(xo[i])*0.707+" " cy*(yo[j])*0.707+" " cz*(zo )*0.707;" " EmitVertex();" " }" " EndPrimitive();" " }" "}" ); // compile it gs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler3D cloudTex;" "in vec3 geomTexCoord;" "in vec3 geomLightDir;" "out vec4 fragColor;" "void main(void)" "{" " float d = texture(cloudTex, geomTexCoord).r;" " float o = 1.0;" " float s = 2.0/128.0;" " float r = s * 8.0;" " vec3 sampleOffs = normalize(geomLightDir) * s;" " vec3 samplePos = geomTexCoord;" " if(d > 0.01) while(o > 0.0)" " {" " if(samplePos.x<0.0 || samplePos.x>1.0)" " break;" " if(samplePos.y<0.0 || samplePos.y>1.0)" " break;" " if(samplePos.z<0.0 || samplePos.z>1.0)" " break;" " o -= texture(cloudTex, samplePos).r*r;" " samplePos += sampleOffs;" " }" " float a = 0.2 * d;" " float i = mix(0.4, 1.0, o);" " fragColor = vec4(i, i, i, a);" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(gs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the clouds clouds.Bind(); // bind the VBO for the cloud positions buffer.Bind(Buffer::Target::Array); { GLfloat positions[3] = {0.5f, 0.1f, 0.2f}; Buffer::Data(Buffer::Target::Array, 3, positions); VertexAttribArray attr(prog, "Position"); attr.Setup(3, DataType::Float); attr.Enable(); } { Texture::Active(0); UniformSampler(prog, "cloudTex").Set(0); auto bound_tex = Bind(cloud_tex, Texture::Target::_3D); bound_tex.Image3D(images::Cloud(128, 128, 128)); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.BorderColor(Vec4f(0.0f, 0.0f, 0.0f, 0.0f)); bound_tex.WrapS(TextureWrap::ClampToBorder); bound_tex.WrapT(TextureWrap::ClampToBorder); bound_tex.WrapR(TextureWrap::ClampToBorder); } Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(10.0f, 1.0f, 5.0f)); gl.ClearColor(0.2f, 0.3f, 0.4f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
SkyBoxExample(void) : prog() , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") { VertexShader vs; vs.Source(StrLit( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix;" "mat4 Matrix = ProjectionMatrix*CameraMatrix;" "in vec3 Corner;" "out vec3 vertTexCoord;" "void main(void)" "{" " gl_Position = Matrix * vec4(Corner * 10.0, 1.0);" " vertTexCoord = Corner;" "}" )); vs.Compile(); prog.AttachShader(vs); FragmentShader fs; fs.Source(StrLit( "#version 330\n" "uniform samplerCube EnvMap;" "in vec3 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(texture(EnvMap, normalize(vertTexCoord)).rgb, 1.0);" "}" )); fs.Compile(); prog.AttachShader(fs); prog.Link(); prog.Use(); sky_box.Bind(); GLfloat sky_box_corners[8*3] = { -1.0f,-1.0f,-1.0f, +1.0f,-1.0f,-1.0f, -1.0f,+1.0f,-1.0f, +1.0f,+1.0f,-1.0f, -1.0f,-1.0f,+1.0f, +1.0f,-1.0f,+1.0f, -1.0f,+1.0f,+1.0f, +1.0f,+1.0f,+1.0f }; corners.Bind(Buffer::Target::Array); Buffer::Data(Buffer::Target::Array, sky_box_corners); VertexAttribArray vert_attr(prog, "Corner"); vert_attr.Setup(3, DataType::Float).Enable(); GLuint sky_box_indices[6*5] = { 1, 3, 5, 7, 9, 4, 6, 0, 2, 9, 2, 6, 3, 7, 9, 4, 0, 5, 1, 9, 5, 7, 4, 6, 9, 0, 2, 1, 3, 9 }; indices.Bind(Buffer::Target::ElementArray); Buffer::Data(Buffer::Target::ElementArray, 6*5, sky_box_indices); gl.Enable(Capability::PrimitiveRestart); gl.PrimitiveRestartIndex(9); { UniformSampler(prog, "EnvMap").Set(0); Texture::Active(0); auto bound_tex = oglplus::Bind(env_map, Texture::Target::CubeMap); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); Texture::Image2D( Texture::CubeMapFace(0), images::LoadTexture("cloudy_day-cm_0", false, false) ); Texture::Image2D( Texture::CubeMapFace(1), images::LoadTexture("cloudy_day-cm_1", false, false) ); Texture::Image2D( Texture::CubeMapFace(2), images::LoadTexture("cloudy_day-cm_2", false, false) ); Texture::Image2D( Texture::CubeMapFace(3), images::LoadTexture("cloudy_day-cm_3", false, false) ); Texture::Image2D( Texture::CubeMapFace(4), images::LoadTexture("cloudy_day-cm_4", false, false) ); Texture::Image2D( Texture::CubeMapFace(5), images::LoadTexture("cloudy_day-cm_5", false, false) ); } gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.ClearDepth(1.0f); }
DOFExample(const ExampleParams& params) : face_instr(make_cube.Instructions()) , edge_instr(make_cube.EdgeInstructions()) , face_indices(make_cube.Indices()) , edge_indices(make_cube.EdgeIndices()) , cube_matrices(MakeCubeMatrices(100, 10.0)) , viewport_width(dof_prog, "ViewportWidth") , viewport_height(dof_prog, "ViewportHeight") , projection_matrix(main_prog, "ProjectionMatrix") , camera_matrix(main_prog, "CameraMatrix") , model_matrix(main_prog, "ModelMatrix") , ambient_color(main_prog, "AmbientColor") , diffuse_color(main_prog, "DiffuseColor") , focus_depth(dof_prog, "FocusDepth") , color_tex(Texture::Target::Rectangle) , depth_tex(Texture::Target::Rectangle) , width(800) , height(600) { main_vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec3 LightPos;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertLightDir;" "out vec3 vertNormal;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertLightDir = normalize(LightPos - gl_Position.xyz);" " vertNormal = normalize(mat3(ModelMatrix)*Normal);" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it main_vs.Compile(); // set the fragment shader source main_fs.Source( "#version 330\n" "uniform vec3 AmbientColor, DiffuseColor;" "in vec3 vertLightDir;" "in vec3 vertNormal;" "out vec4 fragColor;" "void main(void)" "{" " float d = max(dot(vertLightDir,vertNormal),0.0);" " float e = sin(" " 10.0*vertLightDir.x + " " 20.0*vertLightDir.y + " " 25.0*vertLightDir.z " " )*0.9;" " fragColor = vec4(" " mix(AmbientColor, DiffuseColor, d+e)," " 1.0" " );" "}" ); // compile it main_fs.Compile(); // attach the shaders to the program main_prog.AttachShader(main_vs); main_prog.AttachShader(main_fs); // link and use it main_prog.Link(); main_prog.Use(); // bind the VAO for the cube cube.Bind(); // bind the VBO for the cube vertices positions.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray attr(main_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // bind the VBO for the cube normals normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(main_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } Uniform<Vec3f>(main_prog, "LightPos").Set(30.0, 50.0, 20.0); dof_vs.Source( "#version 330\n" "uniform uint ViewportWidth, ViewportHeight;" "in vec4 Position;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = Position;" " vertTexCoord = vec2(" " (Position.x*0.5 + 0.5)*ViewportWidth," " (Position.y*0.5 + 0.5)*ViewportHeight" " );" "}" ); dof_vs.Compile(); dof_fs.Source( "#version 330\n" "uniform sampler2DRect ColorTex;" "uniform sampler2DRect DepthTex;" "uniform float FocusDepth;" "uniform uint SampleMult;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "const float strength = 16.0;" "void main(void)" "{" " float fragDepth = texture(DepthTex, vertTexCoord).r;" " vec3 color = texture(ColorTex, vertTexCoord).rgb;" " float of = abs(fragDepth - FocusDepth);" " int nsam = int(of*SampleMult);" " float inv_nsam = 1.0 / (1.0 + nsam);" " float astep = (3.14151*4.0)/nsam;" " for(int i=0; i!=nsam; ++i)" " {" " float a = i*astep;" " float d = sqrt(i*inv_nsam);" " float sx = cos(a)*of*strength*d;" " float sy = sin(a)*of*strength*d;" " vec2 samTexCoord = vertTexCoord + vec2(sx, sy) + noise2(vec2(sx, sy));" " color += texture(ColorTex, samTexCoord).rgb;" " }" " fragColor = vec4(color * inv_nsam , 1.0);" "}" ); dof_fs.Compile(); dof_prog.AttachShader(dof_vs); dof_prog.AttachShader(dof_fs); dof_prog.Link(); dof_prog.Use(); GLuint sample_mult = params.HighQuality()?512:128; Uniform<GLuint>(dof_prog, "SampleMult") = sample_mult; // bind the VAO for the screen screen.Bind(); corners.Bind(Buffer::Target::Array); { GLfloat screen_verts[8] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; Buffer::Data(Buffer::Target::Array, 8, screen_verts); VertexAttribArray attr(dof_prog, "Position"); attr.Setup<Vec2f>(); attr.Enable(); } Texture::Active(0); UniformSampler(dof_prog, "ColorTex").Set(0); { auto bound_tex = Bind(color_tex, Texture::Target::Rectangle); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.Image2D( 0, PixelDataInternalFormat::RGB, width, height, 0, PixelDataFormat::RGB, PixelDataType::UnsignedByte, nullptr ); } Texture::Active(1); UniformSampler(dof_prog, "DepthTex").Set(1); { auto bound_tex = Bind(depth_tex, Texture::Target::Rectangle); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.Image2D( 0, PixelDataInternalFormat::DepthComponent, width, height, 0, PixelDataFormat::DepthComponent, PixelDataType::Float, nullptr ); } { auto bound_fbo = Bind( fbo, Framebuffer::Target::Draw ); bound_fbo.AttachTexture( FramebufferAttachment::Color, color_tex, 0 ); bound_fbo.AttachTexture( FramebufferAttachment::Depth, depth_tex, 0 ); } // gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.DepthFunc(CompareFn::LEqual); gl.Enable(Capability::LineSmooth); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
SmokeExample(void) : emitters( { { { {-20.0f, -10.0f, 10.0f}, { 20.0f, 0.0f, -20.0f}, { 20.0f, 10.0f, 20.0f}, {-20.0f, 0.0f, -10.0f} }, 15.0, 200.0 }, { { { 30.0f, 0.0f, 5.0f}, {-30.0f, 0.0f, -5.0f}, {-20.0f, 20.0f, 5.0f}, { 20.0f, -10.0f, -5.0f} }, 17.0, 200.0 }, } ), vs(ShaderType::Vertex, "Vertex") , gs(ShaderType::Geometry, "Geometry") , fs(ShaderType::Fragment, "Fragment") , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , light_cam_pos(prog, "LightCamPos") { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 CameraMatrix;" "in vec4 Position;" "in float Age;" "in int Id;" "out float vertAge;" "out int vertId;" "void main(void)" "{" " gl_Position = CameraMatrix * Position;" " vertAge = Age;" " vertId = Id;" "}" ); // compile it vs.Compile(); // Set the geometry shader source gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "uniform vec3 LightCamPos;" "uniform mat4 ProjectionMatrix;" "in float vertAge[];" "in int vertId[];" "out vec2 geomTexCoord;" "out float geomAge;" "out float geomLightVal;" "out float geomLightBias;" "void main(void)" "{" " if(vertAge[0] > 1.0) return;" " vec3 pos = gl_in[0].gl_Position.xyz;" " vec3 lightDir = normalize(LightCamPos - pos);" " float s = 0.8, g = 3.0;" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " float angle = vertId[0];" " float cx = cos(angle), sx = sin(angle);" " mat2 rot = mat2(cx, sx, -sx, cx);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " float xoffs = xo[i]*(1.0+vertAge[0]*g)*s;" " float yoffs = yo[j]*(1.0+vertAge[0]*g)*s;" " vec2 offs = rot*vec2(xoffs, yoffs);" " gl_Position = ProjectionMatrix * vec4(" " pos.x-offs.x," " pos.y-offs.y," " pos.z," " 1.0" " );" " geomTexCoord = vec2(float(i), float(j));" " geomAge = vertAge[0];" " geomLightVal = lightDir.z;" " geomLightBias = -dot(" " normalize(vec3(offs, 0.0))," " lightDir" " );" " EmitVertex();" " }" " EndPrimitive();" "}" ); // compile it gs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler2D SmokeTex;" "in vec2 geomTexCoord;" "in float geomAge;" "in float geomLightVal;" "in float geomLightBias;" "out vec4 fragColor;" "void main(void)" "{" " vec3 c = texture(SmokeTex, geomTexCoord).rgb;" " float depth = c.g - c.r;" " if(depth == 0.0) discard;" " float density = min(depth * c.b * 2.0, 1.0);" " float intensity = min(" " max(" " geomLightVal*0.5+" " geomLightBias," " 0.0" " )+max(" " -geomLightVal*" " (1.0 - density)*" " geomLightBias * 5.0," " 0.0" " )," " 1.0" " ) + 0.1;" " fragColor = vec4(" " intensity," " intensity," " intensity," " (1.0 - geomAge)*density" " );" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(gs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the particles particles.Bind(); // bind the VBO for the particle positions pos_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, positions); VertexAttribArray attr(prog, "Position"); attr.Setup<Vec3f>(); attr.Enable(); } // bind the VBO for the particle ages age_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, ages); VertexAttribArray attr(prog, "Age"); attr.Setup<GLfloat>(); attr.Enable(); } // bind the VBO for the particle identifiers id_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, ids); VertexAttribArray attr(prog, "Id"); attr.Setup<GLint>(); attr.Enable(); } Texture::Active(0); UniformSampler(prog, "SmokeTex").Set(0); { auto bound_tex = Bind(smoke_tex, Texture::Target::_2D); bound_tex.Image2D( images::Cloud2D( images::Cloud( 128, 128, 128, Vec3f(0.1f, -0.5f, 0.3f), 0.5f ) ) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.BorderColor(Vec4f(0.0f, 0.0f, 0.0f, 0.0f)); bound_tex.WrapS(TextureWrap::ClampToBorder); bound_tex.WrapT(TextureWrap::ClampToBorder); } // gl.ClearColor(0.0f, 0.1f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { namespace se = oglplus::smart_enums; VertexShader vs; vs.Source( "#version 120\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "attribute vec4 Position;" "attribute vec3 Normal;" "attribute vec2 TexCoord;" "varying vec3 vertNormal;" "varying vec3 vertLight;" "varying vec2 vertTexCoord;" "uniform vec3 LightPos;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " gl_Position = ModelMatrix * Position;" " vertLight = LightPos - gl_Position.xyz;" " vertTexCoord = TexCoord;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ).Compile(); FragmentShader fs; fs.Source( "#version 120\n" "uniform sampler2D TexUnit;" "varying vec3 vertNormal;" "varying vec3 vertLight;" "varying vec2 vertTexCoord;" "void main(void)" "{" " float l = length(vertLight);" " float d = l > 0 ? dot(vertNormal, normalize(vertLight)) / l : 0.0;" " float i = 0.3 + 2.0*max(d, 0.0);" " vec4 t = texture2D(TexUnit, vertTexCoord);" " gl_FragColor = vec4(t.rgb*i, 1.0);" "}" ).Compile(); prog.AttachShader(vs).AttachShader(fs).Link().Use(); // bind the VAO for the cube cube.Bind(); verts.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(se::Array(), data); (prog|"Position").Setup(n_per_vertex, se::Float()).Enable(); } normals.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(se::Array(), data); (prog|"Normal").Setup(n_per_vertex, se::Float()).Enable(); } texcoords.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(se::Array(), data); (prog|"TexCoord").Setup(n_per_vertex, se::Float()).Enable(); } // setup the texture { auto bound_tex = Bind(tex, se::_2D()); auto image = images::NewtonFractal( 512, 512, Vec3f(1.0f, 1.4f, 1.3f), Vec3f(0.2f, 0.3f, 0.1f), Vec2f(-1.0f, -1.0f), Vec2f( 1.0f, 1.0f), images::NewtonFractal::X4Minus1(), [](double x) -> double { return pow(SineWave(pow(x,0.5)), 4.0); } ); bound_tex.Image2D(image); bound_tex.GenerateMipmap(); bound_tex.MinFilter(se::LinearMipmapLinear()); bound_tex.MagFilter(se::Linear()); bound_tex.WrapS(se::Repeat()); bound_tex.WrapT(se::Repeat()); } // set the uniform values (prog/"TexUnit") = 0; (prog/"LightPos") = Vec3f(1.0f, 2.0f, 3.0f); // gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(se::DepthTest()); gl.Enable(se::CullFace()); gl.FrontFace(make_cube.FaceWinding()); }
MultiViewportExample(void) : make_shape(1.0, 0.1, 8, 4, 48) , shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , camera_position_3(prog, "CameraPosition[3]") , camera_matrix_0(prog, "CameraMatrix[0]") , camera_matrix_1(prog, "CameraMatrix[1]") , camera_matrix_2(prog, "CameraMatrix[2]") , camera_matrix_3(prog, "CameraMatrix[3]") , model_matrix(prog, "ModelMatrix") { VertexShader vs; // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ModelMatrix;" "uniform vec3 LightPos;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertTexCoord;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " vertTexCoord = Normal;" " gl_Position = ModelMatrix * Position;" " vertLightDir = LightPos-gl_Position.xyz;" " vertLightRefl = reflect(-vertLightDir, vertNormal);" "}" ); vs.Compile(); GeometryShader gs; // Set the geometry shader source gs.Source( "#version 330\n" "#extension GL_ARB_viewport_array : enable\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 12) out;" "uniform mat4 CameraMatrix[4];" "uniform vec3 CameraPosition[4];" "in vec3 vertNormal[];" "in vec3 vertTexCoord[];" "in vec3 vertLightDir[];" "in vec3 vertLightRefl[];" "out vec3 geomNormal;" "out vec3 geomTexCoord;" "out vec3 geomLightDir;" "out vec3 geomLightRefl;" "out vec3 geomViewDir;" "out vec3 geomViewRefl;" "void main(void)" "{" " for(int vp=0; vp!=4; ++vp)" " {" " gl_ViewportIndex = vp;" " for(int v=0; v!=3; ++v)" " {" " geomNormal = vertNormal[v];" " geomTexCoord = vertTexCoord[v];" " geomLightDir = vertLightDir[v];" " geomLightRefl = vertLightRefl[v];" " geomViewDir = " " CameraPosition[vp] - " " gl_in[v].gl_Position.xyz;" " geomViewRefl = reflect(" " -geomViewDir," " geomNormal" " );" " gl_Position = " " CameraMatrix[vp] *" " gl_in[v].gl_Position;" " EmitVertex();" " }" " EndPrimitive();" " }" "}" ); gs.Compile(); FragmentShader fs; // set the fragment shader source fs.Source( "#version 330\n" "uniform samplerCube TexUnit;" "in vec3 geomNormal;" "in vec3 geomTexCoord;" "in vec3 geomLightDir;" "in vec3 geomLightRefl;" "in vec3 geomViewDir;" "in vec3 geomViewRefl;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(geomLightDir);" " float d = dot(" " normalize(geomNormal), " " normalize(geomLightDir)" " ) / l;" " float s = dot(" " normalize(geomLightRefl)," " normalize(geomViewDir)" " );" " vec3 lt = vec3(1.0, 1.0, 1.0);" " vec3 tex = texture(TexUnit, geomTexCoord).rgb;" " fragColor = vec4(" " tex * 0.4 + " " (lt + tex) * 1.5 * max(d, 0.0) + " " lt * pow(max(s, 0.0), 64), " " 1.0" " );" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(gs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the shape shape.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // setup the texture { GLuint tex_side = 512; auto image = images::NewtonFractal( tex_side, tex_side, Vec3f(0.8f, 0.8f, 1.0f), Vec3f(0.1f, 0.0f, 0.2f), Vec2f(-0.707f, -0.707f), Vec2f( 0.707f, 0.707f), images::NewtonFractal::X4Minus1(), [](double x) -> double { return pow(SineWave(pow(x,0.5)), 4.0); } ); auto bound_tex = Bind(tex, Texture::Target::CubeMap); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); for(int i=0; i!=6; ++i) Texture::Image2D(Texture::CubeMapFace(i), image); } // UniformSampler(prog, "TexUnit").Set(0); Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(3.0f, 5.0f, 4.0f)); // gl.ClearColor(0.1f, 0.05f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_shape.FaceWinding()); gl.CullFace(Face::Back); Uniform<Vec3f> camera_position(prog, "CameraPosition"); camera_position[0].Set(Vec3f(2, 0, 0)); camera_position[1].Set(Vec3f(0, 2, 0)); camera_position[2].Set(Vec3f(0, 0, 2)); }
CubeMapExample(void) : make_shape(4) , shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "out vec3 vertNormal;" "out vec3 vertTexCoord;" "out vec3 vertLightDir;" "out vec3 vertViewDir;" "uniform vec3 LightPos;" "void main(void)" "{" " vec3 Normal = Position.xyz;" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertTexCoord = Normal;" " vertLightDir = LightPos - gl_Position.xyz;" " vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)*CameraMatrix).xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); vs.Compile(); gs.Source( "#version 330\n" "layout (triangles) in;" "layout (triangle_strip, max_vertices = 3) out;" "in vec3 vertNormal[3];" "in vec3 vertTexCoord[3];" "in vec3 vertLightDir[3];" "in vec3 vertViewDir[3];" "out vec3 geomNormal;" "out vec3 geomTexCoord;" "out vec3 geomLightDir;" "out vec3 geomLightRefl;" "out vec3 geomViewDir;" "void main(void)" "{" " vec3 FaceNormal = 0.333333*(" " vertNormal[0]+" " vertNormal[1]+" " vertNormal[2] " " );" " for(int v=0; v!=3; ++v)" " {" " gl_Position = gl_in[v].gl_Position;" " geomNormal = 0.5*(vertNormal[v]+FaceNormal);" " geomTexCoord = vertTexCoord[v];" " geomLightDir = vertLightDir[v];" " geomLightRefl = reflect(" " -normalize(geomLightDir)," " normalize(FaceNormal)" " );" " geomViewDir = vertViewDir[v];" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); fs.Source( "#version 330\n" "uniform samplerCube TexUnit;" "in vec3 geomNormal;" "in vec3 geomTexCoord;" "in vec3 geomLightDir;" "in vec3 geomLightRefl;" "in vec3 geomViewDir;" "out vec3 fragColor;" "void main(void)" "{" " vec3 lt = vec3(1.0, 1.0, 1.0);" " vec3 tex = texture(TexUnit, geomTexCoord).rgb;" " float d = dot(" " normalize(geomNormal), " " normalize(geomLightDir)" " );" " float s = dot(" " normalize(geomLightRefl)," " normalize(geomViewDir)" " );" " float b = 1.0-sqrt(max(dot(" " normalize(geomNormal)," " normalize(geomViewDir)" " ), 0.0));" " float ea = clamp(tex.b*(-d+0.2), 0.0, 1.0);" " float sr = 1.0-tex.b*0.8;" " fragColor = " " tex * (0.3*ea + 0.6*b + 0.8*max(d, 0.0)) + " " (tex+lt) * 0.8*sr*pow(clamp(s+0.05, 0.0, 1.0), 32);" "}" ); fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(gs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the shape shape.Bind(); positions.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // setup the texture { auto bound_tex = Bind(tex, Texture::Target::CubeMap); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); const char* tex_name[6] = { "cube_0_right", "cube_1_left", "cube_2_top", "cube_3_bottom", "cube_4_front", "cube_5_back" }; for(GLuint i=0; i!=6; ++i) { Texture::Image2D( Texture::CubeMapFace(i), images::LoadTexture(tex_name[i], false, true) ); } } UniformSampler(prog, "TexUnit").Set(0); // Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(3.0f, 5.0f, 4.0f)); // gl.ClearColor(0.05f, 0.2f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_shape.FaceWinding()); gl.CullFace(Face::Back); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertLight;" "out vec2 vertTexCoord;" "uniform vec3 LightPos;" "void main(void)" "{" " vertNormal = mat3(ModelMatrix)*Normal;" " gl_Position = ModelMatrix * Position;" " vertLight = LightPos - gl_Position.xyz;" " vertTexCoord = TexCoord * 6.0;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler2D TexUnit;" "in vec3 vertNormal;" "in vec3 vertLight;" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float l = dot(vertLight, vertLight);" " float d = l != 0.0 ? dot(" " vertNormal, " " normalize(vertLight)" " ) / l : 0.0;" " vec3 c = vec3(0.9, 0.8, 0.2);" " vec4 t = texture(TexUnit, vertTexCoord);" " float a = 1.0 - sqrt(abs(d)), e;" " if(gl_FrontFacing)" " {" " e = d >= 0.0 ?" " d * mix(0.5, 1.0, t.a):" " (-0.9*d) * (1.0 - t.a);" " }" " else" " {" " e = d >= 0.0 ?" " (0.6*d) * (1.0 - t.a):" " (-0.7*d) * mix(0.5, 1.0, t.a);" " }" " float i = 0.1 + 9.0*e;" " fragColor = vec4(" " t.r*c.r*i, " " t.g*c.g*i, " " t.b*c.b*i, " " clamp(pow(t.a,2) + a*0.4, 0.0, 1.0)" " );" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the cube cube.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "Normal"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(prog, "TexCoord"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // setup the texture { auto bound_tex = Bind(tex, Texture::Target::_2D); bound_tex.Image2D(images::LoadTexture("honeycomb")); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::MirroredRepeat); bound_tex.WrapT(TextureWrap::MirroredRepeat); } // UniformSampler(prog, "TexUnit").Set(0); Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(1.0f, 2.0f, 3.0f)); // gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc( BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha ); gl.Enable(Capability::CullFace); gl.FrontFace(make_cube.FaceWinding()); }