Example #1
0
void run_example_loop(
	const x11::Display& display,
	const x11::Window& win,
	const glx::Context& ctx,
	std::unique_ptr<Example>& example,
	ExampleThreadData::Common& common,
	ExampleClock& clock,
	GLuint width,
	GLuint height
)
{
	std::cout << "-+-[Begin]" << std::endl;
#if GL_ARB_debug_output && !OGLPLUS_NO_LAMBDAS
	ARB_debug_output dbg;
	ARB_debug_output::LogSink sink(
		[](const ARB_debug_output::CallbackData& data) -> void
		{
			std::cout << " |" << std::endl;
			std::cout << " +-+-[" << data.id << "] '" <<
				data.message << "'" << std::endl;
			std::cout << " | +---[source]   '" <<
				EnumValueName(data.source).c_str()  << "'" << std::endl;
			std::cout << " | +---[type]     '" <<
				EnumValueName(data.type).c_str()  << "'" << std::endl;
			std::cout << " | `---[severity] '" <<
				EnumValueName(data.severity).c_str()  << "'" << std::endl;
		}
	);

	dbg.Control(
		DebugOutputARBSource::DontCare,
		DebugOutputARBType::DontCare,
		DebugOutputARBSeverity::Low,
		true
	);

	dbg.InsertMessage(
		DebugOutputARBSource::Application,
		DebugOutputARBType::Other,
		0,
		DebugOutputARBSeverity::Low,
		"Starting main loop"
	);
#endif // GL_ARB_debug_output

	win.SelectInput(
		StructureNotifyMask|
		PointerMotionMask|
		KeyPressMask
	);
	::Atom wmDelete = ::XInternAtom(display, "WM_DELETE_WINDOW", True);
	::XSetWMProtocols(display, win, &wmDelete, 1);

	XEvent event;
	os::steady_clock os_clock;
	bool done = false;
	while(!done && !common.failure)
	{
		while(display.NextEvent(event))
		{
			switch(event.type)
			{
				case ClientMessage:
				case DestroyNotify:
					done = true;
					break;
				case ConfigureNotify:
					width = event.xconfigure.width;
					height = event.xconfigure.height;
					example->Reshape(
						width,
						height
					);
				case MotionNotify:
					example->MouseMove(
						event.xmotion.x,
						height-
						event.xmotion.y,
						width,
						height
					);
					break;
				case KeyPress:
					if(::XLookupKeysym(
						&event.xkey,
						0
					) == XK_Escape) done = true;
					break;
				default:;
			}
		}
		clock.Update(os_clock.seconds());
		if(!example->Continue(clock)) break;
		example->Render(clock);
		ctx.SwapBuffers(win);
	}
	std::cout << " `-[Done]" << std::endl;
}
Example #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);
	}
}