示例#1
0
void run_example(
	const char* screenshot_path,
	int argc,
	char ** argv
)
{
	const GLuint width = 800, height = 600;

	SDLInitializer sdl_initializer("OGLplus example", width, height);
	GLAPIInitializer api_init;

	ExampleParams params(argc, argv);
	setupExample(params);
	params.Check();

	std::unique_ptr<Example> example(makeExample(params));

	example->Reshape(width, height);
	example->MouseMove(width/2, height/2, width, height);

	if(screenshot_path)
	{
		make_screenshot(
			example,
			width,
			height,
			screenshot_path
		);
	}
	else run_loop(example, width, height);
}
示例#2
0
void run_example(
	const char* screenshot_path,
	int argc,
	char** argv
)
{
	GLFWInitializer glfw_initializer;

	const GLuint width = 800, height = 600;

	GLFWwindow* window = glfwCreateWindow(
		width,
		height,
		"OGLplus example",
		NULL,
		NULL
	);
	if(!window)
	{
		throw std::runtime_error("Error creating GLFW3 window");
	}
	else
	{
		glfwMakeContextCurrent(window);
		GLAPIInitializer api_init;

		ExampleParams params(argc, argv);
		setupExample(params);
		params.Check();

		std::unique_ptr<Example> example(makeExample(params));

		example->Reshape(width, height);
		example->MouseMove(width/2, height/2, width, height);

		if(screenshot_path)
		{
			make_screenshot(
				example,
				window,
				width,
				height,
				screenshot_path
			);
		}
		else run_loop(example, window, width, height);
	}
}
示例#3
0
void run_example(
	const char* screenshot_path,
	int argc,
	char** argv
)
{
	GLFWInitializer glfw_initializer;

	const GLuint width = 800, height = 600;

	if(!glfwOpenWindow(
		width,
		height,
		8, 8, 8, 8,
		32, 8,
		GLFW_WINDOW
	)) throw std::runtime_error("Error creating GLFW window");
	else
	{
		glfwSetWindowTitle("OGLplus example");
		GLAPIInitializer api_init;

		ExampleParams params(argc, argv);
		setupExample(params);
		params.Check();

		std::unique_ptr<Example> example(makeExample(params));

		example->Reshape(width, height);
		example->MouseMove(width/2, height/2, width, height);

		if(screenshot_path)
		{
			make_screenshot(
				example,
				width,
				height,
				screenshot_path
			);
		}
		else run_loop(example, width, height);
	}
}
示例#4
0
void run_example(
	const x11::Display& display,
	const char* screenshot_path,
	const char* framedump_prefix,
	int argc,
	char ** argv
)
{
	static int visual_attribs[] =
	{
		GLX_X_RENDERABLE    , True,
		GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
		GLX_RENDER_TYPE     , GLX_RGBA_BIT,
		GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
		GLX_RED_SIZE        , 8,
		GLX_GREEN_SIZE      , 8,
		GLX_BLUE_SIZE       , 8,
		GLX_ALPHA_SIZE      , 8,
		GLX_DEPTH_SIZE      , 24,
		GLX_STENCIL_SIZE    , 8,
		GLX_DOUBLEBUFFER    , True,
		None
	};
	glx::Version version(display);
	version.AssertAtLeast(1, 3);

	glx::FBConfig fbc = glx::FBConfigs(
		display,
		visual_attribs
	).FindBest(display);

	x11::VisualInfo vi(display, fbc);

	const GLuint width = framedump_prefix?852:800;
	const GLuint height = framedump_prefix?480:600;

	x11::Window win(
		display,
		vi,
		x11::Colormap(display, vi),
		"OGLplus example",
		width, height
	);

	x11::ScreenNames screen_names;

	ExampleParams params(argc, argv);
	if(framedump_prefix) params.quality = 1.0;
	params.max_threads = 128;
	params.num_gpus = screen_names.size(); // TODO: something more reliable
	setupExample(params);
	params.Check();

	glx::Context ctx(display, fbc, 3, 3);

	ctx.MakeCurrent(win);

	// The clock for animation timing
	ExampleClock clock;

	std::vector<std::thread> threads;
	ThreadSemaphore thread_ready, master_ready;
	ExampleThreadData::Common example_thread_common_data = {
		nullptr,
		params,
		clock,
		screen_names,
		display,
		vi,
		fbc,
		ctx,
		thread_ready,
		master_ready,
		false /*failure*/,
		false /*done*/
	};
	try
	{
		// Initialize the GL API library (GLEW/GL3W/...)
		oglplus::GLAPIInitializer api_init;

		// things required for multi-threaded examples
		std::vector<ExampleThreadData> thread_data;

		// prepare the example data
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			ExampleThreadData example_thread_data = {
				t, nullptr, std::string(),
				&example_thread_common_data
			};
			thread_data.push_back(example_thread_data);
		}

		// start the examples and let them
		// create their own contexts shared with
		// the main context
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			threads.emplace_back(
				call_example_thread_main,
				std::ref(thread_data[t])
			);
			// wait for the thread to create
			// an off-screen context
			thread_ready.Wait();
			// check for errors
			if(!thread_data[t].error_message.empty())
			{
				example_thread_common_data.failure = true;
				example_thread_common_data.master_ready.Signal(t);
				throw std::runtime_error(
					thread_data[t].error_message
				);
			}
		}

		// make the example
		std::unique_ptr<Example> example(makeExample(params));

		// tell the threads about the example
		// and let them call makeExampleThread
		example_thread_common_data.example = example.get();
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			// signal that the example is ready
			master_ready.Signal();
			// wait for the threads to call makeExampleThread
			thread_ready.Wait();
		}
		// check for potential errors and let
		// the example do additional thread-related preparations
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			if(!thread_data[t].error_message.empty())
			{
				example_thread_common_data.failure = true;
				example_thread_common_data.master_ready.Signal(
					params.num_threads
				);
				throw std::runtime_error(
					thread_data[t].error_message
				);
			}
			assert(thread_data[t].example_thread);
			example->PrepareThread(t,*thread_data[t].example_thread);
		}
		// signal that the example threads may start
		// rendering
		master_ready.Signal(params.num_threads);

		example->Reshape(width, height);
		example->MouseMove(width/2, height/2, width, height);

		if(screenshot_path)
		{
			make_screenshot(
				display,
				win,
				ctx,
				example,
				clock,
				width,
				height,
				screenshot_path
			);
		}
		else if(framedump_prefix)
		{
			run_framedump_loop(
				display,
				win,
				ctx,
				example,
				clock,
				width,
				height,
				framedump_prefix
			);
		}
		else
		{
			run_example_loop(
				display,
				win,
				ctx,
				example,
				example_thread_common_data,
				clock,
				width,
				height
			);
		}
		example_thread_common_data.done = true;
		// cancel the example threads
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			if(thread_data[t].example_thread)
				thread_data[t].example_thread->Cancel();
		}
		// join the example threads
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			threads[t].join();
		}

		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			if(!thread_data[t].error_message.empty())
				throw std::runtime_error(
					thread_data[t].error_message
				);
		}
	}
	catch(...)
	{
		example_thread_common_data.failure = true;
		master_ready.Signal(params.num_threads);
		try {for(auto& thread : threads) thread.join(); }
		catch(...){ }
		throw;
	}
	ctx.Release(display);
}
示例#5
0
void run_example(
	const eglplus::Display& display,
	ExampleOptions& opts,
	int argc,
	char ** argv
)
{
	eglplus::Configs configs(
		display,
		eglplus::ConfigAttribs()
			.Add(eglplus::ConfigAttrib::RedSize, 8)
			.Add(eglplus::ConfigAttrib::GreenSize, 8)
			.Add(eglplus::ConfigAttrib::BlueSize, 8)
			.Add(eglplus::ConfigAttrib::DepthSize, 24)
			.Add(eglplus::ConfigAttrib::StencilSize, 8)
			.Add(eglplus::ConfigAttrib::SampleBuffers, opts.samples>0?1:0)
			.Add(eglplus::ConfigAttrib::Samples, opts.samples>0?opts.samples:0)
			.Add(eglplus::ColorBufferType::RGBBuffer)
			.Add(eglplus::RenderableTypeBit::OpenGL)
			.Add(eglplus::SurfaceTypeBit::Pbuffer)
			.Get()
	);

	eglplus::Config config = configs.First();


	eglplus::SurfaceAttribs surface_attribs = eglplus::SurfaceAttribs()
			.Add(eglplus::SurfaceAttrib::Width, GLint(opts.width))
			.Add(eglplus::SurfaceAttrib::Height, GLint(opts.height));

	eglplus::Surface surface = eglplus::Surface::Pbuffer(
		display,
		config,
		surface_attribs.Get()
	);

	eglplus::BindAPI(eglplus::RenderingAPI::OpenGL);

	eglplus::ContextAttribs context_attribs =
		eglplus::ContextAttribs()
			.Add(eglplus::ContextAttrib::MajorVersion, 3)
			.Add(eglplus::ContextAttrib::MinorVersion, 3)
			.Add(eglplus::OpenGLProfileBit::Core);

	eglplus::Context context(
		display,
		config,
		context_attribs.Get()
	);

	context.MakeCurrent(surface);

	ExampleParams params(argc, argv);
	params.quality = 1.0;
	params.max_threads = 128;
	params.num_gpus = 1;
	setupExample(params);
	params.Check();

	ExampleClock clock;

	std::vector<std::thread> threads;
	ThreadSemaphore thread_ready, master_ready;
	ExampleThreadData::Common example_thread_common_data = {
		nullptr,
		params,
		clock,
		display,
		config,
		surface_attribs,
		context_attribs,
		context,
		thread_ready,
		master_ready,
		false, //failure
		false //done
	};
	try
	{
		// Initialize the GL API library (GLEW/GL3W/...)
		oglplus::GLAPIInitializer api_init;

		// things required for multi-threaded examples
		std::vector<ExampleThreadData> thread_data;

		// prepare the example data
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			ExampleThreadData example_thread_data = {
				t, nullptr, std::string(),
				&example_thread_common_data
			};
			thread_data.push_back(example_thread_data);
		}

		// start the examples and let them
		// create their own contexts shared with
		// the main context
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			threads.emplace_back(
				call_example_thread_main,
				std::ref(thread_data[t])
			);
			// wait for the thread to create
			// an off-screen context
			thread_ready.Wait();
			// check for errors
			if(!thread_data[t].error_message.empty())
			{
				example_thread_common_data.failure = true;
				example_thread_common_data.master_ready.Signal(t);
				throw std::runtime_error(
					thread_data[t].error_message
				);
			}
		}

		// make the example
		std::unique_ptr<Example> example(makeExample(params));

		// tell the threads about the example
		// and let them call makeExampleThread
		example_thread_common_data.example = example.get();
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			// signal that the example is ready
			master_ready.Signal();
			// wait for the threads to call makeExampleThread
			thread_ready.Wait();
		}
		// check for potential errors and let
		// the example do additional thread-related preparations
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			if(!thread_data[t].error_message.empty())
			{
				example_thread_common_data.failure = true;
				example_thread_common_data.master_ready.Signal(
					params.num_threads
				);
				throw std::runtime_error(
					thread_data[t].error_message
				);
			}
			assert(thread_data[t].example_thread);
			example->PrepareThread(t,*thread_data[t].example_thread);
		}
		// signal that the example threads may start
		// rendering
		master_ready.Signal(params.num_threads);

		example->Reshape(opts.width, opts.height);
		example->MouseMove(opts.width/2, opts.height/2, opts.width, opts.height);

		if(opts.screenshot_path)
		{
			make_screenshot(surface, example, clock, opts);
		}
		else if(opts.framedump_prefix)
		{
			run_framedump_loop(surface, example, clock, opts);
		}
		else assert(!"Never should get here!");

		example_thread_common_data.done = true;
		// cancel the example threads
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			if(thread_data[t].example_thread)
			{
				thread_data[t].example_thread->Cancel();
			}
		}
		// join the example threads
		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			threads[t].join();
		}

		for(unsigned t=0; t!=params.num_threads; ++t)
		{
			if(!thread_data[t].error_message.empty())
			{
				throw std::runtime_error(
					thread_data[t].error_message
				);
			}
		}
	}
	catch(...)
	{
		example_thread_common_data.failure = true;
		master_ready.Signal(params.num_threads);
		try {for(auto& thread : threads) thread.join(); }
		catch(...){ }
		throw;
	}
}