Beispiel #1
0
	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();
	}
Beispiel #2
0
	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);
	}
Beispiel #5
0
	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);
	}
Beispiel #6
0
	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);
	}
Beispiel #10
0
	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);
	}
Beispiel #11
0
	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();
	}
Beispiel #12
0
	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);
	}
Beispiel #13
0
	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);
    }
Beispiel #15
0
	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);
	}
Beispiel #16
0
	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();
}
Beispiel #18
0
	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);
	}
Beispiel #20
0
	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);
	}
Beispiel #21
0
	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);
	}
Beispiel #22
0
	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 &center = 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);
}
Beispiel #24
0
	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();
	}
Beispiel #25
0
    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);
    }
Beispiel #26
0
	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);
	}
Beispiel #27
0
	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);
    }
Beispiel #30
0
	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);
	}