Exemple #1
0
void ZMinMax::update_buffers(const GraphicContextPtr &gc)
{
	Size texture_size = find_texture_size(normal_z);

	if (!texture0 || texture0->size() != texture_size)
	{ 
		std::string vertex_shader, fragment_shader0, fragment_shader1;
		if (gc->shader_language() == shader_glsl)
			get_shader_glsl(vertex_shader, fragment_shader0, fragment_shader1);
		else
			get_shader_hlsl(vertex_shader, fragment_shader0, fragment_shader1);

		program0 = compile_and_link(gc, vertex_shader, fragment_shader0);
		program1 = compile_and_link(gc, vertex_shader, fragment_shader1);

		Vec4f positions[6] =
		{
			Vec4f(-1.0f, -1.0f, 1.0f, 1.0f),
			Vec4f( 1.0f, -1.0f, 1.0f, 1.0f),
			Vec4f(-1.0f,  1.0f, 1.0f, 1.0f),
			Vec4f( 1.0f, -1.0f, 1.0f, 1.0f),
			Vec4f(-1.0f,  1.0f, 1.0f, 1.0f),
			Vec4f( 1.0f,  1.0f, 1.0f, 1.0f)
		};
		vertices = VertexArrayVector<Vec4f>(gc, positions, 6);

		prim_array = PrimitivesArray::create(gc);
		prim_array->set_attributes(0, vertices);

		texture0 = Texture2D::create(gc, texture_size.width, texture_size.height, tf_rg32f);
		texture0->set_min_filter(filter_nearest);
		texture0->set_mag_filter(filter_nearest);
		texture0->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge);

		texture1 = Texture2D::create(gc, texture_size.width, texture_size.height, tf_rg32f);
		texture1->set_min_filter(filter_nearest);
		texture1->set_mag_filter(filter_nearest);
		texture1->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge);

		fb0 = FrameBuffer::create(gc);
		fb0->attach_color(0, texture0);

		fb1 = FrameBuffer::create(gc);
		fb1->attach_color(0, texture1);

		BlendStateDescription blend_desc;
		blend_desc.enable_blending(false);
		blend_state = gc->create_blend_state(blend_desc);
	}

	result = (iterations % 2 == 0) ? texture1 : texture0;
}
void LightsourceSimplePass::setup(const GraphicContextPtr &gc)
{
	Size viewport_size = inout.viewport.size();
	if (!blend_state)
	{
		BlendStateDescription blend_desc;
		blend_desc.enable_blending(true);
		blend_desc.set_blend_function(blend_one, blend_one, blend_one, blend_one);
		blend_state = gc->create_blend_state(blend_desc);

		DepthStencilStateDescription icosahedron_depth_stencil_desc;
		icosahedron_depth_stencil_desc.enable_depth_write(false);
		icosahedron_depth_stencil_desc.enable_depth_test(true);
		icosahedron_depth_stencil_desc.set_depth_compare_function(compare_lequal);
		icosahedron_depth_stencil_state = gc->create_depth_stencil_state(icosahedron_depth_stencil_desc);

		RasterizerStateDescription icosahedron_rasterizer_desc;
		icosahedron_rasterizer_desc.set_culled(true);
		icosahedron_rasterizer_state = gc->create_rasterizer_state(icosahedron_rasterizer_desc);

		DepthStencilStateDescription rect_depth_stencil_desc;
		rect_depth_stencil_desc.enable_depth_write(false);
		rect_depth_stencil_desc.enable_depth_test(false);
		rect_depth_stencil_state = gc->create_depth_stencil_state(rect_depth_stencil_desc);

		RasterizerStateDescription rect_rasterizer_desc;
		rect_rasterizer_desc.set_culled(false);
		rect_rasterizer_state = gc->create_rasterizer_state(rect_rasterizer_desc);

		uniforms = UniformVector<Uniforms>(gc, 1);

		icosahedron_prim_array = PrimitivesArray::create(gc);
		icosahedron_prim_array->set_attributes(0, icosahedron->vertices);

		Vec4f positions[6] =
		{
			Vec4f(-1.0f, -1.0f, 1.0f, 1.0f),
			Vec4f( 1.0f, -1.0f, 1.0f, 1.0f),
			Vec4f(-1.0f,  1.0f, 1.0f, 1.0f),
			Vec4f( 1.0f, -1.0f, 1.0f, 1.0f),
			Vec4f(-1.0f,  1.0f, 1.0f, 1.0f),
			Vec4f( 1.0f,  1.0f, 1.0f, 1.0f)
		};
		rect_positions = VertexArrayVector<Vec4f>(gc, positions, 6);

		rect_prim_array = PrimitivesArray::create(gc);
		rect_prim_array->set_attributes(0, rect_positions);
	}
}
void ScreenViewController::render_scene(const CanvasPtr &canvas, const ScenePtr &scene)
{
	using namespace uicore;

	canvas->end();

	GraphicContextPtr gc = canvas->gc();

	Pointf viewport_pos = Vec2f(canvas->transform() * Vec4f(0.0f, 0.0f, 0.0f, 1.0f));
	Sizef viewport_size = gc->size();
	Size viewport_size_i = Size(viewport_size);

	scene->set_viewport(viewport_size_i);
	scene->render(gc);

	canvas->begin();
}
void D3DUniformBuffer::upload_data(const GraphicContextPtr &gc, const void *data, int data_size)
{
    if (data_size != size)
        throw Exception("Upload data size does not match vertex array buffer");

    auto d3d_window = static_cast<D3DGraphicContext*>(gc.get())->get_window();
    const auto &device = d3d_window->get_device();
    const auto &device_context = d3d_window->get_device_context();

    device_context->UpdateSubresource(get_handles(device).buffer, 0, 0, data, 0, 0);
}
void InstancesBuffer::render_pass(const GraphicContextPtr &gc, SceneImpl *scene, const Mat4f &world_to_eye, const Mat4f &eye_to_projection, FrustumPlanes frustum, const std::function<void(ModelLOD*, int)> &pass_callback)
{
	ScopeTimeFunction();
	scene->engine()->render.scene_visits++;

	std::vector<Model *> models;

	scene->foreach_object(frustum, [&](SceneObjectImpl *object)
	{
		if (object->instance.get_renderer())
		{
			Vec3f light_probe_color;
			if (object->light_probe_receiver())
			{
				SceneLightProbeImpl *probe = find_nearest_probe(scene, object->position());
				if (probe)
					light_probe_color = probe->color();
			}

			scene->engine()->render.instances_drawn++;
			bool first_instance = object->instance.get_renderer()->add_instance(frame, object->instance, object->get_object_to_world(), light_probe_color);
			if (first_instance)
			{
				models.push_back(object->instance.get_renderer().get());
				scene->engine()->render.models_drawn++;
			}
		}
	});

	frame++;

	clear();
	for (size_t i = 0; i < models.size(); i++)
		add(models[i]->get_instance_vectors_count());

	lock(gc);
	for (size_t i = 0; i < models.size(); i++)
		models[i]->upload(*this, world_to_eye, eye_to_projection);
	unlock(gc);

	gc->set_texture(0, get_indexes());
	gc->set_texture(1, get_vectors());

	for (Model *model : models)
	{
		pass_callback(model->levels[0].get(), model->instances.size());
	}

	// We cannot reset those because GBufferPass::run contains a hack relying on them being bound
	//gc->set_texture(0, nullptr);
	//gc->set_texture(1, nullptr);
}
Exemple #6
0
FinalPass::FinalPass(const GraphicContextPtr &gc, SceneRender &inout) : inout(inout)
{
	if (gc->shader_language() == shader_glsl)
	{
		present_shader = ShaderSetup::compile(gc, "present", vertex_present_glsl(), fragment_present_glsl(), "");
		present_shader->bind_frag_data_location(0, "FragColor");
	}
	else
	{
		present_shader = ShaderSetup::compile(gc, "present", vertex_present_hlsl(), fragment_present_hlsl(), "");
	}
	if (!present_shader->try_link())
		throw Exception("Shader linking failed!");
	present_shader->bind_attribute_location(0, "PositionInProjection");
	present_shader->set_uniform1i("FinalColors", 0);
	present_shader->set_uniform1i("FinalColorsSampler", 0);
	present_shader->set_uniform1i("LogAverageLight", 1);
	present_shader->set_uniform1i("BloomColors", 2);
	present_shader->set_uniform1i("BloomColorsSampler", 2);
	present_shader->set_uniform1i("AmbientOcclusion", 3);
	present_shader->set_uniform1i("AmbientOcclusionSampler", 3);

	Vec4f positions[6] =
	{
		Vec4f(-1.0f, -1.0f, 1.0f, 1.0f),
		Vec4f( 1.0f, -1.0f, 1.0f, 1.0f),
		Vec4f(-1.0f,  1.0f, 1.0f, 1.0f),
		Vec4f( 1.0f, -1.0f, 1.0f, 1.0f),
		Vec4f(-1.0f,  1.0f, 1.0f, 1.0f),
		Vec4f( 1.0f,  1.0f, 1.0f, 1.0f)
	};
	rect_positions = VertexArrayVector<Vec4f>(gc, positions, 6);
	rect_primarray = PrimitivesArray::create(gc);
	rect_primarray->set_attributes(0, rect_positions);

	RasterizerStateDescription rasterizer_desc;
	rasterizer_desc.set_culled(false);
	rasterizer_state = gc->create_rasterizer_state(rasterizer_desc);
}
void LightsourcePass::update_buffers(const GraphicContextPtr &gc)
{
	int needed_num_tiles_x = (inout.viewport.width() + tile_size - 1) / tile_size;
	int needed_num_tiles_y = (inout.viewport.height() + tile_size - 1) / tile_size;

	if (!compute_visible_lights.buffer() || num_tiles_x != needed_num_tiles_x || num_tiles_y != needed_num_tiles_y)
	{
		compute_visible_lights = StorageVector<unsigned int>();
		gc->flush();

		num_tiles_x = needed_num_tiles_x;
		num_tiles_y = needed_num_tiles_y;

		compute_visible_lights = StorageVector<unsigned int>(gc, num_tiles_x * num_tiles_y * light_slots_per_tile);
	}
}
LightsourcePass::LightsourcePass(const GraphicContextPtr &gc, SceneRender &inout) : inout(inout)
{
	if (gc->shader_language() == shader_glsl)
	{
		cull_tiles_program = compile_and_link(gc, "cull tiles", cull_tiles_glsl());
		render_tiles_program = compile_and_link(gc, "render tiles", render_tiles_glsl());
	}
	else
	{
		cull_tiles_program = compile_and_link(gc, "cull tiles", cull_tiles_hlsl());
		render_tiles_program = compile_and_link(gc, "render tiles", render_tiles_hlsl());
	}

	compute_uniforms = UniformVector<Uniforms>(gc, 1);
	compute_lights = StorageVector<GPULight>(gc, max_lights);
	transfer_lights = StagingVector<GPULight>(gc, max_lights);
}
LightsourceSimplePass::LightsourceSimplePass(const GraphicContextPtr &gc, SceneRender &inout) : inout(inout)
{
	if (gc->shader_language() == shader_glsl)
	{
		//icosahedron_light_program = compile_and_link(gc, vertex_icosahedron_glsl(), fragment_light_glsl());
		//rect_light_program = compile_and_link(gc, vertex_rect_glsl(), fragment_light_glsl(), "RECT_PASS");
	}
	else
	{
		icosahedron_light_program = compile_and_link(gc, vertex_icosahedron_hlsl(), fragment_light_hlsl());
		rect_light_program = compile_and_link(gc, vertex_rect_hlsl(), fragment_light_hlsl(), "RECT_PASS");
	}

	light_instance_texture = Texture1D::create(gc, max_lights * vectors_per_light, tf_rgba32f);
	light_instance_transfer = PixelBuffer::create(max_lights * vectors_per_light, 1, tf_rgba32f);

	icosahedron.reset(new Icosahedron(gc, true));
}
DiffuseGIPassCS::DiffuseGIPassCS(const GraphicContextPtr &gc, SceneRender &inout) : inout(inout)
{
	if (gc->shader_language() == shader_glsl)
	{
		//init_lpv_program = compile_and_link(gc, "init lpv", init_lpv_glsl());
		//init_gv_program = compile_and_link(gc, "init gv", init_gv_glsl());
		//propagate_lpv_program = compile_and_link(gc, "propagate lpv", propagate_lpv_glsl());
		//accumulate_lpv_program = compile_and_link(gc, "accumulate lpv", accumulate_lpv_glsl());
		//render_result_program = compile_and_link(gc, "render result", render_result_glsl());
	}
	else
	{
		init_lpv_program = compile_and_link(gc, "init lpv", init_lpv_hlsl());
		init_gv_program = compile_and_link(gc, "init gv", init_gv_hlsl());
		propagate_lpv_program = compile_and_link(gc, "propagate lpv", propagate_lpv_hlsl());
		accumulate_lpv_program = compile_and_link(gc, "accumulate lpv", accumulate_lpv_hlsl());
		render_result_program = compile_and_link(gc, "render result", render_result_hlsl());
	}
}
Exemple #11
0
void D3DUniformBuffer::copy_to(const GraphicContextPtr  &gc, const StagingBufferPtr &buffer, int dest_pos, int src_pos, int copy_size)
{
    auto d3d_window = static_cast<D3DGraphicContext*>(gc.get())->get_window();
    const auto &device = d3d_window->get_device();
    const auto &device_context = d3d_window->get_device_context();

    ComPtr<ID3D11Buffer> &staging_buffer = static_cast<D3DStagingBuffer*>(buffer.get())->get_buffer(device);
    int staging_buffer_size = static_cast<D3DStagingBuffer*>(buffer.get())->get_size();

    if (copy_size == -1)
        copy_size = staging_buffer_size;

    if (dest_pos < 0 || copy_size < 0 || dest_pos + copy_size > staging_buffer_size || src_pos < 0 || src_pos + copy_size > size)
        throw Exception("Out of bounds!");

    D3D11_BOX box;
    box.left = dest_pos;
    box.right = dest_pos + copy_size;
    box.top = 0;
    box.bottom = 1;
    box.front = 0;
    box.back = 1;
    device_context->CopySubresourceRegion(staging_buffer, 0, src_pos, 0, 0, get_handles(device).buffer, 0, &box);
}
LogAverageLight::LogAverageLight(const GraphicContextPtr &gc, SceneRender &inout, int iterations)
: inout(inout), iterations(iterations), current_index(0)
{
	Size texture_size(1 << iterations, 1 << iterations);

	std::string vertex_program =
		"#version 330\r\n"
		"in vec4 PositionInProjection;\r\n"
		"void main()\r\n"
		"{\r\n"
		"	gl_Position = PositionInProjection;\r\n"
		"}\r\n";

	std::string fragment_program0 = string_format(
		"#version 330\r\n"
		"out vec4 FragAverage;\r\n"
		"uniform sampler2D Texture;\r\n"
		"void main()\r\n"
		"{\r\n"
		"	vec3 rgb = texture(Texture, gl_FragCoord.xy / %1).rgb;\r\n"
		"	float light = max(max(rgb.r, rgb.g), rgb.b);\r\n"
		"	FragAverage = vec4(log(0.0001 + light), 0, 0, 0);\r\n"
		"}\r\n",
		texture_size.width);

	std::string fragment_program1 =
		"#version 330\r\n"
		"out vec4 FragAverage;\r\n"
		"uniform sampler2D Texture;\r\n"
		"void main()\r\n"
		"{\r\n"
		"	ivec2 pos = ivec2(gl_FragCoord.xy) * 2;\r\n"
		"	float light0 = texelFetch(Texture, pos, 0).x; \r\n"
		"	float light1 = texelFetch(Texture, pos + ivec2(1,0), 0).x; \r\n"
		"	float light2 = texelFetch(Texture, pos + ivec2(0,1), 0).x; \r\n"
		"	float light3 = texelFetch(Texture, pos + ivec2(1,1), 0).x; \r\n"
		"	FragAverage = vec4((light0 + light1 + light2 + light3) * 0.25, 0, 0, 0);\r\n"
		"}\r\n";

	std::string fragment_program2 =
		"#version 330\r\n"
		"out vec4 FragAverage;\r\n"
		"uniform sampler2D TexturePrev;\r\n"
		"uniform sampler2D TextureCurrent;\r\n"
		"void main()\r\n"
		"{\r\n"
		"	float lightPrev = texelFetch(TexturePrev, ivec2(0,0), 0).x; \r\n"
		"	float lightCurrent = exp(texelFetch(TextureCurrent, ivec2(0,0), 0).x); \r\n"
		"	float c = 0.04;\r\n"
		"	FragAverage = vec4(lightPrev + c * (lightCurrent - lightPrev), 0, 0, 0);\r\n"
		"}\r\n";

	program0 = compile_and_link(gc, vertex_program, fragment_program0);
	program1 = compile_and_link(gc, vertex_program, fragment_program1);
	program2 = compile_and_link(gc, vertex_program, fragment_program2);

	Vec4f positions[6] =
	{
		Vec4f(-1.0f, -1.0f, 1.0f, 1.0f),
		Vec4f( 1.0f, -1.0f, 1.0f, 1.0f),
		Vec4f(-1.0f,  1.0f, 1.0f, 1.0f),
		Vec4f( 1.0f, -1.0f, 1.0f, 1.0f),
		Vec4f(-1.0f,  1.0f, 1.0f, 1.0f),
		Vec4f( 1.0f,  1.0f, 1.0f, 1.0f)
	};
	vertices = VertexArrayVector<Vec4f>(gc, positions, 6);

	prim_array = PrimitivesArray::create(gc);
	prim_array->set_attributes(0, vertices);

	texture0 = Texture2D::create(gc, texture_size.width, texture_size.height, tf_r32f);
	texture0->set_min_filter(filter_nearest);
	texture0->set_mag_filter(filter_nearest);
	texture0->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge);

	texture1 = Texture2D::create(gc, texture_size.width, texture_size.height, tf_r32f);
	texture1->set_min_filter(filter_nearest);
	texture1->set_mag_filter(filter_nearest);
	texture1->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge);

	auto black = PixelBuffer::create(1, 1, tf_r32f);
	black->data<float>()[0] = 0.0f;

	result_texture0 = Texture2D::create(gc, 1, 1, tf_r32f);
	result_texture0->set_min_filter(filter_nearest);
	result_texture0->set_mag_filter(filter_nearest);
	result_texture0->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge);
	result_texture0->set_subimage(gc, 0, 0, black, black->size());

	result_texture1 = Texture2D::create(gc, 1, 1, tf_r32f);
	result_texture1->set_min_filter(filter_nearest);
	result_texture1->set_mag_filter(filter_nearest);
	result_texture1->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge);
	result_texture1->set_subimage(gc, 0, 0, black, black->size());

	fb0 = FrameBuffer::create(gc);
	fb0->attach_color(0, texture0);

	fb1 = FrameBuffer::create(gc);
	fb1->attach_color(0, texture1);

	fb2 = FrameBuffer::create(gc);
	fb2->attach_color(0, result_texture0);

	fb3 = FrameBuffer::create(gc);
	fb3->attach_color(0, result_texture1);

	BlendStateDescription blend_desc;
	blend_desc.enable_blending(false);
	blend_state = gc->create_blend_state(blend_desc);
}
Exemple #13
0
void GaussianBlur::setup(const GraphicContextPtr &gc, float blur_amount, int sample_count)
{
	for (blur_setup_index = 0; blur_setup_index < blur_setups.size(); blur_setup_index++)
	{
		if (blur_setups[blur_setup_index].blur_amount == blur_amount && blur_setups[blur_setup_index].sample_count == sample_count)
			return;
	}

	std::string vertex_shader, vertical_fragment_shader, horizontal_fragment_shader;
	if (gc->shader_language() == shader_glsl)
	{
		vertex_shader = vertex_shader_glsl();
		horizontal_fragment_shader = fragment_shader_glsl(blur_amount, sample_count, false);
		vertical_fragment_shader = fragment_shader_glsl(blur_amount, sample_count, true);
	}
	else
	{
		vertex_shader = vertex_shader_hlsl();
		horizontal_fragment_shader = fragment_shader_hlsl(blur_amount, sample_count, false);
		vertical_fragment_shader = fragment_shader_hlsl(blur_amount, sample_count, true);
	}

	auto vertex = ShaderObject::create(gc, ShaderType::vertex, vertex_shader);
	auto vertical_fragment = ShaderObject::create(gc, ShaderType::fragment, vertical_fragment_shader);
	auto horizontal_fragment = ShaderObject::create(gc, ShaderType::fragment, horizontal_fragment_shader);
	if (!vertex->try_compile())
		throw Exception(string_format("Could not compile Gaussian blur vertex shader: %1", vertex->info_log()));
	if (!vertical_fragment->try_compile())
		throw Exception(string_format("Could not compile vertical Gaussian blur fragment shader: %1", vertical_fragment->info_log()));
	if (!horizontal_fragment->try_compile())
		throw Exception(string_format("Could not compile horizontal Gaussian blur fragment shader: %1", horizontal_fragment->info_log()));

	BlurSetup blur_setup(blur_amount, sample_count);
	blur_setup.vertical_blur_program = ProgramObject::create(gc);
	blur_setup.vertical_blur_program->attach(vertex);
	blur_setup.vertical_blur_program->attach(vertical_fragment);
	blur_setup.vertical_blur_program->bind_frag_data_location(0, "FragColor");
	blur_setup.vertical_blur_program->bind_attribute_location(0, "PositionInProjection");
	if (!blur_setup.vertical_blur_program->try_link())
		throw Exception("Could not link vertical Gaussian blur program");
	blur_setup.vertical_blur_program->set_uniform1i("SourceTexture", 0);
	blur_setup.vertical_blur_program->set_uniform1i("SourceSampler", 0);

	blur_setup.horizontal_blur_program = ProgramObject::create(gc);
	blur_setup.horizontal_blur_program->attach(vertex);
	blur_setup.horizontal_blur_program->attach(horizontal_fragment);
	blur_setup.horizontal_blur_program->bind_frag_data_location(0, "FragColor");
	blur_setup.horizontal_blur_program->bind_attribute_location(0, "PositionInProjection");
	if (!blur_setup.horizontal_blur_program->try_link())
		throw Exception("Could not link horizontal Gaussian blur program");
	blur_setup.horizontal_blur_program->set_uniform1i("SourceTexture", 0);
	blur_setup.horizontal_blur_program->set_uniform1i("SourceSampler", 0);

	blur_setups.push_back(blur_setup);

	if (!gpu_positions.buffer())
	{
		Vec4f positions[6] =
		{
			Vec4f(-1.0f, -1.0f, 1.0f, 1.0f),
			Vec4f( 1.0f, -1.0f, 1.0f, 1.0f),
			Vec4f(-1.0f,  1.0f, 1.0f, 1.0f),
			Vec4f( 1.0f, -1.0f, 1.0f, 1.0f),
			Vec4f(-1.0f,  1.0f, 1.0f, 1.0f),
			Vec4f( 1.0f,  1.0f, 1.0f, 1.0f)
		};
		gpu_positions = VertexArrayVector<Vec4f>(gc, positions, 6);

		prim_array = PrimitivesArray::create(gc);
		prim_array->set_attributes(0, gpu_positions);

		BlendStateDescription blend_desc;
		blend_desc.enable_blending(false);
		blend_state = gc->create_blend_state(blend_desc);
	}
}
void LightsourcePass::find_lights(const GraphicContextPtr &gc, SceneImpl *scene)
{
	lights.clear();

	Size viewport_size = inout.viewport.size();

	Mat4f eye_to_projection = Mat4f::perspective(inout.field_of_view, viewport_size.width/(float)viewport_size.height, 0.1f, 1.e10f, handed_left, gc->clip_z_range());
	Mat4f eye_to_cull_projection = Mat4f::perspective(inout.field_of_view, viewport_size.width/(float)viewport_size.height, 0.1f, 150.0f, handed_left, clip_negative_positive_w);
	FrustumPlanes frustum(eye_to_cull_projection * inout.world_to_eye);
	scene->foreach_light(frustum, [&](SceneLightImpl *light)
	{
		if ((light->type() == SceneLight::type_omni || light->type() == SceneLight::type_spot) && light->light_caster() && lights.size() < max_lights - 1)
		{
#ifdef TEST_LIGHT_DISTANCE
			float dist = (world_to_eye * Vec4f(light->position, 1.0f)).length3() - light->attenuation_end;
			if (dist < 30.0f)
				lights.push_back(light);
#else
			lights.push_back(light);
#endif
		}
	});
}
void LightsourceSimplePass::render(const GraphicContextPtr &gc, GPUTimer &timer)
{
	ScopeTimeFunction();

	//timer.begin_time(gc, "light(simple)");

	gc->set_frame_buffer(inout.fb_final_color);

	gc->set_viewport(inout.viewport.size(), gc->texture_image_y_axis());

	gc->set_depth_range(0.0f, 0.9f);

	gc->set_uniform_buffer(0, uniforms);
	gc->set_texture(0, light_instance_texture);
	gc->set_texture(1, inout.normal_z_gbuffer);
	gc->set_texture(2, inout.diffuse_color_gbuffer);
	gc->set_texture(3, inout.specular_color_gbuffer);
	gc->set_texture(4, inout.specular_level_gbuffer);
	gc->set_texture(5, inout.shadow_maps);
	gc->set_texture(6, inout.self_illumination_gbuffer);

	gc->set_blend_state(blend_state);

	gc->clear();

	// To do: use icosahedron for smaller lights and when the camera is not inside the light influence sphere
	// To do: combine multiple lights into the same rect pass to reduce overdraw penalty

	gc->set_depth_stencil_state(rect_depth_stencil_state);
	gc->set_rasterizer_state(rect_rasterizer_state);
	gc->set_program_object(rect_light_program);

	gc->set_primitives_array(rect_prim_array);
	gc->draw_primitives_array_instanced(type_triangles, 0, 6, std::max(lights.size(), (size_t)1));
	gc->reset_primitives_array();

/*
	gc->set_depth_stencil_state(icosahedron_depth_stencil_state);
	gc->set_rasterizer_state(icosahedron_rasterizer_state);
	gc->set_program_object(icosahedron_light_program);

	gc->set_primitives_array(icosahedron_prim_array);
	gc->draw_primitives_elements_instanced(type_triangles, icosahedron->num_elements, icosahedron->elements, 0, lights.size());
	gc->reset_primitives_array();
*/

	gc->set_depth_stencil_state(icosahedron_depth_stencil_state);
	gc->set_rasterizer_state(icosahedron_rasterizer_state);
	gc->set_program_object(icosahedron_light_program);

	gc->set_primitives_array(icosahedron_prim_array);
	gc->draw_primitives_elements_instanced(type_triangles, icosahedron->num_elements, icosahedron->elements, type_unsigned_int, 0, lights.size());
	gc->reset_primitives_array();

	//timer.end_time(gc);
	//timer.begin_time(gc, "light(simple)");

	gc->reset_texture(6);
	gc->reset_texture(5);
	gc->reset_texture(4);
	gc->reset_texture(3);
	gc->reset_texture(2);
	gc->reset_texture(1);
	gc->reset_texture(0);
	gc->reset_uniform_buffer(0);

	//timer.end_time(gc);
}
Exemple #16
0
void FinalPass::run(const GraphicContextPtr &gc, SceneImpl *scene)
{
	ScopeTimeFunction();
	//Texture2DPtr &log_average_light_texture = log_average_light.find_log_average_light(gc, lightsource_pass.final_color);

	inout.bloom_contribution->set_min_filter(filter_linear);
	inout.bloom_contribution->set_mag_filter(filter_linear);
	inout.ambient_occlusion->set_min_filter(filter_linear);
	inout.ambient_occlusion->set_mag_filter(filter_linear);
	inout.final_color->set_min_filter(filter_nearest);
	inout.final_color->set_mag_filter(filter_nearest);

	if (inout.fb_viewport) gc->set_frame_buffer(inout.fb_viewport);
	gc->set_viewport(inout.viewport, gc->texture_image_y_axis());
	gc->set_texture(0, inout.final_color);
	gc->set_texture(2, inout.bloom_contribution);
	gc->set_texture(3, inout.ambient_occlusion);
	gc->set_program_object(present_shader);
	gc->set_rasterizer_state(rasterizer_state);
	gc->draw_primitives(type_triangles, 6, rect_primarray);
	gc->reset_program_object();
	gc->reset_texture(0);
	gc->reset_texture(2);
	gc->reset_texture(3);
	gc->reset_frame_buffer();
}
void LightsourceSimplePass::upload(const GraphicContextPtr &gc, SceneImpl *scene)
{
	ScopeTimeFunction();

	Size viewport_size = inout.viewport.size();
	Mat4f eye_to_projection = Mat4f::perspective(inout.field_of_view, viewport_size.width/(float)viewport_size.height, 0.1f, 1.e4f, handed_left, gc->clip_z_range());

	float aspect = inout.viewport.width()/(float)inout.viewport.height();
	float field_of_view_y_degrees = inout.field_of_view;
	float field_of_view_y_rad = (float)(field_of_view_y_degrees * PI / 180.0);
	float f = 1.0f / tan(field_of_view_y_rad * 0.5f);
	float rcp_f = 1.0f / f;
	float rcp_f_div_aspect = 1.0f / (f / aspect);
	Vec2f two_rcp_viewport_size(2.0f / inout.viewport.width(), 2.0f / inout.viewport.height());

	Uniforms cpu_uniforms;
	cpu_uniforms.eye_to_projection = eye_to_projection;
	cpu_uniforms.object_to_eye = Quaternionf::inverse(scene->camera()->orientation()).to_matrix();
	cpu_uniforms.rcp_f = rcp_f;
	cpu_uniforms.rcp_f_div_aspect = rcp_f_div_aspect;
	cpu_uniforms.two_rcp_viewport_size = two_rcp_viewport_size;
	uniforms.upload_data(gc, &cpu_uniforms, 1);

	int num_lights = lights.size();

	Mat4f normal_world_to_eye = Mat4f(Mat3f(inout.world_to_eye)); // This assumes uniform scale
	Mat4f eye_to_world = Mat4f::inverse(inout.world_to_eye);

	Vec4f *instance_data = light_instance_transfer->data<Vec4f>();

	for (int i = 0; i < num_lights; i++)
	{
		float radius = lights[i]->attenuation_end();
		if (lights[i]->rectangle_shape())
			radius *= 1.414213562373f;

		float attenuation_delta = lights[i]->attenuation_end() - lights[i]->attenuation_start();
		if (attenuation_delta == 0.0f)
			attenuation_delta = 1e-6f;
		float sqr_radius = radius * radius;
#ifdef USE_QUADRATIC_ATTENUATION
		float sqr_attenuation_start = lights[i]->attenuation_start * lights[i]->attenuation_start;
		float sqr_attenuation_delta = attenuation_delta * attenuation_delta;
#else
		float attenuation_start = lights[i]->attenuation_start();
#endif
		float sqr_falloff_begin = 0.0f;
		float light_type = 0.0f;
		if (lights[i]->type() == SceneLight::type_spot)
		{
			light_type = lights[i]->rectangle_shape() ? 2.0f : 1.0f;
			float falloff_begin = lights[i]->hotspot() / lights[i]->falloff();
			sqr_falloff_begin = falloff_begin * falloff_begin;
		}
		Vec3f position_in_eye = Vec3f(inout.world_to_eye * Vec4f(lights[i]->position(), 1.0f));
		Mat4f eye_to_shadow_projection = lights[i]->vsm_data->world_to_shadow_projection * eye_to_world;

		int shadow_map_index = lights[i]->vsm_data->shadow_map.get_index();

		instance_data[i * vectors_per_light + 0] = Vec4f(position_in_eye, (float)shadow_map_index);
		instance_data[i * vectors_per_light + 1] = Vec4f(lights[i]->color(), lights[i]->ambient_illumination());
#ifdef USE_QUADRATIC_ATTENUATION
		instance_data[i * vectors_per_light + 2] = Vec4f(sqr_radius, sqr_attenuation_start, 1.0f / sqr_attenuation_delta, sqr_falloff_begin);
#else
		instance_data[i * vectors_per_light + 2] = Vec4f(sqr_radius, attenuation_start, 1.0f / attenuation_delta, sqr_falloff_begin);
#endif
		instance_data[i * vectors_per_light + 3] = Vec4f(eye_to_shadow_projection[0], eye_to_shadow_projection[4], eye_to_shadow_projection[8], light_type);
		instance_data[i * vectors_per_light + 4] = Vec4f(eye_to_shadow_projection[1], eye_to_shadow_projection[5], eye_to_shadow_projection[9], 0.0f);
		instance_data[i * vectors_per_light + 5] = Vec4f(eye_to_shadow_projection[2], eye_to_shadow_projection[6], eye_to_shadow_projection[10], 0.0f);
	}

	instance_data[num_lights * vectors_per_light + 0] = Vec4f(0.0f);
	instance_data[num_lights * vectors_per_light + 1] = Vec4f(0.0f);
	instance_data[num_lights * vectors_per_light + 2] = Vec4f(0.0f);
	instance_data[num_lights * vectors_per_light + 3] = Vec4f(0.0f);
	instance_data[num_lights * vectors_per_light + 4] = Vec4f(0.0f);
	instance_data[num_lights * vectors_per_light + 5] = Vec4f(0.0f);

	light_instance_texture->set_image(gc, light_instance_transfer);
}
void LightsourceSimplePass::find_lights(const GraphicContextPtr &gc, SceneImpl *scene)
{
	lights.clear();

	Size viewport_size = inout.viewport.size();

	Mat4f eye_to_projection = Mat4f::perspective(inout.field_of_view, viewport_size.width/(float)viewport_size.height, 0.1f, 1.e10f, handed_left, gc->clip_z_range());
	Mat4f eye_to_cull_projection = Mat4f::perspective(inout.field_of_view, viewport_size.width/(float)viewport_size.height, 0.1f, 150.0f, handed_left, clip_negative_positive_w);
	FrustumPlanes frustum(eye_to_cull_projection * inout.world_to_eye);
	scene->foreach_light(frustum, [&](SceneLightImpl *light)
	{
		if ((light->type() == SceneLight::type_omni || light->type() == SceneLight::type_spot) && light->light_caster() && lights.size() < max_lights - 1)
		{
			lights.push_back(light);
		}
	});
}
Exemple #19
0
	std::shared_ptr<FrameBuffer> FrameBuffer::create(const GraphicContextPtr &gc)
	{
		return static_cast<GraphicContextImpl*>(gc.get())->create_frame_buffer();
	}
Exemple #20
0
std::shared_ptr<StagingBuffer> StagingBuffer::create(const GraphicContextPtr &gc, const void *data, int size, BufferUsage usage)
{
    return static_cast<GraphicContextImpl*>(gc.get())->create_staging_buffer(data, size, usage);
}
void LightsourcePass::render(const GraphicContextPtr &gc, GPUTimer &timer)
{
	ScopeTimeFunction();

	zminmax.viewport = inout.viewport;
	zminmax.normal_z = inout.normal_z_gbuffer;
	zminmax.minmax(gc);
	update_buffers(gc);

	//timer.begin_time(gc, "light(cull)");

	gc->set_uniform_buffer(0, compute_uniforms);
	gc->set_storage_buffer(0, compute_lights);
	gc->set_storage_buffer(1, compute_visible_lights);
	gc->set_texture(0, zminmax.result);
	gc->set_texture(1, inout.normal_z_gbuffer);
	gc->set_texture(2, inout.diffuse_color_gbuffer);
	gc->set_texture(3, inout.specular_color_gbuffer);
	gc->set_texture(4, inout.specular_level_gbuffer);
	gc->set_texture(5, inout.shadow_maps);
	gc->set_texture(6, inout.self_illumination_gbuffer);
	gc->set_image_texture(0, inout.final_color);

	gc->set_program_object(cull_tiles_program);
	gc->dispatch((num_tiles_x + tile_size - 1) / tile_size, (num_tiles_y + tile_size - 1) / tile_size);

	//timer.end_time(gc);
	//timer.begin_time(gc, "light(render)");

	gc->set_program_object(render_tiles_program);
	gc->dispatch(num_tiles_x, num_tiles_y);

	gc->reset_image_texture(0);
	gc->reset_texture(6);
	gc->reset_texture(5);
	gc->reset_texture(4);
	gc->reset_texture(3);
	gc->reset_texture(2);
	gc->reset_texture(1);
	gc->reset_texture(0);
	gc->reset_uniform_buffer(2);
	gc->reset_uniform_buffer(1);
	gc->reset_uniform_buffer(0);

	//timer.end_time(gc);
}
Exemple #22
0
void ZMinMax::minmax(const GraphicContextPtr &gc)
{
	update_buffers(gc);

	normal_z->set_min_filter(filter_nearest);
	normal_z->set_mag_filter(filter_nearest);
	normal_z->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge);

	gc->set_primitives_array(prim_array);
	gc->set_program_object(program0);
	gc->set_blend_state(blend_state);

	Size texture_size = find_texture_size(normal_z);

	for (int i = 0; i < iterations; i++)
	{
		if (i == 1)
			gc->set_program_object(program1);

		int iteration_width = texture_size.width >> i;
		int iteration_height = texture_size.height >> i;

		gc->set_frame_buffer((i % 2 == 0) ? fb0 : fb1);
		gc->set_viewport(Size(iteration_width, iteration_height), gc->texture_image_y_axis());
		if (i == 0)
			gc->set_texture(0, normal_z);
		else
			gc->set_texture(0, (i % 2 == 0) ? texture1 : texture0);
		gc->draw_primitives_array(type_triangles, 6);
	}

	gc->reset_texture(0);
	gc->reset_program_object();
	gc->reset_primitives_array();
	gc->reset_frame_buffer();
	gc->set_viewport(viewport.size(), gc->texture_image_y_axis());
}
	void RenderBatchTriangle::flush(const GraphicContextPtr &gc)
	{
		if (position > 0)
		{
			gc->set_program_object(program_sprite);

			int gpu_index;
			VertexArrayVector<SpriteVertex> gpu_vertices(batch_buffer->get_vertex_buffer(gc, gpu_index));

			if (!prim_array[gpu_index])
			{
				prim_array[gpu_index] = PrimitivesArray::create(gc);
				prim_array[gpu_index]->set_attributes(0, gpu_vertices, cl_offsetof(SpriteVertex, position));
				prim_array[gpu_index]->set_attributes(1, gpu_vertices, cl_offsetof(SpriteVertex, color));
				prim_array[gpu_index]->set_attributes(2, gpu_vertices, cl_offsetof(SpriteVertex, texcoord));
				prim_array[gpu_index]->set_attributes(3, gpu_vertices, cl_offsetof(SpriteVertex, texindex));

				if (!glyph_blend)
				{
					BlendStateDescription blend_desc;
					blend_desc.set_blend_function(blend_constant_color, blend_one_minus_src_color, blend_zero, blend_one);
					glyph_blend = gc->create_blend_state(blend_desc);
				}
			}

			gpu_vertices.upload_data(gc, 0, vertices, position);

			for (int i = 0; i < num_current_textures; i++)
				gc->set_texture(i, current_textures[i]);

#ifdef _DEBUG // Suppress a warning when the D3D debug layer is active (to do: add a boolean on gc that can report if a debug layer is present)
			if (num_current_textures > 0)
			{
				for (int i = num_current_textures; i < max_textures; i++)
					gc->set_texture(i, current_textures[0]);
			}
#endif

			if (use_glyph_program)
			{
				gc->set_blend_state(glyph_blend, constant_color);
				gc->draw_primitives(type_triangles, position, prim_array[gpu_index]);
				gc->reset_blend_state();
			}
			else
			{
				gc->draw_primitives(type_triangles, position, prim_array[gpu_index]);
			}

			for (int i = 0; i < num_current_textures; i++)
				gc->reset_texture(i);

#ifdef _DEBUG // Suppress a warning when the D3D debug layer is active (to do: add a boolean on gc that can report if a debug layer is present)
			if (num_current_textures > 0)
			{
				for (int i = num_current_textures; i < max_textures; i++)
					gc->reset_texture(i);
			}
#endif

			gc->reset_program_object();

			position = 0;
			for (int i = 0; i < num_current_textures; i++)
				current_textures[i] = Texture2DPtr();
			num_current_textures = 0;

		}
	}
Exemple #24
0
std::shared_ptr<Texture2D> Texture2D::create(const GraphicContextPtr &context, int width, int height, TextureFormat format, int levels)
{
    return static_cast<GraphicContextImpl*>(context.get())->create_texture_2d(width, height, format, levels);
}
Exemple #25
0
	std::shared_ptr<Texture2DArray> Texture2DArray::create(const GraphicContextPtr &context, int width, int height, int array_size, TextureFormat texture_format, int levels)
	{
		return static_cast<GraphicContextImpl*>(context.get())->create_texture_2d_array(width, height, array_size, texture_format, levels);
	}
	std::shared_ptr<ElementArrayBuffer> ElementArrayBuffer::create(const GraphicContextPtr &gc, const void *data, int size, BufferUsage usage)
	{
		return static_cast<GraphicContextImpl*>(gc.get())->create_element_array_buffer(data, size, usage);
	}