示例#1
0
	FlareExample(void)
	 : shape(shape_prog, shapes::SpiralSphere())
	 , n_flares(32)
	 , queries(n_flares)
	{
		std::vector<Vec3f> light_positions(n_flares);
		for(GLuint i=0; i!=n_flares; ++i)
		{
			const float rand_max = float(RAND_MAX);
			auto angle = FullCircles(std::rand()/rand_max);

			light_positions[i] = Vec3f(
				7.0f*Cos(angle),
				0.2f*(std::rand()/rand_max)-0.1f,
				7.0f*Sin(angle)
			);
		}

		shape_prog.light_position.Set(light_positions);
		shape_prog.color_1 = Vec3f(0.3f, 0.3f, 0.5f);
		shape_prog.color_2 = Vec3f(0.8f, 0.8f, 1.0f);

		Texture::Active(0);
		shape_prog.metal_tex.Set(0);
		metal_texture
			<< TextureTarget::_2D
			<< TextureMinFilter::LinearMipmapLinear
			<< TextureMagFilter::Linear
			<< TextureWrap::Repeat
			<< images::BrushedMetalUByte(
				512, 512,
				5120,
				-12, +12,
				32, 64
			)
			<< TextureMipmap();

		Texture::Active(1);
		UniformSampler(flare_prog, "FlareTex").Set(1);
		flare_texture
			<< TextureTarget::_2D
			<< TextureMinFilter::LinearMipmapLinear
			<< TextureMagFilter::Linear
			<< images::LoadTexture("flare_1")
			<< TextureMipmap();

		(TextureTarget::_2D|0) << TextureWrap::MirroredRepeat;
		(TextureTarget::_2D|1) << TextureWrap::Repeat;

		lights.Bind();
		try
		{
			light_pos.Bind(Buffer::Target::Array);
			Buffer::Data(Buffer::Target::Array, light_positions);

			light_prog.Use();
			VertexArrayAttrib light_attr(light_prog, "Position");
			light_attr.Setup<Vec3f>();
			light_attr.Enable();

			flare_prog.Use();
			VertexArrayAttrib flare_attr(flare_prog, "Position");
			flare_attr.Setup<Vec3f>();
			flare_attr.Enable();
		}
		catch(Error&)
		{ }

		gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::ProgramPointSize);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
		gl.CullFace(Face::Back);
		gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::One);
	}
	VolLightExample(void)
	 : volume_vs(ShaderType::Vertex, ObjectDesc("Volume vertex"))
	 , plane_vs(ShaderType::Vertex, ObjectDesc("Plane vertex"))
	 , volume_gs(ShaderType::Geometry, ObjectDesc("Volume geometry"))
	 , volume_fs(ShaderType::Fragment, ObjectDesc("Volume fragment"))
	 , plane_fs(ShaderType::Fragment, ObjectDesc("Plane fragment"))
	 , volume_prog(ObjectDesc("Volume"))
	 , plane_prog(ObjectDesc("Plane"))
	 , samples(150)
	{
		volume_vs.Source(
			"#version 330\n"
			"in vec4 Position;"
			"out float vertZOffs;"
			"uniform int SampleCount;"
			"uniform mat4 CameraMatrix;"
			"uniform vec3 ViewZ;"
			"uniform float Size;"
			"void main(void)"
			"{"
			"	float hp = (SampleCount-1) * 0.5;"
			"	vertZOffs = (gl_InstanceID - hp)/hp;"
			"	gl_Position = vec4("
			"		Position.xyz +"
			"		ViewZ*vertZOffs*Size*0.5,"
			"		1.0"
			"	);"
			"}"
		);
		volume_vs.Compile();

		volume_gs.Source(
			"#version 330\n"
			"layout(points) in;"
			"layout(triangle_strip, max_vertices = 4) out;"
			"uniform mat4 CameraMatrix, ProjectionMatrix;"
			"uniform mat4 TexProjectionMatrix;"
			"uniform vec3 ViewX, ViewY;"
			"uniform float Size;"
			"in float vertZOffs[];"
			"out vec4 geomTexCoord;"
			"void main(void)"
			"{"
			"	float zo = vertZOffs[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 * xo[i] * Size+"
			"			ViewY * yo[j] * Size,"
			"			1.0"
			"		);"
			"		geomTexCoord = "
			"			TexProjectionMatrix *"
			"			v;"
			"		gl_Position = "
			"			ProjectionMatrix *"
			"			CameraMatrix * v;"
			"		EmitVertex();"
			"	}"
			"	EndPrimitive();"
			"}"
		);
		volume_gs.Compile();

		volume_fs.Source(
			"#version 330\n"
			"uniform sampler2D LightTex;"
			"uniform int SampleCount;"
			"in vec4 geomTexCoord;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	vec2 coord = geomTexCoord.st/geomTexCoord.q;"
			"	float depth = geomTexCoord.z;"
			"	if(depth < 0.0) discard;"
			"	vec4 t  = texture(LightTex, coord*0.5 + 0.5);"
			"	if(t.a == 0.0) discard;"
			"	float alpha = 10.0*(1.0-t.a)/SampleCount;"
			"	alpha *= (t.r+t.g+t.b)*0.3333;"
			"	alpha /= sqrt(depth);"
			"	fragColor = vec4(t.rgb, alpha);"
			"}"
		);
		volume_fs.Compile();

		volume_prog.AttachShader(volume_vs);
		volume_prog.AttachShader(volume_gs);
		volume_prog.AttachShader(volume_fs);
		volume_prog.Link();
		volume_prog.Use();

		// bind the VAO for the volumes
		volume.Bind();

		// bind the VBO for the volume positions
		volume_pos.Bind(Buffer::Target::Array);
		{
			GLfloat position[3] = {0.0, 0.0, 0.0};
			Buffer::Data(Buffer::Target::Array, 3, position);
			VertexArrayAttrib attr(volume_prog, "Position");
			attr.Setup<Vec3f>();
			attr.Enable();
		}

		Vec3f lightPos(2.0f, 4.0f, -3.0f);
		auto texProjMat =
			CamMatrixf::PerspectiveX(Degrees(30), 1.0, 0.3, 20.0) *
			CamMatrixf::LookingAt(lightPos, Vec3f(0, 0, 0));

		Uniform<GLint>(volume_prog, "SampleCount").Set(samples);
		Uniform<GLfloat>(volume_prog, "Size").Set(Length(lightPos));
		Uniform<Mat4f>(volume_prog, "TexProjectionMatrix").Set(texProjMat);

		plane_vs.Source(
			"#version 330\n"
			"in vec4 Position;"
			"uniform mat4 CameraMatrix, ProjectionMatrix;"
			"uniform mat4 TexProjectionMatrix;"
			"out vec2 vertChecker;"
			"out vec4 vertTexCoord;"
			"void main(void)"
			"{"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		Position;"
			"	vertTexCoord = "
			"		TexProjectionMatrix *"
			"		Position;"
			"	vertChecker = Position.xz;"
			"}"
		);
		plane_vs.Compile();

		plane_fs.Source(
			"#version 330\n"
			"uniform sampler2D LightTex;"
			"in vec4 vertTexCoord;"
			"in vec2 vertChecker;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	vec2 coord = vertTexCoord.st/vertTexCoord.q;"
			"	vec4 t  = texture(LightTex, coord*0.5 + 0.5);"
			"	float i = ("
			"		1 +"
			"		int(vertChecker.x+10) % 2+"
			"		int(vertChecker.y+10) % 2"
			"	) % 2;"
			"	vec3 color = vec3(0.1, 0.1, 0.1);"
			"	color += t.rgb * (1.0 - t.a);"
			"	color *= mix("
			"		vec3(0.9, 0.9, 1.0), "
			"		vec3(0.4, 0.4, 0.9), "
			"		i"
			"	);"
			"	fragColor = vec4(color, 1.0);"
			"}"
		);
		plane_fs.Compile();

		plane_prog.AttachShader(plane_vs);
		plane_prog.AttachShader(plane_fs);
		plane_prog.Link();
		plane_prog.Use();

		Uniform<Mat4f>(plane_prog, "TexProjectionMatrix").Set(texProjMat);

		plane.Bind();

		// bind the VBO for the plane vertices
		plane_pos.Bind(Buffer::Target::Array);
		{
			GLfloat data[4*3] = {
				-9.0f, -4.0f,  9.0f,
				-9.0f, -4.0f, -9.0f,
				 9.0f, -4.0f,  9.0f,
				 9.0f, -4.0f, -9.0f
			};
			Buffer::Data(Buffer::Target::Array, 4*3, data);
			plane_prog.Use();
			VertexArrayAttrib attr(plane_prog, "Position");
			attr.Setup<Vec3f>();
			attr.Enable();
		}

		Texture::Active(0);
		ProgramUniformSampler(volume_prog, "LightTex").Set(0);

		light_tex
			<< Texture::Target::_2D
			<< TextureMinFilter::LinearMipmapLinear
			<< TextureMagFilter::Linear
			<< TextureWrap::ClampToBorder
			<< Vec4f(0.0f, 0.0f, 0.0f, 0.0f)
			<< images::LoadTexture("flower_glass")
			<< TextureMipmap();

		gl.ClearColor(0.0f, 0.05f, 0.1f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::One);
	}