Beispiel #1
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 #2
0
void window_loop(
	const x11::Window& window,
	AppData& app_data,
	CommonData& common,
	RaytracerTarget& rt_target,
	std::size_t n_threads
)
{
	Context gl;
	Renderer renderer(app_data, rt_target.tex_unit);
	renderer.Use(app_data);
	Saver saver(app_data);

	window.SelectInput(StructureNotifyMask| PointerMotionMask| KeyPressMask);
	::XEvent event;

	while(!common.Done())
	{
		if(app_data.verbosity > 0)
		{
			app_data.logstr()
				<< "Rendering cube face "
				<< common.Face()
				<< std::endl;
		}

		// clear the raytrace target
		rt_target.Clear(app_data);
		renderer.InitFrame(app_data, common.Face());
		renderer.Render(app_data);
		common.context.SwapBuffers(window);

		// setup logging period
		std::chrono::system_clock::duration log_period;
		if(app_data.verbosity > 4)
		{
			log_period = std::chrono::seconds(1);
		}
		else if(app_data.verbosity > 3)
		{
			log_period = std::chrono::seconds(5);
		}
		else if(app_data.verbosity > 2)
		{
			log_period = std::chrono::seconds(15);
		}
		else if(app_data.verbosity > 1)
		{
			log_period = std::chrono::minutes(1);
		}

		auto log_time = std::chrono::system_clock::now();

		// signal all threads that they can start raytracing tiles
		common.master_ready.Signal(n_threads);

		while(!common.FaceDone())
		{
			unsigned slot = 0;
			while(common.display.NextEvent(event))
			{
				switch(event.type)
				{
					case ClientMessage:
					case DestroyNotify:
						common.Stop();
						break;
					case ConfigureNotify:
						app_data.render_width = event.xconfigure.width;
						app_data.render_height = event.xconfigure.height;
						break;
					case MotionNotify:
						break;
					case KeyPress:
						if(::XLookupKeysym(&event.xkey, 0) == XK_Escape)
							common.Stop();
						break;
					default:;
				}
			}

			if(common.Done()) break;

			if((slot++ % 5) == 0)
			{
				auto lock = common.Lock();
				renderer.Render(app_data);
				gl.Finish();
				lock.unlock();

				common.context.SwapBuffers(window);
			}

			if(app_data.verbosity > 1)
			{
				auto now = std::chrono::system_clock::now();
				if(log_time + log_period < now)
				{
					common.LogProgress(app_data);
					log_time = now;
				}
			}
			std::chrono::milliseconds period(5);
			std::this_thread::sleep_for(period);
		}

		if(common.Done()) break;

		// wait for all raytracer threads to finish
		common.thread_ready.Wait(n_threads);

		renderer.Render(app_data);
		common.context.SwapBuffers(window);

		if(app_data.verbosity > 1)
		{
			app_data.logstr()
				<< "Finished cube face "
				<< common.Face()
				<< std::endl;
		}

		// save the face image
		saver.SaveFrame(app_data, rt_target, common.Face());
		// switch the face
		common.NextFace(app_data);

		// signal that the master is ready to render
		// the next face
		common.master_ready.Signal(n_threads);
	}
}
Beispiel #3
0
void pbuffer_loop(
	const glx::Pbuffer& pbuffer,
	AppData& app_data,
	CommonData& common,
	RaytracerTarget& rt_target,
	std::size_t n_threads
)
{
	Context gl;
	Renderer renderer(app_data, rt_target.tex_unit);
	renderer.Use(app_data);
	Saver saver(app_data);

	while(!common.Done())
	{
		if(app_data.verbosity > 0)
		{
			app_data.logstr()
				<< "Rendering cube face "
				<< common.Face()
				<< std::endl;
		}

		// clear the raytrace target
		rt_target.Clear(app_data);

		renderer.InitFrame(app_data, common.Face());
		renderer.Render(app_data);
		gl.Finish();

		// signal all threads that they can start raytracing tiles
		common.master_ready.Signal(n_threads);

		if(common.Done()) break;

		if(app_data.verbosity > 1)
		{
			// setup logging period
			std::chrono::system_clock::duration log_period;
			if(app_data.verbosity > 4)
			{
				log_period = std::chrono::seconds(1);
			}
			else if(app_data.verbosity > 3)
			{
				log_period = std::chrono::seconds(5);
			}
			else if(app_data.verbosity > 2)
			{
				log_period = std::chrono::seconds(10);
			}
			else if(app_data.verbosity > 1)
			{
				log_period = std::chrono::seconds(30);
			}

			auto log_time = std::chrono::system_clock::now();

			while(!common.thread_ready.Signalled())
			{
				auto now = std::chrono::system_clock::now();
				if(log_time + log_period < now)
				{
					common.LogProgress(app_data);
					log_time = now;
				}
				std::chrono::milliseconds period(50);
				std::this_thread::sleep_for(period);
			}
		}

		// wait for all raytracer threads to finish
		common.thread_ready.Wait(n_threads);

		for(unsigned b=0; b!=2; ++b)
		{
			renderer.Render(app_data);
			gl.Finish();
			common.context.SwapBuffers(pbuffer);
		}

		// save the face image
		saver.SaveFrame(app_data, rt_target, common.Face());
		// switch the face
		common.NextFace(app_data);

		// signal that the master is ready to render
		// the next face
		common.master_ready.Signal(n_threads);
	}
}
Beispiel #4
0
void thread_loop(AppData& app_data, CommonData& common, x11::Display& display, glx::Context& context)
{
	Context gl;
	ResourceAllocator alloc;
	RaytraceCopier::Params rtc_params(
		display,
		context,
		common.context
	);
	RaytraceCopier rt_copier(app_data, common.rt_target);
	RaytracerResources rt_res(app_data, common.rt_data, alloc);
	Raytracer raytracer(app_data, rt_res);
	raytracer.Use(app_data);

	std::vector<unsigned> backlog(app_data.cols());
	std::chrono::milliseconds bl_interval(100);

	while(!common.Done())
	{
		// all threads must wait until
		// the raytrace target is cleared
		common.master_ready.Wait();

		if(common.Done()) break;

		raytracer.InitFrame(app_data, common.Face());

		auto bl_begin = std::chrono::steady_clock::now();
		unsigned tile = 0;
		while(common.NextFaceTile(tile))
		{
			raytracer.Raytrace(app_data, tile);
			backlog.push_back(tile);

			auto now = std::chrono::steady_clock::now();

			if(bl_begin + bl_interval < now)
			{
				gl.Finish();
				auto lock = common.Lock();
				for(unsigned bl_tile : backlog)
				{
					rt_copier.Copy(
						app_data,
						rtc_params,
						raytracer,
						bl_tile
					);
				}
				lock.unlock();
				backlog.clear();
				bl_begin = now;
			}
			else gl.Finish();
		}
		auto lock = common.Lock();
		for(unsigned bl_tile : backlog)
		{
			rt_copier.Copy(
				app_data,
				rtc_params,
				raytracer,
				bl_tile
			);
		}
		lock.unlock();
		backlog.clear();
		gl.Finish();

		// signal to the master that the raytracing
		// of the current face has finished
		common.thread_ready.Signal();

		if(common.Done()) break;

		// wait for the master to save the face image
		common.master_ready.Wait();
	}
}
Beispiel #5
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);
	}