void RenderOffscreen(double time) { fbo.Bind(); gl.Clear().ColorBuffer().DepthBuffer(); gl.BlendFunc(BlendFn::One, BlendFn::One); gl.Enable(Capability::Blend); gl.Enable(Capability::DepthTest); draw_prog.Use(); draw_prog.camera_matrix.Set( CamMatrixf::Orbiting( Vec3f(), 27.0, Degrees(time * 23), Degrees(SineWave(time / 23.0) * 80) ) ); cube.Use(); cube.Draw(n*n*n); gl.Disable(Capability::DepthTest); gl.Disable(Capability::Blend); fbo.Unbind(); }
void BSP(const Mat4f& camera, std::size_t p) { assert(p < std::size_t(plane.size())); // the normal vector of the plane Vec4f normal(make_plane[p].Normal(), 0.0); // check if we are seeing the front or the back face GLfloat sign = ((camera*normal).z() >= 0.0f)? 1.0f: -1.0f; bool at_leaf = p+1 == plane.size(); gl.Enable(Functionality::ClipDistance, p); torus_clip_signs[p].Set(-sign); plane_clip_signs[p].Set(-sign); if(at_leaf) RenderTorus(); else BSP(camera, p+1); gl.Disable(Functionality::ClipDistance, p); RenderPlane(p); gl.Enable(Functionality::ClipDistance, p); torus_clip_signs[p].Set(+sign); plane_clip_signs[p].Set(+sign); if(at_leaf) RenderTorus(); else BSP(camera, p+1); gl.Disable(Functionality::ClipDistance, p); }
void RenderGlassShadowMap( const Vec3f& light_position, const Vec3f& torus_center, const Mat4f& torus_matrix, const Mat4f& light_proj_matrix ) { glass_shadow_fbo.Bind(Framebuffer::Target::Draw); gl.Viewport(shadow_tex_side, shadow_tex_side); const GLfloat clear_color[4] = {1.0f, 1.0f, 1.0f, 0.0f}; gl.ClearColorBuffer(0, clear_color); transf_prog.camera_matrix.Set(light_proj_matrix); transf_prog.camera_position.Set(light_position); transf_prog.light_proj_matrix.Set(light_proj_matrix); transf_prog.light_position.Set(light_position); // Render the torus' frame transf_prog.model_matrix.Set(torus_matrix); // setup the view clipping plane Planef clip_plane = Planef::FromPointAndNormal( torus_center, Normalized(light_position-torus_center) ); transf_prog.clip_plane.Set(clip_plane.Equation()); light_pp.Bind(); light_prog.color = Vec3f(0.6f, 0.4f, 0.1f); gl.Disable(Capability::DepthTest); gl.Enable(Functionality::ClipDistance, 0); gl.Enable(Capability::Blend); for(int c=0; c!=2; ++c) { transf_prog.clip_direction.Set((c == 0)?1:-1); for(int p=3; p>=0; --p) { if(p % 2 == 0) gl.CullFace(Face::Front); else gl.CullFace(Face::Back); torus.Draw( [&p](GLuint phase) -> bool { if(p == 0 || p == 3) { return (phase == 4); } else return (phase > 4); } ); } } gl.Disable(Capability::Blend); gl.Disable(Functionality::ClipDistance, 0); gl.Enable(Capability::DepthTest); }
void Render(double time) { gl.Clear().ColorBuffer().DepthBuffer().StencilBuffer(); // make the camera matrix orbiting around the origin // at radius of 3.5 with elevation between 15 and 90 degrees camera_matrix.Set( CamMatrixf::Orbiting( Vec3f(), 5.0, Degrees(time * 11), Degrees(15 + (-SineWave(0.25+time/12.5)+1.0)*0.5*75) ) ); ModelMatrixf identity; // make the model transformation matrix ModelMatrixf model = ModelMatrixf::Translation(0.0f, 1.5f, 0.0) * ModelMatrixf::RotationZ(Degrees(time * 43))* ModelMatrixf::RotationY(Degrees(time * 63))* ModelMatrixf::RotationX(Degrees(time * 79)); // make the reflection matrix auto reflection = ModelMatrixf::Reflection(false, true, false); // gl.Disable(Capability::Blend); gl.Disable(Capability::DepthTest); gl.Enable(Capability::StencilTest); gl.ColorMask(false, false, false, false); gl.StencilFunc(CompareFunction::Always, 1, 1); gl.StencilOp(StencilOp::Keep, StencilOp::Keep, StencilOp::Replace); gl.Bind(plane); model_matrix.Set(identity); gl.DrawArrays(PrimitiveType::TriangleStrip, 0, 4); gl.ColorMask(true, true, true, true); gl.Enable(Capability::DepthTest); gl.StencilFunc(CompareFunction::Equal, 1, 1); gl.StencilOp(StencilOp::Keep, StencilOp::Keep, StencilOp::Keep); // draw the cube using the reflection program model_matrix.Set(reflection * model); gl.Bind(cube); cube_instr.Draw(cube_indices); gl.Disable(Capability::StencilTest); // draw the cube using the normal object program model_matrix.Set(model); cube_instr.Draw(cube_indices); // blend-in the plane gl.Enable(Capability::Blend); gl.BlendEquation(BlendEquation::Max); gl.Bind(plane); model_matrix.Set(identity); gl.DrawArrays(PrimitiveType::TriangleStrip, 0, 4); }
void Render(double time) { namespace se = oglplus::smart_enums; gl.Clear().ColorBuffer().DepthBuffer().StencilBuffer(); // make the camera matrix orbiting around the origin // at radius of 3.5 with elevation between 15 and 90 degrees Mat4f camera = CamMatrixf::Orbiting( Vec3f(), 6.5, Degrees(time * 135), Degrees(15 + (-SineWave(0.25+time/12.5)+1.0)*0.5*75) ); ModelMatrixf model = ModelMatrixf::Translation(0.0f, 1.5f, 0.0); ModelMatrixf identity; // SetProgramUniform(prog_norm, "CameraMatrix", camera); SetProgramUniform(prog_refl, "CameraMatrix", camera); // draw the plane into the stencil buffer prog_norm.Use(); gl.Disable(se::Blend()); gl.Disable(se::DepthTest()); gl.Enable(se::StencilTest()); gl.ColorMask(false, false, false, false); gl.StencilFunc(se::Always(), 1, 1); gl.StencilOp(se::Keep(), se::Keep(), se::Replace()); Uniform<Mat4f> model_matrix_norm(prog_norm, "ModelMatrix"); model_matrix_norm.Set(identity); plane.Bind(); gl.DrawArrays(se::TriangleStrip(), 0, 4); gl.ColorMask(true, true, true, true); gl.Enable(se::DepthTest()); gl.StencilFunc(se::Equal(), 1, 1); gl.StencilOp(se::Keep(), se::Keep(), se::Keep()); // draw the torus using the reflection program prog_refl.Use(); Uniform<Mat4f>(prog_refl, "ModelMatrix").Set(model); torus.Bind(); torus_instr.Draw(torus_indices); gl.Disable(se::StencilTest()); prog_norm.Use(); // draw the torus using the normal object program model_matrix_norm.Set(model); torus_instr.Draw(torus_indices); // blend-in the plane gl.Enable(se::Blend()); gl.BlendEquation(se::Max()); model_matrix_norm.Set(identity); plane.Bind(); gl.DrawArrays(se::TriangleStrip(), 0, 4); }
void Render(double time) { gl.Clear().ColorBuffer().DepthBuffer(); CamMatrixf camera = CamMatrixf::Orbiting( Vec3f(), 4.5f + float(SineWave(time / 25.0)), FullCircles(time / 30.0), Degrees(SineWave(time / 19.0) * 20) ); light_prog.camera_matrix.Set(camera); flare_prog.camera_matrix.Set(camera); shape_prog.camera_matrix.Set(camera); shape_prog.camera_position.Set(camera.Position()); shape_prog.model_matrix.Set( ModelMatrixf::RotationX(FullCircles(time / 30.0)) ); shape_prog.Use(); shape.Draw(); NoProgram().Use(); lights.Bind(); light_prog.Use(); for(GLuint l=0; l!=n_flares; ++l) { queries[l].Begin(Query::Target::SamplesPassed); gl.DrawArrays(PrimitiveType::Points, l, 1); queries[l].End(Query::Target::SamplesPassed); } gl.Enable(Capability::Blend); gl.Disable(Capability::DepthTest); flare_prog.Use(); for(GLuint l=0; l!=n_flares; ++l) { GLint samples = 0; queries[l].WaitForResult(samples); if(samples != 0) { flare_prog.samples = samples; gl.DrawArrays(PrimitiveType::Points, l, 1); } } gl.Enable(Capability::DepthTest); gl.Disable(Capability::Blend); }
void SpectraDefaultGPUMatrixTransf::FinishBatch(void) { using namespace oglplus; Context gl; gl.Disable(Capability::RasterizerDiscard); VertexArray::Unbind(); }
void ShadowMapRenderer::BlurShadowMap() { using namespace oglplus; static Context gl; auto &prog = BlurShader(); CurrentProgram<BlurProgram>(prog); // horizontal blur blurFramebuffer.Bind(FramebufferTarget::Draw); gl.Disable(Capability::DepthTest); // active shadow to be read shadowMap.Active(0); shadowMap.Bind(TextureTarget::_2D); // update uniform prog.source.Set(0); prog.blurDirection.Set(glm::vec2(1.0f / shadowMapSize.x * blurScale, 0.0f)); prog.blurType.Set(blurQuality); gl.Clear().DepthBuffer().ColorBuffer(); fsQuad.DrawElements(); // blur vertically shadowFramebuffer.Bind(FramebufferTarget::Draw); // active shadow to be read blurShadow.Bind(TextureTarget::_2D); // update uniform prog.source.Set(0); prog.blurDirection.Set(glm::vec2(0.0f, 1.0f / shadowMapSize.y * blurScale)); prog.blurType.Set(blurQuality); gl.Clear().DepthBuffer().ColorBuffer(); fsQuad.DrawElements(); gl.Enable(Capability::DepthTest); }
void RenderFrameShadowMap( const Vec3f& light_position, const Mat4f& torus_matrix, const Mat4f& light_proj_matrix ) { frame_shadow_fbo.Bind(Framebuffer::Target::Draw); gl.Viewport(shadow_tex_side, shadow_tex_side); gl.ClearDepthBuffer(1.0f); gl.CullFace(Face::Back); transf_prog.camera_matrix.Set(light_proj_matrix); transf_prog.camera_position.Set(light_position); // Render the torus' frame transf_prog.model_matrix.Set(torus_matrix); shadow_pp.Bind(); gl.Enable(Capability::PolygonOffsetFill); torus.Draw( [](GLuint phase) -> bool { return (phase <= 3); } ); gl.Disable(Capability::PolygonOffsetFill); }
void Render(double time) { static const Mat4f reflection( Vec4f( 1.0, 0.0, 0.0, 0.0), Vec4f( 0.0,-1.0, 0.0, 0.0), Vec4f( 0.0, 0.0, 1.0, 0.0), Vec4f( 0.0, 0.0, 0.0, 1.0) ); auto camera = CamMatrixf::Orbiting( Vec3f(), GLfloat(7.0 + SineWave(time / 12.0)*2.5), FullCircles(time / 10.0), Degrees(45.0 - SineWave(time / 7.0)*35.0) ); shape_prog.Use(); shape.Bind(); gl.Enable(Capability::CullFace); gl.FrontFace(make_shape.FaceWinding()); // render into the off-screen framebuffer fbo.Bind(Framebuffer::Target::Draw); gl.Viewport( (width - refl_tex_side) / 2, (height - refl_tex_side) / 2, refl_tex_side, refl_tex_side ); gl.Clear().ColorBuffer().DepthBuffer(); shape_camera_matrix.Set( camera * ModelMatrixf::Translation(0.0f, -1.0f, 0.0f) * reflection ); gl.CullFace(Face::Front); shape_instr.Draw(shape_indices); gl.Bind(Framebuffer::Target::Draw, DefaultFramebuffer()); gl.Viewport(width, height); gl.Clear().ColorBuffer().DepthBuffer(); shape_camera_matrix.Set(camera); gl.CullFace(Face::Back); shape_instr.Draw(shape_indices); gl.Disable(Capability::CullFace); // Render the plane plane_prog.Use(); plane.Bind(); plane_camera_matrix.Set(camera); plane_camera_position.Set(camera.Position()); plane_instr.Draw(plane_indices); }
void Update(double time) { gl.Viewport(size, size); fbo.Bind(Framebuffer::Target::Draw); Framebuffer::AttachColorTexture( Framebuffer::Target::Draw, 1, holder.CurrentHeightMap(), 0 ); Context::ColorBuffer draw_buffs[2] = { FramebufferColorAttachment::_0, FramebufferColorAttachment::_1 }; gl.DrawBuffers(draw_buffs); prog.Use(); prog.hmap_1.Set(holder.HMapUnit1()); prog.hmap_2.Set(holder.HMapUnit2()); prog.time.Set(time); screen.Use(); gl.Disable(Capability::DepthTest); screen.Draw(); gl.Enable(Capability::DepthTest); holder.Swap(); }
void operator()(const Particles& particles) { gl.Enable(Capability::Blend); gl.Bind(vao); gl.Use(prog); gl.DrawElements(PrimitiveType::Points, particles.Count(), (GLuint*)0); gl.Disable(Capability::Blend); }
void RenderPlane(std::size_t p) { gl.Enable(Capability::Blend); plane_prog.Use(); plane_normal.Set(make_plane[p].Normal()); plane[p].Bind(); plane_instr.Draw(plane_indices); gl.Disable(Capability::Blend); }
ParallaxMapExample() : prog(make()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , camera_position(prog, "CameraPosition") , light_position(prog, "LightPosition") , shape( List("Position")("Normal")("Tangent")("TexCoord").Get(), shapes::Torus(1.0f, 0.5, 72, 48)) { shape.UseInProgram(prog); auto tex_image = images::LoadTexture("bricks_color_hmap"); Texture::Active(0); try { UniformSampler(prog, "ColorMap").Set(0); gl.Bound(Texture::Target::_2D, color_tex) .MinFilter(TextureMinFilter::LinearMipmapLinear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::Repeat) .WrapT(TextureWrap::Repeat) .Image2D(tex_image) .GenerateMipmap(); } catch(Error&) { } Texture::Active(1); try { UniformSampler(prog, "BumpMap").Set(1); gl.Bound(Texture::Target::_2D, bump_tex) .MinFilter(TextureMinFilter::LinearMipmapLinear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::Repeat) .WrapT(TextureWrap::Repeat) .Image2D( images::NormalMap(tex_image, images::NormalMap::FromAlpha())) .GenerateMipmap(); } 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); }
void Draw(double time, double fade) { // Shadow map shadows_fbo.Bind(FramebufferTarget::Draw); gl.Viewport(shadow_size, shadow_size); gl.Clear().DepthBuffer(); auto light = CamMatrixf::Orbiting( Vec3f(0, side*0.25, 0), side*1.5, Degrees(-time * 27), Degrees(SineWave(time / 19.0)*25 + 45) ); shadow_prog.fade.Set(fade); shadow_prog.camera_matrix.Set(light); shadow_prog.Use(); shadow_vao.Bind(); gl.Enable(Capability::PolygonOffsetFill); cube.Draw(side*side); gl.Disable(Capability::PolygonOffsetFill); gl.Finish(); // On-screen default_fb.Bind(Framebuffer::Target::Draw); gl.Viewport(width, height); gl.Clear().ColorBuffer().DepthBuffer(); auto camera = CamMatrixf::Orbiting( Vec3f(), side*1.1, Degrees(time * 19), Degrees(SineWave(time / 20.0) * 39 + 50) ); display_prog.fade.Set(fade); display_prog.light_pos.Set(light.Position()); display_prog.camera_pos.Set(camera.Position()); display_prog.light_matrix.Set(light); display_prog.camera_matrix.Set(camera); display_prog.Use(); display_vao.Bind(); cube.Draw(side*side); }
void Render(double time) { fbo.Bind(Framebuffer::Target::Draw); gl.Clear().ColorBuffer().DepthBuffer(); main_prog.Use(); cube.Bind(); camera_matrix.Set( CamMatrixf::Orbiting( Vec3f(), 20.5, FullCircles(time / 20.0), Degrees(SineWave(time / 25.0) * 30) ) ); auto i = cube_matrices.begin(), e = cube_matrices.end(); while(i != e) { model_matrix.Set(*i); ambient_color.Set(0.7f, 0.6f, 0.2f); diffuse_color.Set(1.0f, 0.8f, 0.3f); face_instr.Draw(face_indices); ambient_color.Set(0.1f, 0.1f, 0.1f); diffuse_color.Set(0.3f, 0.3f, 0.3f); edge_instr.Draw(edge_indices); ++i; } dfb.Bind(Framebuffer::Target::Draw); gl.Clear().ColorBuffer().DepthBuffer(); dof_prog.Use(); screen.Bind(); focus_depth.Set(0.6 + SineWave(time / 9.0)*0.3); gl.Enable(Capability::Blend); gl.DrawArrays(PrimitiveType::TriangleStrip, 0, 4); gl.Disable(Capability::Blend); }
void GIDeferredRenderer::Render() { using namespace oglplus; static Context gl; static auto &camera = Camera::Active(); static auto &scene = Scene::Active(); static auto &info = Window().Info(); if (!camera || !scene || !scene->IsLoaded() || VoxelizerRenderer::ShowVoxels) { return; } SetAsActive(); // bind g buffer for writing geometryBuffer.Bind(FramebufferTarget::Draw); gl.ColorMask(true, true, true, true); gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.Viewport(info.framebufferWidth, info.framebufferHeight); gl.Clear().ColorBuffer().DepthBuffer(); // activate geometry pass shader program CurrentProgram<GeometryProgram>(GeometryPass()); // rendering and GL flags gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Disable(Capability::Blend); gl.Enable(Capability::CullFace); gl.FrontFace(FaceOrientation::CCW); gl.CullFace(Face::Back); camera->DoFrustumCulling(true); // draw whole scene tree from root node scene->rootNode->DrawList(); // start light pass DefaultFramebuffer().Bind(FramebufferTarget::Draw); gl.ColorMask(true, true, true, true); gl.Viewport(info.framebufferWidth, info.framebufferHeight); gl.Clear().ColorBuffer().DepthBuffer(); CurrentProgram<LightingProgram>(LightingPass()); // pass light info and texture locations for final light pass SetLightPassUniforms(); // draw the result onto a fullscreen quad fsQuad.DrawElements(); }
void Render(double time) { gl.Clear().ColorBuffer().DepthBuffer(); auto camera = CamMatrixf::Orbiting( Vec3f(), 8.5, FullCircles(time / 5.0), Degrees(15 + (-SineWave(time/10.0)+1.0)* 0.5 * 75) ); ModelMatrixf model = ModelMatrixf::Translation(0.0f, 2.5f, 0.0) * ModelMatrixf::RotationA( Vec3f(1.0f, 1.0f, 1.0f), FullCircles(time / 7.0) ); plane_prog.Use(); plane_camera_matrix.Set(camera); plane.Bind(); gl.DrawArrays(PrimitiveType::TriangleStrip, 0, 4); shape_prog.Use(); shape_camera_matrix.Set(camera); shape_model_matrix.Set(model); shape.Bind(); shape_instr.Draw(shape_indices); halo_prog.Use(); halo_camera_matrix.Set(camera); halo_model_matrix.Set(model); gl.DepthMask(false); gl.Enable(Capability::Blend); shape_instr.Draw(shape_indices); gl.Disable(Capability::Blend); gl.DepthMask(true); }
void Render(double time) { gl.Clear().ColorBuffer().DepthBuffer(); auto cameraMatrix = CamMatrixf::Orbiting( Vec3f(0.0f, 3.0f, 0.0f), 8.0f, FullCircles(time / 12.0), Degrees(SineWave(time / 20.0) * 80) ); plane.Bind(); plane_prog.Use(); Uniform<Mat4f>(plane_prog, "CameraMatrix").Set(cameraMatrix); gl.DrawArrays(PrimitiveType::TriangleStrip, 0, 4); gl.Enable(Capability::Blend); volume.Bind(); volume_prog.Use(); Uniform<Mat4f>(volume_prog, "CameraMatrix").Set(cameraMatrix); Uniform<Vec3f>(volume_prog, "ViewX").Set( cameraMatrix.Row(0).xyz() ); Uniform<Vec3f>(volume_prog, "ViewY").Set( cameraMatrix.Row(1).xyz() ); Uniform<Vec3f>(volume_prog, "ViewZ").Set( cameraMatrix.Row(2).xyz() ); gl.DrawArraysInstanced( PrimitiveType::Points, 0, 1, samples ); gl.Disable(Capability::Blend); }
void RenderImage( double time, const Mat4f& torus_matrix, const Mat4f& light_proj_matrix ) { // this is going into the on-screen framebuffer DefaultFramebuffer().Bind(Framebuffer::Target::Draw); gl.ClearColor(1.0f, 0.9f, 0.8f, 0.0f); gl.Viewport(width, height); gl.Clear().ColorBuffer().DepthBuffer(); gl.CullFace(Face::Back); // transf_prog.light_proj_matrix.Set(light_proj_matrix); Mat4f perspective = CamMatrixf::PerspectiveX( Degrees(60), float(width)/height, 1, 60 ); // setup the camera Vec3f camera_target(0.0f, 0.8f, 0.0f); auto camera = CamMatrixf::Orbiting( camera_target, GLfloat(7.0 - SineWave(time / 14.0)*3.0), FullCircles(time / 26.0), Degrees(45 + SineWave(time / 17.0) * 40) ); Vec3f camera_position = camera.Position(); transf_prog.camera_matrix.Set(perspective*camera); transf_prog.camera_position.Set(camera_position); // render into the depth buffer shadow_pp.Bind(); gl.Enable(Capability::PolygonOffsetFill); gl.ColorMask(false, false, false, false); transf_prog.model_matrix = ModelMatrixf(); plane.Draw(); transf_prog.model_matrix.Set(torus_matrix); torus.Draw(); gl.ColorMask(true, true, true, true); gl.Disable(Capability::PolygonOffsetFill); gl.Enable(Capability::Blend); gl.Disable(Capability::Blend); // render into the color buffer sketch_pp.Bind(); gl.Enable(Capability::Blend); transf_prog.model_matrix = ModelMatrixf(); transf_prog.texture_matrix.Set(Mat2f(Vec2f(3.0, 0.0), Vec2f(0.0, 3.0))); plane.Draw(); transf_prog.model_matrix.Set(torus_matrix); transf_prog.texture_matrix.Set(Mat2f(Vec2f(8.0, 0.0), Vec2f(0.0, 2.0))); torus.Draw([](GLuint phase) -> bool { return phase < 4; }); transf_prog.texture_matrix.Set(Mat2f(Vec2f(0.0, 2.0), Vec2f(8.0, 0.0))); torus.Draw([](GLuint phase) -> bool { return phase >= 4; }); // render the edges line_pp.Bind(); transf_prog.model_matrix = ModelMatrixf(); plane.DrawEdges(); transf_prog.model_matrix.Set(torus_matrix); torus.DrawEdges(); gl.Disable(Capability::Blend); }
void Render(double time) { // // the camera matrix Mat4f camera = CamMatrixf::Orbiting( Vec3f(), 6.5 + SineWave(time / 16.0) * 1.5, FullCircles(time / 12.0), Degrees(SineWave(time / 30.0) * 90) ); // // the model matrix Mat4f model = ModelMatrixf::RotationA( Vec3f(1.0f, 1.0f, 1.0f), FullCircles(time / 10.0) ); // the light position Vec3f lightPos(0.0f, SineWave(time / 7.0) * 0.5, 0.0f); // SetProgramUniform(shape_prog, "LightPos", lightPos); SetProgramUniform(depth_prog, "LightPos", lightPos); SetProgramUniform(light_prog, "LightPos", lightPos); // SetProgramUniform(shape_prog, "CameraMatrix", camera); SetProgramUniform(light_prog, "CameraMatrix", camera); SetProgramUniform(shape_prog, "ModelMatrix", model); SetProgramUniform(depth_prog, "ModelMatrix", model); // render the shadow map depth_fbo.Bind(Framebuffer::Target::Draw); gl.DrawBuffer(ColorBuffer::None); gl.Viewport(tex_side, tex_side); gl.Clear().DepthBuffer(); depth_prog.Use(); shape.Bind(); shape_instr.Draw(shape_indices); // render the output frame Framebuffer::BindDefault(Framebuffer::Target::Draw); gl.DrawBuffer(ColorBuffer::Back); gl.Viewport(width, height); gl.Clear().ColorBuffer().DepthBuffer(); shape_prog.Use(); shape.Bind(); shape_instr.Draw(shape_indices); gl.Enable(Capability::Blend); light_prog.Use(); SetUniform(light_prog, "ViewX", camera.Row(0).xyz()); SetUniform(light_prog, "ViewY", camera.Row(1).xyz()); SetUniform(light_prog, "ViewZ", camera.Row(2).xyz()); light.Bind(); gl.DrawArraysInstanced( PrimitiveType::Points, 0, 1, sample_count ); gl.Disable(Capability::Blend); }
void RenderShadowMap(GLuint size) { // matrices auto lt_proj= CamMatrixf::PerspectiveX(Degrees(12), 1.0, 85.0, 110.0); auto light = CamMatrixf::LookingAt(light_position, Vec3f()); // setup the texture Texture::Active(shadow_tex_unit); mask_prog.Use(); Uniform<Mat4f>(mask_prog, "LightMatrix").Set(lt_proj*light); UniformSampler(mask_prog, "ShadowMap").Set(GLuint(shadow_tex_unit)); draw_prog.Use(); Uniform<Mat4f>(draw_prog, "LightMatrix").Set(lt_proj*light); UniformSampler(draw_prog, "ShadowMap").Set(GLuint(shadow_tex_unit)); Texture::Target tex_tgt = Texture::Target::_2D; shadow_map.Bind(tex_tgt); Texture::MinFilter(tex_tgt, TextureMinFilter::Linear); Texture::MagFilter(tex_tgt, TextureMagFilter::Linear); Texture::WrapS(tex_tgt, TextureWrap::ClampToEdge); Texture::WrapT(tex_tgt, TextureWrap::ClampToEdge); Texture::CompareMode(tex_tgt, TextureCompareMode::CompareRefToTexture); Texture::Image2D( tex_tgt, 0, PixelDataInternalFormat::DepthComponent32, size, size, 0, PixelDataFormat::DepthComponent, PixelDataType::Float, nullptr ); // create shadow program ShadowProgram shadow_prog(vert_shader); // VAO for the meshes in shadow program VertexArray vao = meshes.VAOForProgram(shadow_prog); vao.Bind(); // FBO for offscreen rendering of the shadow map Framebuffer::Target fbo_tgt = Framebuffer::Target::Draw; Framebuffer fbo; fbo.Bind(fbo_tgt); Framebuffer::AttachTexture(fbo_tgt, FramebufferAttachment::Depth, shadow_map, 0); // RBO for offscreen rendering Renderbuffer::Target rbo_tgt = Renderbuffer::Target::Renderbuffer; Renderbuffer rbo; rbo.Bind(rbo_tgt); Renderbuffer::Storage(rbo_tgt, PixelDataInternalFormat::RGBA, size, size); Framebuffer::AttachRenderbuffer(fbo_tgt, FramebufferAttachment::Color, rbo); // setup the matrices shadow_prog.projection_matrix.Set(lt_proj); shadow_prog.camera_matrix.Set(light); // setup and clear the viewport gl.Viewport(size, size); gl.Clear().DepthBuffer(); // draw the meshes gl.PolygonOffset(1.0, 1.0); gl.Enable(Capability::PolygonOffsetFill); meshes.Draw(); gl.Disable(Capability::PolygonOffsetFill); gl.Finish(); // bind the default framebuffer DefaultFramebuffer().Bind(Framebuffer::Target::Draw); }
void ShadowMapRenderer::Render() { using namespace oglplus; static Context gl; static Scene * scenePtr = nullptr; static auto &scene = Scene::Active(); auto camera = Camera::Active().get(); if (!camera || !scene || !scene->IsLoaded() || !shadowCaster) { return; } // initially assign invalid direction static auto &changes = Transform::TransformChangedMap(); static bool updateShadowMap = true; // any node transformation happened for (auto &c : changes) { auto &type = typeid(*c.first); if (type == typeid(Node)) { updateShadowMap = true; break; } } // shadow caster change if (shadowCaster->TransformChanged()) { updateShadowMap = true; } // scene change if (scenePtr != scene.get()) { scenePtr = scene.get(); updateShadowMap = true; } if (!updateShadowMap) { return; } updateShadowMap = false; // update shadow map SetAsActive(); lightView.SetAsActive(); shadowFramebuffer.Bind(FramebufferTarget::Draw); gl.Viewport(0, 0, shadowMapSize.x, shadowMapSize.y); gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.Clear().DepthBuffer().ColorBuffer(); // activate geometry pass shader program auto &prog = DepthShader(); CurrentProgram<DepthProgram>(prog); // rendering flags gl.Disable(Capability::Blend); gl.Enable(Capability::DepthTest); gl.Disable(Capability::CullFace); // unneded since directional light cover the whole scene // can be useful for view frustum aware light frustum later lightView.DoFrustumCulling(false); // scene spatial cues auto sceneBB = scene->rootNode->boundaries; auto ¢er = sceneBB.Center(); auto radius = distance(center, sceneBB.MaxPoint()); // fix light frustum to fit scene bounding sphere lightView.OrthoRect(glm::vec4(-radius, radius, -radius, radius)); lightView.ClipPlaneNear(-radius); lightView.ClipPlaneFar(2.0f * radius); lightView.Projection(Camera::ProjectionMode::Orthographic); lightView.transform.Position(center + shadowCaster->Direction() * radius); lightView.transform.Forward(-shadowCaster->Direction()); // update lightview matrix LightSpaceMatrix(); // uniforms prog.exponents.Set(exponents); // draw whole scene tree from root node scene->rootNode->DrawList(); // recover original render camera camera->SetAsActive(); // blur the result evsm map if(blurScale > 0) { BlurShadowMap(); } // recover DefaultFramebuffer().Bind(FramebufferTarget::Draw); // no trilinear filtering if (filtering < 2) return; // mip map shadow map shadowMap.Bind(TextureTarget::_2D); shadowMap.GenerateMipmap(TextureTarget::_2D); }
void Render(double time) { GLfloat bs_rad = shape.BoundingSphere().Radius()*1.2f; auto light = CamMatrixf::Orbiting( shape.BoundingSphere().Center(), shape.BoundingSphere().Radius()*10.0f, FullCircles(time / 23.0), Degrees(-CosineWave(time / 31.0) * 80) ); auto camera = CamMatrixf::Orbiting( shape.BoundingSphere().Center(), shape.BoundingSphere().Radius()* GLfloat(3.2+SineWave(time / 23.0)*0.8), FullCircles(time / 19.0), Degrees(SineWave(time / 21.0) * 80) ); GLfloat cam_tgt_dist = Distance( shape.BoundingSphere().Center(), camera.Position() ); auto cam_proj = CamMatrixf::PerspectiveX( Degrees(45), width, height, cam_tgt_dist-bs_rad, cam_tgt_dist+bs_rad ); auto model = ModelMatrixf::RotationZ(Degrees(SineWave(time / 21.0)*25))* ModelMatrixf::Translation(0.0f,-bs_rad*0.25f, 0.0f); data_prog.Use(); data_prog.camera_matrix.Set(cam_proj*camera); data_prog.model_matrix.Set(model); data_prog.camera_position.Set(camera.Position()); data_prog.light_position.Set(light.Position()); data_buffer.Bind(); gl.Enable(Capability::DepthTest); gl.Clear().ColorBuffer().DepthBuffer(); shape.Use(); shape.Draw(); draw_prog.Use(); draw_prog.slider.Set(GLfloat(CosineWave01(time / 11.0)*width)); DefaultFramebuffer().Bind(Framebuffer::Target::Draw); gl.Disable(Capability::DepthTest); gl.Clear().ColorBuffer(); screen.Use(); screen.Draw(); }
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); }
void Render(double time) { gl.Clear().ColorBuffer().DepthBuffer(); // auto camera = CamMatrixf::Orbiting( Vec3f(), 5.5, FullCircles(time / 10.0), Degrees(45.0 + SineWave(time / 7.0)*30.0) ); // Render the plane plane_prog.Use(); plane_camera_matrix.Set(camera); plane_model_matrix.Set( ModelMatrixf::Translation(0.0f, -1.1f, 0.0f) ); gl.Bind(plane); plane_instr.Draw(plane_indices); // Render the shape shape_prog.Use(); auto clip_plane = Planef::FromNormal(Vec3f(Data(camera.Row(2)), 3)); shape_clip_plane.Set(clip_plane.Equation()); shape_camera_matrix.Set(camera); shape_model_matrix.Set( ModelMatrixf::RotationX(FullCircles(time / 12.0)) ); gl.Bind(shape); gl.Enable(Capability::CullFace); gl.Enable(Functionality::ClipDistance, 0); gl.FrontFace(make_shape.FaceWinding()); GLfloat clip_dirs[2] = {-1.0f, 1.0f}; Face facing_dirs[2] = {Face::Front, Face::Back}; for(int c=0; c!=2; ++c) { shape_clip_direction.Set(clip_dirs[c]); for(int f=0; f!=2; ++f) { Texture::CopyImage2D( Texture::Target::_2D, 0, PixelDataInternalFormat::RGB, tex_side == width ? 0 : (width - tex_side) / 2, tex_side == height? 0 : (height- tex_side) / 2, tex_side, tex_side, 0 ); gl.CullFace(facing_dirs[f]); shape_instr.Draw(shape_indices); } } gl.Disable(Functionality::ClipDistance, 0); gl.Disable(Capability::CullFace); }
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); }
void RenderImage( double time, const Vec3f& torus_center, const Mat4f& torus_matrix, const Mat4f& light_proj_matrix ) { // this is going into the on-screen framebuffer DefaultFramebuffer().Bind(Framebuffer::Target::Draw); gl.ClearColor(0.6f, 0.6f, 0.5f, 0.0f); gl.Viewport(width, height); gl.Clear().ColorBuffer().DepthBuffer(); gl.CullFace(Face::Back); // transf_prog.light_proj_matrix.Set(light_proj_matrix); Mat4f perspective = CamMatrixf::PerspectiveX( Degrees(60), float(width)/height, 1, 60 ); // setup the camera Vec3f camera_target(0.0f, 0.8f, 0.0f); auto camera = CamMatrixf::Orbiting( camera_target, GLfloat(8.0 - SineWave(time / 15.0)*3.0), FullCircles(time / 24.0), Degrees(45 + SineWave(time / 20.0) * 40) ); Vec3f camera_position = camera.Position(); transf_prog.camera_matrix.Set(perspective*camera); transf_prog.camera_position.Set(camera_position); // setup the view clipping plane Planef clip_plane = Planef::FromPointAndNormal( torus_center, Normalized(camera_position-torus_center) ); metal_pp.Bind(); // Render the plane transf_prog.model_matrix = ModelMatrixf(); transf_prog.texture_matrix.Set(Mat2f(Vec2f(9.0f,0.0f), Vec2f(0.0f,9.0f))); metal_prog.color_1 = Vec3f(1.0f, 0.9f, 0.8f); metal_prog.color_2 = Vec3f(0.9f, 0.8f, 0.6f); metal_prog.with_glass_shadow = 1; plane.Draw([](GLuint) -> bool {return true;}); // Render the torus transf_prog.model_matrix.Set(torus_matrix); transf_prog.texture_matrix.Set(Mat2f(Vec2f(16.0f,0.0f), Vec2f(0.0f, 4.0f))); metal_prog.metal_tex.Set(0); metal_prog.color_1 = Vec3f(0.9f, 0.9f, 0.9f); metal_prog.color_2 = Vec3f(0.3f, 0.3f, 0.3f); metal_prog.with_glass_shadow = 0; // the metal-part torus.Draw( [](GLuint phase) -> bool { return (phase <= 3); } ); // now the glass part glass_pp.Bind(); glass_prog.color = Vec3f(0.6f, 0.4f, 0.1f); gl.Enable(Functionality::ClipDistance, 0); gl.Enable(Capability::Blend); transf_prog.clip_plane.Set(clip_plane.Equation()); for(int c=0; c!=2; ++c) { transf_prog.clip_direction.Set((c == 0)?-1:1); for(int p=0; p!=4; ++p) { if(p % 2 == 0) gl.CullFace(Face::Front); else gl.CullFace(Face::Back); torus.Draw( [&p](GLuint phase) -> bool { if(p == 0 || p == 3) return (phase == 4); else return (phase > 4); } ); } } gl.Disable(Capability::Blend); gl.Disable(Functionality::ClipDistance, 0); }
void Render(double time) { gl.Clear().ColorBuffer().DepthBuffer().StencilBuffer(); auto camera = CamMatrixf::Orbiting( Vec3f(), 9.0, FullCircles(time * 0.1), Degrees(15 + (-SineWave(0.25 + time / 12.5) + 1.0) * 0.5 * 75)); ModelMatrixf identity; ModelMatrixf model = ModelMatrixf::Translation(0.0f, 2.5f, 0.0) * ModelMatrixf::RotationA( Vec3f(1.0f, 1.0f, 1.0f), FullCircles(time * 0.2)); gl.CullFace(Face::Back); gl.ColorMask(true, true, true, true); gl.DepthMask(true); gl.Disable(Capability::StencilTest); object_prog.Use(); object_camera_matrix.Set(camera); object_light_mult.Set(0.2f); object_model_matrix.Set(identity); plane.Bind(); gl.DrawArrays(PrimitiveType::TriangleStrip, 0, 4); object_model_matrix.Set(model); torus.Bind(); torus_instr.Draw(torus_indices); gl.ColorMask(false, false, false, false); gl.DepthMask(false); gl.Enable(Capability::StencilTest); gl.StencilFunc(CompareFunction::Always, 0); gl.StencilOpSeparate( Face::Front, StencilOp::Keep, StencilOp::Keep, StencilOp::Incr); gl.StencilOpSeparate( Face::Back, StencilOp::Keep, StencilOp::Keep, StencilOp::Decr); shadow_prog.Use(); shadow_camera_matrix.Set(camera); shadow_model_matrix.Set(model); gl.CullFace(Face::Back); torus_instr.Draw(torus_indices); gl.CullFace(Face::Front); torus_instr.Draw(torus_indices); gl.CullFace(Face::Back); gl.ColorMask(true, true, true, true); gl.DepthMask(true); gl.Clear().DepthBuffer(); gl.StencilFunc(CompareFunction::Equal, 0); gl.StencilOp(StencilOp::Keep, StencilOp::Keep, StencilOp::Keep); object_prog.Use(); object_light_mult.Set(2.5); object_model_matrix.Set(identity); object_color.Set(0.8f, 0.7f, 0.4f); plane.Bind(); gl.DrawArrays(PrimitiveType::TriangleStrip, 0, 4); object_model_matrix.Set(model); object_color.Set(0.9f, 0.8f, 0.1f); torus.Bind(); torus_instr.Draw(torus_indices); }
MetaballExample(void) { for(GLuint i=0; i!=64; ++i) { GLuint j = 0, n = 3+std::rand()%3; std::vector<Vec4f> points(n); while(j != n) { points[j] = Vec4f( 1.4*std::rand()/GLdouble(RAND_MAX) - 0.7, 1.4*std::rand()/GLdouble(RAND_MAX) - 0.7, 0.0, 0.1*std::rand()/GLdouble(RAND_MAX) + 0.1 ); ++j; } ball_paths.push_back(CubicBezierLoop<Vec4f, double>(points)); ++i; } // Set the vertex shader source vs.Source(StrLit( "#version 330\n" "in vec2 Position;" "out vec3 vertPosition;" "void main(void)" "{" " vertPosition = vec3(Position, 0.0);" " gl_Position = vec4(vertPosition, 1.0);" "}" )); // compile it vs.Compile(); // set the fragment shader source fs.Source(StrLit( "#version 330\n" "uniform sampler1D Metaballs;" "in vec3 vertPosition;" "out vec3 fragColor;" "const vec3 AmbientColor = vec3(0.3, 0.4, 0.9);" "const vec3 DiffuseColor = vec3(0.5, 0.6, 1.0);" "const vec3 LightDir = normalize(vec3(1.0, 1.0, 1.0));" "void main(void)" "{" " int i = 0, n = textureSize(Metaballs, 0);" " float InvN = 1.0/n;" " float Value = 0.0;" " vec3 Normal = vec3(0.0, 0.0, 0.0);" " while(i != n)" " {" " vec4 Metaball = texelFetch(Metaballs, i, 0);" " float Radius = Metaball.w;" " vec3 Vect = vertPosition - Metaball.xyz;" " float Tmp = pow(Radius,2.0)/dot(Vect, Vect)-0.25;" " Value += Tmp;" " float Mul = max(Tmp, 0.0);" " Normal += Mul*vec3(Vect.xy, Mul*InvN/Radius);" " ++i;" " }" " if(Value > 0.0)" " {" " float Diffuse = 1.4*max(dot(" " LightDir," " normalize(Normal)" " ), 0.0);" " float Ambient = 0.3;" " fragColor = " " Ambient*AmbientColor+" " Diffuse*DiffuseColor;" " }" " else fragColor = vec3(0.4, 0.4, 0.4);" "}" )); // compile it fs.Compile(); // attach the shaders to the program prog << vs << fs; // link and use it prog.Link().Use(); // bind the VAO for the rectangle rectangle.Bind(); GLfloat rectangle_verts[8] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; // bind the VBO for the rectangle vertices verts.Bind(Buffer::Target::Array); // upload the data Buffer::Data(Buffer::Target::Array, rectangle_verts); // setup the vertex attribs array for the vertices VertexAttribArray vert_attr(prog, "Position"); vert_attr.Setup<Vec2f>().Enable(); // Texture::Active(0); UniformSampler(prog, "Metaballs").Set(0); { auto bound_tex = Bind(metaballs_tex, Texture::Target::_1D); bound_tex.Image1D( 0, InternalFormat::RGBA32F, ball_paths.size(), 0, Format::RGBA, DataType::Float, nullptr ); bound_tex.MinFilter(TextureMinFilter::Nearest); bound_tex.MagFilter(TextureMagFilter::Nearest); bound_tex.WrapS(TextureWrap::MirroredRepeat); } gl.Disable(Capability::DepthTest); }