Example #1
0
	double Draw(double time)
	{
		assert(!shapes.empty());
		assert(ishape != shapes.end());
		shapes::ShapeWrapper& shape = *ishape;


		const double interval = 11.0;
		double segment = time - shape_time;
		double fade = segment*(interval-segment);
		fade -= 1.0;
		if(fade < 0.0) fade = 0.0;
		fade = std::sqrt(fade/interval);
		if(fade > 1.0) fade = 1.0;

		if(segment > interval)
		{
			if(++ishape == shapes.end())
			{
				ishape = shapes.begin();
			}
			shape_time = time;
		}

		gl.Clear().DepthBuffer();

		float dist = (1.0+SineWave(time / 13.0))*2.5;

		projection_matrix.Set(
			CamMatrixf::PerspectiveX(
				Degrees(45),
				1.0,
				1.0+dist,
				shape.BoundingSphere().Radius()*2.0+1.0+dist
			)
		);

		camera_matrix.Set(
			CamMatrixf::Orbiting(
				Vec3f(),
				shape.BoundingSphere().Radius()+1.5+dist,
				FullCircles(time / 27.0),
				Degrees(SineWave(time / 23.0) * 89)
			)
		);
		model_matrix.Set(
			ModelMatrixf::RotationA(
				Vec3f(1,1,1),
				FullCircles(time /-37.0)
			)
		);

		prog.Use();
		shape.Use();
		shape.Draw();

		return fade;
	}
Example #2
0
	void Render(double time)
	{
		fbo.Bind(Framebuffer::Target::Draw);

		gl.Clear().ColorBuffer().DepthBuffer();

		main_prog.Use();
		cube.Bind();

		camera_matrix.Set(
			CamMatrixf::Orbiting(
				Vec3f(),
				20.5,
				FullCircles(time / 20.0),
				Degrees(SineWave(time / 25.0) * 30)
			)
		);

		auto i = cube_matrices.begin(), e = cube_matrices.end();
		while(i != e)
		{
			model_matrix.Set(*i);
			ambient_color.Set(0.7f, 0.6f, 0.2f);
			diffuse_color.Set(1.0f, 0.8f, 0.3f);
			face_instr.Draw(face_indices);

			ambient_color.Set(0.1f, 0.1f, 0.1f);
			diffuse_color.Set(0.3f, 0.3f, 0.3f);
			edge_instr.Draw(edge_indices);
			++i;
		}

		dfb.Bind(Framebuffer::Target::Draw);

		gl.Clear().ColorBuffer().DepthBuffer();

		dof_prog.Use();
		screen.Bind();

		focus_depth.Set(0.6 + SineWave(time / 9.0)*0.3);

		gl.Enable(Capability::Blend);
		gl.DrawArrays(PrimitiveType::TriangleStrip, 0, 4);
		gl.Disable(Capability::Blend);
	}
Example #3
0
	void RenderPlane(std::size_t p)
	{
		gl.Enable(Capability::Blend);
		plane_prog.Use();
		plane_normal.Set(make_plane[p].Normal());
		plane[p].Bind();
		plane_instr.Draw(plane_indices);
		gl.Disable(Capability::Blend);
	}
Example #4
0
	void Reshape(GLuint vp_width, GLuint vp_height)
	{
		width = vp_width;
		height = vp_height;
		tex_side = width < height ? width : height;

		gl.Viewport(width, height);

		Mat4f projection = CamMatrixf::PerspectiveX(
			Degrees(48),
			float(width)/height,
			1, 15
		);
		plane_prog.Use();
		plane_proj_matrix.Set(projection);
		shape_prog.Use();
		shape_proj_matrix.Set(projection);
	}
Example #5
0
	void Render(const Mat4f& model)
	{
		prog.Use();
		model_matrix.Set(model);
		// bind the VAO
		sphere.Bind();
		// use the instructions to draw the sphere
		// (this basically calls glDrawArrays* or glDrawElements*)
		sphere_instr.Draw(sphere_indices);
	}
	static Program make_prog(void)
	{
		VertexShader vs;
		vs.Source(
			"#version 130\n"
			"uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;"
			"uniform vec4 ClipPlane;"
			"attribute vec4 Position;"
			"attribute vec2 TexCoord;"
			"varying vec2 vertTexCoord;"
			"void main(void)"
			"{"
			"	vertTexCoord = TexCoord;"
			"	gl_Position = "
			"		ModelMatrix *"
			"		Position;"
			"	gl_ClipDistance[0] = dot(ClipPlane, gl_Position);"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		gl_Position;"
			"}"
		);
		vs.Compile();

		FragmentShader fs;
		fs.Source(
			"#version 130\n"
			"varying vec2 vertTexCoord;"
			"void main(void)"
			"{"
			"	float i = ("
			"		int(vertTexCoord.x*36) % 2+"
			"		int(vertTexCoord.y*24) % 2"
			"	) % 2;"
			"	if(gl_FrontFacing)"
			"	{"
			"		gl_FragColor = vec4(1-i/2, 1-i/2, 1-i/2, 1.0);"
			"	}"
			"	else"
			"	{"
			"		gl_FragColor = vec4(0+i/2, 0+i/2, 0+i/2, 1.0);"
			"	}"
			"}"
		);
		fs.Compile();

		Program prog;
		prog.AttachShader(vs);
		prog.AttachShader(fs);
		prog.Link();
		prog.Use();

		return prog;
	}
Example #7
0
	void Reshape(GLuint width, GLuint height)
	{
		gl.Viewport(width, height);
		auto projection = CamMatrixf::PerspectiveX(
			Degrees(60),
			double(width)/height,
			1, 20
		);
		prog.Use();
		projection_matrix.Set(projection);
	}
Example #8
0
	void Reshape(GLuint width, GLuint height)
	{
		gl.Viewport(width, height);
		prog.Use();
		projection_matrix.Set(
			CamMatrixf::PerspectiveX(
				Degrees(75),
				double(width)/height,
				1, 30
			)
		);
	}
Example #9
0
	void Reshape(GLuint width, GLuint height)
	{
		gl.Viewport(width, height);
		prog.Use();
		Uniform<Mat4f>(prog, "ProjectionMatrix").Set(
			CamMatrixf::PerspectiveX(
				Degrees(70),
				double(width)/height,
				1, 20
			)
		);
	}
Example #10
0
	void Render(double time)
	{
		gl.Clear().ColorBuffer().DepthBuffer();

		auto camera = CamMatrixf::Orbiting(
			Vec3f(),
			8.5,
			FullCircles(time / 5.0),
			Degrees(15 + (-SineWave(time/10.0)+1.0)* 0.5 * 75)
		);
		ModelMatrixf model =
			ModelMatrixf::Translation(0.0f, 2.5f, 0.0) *
			ModelMatrixf::RotationA(
				Vec3f(1.0f, 1.0f, 1.0f),
				FullCircles(time / 7.0)
			);

		plane_prog.Use();
		plane_camera_matrix.Set(camera);

		plane.Bind();
		gl.DrawArrays(PrimitiveType::TriangleStrip, 0, 4);

		shape_prog.Use();
		shape_camera_matrix.Set(camera);

		shape_model_matrix.Set(model);
		shape.Bind();
		shape_instr.Draw(shape_indices);

		halo_prog.Use();
		halo_camera_matrix.Set(camera);
		halo_model_matrix.Set(model);

		gl.DepthMask(false);
		gl.Enable(Capability::Blend);
		shape_instr.Draw(shape_indices);
		gl.Disable(Capability::Blend);
		gl.DepthMask(true);
	}
	void Render(double time)
	{
		gl.Clear().ColorBuffer().DepthBuffer();

		auto cameraMatrix = CamMatrixf::Orbiting(
			Vec3f(0.0f, 3.0f, 0.0f),
			8.0f,
			FullCircles(time / 12.0),
			Degrees(SineWave(time / 20.0) * 80)
		);

		plane.Bind();
		plane_prog.Use();
		Uniform<Mat4f>(plane_prog, "CameraMatrix").Set(cameraMatrix);

		gl.DrawArrays(PrimitiveType::TriangleStrip, 0, 4);

		gl.Enable(Capability::Blend);

		volume.Bind();
		volume_prog.Use();
		Uniform<Mat4f>(volume_prog, "CameraMatrix").Set(cameraMatrix);
		Uniform<Vec3f>(volume_prog, "ViewX").Set(
			cameraMatrix.Row(0).xyz()
		);
		Uniform<Vec3f>(volume_prog, "ViewY").Set(
			cameraMatrix.Row(1).xyz()
		);
		Uniform<Vec3f>(volume_prog, "ViewZ").Set(
			cameraMatrix.Row(2).xyz()
		);
		gl.DrawArraysInstanced(
			PrimitiveType::Points,
			0, 1,
			samples
		);

		gl.Disable(Capability::Blend);
	}
Example #12
0
    void Render(double time)
    {
        gl.Clear().ColorBuffer().DepthBuffer();

        auto lightPos = light_path.Position(time * 0.05);
        auto cameraMatrix = CamMatrixf::Orbiting(
                                Vec3f(),
                                4.5f,
                                Degrees(0),
                                Degrees(SineWave(time / 20.0) * 80)
                            );

        light.Bind();
        light_prog.Use();

        Uniform<Vec3f>(light_prog, "LightPos").Set(lightPos);
        Uniform<Mat4f>(light_prog, "CameraMatrix").Set(cameraMatrix);

        sphere_instr.Draw(sphere_indices);

        clouds.Bind();
        cloud_prog.Use();

        Uniform<Vec3f>(cloud_prog, "LightPos").Set(lightPos);
        Uniform<Mat4f>(cloud_prog, "CameraMatrix").Set(cameraMatrix);
        Uniform<Vec4f>(cloud_prog, "ViewX").Set(cameraMatrix.Row(0));
        Uniform<Vec4f>(cloud_prog, "ViewY").Set(cameraMatrix.Row(1));
        Uniform<Vec4f>(cloud_prog, "ViewZ").Set(cameraMatrix.Row(2));
        for(std::size_t i=0, n=positions.size(); i!=n; ++i)
        {
            cloud_tex[i].Bind(Texture::Target::_3D);
            gl.DrawArraysInstanced(
                PrimitiveType::Points,
                i, 1,
                samples
            );
        }
    }
Example #13
0
	Particle(const VertexShader& vs, FragmentShader&& frag)
	 : sphere_instr(make_sphere.Instructions())
	 , sphere_indices(make_sphere.Indices())
	 , fs(std::forward<FragmentShader>(frag))
	{
		// attach the shaders to the program
		prog.AttachShader(vs);
		prog.AttachShader(fs);
		// link and use it
		prog.Link();
		prog.Use();

		projection_matrix = (prog/"ProjectionMatrix");
		camera_matrix = (prog/"CameraMatrix");
		model_matrix = (prog/"ModelMatrix");
		light_pos = (prog/"LightPos");

		// bind the VAO for the sphere
		sphere.Bind();

		const GLuint n_attr = 2;
		// pointers to the vertex attribute data build functions
		typedef GLuint (shapes::Sphere::*Func)(std::vector<GLfloat>&) const;
		Func func[n_attr] = {
			&shapes::Sphere::Positions,
			&shapes::Sphere::Normals,
		};
		// managed references to the VBOs
		Reference<Buffer> vbo[n_attr] = {verts, normals};
		// vertex attribute identifiers from the shaders
		const GLchar* ident[n_attr] = {"Position", "Normal"};

		for(GLuint i=0; i!=n_attr; ++i)
		{
			// bind the VBO
			vbo[i].Bind(Buffer::Target::Array);
			// make the data
			std::vector<GLfloat> data;
			GLuint n_per_vertex = (make_sphere.*func[i])(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			// setup the vertex attrib
			VertexArrayAttrib attr(prog, ident[i]);
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}
	}
	void Use(void)
	{
		gl.ClearDepth(1.0f);
		gl.ClearColor(0.8f, 0.8f, 0.8f, 0.0f);

		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
		gl.CullFace(Face::Back);

		dfb.Bind(Framebuffer::Target::Draw);
		gl.Viewport(width, height);

		prog.Use();
		cube.Use();

		SetProjection();
	}
	void Use(void)
	{
		gl.ClearDepth(1.0f);
		gl.ClearColor(0.9f, 0.4f, 0.4f, 1.0f);

		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
		gl.CullFace(Face::Back);

		fbo.Bind(Framebuffer::Target::Draw);
		gl.Viewport(tex_side, tex_side);

		prog.Use();
		shape.Use();

		projection_matrix.Set(CamMatrixf::PerspectiveX(Degrees(48), 1.0, 1, 100));
	}
	void Render(
		const Vec3f& light,
		const Mat4f& camera,
		const Mat4f& model
	)
	{
		// use the shading program
		prog.Use();
		// set the uniforms
		light_pos.Set(light);
		camera_matrix.Set(camera);
		model_matrix.Set(model);
		// bind the VAO
		shape.Bind();
		// use the instructions to draw the shape
		// (this basically calls glDrawArrays* or glDrawElements*)
		shape_instr.Draw(shape_indices);
	}
Example #17
0
void Uniform::Bind(const Program& program, const std::string& name, const Vector4& value)
{
	GLint location = program[name];
	if (location != -1)
	{
		if (Program::msCurrentlyInUse == program.mProgram)
			glUniform4fv(location, 1, value);
		else
		{
			GLint current;
			glGetIntegerv(GL_CURRENT_PROGRAM, &current);
			program.Use();
			glUniform3fv(location, 1, value);
			glUseProgram(current);
			Program::msCurrentlyInUse = current;
		}
	}
	checkOpenGLError("Failed to bind uniform " + name);
}
Example #18
0
void Game::SwapBuffers() {
	Program* p = this->_blitProgram;

	if (this->_paused) {
		p = this->_blitProgramMap["Sepia"];
	}

	if (p != NULL && p->ProgramId != 0) {
		p->Use();
		p->BindTextures();
		if (this->_paused) {
			p->SetUniform("sepiaRgb", vec3(1.2f, 1.0f, 0.8f));
		}
		p->SetUniform("iGlobalTime", (float)this->_totalTicks);
		p->SetUniform("MVP", GLFuncs::GetInstance()->StaticProjection);
		p->SetUniform("iResolution", vec2(this->_g->DisplayWidth, this->_g->DisplayHeight));
	}

	this->_g->SwapBuffers();
}
	CubeMapExample(void)
	 : make_shape(4)
	 , shape_instr(make_shape.Instructions())
	 , shape_indices(make_shape.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	{
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"out vec3 vertNormal;"
			"out vec3 vertTexCoord;"
			"out vec3 vertLightDir;"
			"out vec3 vertViewDir;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	vec3 Normal = Position.xyz;"
			"	gl_Position = ModelMatrix * Position;"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	vertTexCoord = Normal;"
			"	vertLightDir = LightPos - gl_Position.xyz;"
			"	vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)*CameraMatrix).xyz;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		vs.Compile();

		gs.Source(
			"#version 330\n"
			"layout (triangles) in;"
			"layout (triangle_strip, max_vertices = 3) out;"

			"in vec3 vertNormal[3];"
			"in vec3 vertTexCoord[3];"
			"in vec3 vertLightDir[3];"
			"in vec3 vertViewDir[3];"

			"out vec3 geomNormal;"
			"out vec3 geomTexCoord;"
			"out vec3 geomLightDir;"
			"out vec3 geomLightRefl;"
			"out vec3 geomViewDir;"

			"void main(void)"
			"{"
			"	vec3 FaceNormal = 0.333333*("
			"		vertNormal[0]+"
			"		vertNormal[1]+"
			"		vertNormal[2] "
			"	);"
			"	for(int v=0; v!=3; ++v)"
			"	{"
			"		gl_Position = gl_in[v].gl_Position;"
			"		geomNormal = 0.5*(vertNormal[v]+FaceNormal);"
			"		geomTexCoord = vertTexCoord[v];"
			"		geomLightDir = vertLightDir[v];"
			"		geomLightRefl = reflect("
			"			-normalize(geomLightDir),"
			"			normalize(FaceNormal)"
			"		);"
			"		geomViewDir = vertViewDir[v];"
			"		EmitVertex();"
			"	}"
			"	EndPrimitive();"
			"}"
		);
		gs.Compile();

		fs.Source(
			"#version 330\n"
			"uniform samplerCube TexUnit;"
			"in vec3 geomNormal;"
			"in vec3 geomTexCoord;"
			"in vec3 geomLightDir;"
			"in vec3 geomLightRefl;"
			"in vec3 geomViewDir;"
			"out vec3 fragColor;"
			"void main(void)"
			"{"
			"	vec3 lt = vec3(1.0, 1.0, 1.0);"
			"	vec3 tex = texture(TexUnit, geomTexCoord).rgb;"
			"	float d = dot("
			"		normalize(geomNormal), "
			"		normalize(geomLightDir)"
			"	);"
			"	float s = dot("
			"		normalize(geomLightRefl),"
			"		normalize(geomViewDir)"
			"	);"
			"	float b = 1.0-sqrt(max(dot("
			"		normalize(geomNormal),"
			"		normalize(geomViewDir)"
			"	), 0.0));"
			"	float ea = clamp(tex.b*(-d+0.2), 0.0, 1.0);"
			"	float sr = 1.0-tex.b*0.8;"

			"	fragColor = "
			"		tex * (0.3*ea + 0.6*b + 0.8*max(d, 0.0)) + "
			"		(tex+lt) * 0.8*sr*pow(clamp(s+0.05, 0.0, 1.0), 32);"
			"}"
		);
		fs.Compile();

		// attach the shaders to the program
		prog.AttachShader(vs);
		prog.AttachShader(gs);
		prog.AttachShader(fs);
		// link and use it
		prog.Link();
		prog.Use();

		// bind the VAO for the shape
		shape.Bind();

		positions.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_shape.Positions(data);
			Buffer::Data(Buffer::Target::Array, data);
			VertexAttribArray attr(prog, "Position");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		// setup the texture
		{
			auto bound_tex = Bind(tex, Texture::Target::CubeMap);
			bound_tex.MinFilter(TextureMinFilter::Linear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::ClampToEdge);
			bound_tex.WrapT(TextureWrap::ClampToEdge);
			bound_tex.WrapR(TextureWrap::ClampToEdge);

			const char* tex_name[6] = {
				"cube_0_right",
				"cube_1_left",
				"cube_2_top",
				"cube_3_bottom",
				"cube_4_front",
				"cube_5_back"
			};
			for(GLuint i=0; i!=6; ++i)
			{
				Texture::Image2D(
					Texture::CubeMapFace(i),
					images::LoadTexture(tex_name[i], false, true)
				);
			}
		}
		UniformSampler(prog, "TexUnit").Set(0);

		//
		Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(3.0f, 5.0f, 4.0f));
		//
		gl.ClearColor(0.05f, 0.2f, 0.1f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);

		gl.Enable(Capability::CullFace);
		gl.FrontFace(make_shape.FaceWinding());
		gl.CullFace(Face::Back);
	}
Example #20
0
	ReflectionExample(void)
	 : torus_indices(make_torus.Indices())
	 , torus_instr(make_torus.Instructions())
	 , vs_norm(ObjectDesc("Vertex-Normal"))
	 , vs_refl(ObjectDesc("Vertex-Reflection"))
	 , gs_refl(ObjectDesc("Geometry-Reflection"))
	{
		namespace se = oglplus::smart_enums;
		// Set the normal object vertex shader source
		vs_norm.Source(
			"#version 330\n"
			"in vec4 Position;"
			"in vec3 Normal;"
			"out vec3 geomColor;"
			"out vec3 geomNormal;"
			"out vec3 geomLight;"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	gl_Position = ModelMatrix * Position;"
			"	geomColor = Normal;"
			"	geomNormal = mat3(ModelMatrix)*Normal;"
			"	geomLight = LightPos-gl_Position.xyz;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		// compile it
		vs_norm.Compile();

		// Set the reflected object vertex shader source
		// which just passes data to the geometry shader
		vs_refl.Source(
			"#version 330\n"
			"in vec4 Position;"
			"in vec3 Normal;"
			"out vec3 vertNormal;"
			"void main(void)"
			"{"
			"	gl_Position = Position;"
			"	vertNormal = Normal;"
			"}"
		);
		// compile it
		vs_refl.Compile();

		// Set the reflected object geometry shader source
		// This shader creates a reflection matrix that
		// relies on the fact that the reflection is going
		// to be done by the y-plane
		gs_refl.Source(
			"#version 330\n"
			"layout(triangles) in;"
			"layout(triangle_strip, max_vertices = 6) out;"

			"in vec3 vertNormal[];"

			"uniform mat4 ProjectionMatrix;"
			"uniform mat4 CameraMatrix;"
			"uniform mat4 ModelMatrix;"

			"out vec3 geomColor;"
			"out vec3 geomNormal;"
			"out vec3 geomLight;"
			"uniform vec3 LightPos;"

			"mat4 ReflectionMatrix = mat4("
			"	1.0, 0.0, 0.0, 0.0,"
			"	0.0,-1.0, 0.0, 0.0,"
			"	0.0, 0.0, 1.0, 0.0,"
			"	0.0, 0.0, 0.0, 1.0 "
			");"
			"void main(void)"
			"{"
			"	for(int v=0; v!=gl_in.length(); ++v)"
			"	{"
			"		vec4 Position = gl_in[v].gl_Position;"
			"		gl_Position = ModelMatrix * Position;"
			"		geomColor = vertNormal[v];"
			"		geomNormal = mat3(ModelMatrix)*vertNormal[v];"
			"		geomLight = LightPos - gl_Position.xyz;"
			"		gl_Position = "
			"			ProjectionMatrix *"
			"			CameraMatrix *"
			"			ReflectionMatrix *"
			"			gl_Position;"
			"		EmitVertex();"
			"	}"
			"	EndPrimitive();"
			"}"
		);
		// compile it
		gs_refl.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"in vec3 geomColor;"
			"in vec3 geomNormal;"
			"in vec3 geomLight;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float l = length(geomLight);"
			"	float d = l > 0.0 ? dot("
			"		geomNormal, "
			"		normalize(geomLight)"
			"	 ) / l : 0.0;"
			"	float i = 0.2 + max(d, 0.0) * 2.0;"
			"	fragColor = vec4(abs(geomNormal)*i, 1.0);"
			"}"
		);
		// compile it
		fs.Compile();

		// attach the shaders to the normal rendering program
		prog_norm.AttachShader(vs_norm);
		prog_norm.AttachShader(fs);
		// link it
		prog_norm.Link();

		// attach the shaders to the reflection rendering program
		prog_refl.AttachShader(vs_refl);
		prog_refl.AttachShader(gs_refl);
		prog_refl.AttachShader(fs);
		// link it
		prog_refl.Link();

		// bind the VAO for the torus
		torus.Bind();

		// bind the VBO for the torus vertices
		torus_verts.Bind(se::Array());
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.Positions(data);
			// upload the data
			Buffer::Data(se::Array(), data);

			// setup the vertex attribs array for the vertices
			typedef VertexAttribArray VAA;
			VertexAttribSlot
				loc_norm = VAA::GetLocation(prog_norm, "Position"),
				loc_refl = VAA::GetLocation(prog_refl, "Position");

			assert(loc_norm == loc_refl);
			VertexAttribArray attr(loc_norm);
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		// bind the VBO for the torus normals
		torus_normals.Bind(se::Array());
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.Normals(data);
			// upload the data
			Buffer::Data(se::Array(), data);

			// setup the vertex attribs array for the normals
			typedef VertexAttribArray VAA;
			VertexAttribSlot
				loc_norm = VAA::GetLocation(prog_norm, "Normal"),
				loc_refl = VAA::GetLocation(prog_refl, "Normal");

			assert(loc_norm == loc_refl);
			VertexAttribArray attr(loc_norm);
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		// bind the VAO for the plane
		plane.Bind();

		// bind the VBO for the plane vertices
		plane_verts.Bind(se::Array());
		{
			GLfloat data[4*3] = {
				-2.0f, 0.0f,  2.0f,
				-2.0f, 0.0f, -2.0f,
				 2.0f, 0.0f,  2.0f,
				 2.0f, 0.0f, -2.0f
			};
			// upload the data
			Buffer::Data(se::Array(), 4*3, data);
			// setup the vertex attribs array for the vertices
			prog_norm.Use();
			VertexAttribArray attr(prog_norm, "Position");
			attr.Setup<Vec3f>();
			attr.Enable();
		}

		// bind the VBO for the torus normals
		plane_normals.Bind(se::Array());
		{
			GLfloat data[4*3] = {
				-0.1f, 1.0f,  0.1f,
				-0.1f, 1.0f, -0.1f,
				 0.1f, 1.0f,  0.1f,
				 0.1f, 1.0f, -0.1f
			};
			// upload the data
			Buffer::Data(se::Array(), 4*3, data);
			// setup the vertex attribs array for the normals
			prog_norm.Use();
			VertexAttribArray attr(prog_norm, "Normal");
			attr.Setup<Vec3f>();
			attr.Enable();
		}
		VertexArray::Unbind();

		Vec3f lightPos(2.0f, 2.0f, 3.0f);
		prog_norm.Use();
		SetUniform(prog_norm, "LightPos", lightPos);
		prog_refl.Use();
		SetUniform(prog_refl, "LightPos", lightPos);
		//
		gl.ClearColor(0.2f, 0.2f, 0.2f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.ClearStencil(0);
	}
Example #21
0
	CubeExample(void)
	 : cube_instr(make_cube.Instructions())
	 , cube_indices(make_cube.Indices())
	{
		// Set the vertex shader source
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix;"
			"in vec4 Position;"
			"in vec2 TexCoord;"
			"out vec2 vertTexCoord;"
			"void main(void)"
			"{"
			"	vertTexCoord = TexCoord;"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		Position;"
			"}"
		);
		// compile it
		vs.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"in vec2 vertTexCoord;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float i = ("
			"		1 +"
			"		int(vertTexCoord.x*8) % 2+"
			"		int(vertTexCoord.y*8) % 2"
			"	) % 2;"
			"	fragColor = vec4(i, i, i, 1.0);"
			"}"
		);
		// compile it
		fs.Compile();

		// attach the shaders to the program
		prog.AttachShader(vs);
		prog.AttachShader(fs);
		// link and use it
		prog.Link();
		prog.Use();

		// bind the VAO for the cube
		cube.Bind();

		// bind the VBO for the cube vertices
		verts.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.Positions(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			// setup the vertex attribs array for the vertices
			VertexAttribArray attr(prog, "Position");
			attr.Setup(n_per_vertex, DataType::Float);
			attr.Enable();
		}

		// bind the VBO for the cube texture-coordinates
		texcoords.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.TexCoordinates(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			// setup the vertex attribs array for the vertices
			VertexAttribArray attr(prog, "TexCoord");
			attr.Setup(n_per_vertex, DataType::Float);
			attr.Enable();
		}
		//
		gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
	}
Example #22
0
	LandscapeExample(void)
	 : grid_side(8)
	 , make_plane(
		Vec3f(0.0f, 0.0f, 0.0f),
		Vec3f(1.0f, 0.0f, 0.0f),
		Vec3f(0.0f, 0.0f,-1.0f),
		grid_side, grid_side
	), plane_instr(make_plane.Instructions())
	 , plane_indices(make_plane.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , vc_int(prog, "vc_int")
	 , gc_int(prog, "gc_int")
	 , fc_int(prog, "fc_int")
	{
		VertexShader vs;
		vs.Source(StrLit(
			"#version 420\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix;"

			"layout(binding = 0, offset = 0) uniform atomic_uint vc;"
			"const float mult = 1.0/128.0;"
			"uniform float vc_int;"

			"in vec4 Position;"

			"out vec3 vertColor;"

			"void main(void)"
			"{"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		Position;"
			"	vertColor = vec3("
			"		fract(atomicCounterIncrement(vc)*mult),"
			"		0.0,"
			"		0.0 "
			"	)*max(vc_int, 0.0);"
			"}"
		));
		vs.Compile();
		prog.AttachShader(vs);

		GeometryShader gs;
		gs.Source(StrLit(
			"#version 420\n"
			"layout (triangles) in;"
			"layout (triangle_strip, max_vertices = 3) out;"

			"layout(binding = 0, offset = 4) uniform atomic_uint gc;"
			"const float mult = 1.0/128.0;"
			"uniform float gc_int;"

			"in vec3 vertColor[3];"

			"out vec3 geomColor;"

			"void main(void)"
			"{"
			"	vec3 Color = vec3("
			"		0.0,"
			"		fract(atomicCounterIncrement(gc)*mult),"
			"		0.0 "
			"	)*max(gc_int, 0.0);"
			"	for(int v=0; v!=3; ++v)"
			"	{"
			"		gl_Position = gl_in[v].gl_Position;"
			"		geomColor = vertColor[v] + Color;"
			"		EmitVertex();"
			"	}"
			"	EndPrimitive();"
			"}"
		));
		gs.Compile();
		prog.AttachShader(gs);

		FragmentShader fs;
		fs.Source(StrLit(
			"#version 420\n"

			"layout(binding = 0, offset = 8) uniform atomic_uint fc;"
			"const float mult = 1.0/4096.0;"
			"uniform float fc_int;"

			"in vec3 geomColor;"

			"out vec3 fragColor;"

			"void main(void)"
			"{"
			"	vec3 Color = vec3("
			"		0.0,"
			"		0.0,"
			"		sqrt(fract(atomicCounterIncrement(fc)*mult))"
			"	)*max(fc_int, 0.0);"
			"	fragColor = geomColor + Color;"
			"}"
		));
		fs.Compile();
		prog.AttachShader(fs);

		prog.Link();
		prog.Use();

		// bind the VAO for the plane
		plane.Bind();

		// bind the VBO for the plane vertices
		positions.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_plane.Positions(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			// setup the vertex attribs array for the vertices
			VertexAttribArray attr(prog, "Position");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		counters.Bind(Buffer::Target::AtomicCounter);
		{
			const GLuint tmp[3] = {0u, 0u, 0u};
			Buffer::Data(
				Buffer::Target::AtomicCounter,
				3, tmp,
				BufferUsage::DynamicDraw
			);
		}
		counters.BindBase(Buffer::IndexedTarget::AtomicCounter, 0);

		gl.ClearColor(0.2f, 0.2f, 0.2f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		plane.Bind();
	}
Example #23
0
	SphereExample(void)
	 : sphere_instr(make_sphere.Instructions())
	 , sphere_indices(make_sphere.Indices())
	 , hole_count(50)
	 , hole_diameter(0.30f)
	{
		// This shader will be used in transform fedback mode
		// to transform the vertices used to "cut out the holes"
		// the same way the sphere is transformed
		vs_tfb.Source(
			"#version 330\n"
			"uniform mat4 CameraMatrix, ModelMatrix;"
			"uniform float Diameter;"
			"in vec3 Hole;"
			"out vec3 vertTransfHole;"
			"void main(void)"
			"{"
			"	vertTransfHole = ("
			"		CameraMatrix *"
			"		ModelMatrix *"
			"		vec4(Hole * (1.0 + 0.5 * Diameter), 0.0)"
			"	).xyz;"
			"}"
		);
		// compile, setup transform feedback output variables
		// link and use the program
		vs_tfb.Compile();
		prog_tfb.AttachShader(vs_tfb);

		const GLchar* var_name = "vertTransfHole";
		prog_tfb.TransformFeedbackVaryings(
			1, &var_name,
			TransformFeedbackMode::InterleavedAttribs
		);
		prog_tfb.Link();
		prog_tfb.Use();

		Uniform<GLfloat> diameter(prog_tfb, "Diameter");
		diameter.Set(hole_diameter);

		// bind the VAO for the holes
		holes.Bind();

		// bind the VBO for the hole vertices
		hole_verts.Bind(Buffer::Target::Array);
		// and the VBO for the transformed hole vertices captured by tfb
		transf_hole_verts.Bind(Buffer::Target::TransformFeedback);
		{
			std::vector<GLfloat> data;
			make_hole_data(data, hole_count);
			Buffer::Data(Buffer::Target::TransformFeedback, data);
			Buffer::Data(Buffer::Target::Array, data);
			VertexAttribArray attr(prog_tfb, "Hole");
			attr.Setup<Vec3f>();
			attr.Enable();
		}
		transf_hole_verts.BindBase(
			Buffer::IndexedTarget::TransformFeedback,
			0
		);

		// Set the vertex shader source
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"out vec3 vertNormal;"
			"out vec3 vertLight;"
			"const vec3 LightPos = vec3(2.0, 3.0, 3.0);"
			"void main(void)"
			"{"
			"	gl_Position = ModelMatrix * Position;"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	vertLight = LightPos-gl_Position.xyz;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		// compile it
		vs.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"in vec3 vertNormal;"
			"in vec3 vertLight;"
			"out vec4 fragColor;"
			"const int HoleCount = 50;"
			"uniform vec3 TransfHole[50];"
			"uniform float Diameter;"
			"void main(void)"
			"{"
			"	int imax = 0;"
			"	float dmax = -1.0;"
			"	for(int i=0; i!=HoleCount; ++i)"
			"	{"
			"		float d = dot(vertNormal, TransfHole[i]);"
			"		if(dmax < d)"
			"		{"
			"			dmax = d;"
			"			imax = i;"
			"		}"
			"	}"
			"	float l = length(vertLight);"
			"	vec3 FragDiff = TransfHole[imax] - vertNormal;"
			"	vec3 FinalNormal = "
			"		length(FragDiff) > Diameter?"
			"		vertNormal:"
			"		normalize(FragDiff+vertNormal*Diameter);"
			"	float i = (l > 0.0) ? dot("
			"		FinalNormal, "
			"		normalize(vertLight)"
			"	) / l : 0.0;"
			"	i = 0.2+max(i*2.5, 0.0);"
			"	fragColor = vec4(i, i, i, 1.0);"
			"}"
		);
		// compile it
		fs.Compile();

		// attach the shaders to the program
		prog.AttachShader(vs);
		prog.AttachShader(fs);
		// link and use it
		prog.Link();
		prog.Use();

		diameter.Set(hole_diameter);

		// bind the VAO for the sphere
		sphere.Bind();

		// bind the VBO for the sphere vertices
		verts.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_sphere.Positions(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			// setup the vertex attribs array for the vertices
			VertexAttribArray attr(prog, "Position");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		// bind the VBO for the sphere normals
		normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_sphere.Normals(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			// setup the vertex attribs array for the vertices
			VertexAttribArray attr(prog, "Normal");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
	}
Example #24
0
	void Use(void)
	{
		_program.Use();
	}
	TessellationExample(void)
	 : shape_instr(make_shape.Instructions(PrimitiveType::Patches))
	 , shape_indices(make_shape.Indices())
	 , vs(ObjectDesc("Vertex"))
	 , cs(ObjectDesc("Tessellation Control"))
	 , es(ObjectDesc("Tessellation Evaluation"))
	 , gs(ObjectDesc("Geometry"))
	 , fs(ObjectDesc("Fragment"))
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	 , offset(prog, "Offset")
	 , view_position(prog, "ViewPosition")
	 , viewport_dimensions(prog, "ViewportDimensions")
	{
		vs.Source(
			"#version 330\n"

			"uniform vec3 ViewPosition;"

			"in vec3 Position;"

			"out vec3 vertPosition;"
			"out float vertDistance;"

			"void main(void)"
			"{"
			"	vertPosition = Position;"
			"	vertDistance = length(ViewPosition - vertPosition);"
			"}"
		);
		vs.Compile();

		cs.Source(
			"#version 330\n"
			"#extension ARB_tessellation_shader : enable\n"

			"layout(vertices = 3) out;"

			"in vec3 vertPosition[];"
			"in float vertDistance[];"

			"out vec3 tecoPosition[];"

			"int tessLevel(float dist)"
			"{"
			"	return int(9.0 / sqrt(dist+0.1));"
			"}"

			"void main(void)"
			"{"
			"	tecoPosition[gl_InvocationID] ="
			"		vertPosition[gl_InvocationID];"

			"	if(gl_InvocationID == 0)"
			"	{"
			"		gl_TessLevelInner[0] = tessLevel(("
			"			vertDistance[0]+"
			"			vertDistance[1]+"
			"			vertDistance[2] "
			"		)*0.333);"
			"		gl_TessLevelOuter[0] = tessLevel(("
			"			vertDistance[1]+"
			"			vertDistance[2] "
			"		)*0.5);"
			"		gl_TessLevelOuter[1] = tessLevel(("
			"			vertDistance[2]+"
			"			vertDistance[0] "
			"		)*0.5);"
			"		gl_TessLevelOuter[2] = tessLevel(("
			"			vertDistance[0]+"
			"			vertDistance[1] "
			"		)*0.5);"
			"	}"
			"}"
		);
		cs.Compile();

		es.Source(
			"#version 330\n"
			"#extension ARB_tessellation_shader : enable\n"

			"layout(triangles, equal_spacing, ccw) in;"

			"const vec3 LightPosition = vec3(12.0, 10.0, 7.0);"

			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"

			"in vec3 tecoPosition[];"

			"out vec3 teevNormal;"
			"out vec3 teevLightDir;"

			"void main(void)"
			"{"
			"	vec3 p0 = gl_TessCoord.x * tecoPosition[0];"
			"	vec3 p1 = gl_TessCoord.y * tecoPosition[1];"
			"	vec3 p2 = gl_TessCoord.z * tecoPosition[2];"

			"	vec4 tempPosition = vec4(normalize(p0+p1+p2), 0.0);"
			"	teevNormal = (ModelMatrix * tempPosition).xyz;"
			"	tempPosition.w = 1.0;"
			"	tempPosition = ModelMatrix * tempPosition;"
			"	teevLightDir = LightPosition - tempPosition.xyz;"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		tempPosition;"
			"}"
		);
		es.Compile();

		gs.Source(
			"#version 330\n"
			"layout (triangles) in;"
			"layout (triangle_strip, max_vertices = 3) out;"

			"uniform vec3 Offset;"
			"uniform vec2 ViewportDimensions;"

			"in vec3 teevNormal[], teevLightDir[];"

			"noperspective out vec3 geomDist;"
			"flat out vec3 geomNormal;"
			"out vec3 geomColor;"
			"out vec3 geomLightDir;"

			"void main(void)"
			"{"
			"	geomNormal = normalize("
			"		teevNormal[0]+"
			"		teevNormal[1]+"
			"		teevNormal[2]"
			"	);"

			"	vec2 ScreenPos[3];"
			"	for(int i=0; i!=3; ++i)"
			"	{"
			"		ScreenPos[i] = "
			"			ViewportDimensions*"
			"			gl_in[i].gl_Position.xy/"
			"			gl_in[i].gl_Position.w;"
			"	}"

			"	vec2 TmpVect[3];"
			"	for(int i=0; i!=3; ++i)"
			"	{"
			"		TmpVect[i] = "
			"			ScreenPos[(i+2)%3]-"
			"			ScreenPos[(i+1)%3];"
			"	}"

			"	const vec3 EdgeMask[3] = vec3[3]("
			"		vec3(1.0, 0.0, 0.0),"
			"		vec3(0.0, 1.0, 0.0),"
			"		vec3(0.0, 0.0, 1.0) "
			"	);"

			"	for(int i=0; i!=3; ++i)"
			"	{"
			"		float Dist = abs("
			"			TmpVect[(i+1)%3].x*TmpVect[(i+2)%3].y-"
			"			TmpVect[(i+1)%3].y*TmpVect[(i+2)%3].x "
			"		) / length(TmpVect[i]);"
			"		vec3 DistVect = vec3(Dist, Dist, Dist);"

			"		gl_Position = gl_in[i].gl_Position;"
			"		geomColor = normalize(abs("
			"			vec3(2.0, 2.0, 2.0)-"
			"			teevNormal[i]-"
			"			Offset"
			"		));"
			"		geomLightDir = teevLightDir[i];"
			"		geomDist = EdgeMask[i] * DistVect;"
			"		EmitVertex();"
			"	}"
			"	EndPrimitive();"
			"}"
		);
		gs.Compile();

		fs.Source(
			"#version 330\n"

			"noperspective in vec3 geomDist;"
			"flat in vec3 geomNormal;"
			"in vec3 geomColor;"
			"in vec3 geomLightDir;"

			"out vec3 fragColor;"

			"void main(void)"
			"{"
			"	float MinDist = min(min(geomDist.x,geomDist.y),geomDist.z);"
			"	float EdgeAlpha = exp2(-pow(MinDist, 2.0));"

			"	const float Ambient = 0.8;"
			"	float Diffuse = max(dot("
			"		normalize(geomNormal),"
			"		normalize(geomLightDir)"
			"	), 0.0);"

			"	vec3 FaceColor = geomColor * (Diffuse + Ambient);"
			"	const vec3 EdgeColor = vec3(0.0, 0.0, 0.0);"

			"	fragColor = mix(FaceColor, EdgeColor, EdgeAlpha);"
			"}"
		);
		fs.Compile();

		prog.AttachShader(vs);
		prog.AttachShader(cs);
		prog.AttachShader(es);
		prog.AttachShader(gs);
		prog.AttachShader(fs);
		prog.Link();
		prog.Use();

		shape.Bind();

		verts.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_shape.Positions(data);
			Buffer::Data(Buffer::Target::Array, data);
			VertexAttribArray attr(prog, "Position");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();

			indices.Bind(Buffer::Target::ElementArray);
			Buffer::Data(Buffer::Target::ElementArray, shape_indices);
			shape_indices.clear();
		}

		//
		gl.ClearColor(0.8f, 0.8f, 0.8f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);

		prog.Use();
	}
Example #26
0
	HaloExample(void)
	 : make_shape()
	 , shape_indices(make_shape.Indices())
	 , shape_instr(make_shape.Instructions())
	 , vs_shape(ObjectDesc("Shape VS"))
	 , vs_plane(ObjectDesc("Plane VS"))
	 , fs_shape(ObjectDesc("Shape FS"))
	 , fs_plane(ObjectDesc("Plane FS"))
	 , vs_halo(ObjectDesc("Halo VS"))
	 , gs_halo(ObjectDesc("Halo GS"))
	 , fs_halo(ObjectDesc("Halo FS"))
	 , shape_projection_matrix(shape_prog, "ProjectionMatrix")
	 , shape_camera_matrix(shape_prog, "CameraMatrix")
	 , shape_model_matrix(shape_prog, "ModelMatrix")
	 , plane_projection_matrix(plane_prog, "ProjectionMatrix")
	 , plane_camera_matrix(plane_prog, "CameraMatrix")
	 , halo_projection_matrix(halo_prog, "ProjectionMatrix")
	 , halo_camera_matrix(halo_prog, "CameraMatrix")
	 , halo_model_matrix(halo_prog, "ModelMatrix")
	{
		vs_shape.Source(
			"#version 140\n"
			"in vec4 Position;"
			"in vec3 Normal;"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"uniform vec3 LightPos;"
			"out vec3 vertNormal;"
			"out vec3 vertViewNormal;"
			"out vec3 vertLight;"
			"void main(void)"
			"{"
			"	gl_Position = ModelMatrix * Position;"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	vertViewNormal = mat3(CameraMatrix)*vertNormal;"
			"	vertLight = LightPos - gl_Position.xyz;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		vs_shape.Compile();

		fs_shape.Source(
			"#version 140\n"
			"in vec3 vertNormal;"
			"in vec3 vertViewNormal;"
			"in vec3 vertLight;"
			"uniform mat4 CameraMatrix;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float ltlen = sqrt(length(vertLight));"
			"	float ltexp = dot("
			"		normalize(vertNormal),"
			"		normalize(vertLight)"
			"	);"
			"	float lview = dot("
			"		normalize(vertLight),"
			"		normalize(vec3("
			"			CameraMatrix[0][2],"
			"			CameraMatrix[1][2],"
			"			CameraMatrix[2][2] "
			"		))"
			"	);"
			"	float depth = normalize(vertViewNormal).z;"
			"	vec3 ftrefl = vec3(0.9, 0.8, 0.7);"
			"	vec3 scatter = vec3(0.9, 0.6, 0.1);"
			"	vec3 bklt = vec3(0.8, 0.6, 0.4);"
			"	vec3 ambient = vec3(0.5, 0.4, 0.3);"
			"	fragColor = vec4("
			"		pow(max(ltexp, 0.0), 8.0)*ftrefl+"
			"		( ltexp+1.0)/ltlen*pow(depth,2.0)*scatter+"
			"		(-ltexp+1.0)/ltlen*(1.0-depth)*scatter+"
			"		(-lview+1.0)*0.6*(1.0-abs(depth))*bklt+"
			"		0.2*ambient,"
			"		1.0"
			"	);"
			"}"
		);
		fs_shape.Compile();

		shape_prog.AttachShader(vs_shape);
		shape_prog.AttachShader(fs_shape);
		shape_prog.Link();

		vs_plane.Source(
			"#version 140\n"
			"in vec4 Position;"
			"in vec3 Normal;"
			"uniform mat4 ProjectionMatrix, CameraMatrix;"
			"uniform vec3 LightPos;"
			"out vec3 vertNormal;"
			"out vec3 vertLight;"
			"void main(void)"
			"{"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		Position;"
			"	vertNormal = Normal;"
			"	vertLight = LightPos-Position.xyz;"
			"}"
		);
		vs_plane.Compile();

		fs_plane.Source(
			"#version 140\n"
			"in vec3 vertNormal;"
			"in vec3 vertLight;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float l = sqrt(length(vertLight));"
			"	float e = dot("
			"		vertNormal,"
			"		normalize(vertLight)"
			"	);"
			"	float d = l > 0.0 ? e / l : 0.0;"
			"	float i = 0.2 + 2.5 * d;"
			"	fragColor = vec4(0.8*i, 0.7*i, 0.4*i, 1.0);"
			"}"
		);
		fs_plane.Compile();

		plane_prog.AttachShader(vs_plane);
		plane_prog.AttachShader(fs_plane);
		plane_prog.Link();

		vs_halo.Source(
			"#version 150\n"
			"in vec4 Position;"
			"in vec3 Normal;"
			"uniform mat4 ModelMatrix, CameraMatrix;"
			"out vec3 vertNormal;"
			"out float vd;"
			"void main(void)"
			"{"
			"	gl_Position = "
			"		CameraMatrix *"
			"		ModelMatrix *"
			"		Position;"
			"	vertNormal = ("
			"		CameraMatrix *"
			"		ModelMatrix *"
			"		vec4(Normal, 0.0)"
			"	).xyz;"
			"	vd = vertNormal.z;"
			"}"
		);
		vs_halo.Compile();

		gs_halo.Source(
			"#version 150\n"
			"layout(triangles) in;"
			"layout(triangle_strip, max_vertices = 12) out;"

			"in vec3 vertNormal[];"
			"in float vd[];"

			"uniform mat4 CameraMatrix, ProjectionMatrix;"
			"uniform vec3 LightPos;"

			"out float geomAlpha;"

			"void main(void)"
			"{"
			"	for(int v=0; v!=3; ++v)"
			"	{"
			"		int a = v, b = (v+1)%3, c = (v+2)%3;"
			"		vec4 pa = gl_in[a].gl_Position;"
			"		vec4 pb = gl_in[b].gl_Position;"
			"		vec4 pc = gl_in[c].gl_Position;"
			"		vec4 px, py;"
			"		vec3 na = vertNormal[a];"
			"		vec3 nb = vertNormal[b];"
			"		vec3 nc = vertNormal[c];"
			"		vec3 nx, ny;"
			"		if(vd[a] == 0.0 && vd[b] == 0.0)"
			"		{"
			"			px = pa;"
			"			nx = na;"
			"			py = pb;"
			"			ny = nb;"
			"		}"
			"		else if(vd[a] > 0.0 && vd[b] < 0.0)"
			"		{"
			"			float x = vd[a]/(vd[a]-vd[b]);"
			"			float y;"
			"			px = mix(pa, pb, x);"
			"			nx = mix(na, nb, x);"
			"			if(vd[c] < 0.0)"
			"			{"
			"				y = vd[a]/(vd[a]-vd[c]);"
			"				py = mix(pa, pc, y);"
			"				ny = mix(na, nc, y);"
			"			}"
			"			else"
			"			{"
			"				y = vd[c]/(vd[c]-vd[b]);"
			"				py = mix(pc, pb, y);"
			"				ny = mix(nc, nb, y);"
			"			}"
			"		}"
			"		else continue;"
			"		vec4 gx1 = vec4(px.xyz, 1.0);"
			"		vec4 gy1 = vec4(py.xyz, 1.0);"
			"		vec4 gx2 = vec4(px.xyz + nx*0.3, 1.0);"
			"		vec4 gy2 = vec4(py.xyz + ny*0.3, 1.0);"
			"		gl_Position = ProjectionMatrix * gy1;"
			"		geomAlpha = 1.0;"
			"		EmitVertex();"
			"		gl_Position = ProjectionMatrix * gx1;"
			"		geomAlpha = 1.0;"
			"		EmitVertex();"
			"		gl_Position = ProjectionMatrix * gy2;"
			"		geomAlpha = 0.0;"
			"		EmitVertex();"
			"		gl_Position = ProjectionMatrix * gx2;"
			"		geomAlpha = 0.0;"
			"		EmitVertex();"
			"		EndPrimitive();"
			"		break;"
			"	}"
			"}"
		);
		gs_halo.Compile();

		fs_halo.Source(
			"#version 150\n"
			"in float geomAlpha;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	fragColor = vec4("
			"		0.5, 0.4, 0.3,"
			"		pow(geomAlpha, 2.0)"
			"	);"
			"}"
		);
		fs_halo.Compile();

		halo_prog.AttachShader(vs_halo);
		halo_prog.AttachShader(gs_halo);
		halo_prog.AttachShader(fs_halo);
		halo_prog.Link();

		// bind the VAO for the shape
		shape.Bind();

		// bind the VBO for the shape vertices
		shape_verts.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_shape.Positions(data);
			Buffer::Data(Buffer::Target::Array, data);

			VertexAttribSlot location;
			if(VertexArrayAttrib::QueryCommonLocation(
				MakeGroup(shape_prog, halo_prog),
				"Position",
				location
			))
			{
				VertexArrayAttrib attr(location);
				attr.Setup<GLfloat>(n_per_vertex);
				attr.Enable();
			}
			else OGLPLUS_ABORT("Inconsistent 'Position' location");
		}

		// bind the VBO for the shape normals
		shape_normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_shape.Normals(data);
			Buffer::Data(Buffer::Target::Array, data);

			shape_prog.Use();
			VertexArrayAttrib attr(shape_prog, "Normal");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		// bind the VAO for the plane
		plane.Bind();

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

		// bind the VBO for the plane normals
		plane_normals.Bind(Buffer::Target::Array);
		{
			GLfloat data[4*3] = {
				-0.1f, 1.0f,  0.1f,
				-0.1f, 1.0f, -0.1f,
				 0.1f, 1.0f,  0.1f,
				 0.1f, 1.0f, -0.1f
			};
			Buffer::Data(Buffer::Target::Array, 4*3, data);
			plane_prog.Use();
			VertexArrayAttrib attr(plane_prog, "Normal");
			attr.Setup<Vec3f>();
			attr.Enable();
		}

		Vec3f lightPos(2.0f, 2.5f, 9.0f);

		ProgramUniform<Vec3f>(shape_prog, "LightPos").Set(lightPos);
		ProgramUniform<Vec3f>(plane_prog, "LightPos").Set(lightPos);

		gl.ClearColor(0.2f, 0.2f, 0.2f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.ClearStencil(0);

		gl.Enable(Capability::DepthTest);
		gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::One);
	}
    ReflectionExample()
      : make_plane(
          Vec3f(), Vec3f(3.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, -3.0f), 15, 15)
      , plane_instr(make_plane.Instructions())
      , plane_indices(make_plane.Indices())
      , make_shape()
      , shape_instr(make_shape.Instructions())
      , shape_indices(make_shape.Indices())
      , plane_vs(ObjectDesc("Plane vertex"))
      , shape_vs(ObjectDesc("Shape vertex"))
      , plane_fs(ObjectDesc("Plane fragment"))
      , shape_fs(ObjectDesc("Shape fragment"))
      , plane_projection_matrix(plane_prog)
      , plane_camera_matrix(plane_prog)
      , plane_model_matrix(plane_prog)
      , shape_projection_matrix(shape_prog)
      , shape_camera_matrix(shape_prog)
      , shape_model_matrix(shape_prog)
      , width(800)
      , height(600)
      , tex_size_div(2) {
        plane_vs.Source(
          "#version 140\n"
          "uniform vec3 LightPosition;"
          "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
          "in vec4 Position;"
          "out vec3 vertLightDir;"
          "out vec4 vertTexCoord;"
          "void main()"
          "{"
          "	gl_Position = ModelMatrix*Position;"
          "	vertLightDir = LightPosition - gl_Position.xyz;"
          "	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
          "	vertTexCoord = gl_Position;"
          "}");
        plane_vs.Compile();

        plane_fs.Source(
          "#version 140\n"
          "uniform sampler2DRect ReflectTex;"
          "uniform vec3 Normal;"
          "in vec3 vertLightDir;"
          "in vec4 vertTexCoord;"
          "out vec3 fragColor;"
          "const int n = 5;"
          "const int ns = (n*n);"
          "const float blur = 0.15/n;"
          "void main()"
          "{"
          "	float d = dot(Normal, normalize(vertLightDir));"
          "	float intensity = 0.5 + pow(1.4*d, 2.0);"
          "	vec3 color = vec3(0.0, 0.0, 0.0);"
          "	int n = 2;"
          "	float pct = 0.5/vertTexCoord.w;"
          "	for(int y=-n; y!=(n+1); ++y)"
          "	for(int x=-n; x!=(n+1); ++x)"
          "	{"
          "		vec2 coord = vertTexCoord.xy;"
          "		coord += vec2(blur*x, blur*y);"
          "		coord *= pct;"
          "		coord += vec2(0.5, 0.5);"
          "		coord *= textureSize(ReflectTex);"
          "		color += texture(ReflectTex, coord).rgb/ns;"
          "	}"
          "	fragColor = color*intensity;"
          "}");
        plane_fs.Compile();

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

        plane_projection_matrix.BindTo("ProjectionMatrix");
        plane_camera_matrix.BindTo("CameraMatrix");
        plane_model_matrix.BindTo("ModelMatrix");

        Vec3f lightPos(3.0f, 0.5f, 2.0f);
        Uniform<Vec3f>(plane_prog, "LightPosition").Set(lightPos);
        Uniform<Vec3f>(plane_prog, "Normal").Set(make_plane.Normal());

        plane.Bind();

        plane_verts.Bind(Buffer::Target::Array);
        {
            std::vector<GLfloat> data;
            GLuint n_per_vertex = make_plane.Positions(data);
            Buffer::Data(Buffer::Target::Array, data);
            VertexArrayAttrib attr(plane_prog, "Position");
            attr.Setup<GLfloat>(n_per_vertex);
            attr.Enable();
        }
        //
        Texture::Active(1);
        gl.Bound(Texture::Target::Rectangle, depth_tex)
          .MinFilter(TextureMinFilter::Linear)
          .MagFilter(TextureMagFilter::Linear)
          .WrapS(TextureWrap::ClampToEdge)
          .WrapT(TextureWrap::ClampToEdge);

        Texture::Active(0);
        ProgramUniformSampler(plane_prog, "ReflectTex").Set(0);
        gl.Bound(Texture::Target::Rectangle, reflect_tex)
          .MinFilter(TextureMinFilter::Linear)
          .MagFilter(TextureMagFilter::Linear)
          .WrapS(TextureWrap::ClampToEdge)
          .WrapT(TextureWrap::ClampToEdge);

        gl.Bound(Framebuffer::Target::Draw, fbo)
          .AttachTexture(FramebufferAttachment::Color, reflect_tex, 0)
          .AttachTexture(FramebufferAttachment::Depth, depth_tex, 0);

        shape_vs.Source(
          "#version 140\n"
          "uniform vec3 LightPosition;"
          "uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;"
          "in vec4 Position;"
          "in vec3 Normal;"
          "out vec3 vertNormal;"
          "out vec3 vertLightDir;"
          "out vec3 vertLightRefl;"
          "out vec3 vertViewDir;"
          "out vec3 vertColor;"
          "void main()"
          "{"
          "	gl_Position = ModelMatrix * Position;"
          "	vertLightDir = LightPosition - gl_Position.xyz;"
          "	vertNormal = mat3(ModelMatrix)*Normal;"
          "	vertLightRefl = reflect("
          "		-normalize(vertLightDir),"
          "		normalize(vertNormal)"
          "	);"
          "	vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)*CameraMatrix).xyz;"
          "	vertColor = vec3(1, 1, 1) - vertNormal;"
          "	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
          "}");
        shape_vs.Compile();

        shape_fs.Source(
          "#version 140\n"
          "in vec3 vertNormal;"
          "in vec3 vertLightDir;"
          "in vec3 vertLightRefl;"
          "in vec3 vertViewDir;"
          "in vec3 vertColor;"
          "out vec3 fragColor;"

          "void main()"
          "{"
          "	float l = length(vertLightDir);"
          "	float d = dot("
          "		normalize(vertNormal), "
          "		normalize(vertLightDir)"
          "	) / l;"
          "	float s = dot("
          "		normalize(vertLightRefl),"
          "		normalize(vertViewDir)"
          "	);"
          "	vec3 lt = vec3(1.0, 1.0, 1.0);"
          "	fragColor = "
          "		vertColor * 0.4 + "
          "		(lt + vertColor)*pow(max(2.5*d, 0.0), 3) + "
          "		lt * pow(max(s, 0.0), 64);"
          "}");
        shape_fs.Compile();

        shape_prog.AttachShader(shape_vs);
        shape_prog.AttachShader(shape_fs);
        shape_prog.Link();
        shape_prog.Use();

        shape_projection_matrix.BindTo("ProjectionMatrix");
        shape_camera_matrix.BindTo("CameraMatrix");
        shape_model_matrix.BindTo("ModelMatrix");

        Uniform<Vec3f>(shape_prog, "LightPosition").Set(lightPos);

        shape.Bind();

        shape_verts.Bind(Buffer::Target::Array);
        {
            std::vector<GLfloat> data;
            GLuint n_per_vertex = make_shape.Positions(data);
            Buffer::Data(Buffer::Target::Array, data);
            VertexArrayAttrib attr(shape_prog, "Position");
            attr.Setup<GLfloat>(n_per_vertex);
            attr.Enable();
        }

        shape_normals.Bind(Buffer::Target::Array);
        {
            std::vector<GLfloat> data;
            GLuint n_per_vertex = make_shape.Normals(data);
            Buffer::Data(Buffer::Target::Array, data);
            VertexArrayAttrib attr(shape_prog, "Normal");
            attr.Setup<GLfloat>(n_per_vertex);
            attr.Enable();
        }
        //
        gl.ClearColor(0.5f, 0.5f, 0.4f, 0.0f);
        gl.ClearDepth(1.0f);
        gl.Enable(Capability::DepthTest);
        gl.Enable(Capability::CullFace);
    }
Example #28
0
	TorusExample(void)
	 : make_torus(1.0, 0.5, 18, 36)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	 , transf_prog(make_transf_prog())
	 , face_prog(make_face_prog())
	 , frame_prog(make_frame_prog())
	 , projection_matrix(transf_prog, "ProjectionMatrix")
	 , camera_matrix(transf_prog, "CameraMatrix")
	 , model_matrix(transf_prog, "ModelMatrix")
	 , transf_time(transf_prog, "Time")
	{
		transf_prog.Use();
		torus.Bind();
		verts.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.Positions(data);
			Buffer::Data(Buffer::Target::Array, data);

			VertexArrayAttrib attr(transf_prog, "Position");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.Normals(data);
			Buffer::Data(Buffer::Target::Array, data);

			VertexArrayAttrib attr(transf_prog, "Normal");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		texcoords.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.TexCoordinates(data);
			Buffer::Data(Buffer::Target::Array, data);

			VertexArrayAttrib attr(transf_prog, "TexCoord");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		face_pp.Bind();
		face_prog.Use();
		face_pp.UseStages(transf_prog).Vertex().Geometry();
		face_pp.UseStages(face_prog).Fragment();


		frame_pp.Bind();
		frame_prog.Use();
		frame_pp.UseStages(transf_prog).Vertex().Geometry();
		frame_pp.UseStages(frame_prog).Fragment();

		gl.Bind(NoProgramPipeline());
		gl.Use(NoProgram());

		gl.ClearColor(0.7f, 0.6f, 0.5f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.DepthFunc(CompareFn::Less);
		gl.FrontFace(make_torus.FaceWinding());
	}
Example #29
0
	CubeExample(void)
	 : cube_instr(make_cube.Instructions())
	 , cube_indices(make_cube.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	 , front_facing(prog, "FrontFacing")
	 , inst_count(32)
	{
		// Set the vertex shader source
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"uniform vec3 LightPos;"
			"uniform int InstCount;"
			"uniform int FrontFacing;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"out float vertMult;"
			"out vec3 vertColor;"
			"out vec3 vertWrapNormal;"
			"out vec3 vertNormal;"
			"out vec3 vertLight;"
			"void main(void)"
			"{"
			"	int inst = (FrontFacing != 0) ? "
			"		(InstCount - gl_InstanceID - 1):"
			"		gl_InstanceID;"
			"	vertMult = float(inst) / float(InstCount-1);"
			"	float sca = 1.0 - 0.3 * pow(vertMult, 2);"
			"	mat4 ScaleMatrix = mat4("
			"		sca, 0.0, 0.0, 0.0,"
			"		0.0, sca, 0.0, 0.0,"
			"		0.0, 0.0, sca, 0.0,"
			"		0.0, 0.0, 0.0, 1.0 "
			"	);"
			"	gl_Position = ModelMatrix * Position;"
			"	vertColor = Normal;"
			"	vec3 wrap = Position.xyz - Normal;"
			"	vertWrapNormal = "
			"		mat3(ModelMatrix)*"
			"		normalize(mix("
			"			Normal,"
			"			wrap,"
			"			mix(0.5, 1.0, vertMult)"
			"		));"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	vertLight = LightPos-gl_Position.xyz;"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		ScaleMatrix *"
			"		gl_Position;"
			"}"
		);
		// compile it
		vs.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"in float vertMult;"
			"in vec3 vertColor;"
			"in vec3 vertWrapNormal;"
			"in vec3 vertNormal;"
			"in vec3 vertLight;"
			"out vec4 fragColor;"
			"uniform int InstCount;"
			"void main(void)"
			"{"
			"	float l = dot(vertLight, vertLight);"
			"	float d = l > 0.0 ? dot("
			"		vertNormal, "
			"		normalize(vertLight)"
			"	) / l : 0.0;"
			"	float s = max("
			"		dot(vertWrapNormal, vertLight)/l,"
			"		0.0"
			"	);"
			"	float intensity = clamp("
			"		0.2 + d * 3.0 + s * 5.5,"
			"		0.0,"
			"		1.0"
			"	);"
			"	fragColor = vec4("
			"		abs(vertColor) * intensity,"
			"		(2.5 + 1.5*d + 1.5*s) / InstCount"
			"	);"
			"}"
		);
		// compile it
		fs.Compile();

		// attach the shaders to the program
		prog.AttachShader(vs);
		prog.AttachShader(fs);
		// link and use it
		prog.Link();
		prog.Use();

		// bind the VAO for the cube
		cube.Bind();

		// bind the VBO for the cube vertices
		verts.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.Positions(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			// setup the vertex attribs array for the vertices
			VertexArrayAttrib attr(prog, "Position");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		// bind the VBO for the cube normals
		normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.Normals(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			VertexArrayAttrib attr(prog, "Normal");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}
		// the light position
		Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(-3.0f, -2.0f, -3.0f));
		// and the instance count
		Uniform<GLint>(prog, "InstCount").Set(inst_count);
		//
		gl.ClearColor(0.5f, 0.6f, 0.5f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
		gl.FrontFace(make_cube.FaceWinding());
		gl.Enable(Capability::Blend);
		gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha);
	}
Example #30
0
	static Program make_prog(void)
	{
		Program prog;
		VertexShader vs;
		vs.Source(StrCRef(
			"#version 330\n"
			"in vec3 Position;"
			"in vec2 TexCoord;"
			"out vec2 vertTexCoord;"
			"void main(void)"
			"{"
			"	gl_Position = vec4(Position, 1.0);"
			"	vertTexCoord = TexCoord;"
			"}"
		)).Compile();
		prog.AttachShader(vs);

		GeometryShader gs;
		gs.Source(StrCRef(
			"#version 330\n"
			"#extension GL_ARB_gpu_shader5 : enable\n"
			"layout(triangles, invocations = 7) in;"
			"layout(triangle_strip, max_vertices = 21) out;"

			"uniform mat4 ProjectionMatrix, CameraMatrix;"
			"mat4 Matrix = ProjectionMatrix * CameraMatrix;"
			"uniform vec3 CameraPosition;"

			"in vec2 vertTexCoord[3];"

			"out gl_PerVertex {"
			"	vec4 gl_Position;"
			"	float gl_ClipDistance[3];"
			"};"
			"flat out mat3 geomPositionFront;"
			"flat out mat3 geomTexCoordFront;"
			"flat out vec3 geomWFront;"
			"noperspective out vec3 geomBarycentric;"
			"out vec3 geomPosition;"
			"out vec3 geomTexCoord;"

			"void main(void)"
			"{"
			"	vec4 world_pos[8*3];"
			"	vec3 tex_coord[8*3];"

			"	vec4 view_pos[8*3];"
			"	vec3 screen_pos[8*3];"
			"	bool front_facing[8];"

			"	int ft = gl_InvocationID+1;"

			"	for(int pass=0; pass!=2; ++pass)"
			"	{"
			"		bool first = pass == 0;"
			"		if(((ft == 0) && first) || (((ft != 0) && !first)))"
			"		{"
			"			for(int v=0; v!=3; ++v)"
			"			{"
			"				int w = 2-v;"
			"				world_pos[0+v] = gl_in[w].gl_Position;"
			"				tex_coord[0+v] = vec3(vertTexCoord[w], 0.0);"
			"			}"
			"		}"

			"		vec4 n = vec4(-0.15 * normalize(cross("
			"			gl_in[1].gl_Position.xyz-gl_in[0].gl_Position.xyz,"
			"			gl_in[2].gl_Position.xyz-gl_in[0].gl_Position.xyz "
			"		)), 0.0);"

			"		if(((ft == 1) && first) || (((ft != 1) && !first)))"
			"		{"
			"			for(int v=0; v!=3; ++v)"
			"			{"
			"				world_pos[3+v] = gl_in[v].gl_Position + n;"
			"				tex_coord[3+v] = vec3(vertTexCoord[v], 1.0);"
			"			}"
			"		}"

			"		for(int v=0; v!=3; ++v)"
			"		{"
			"			int w = (v+1)%3;"
			"			int k = 2+2*v;"
			"			if(((ft == k) && first) || (((ft != k) && !first)))"
			"			{"
			"				world_pos[6+0+v*6] = gl_in[v].gl_Position;"
			"				tex_coord[6+0+v*6] = vec3(vertTexCoord[v], 0.0);"
			"				world_pos[6+1+v*6] = gl_in[w].gl_Position;"
			"				tex_coord[6+1+v*6] = vec3(vertTexCoord[w], 0.0);"
			"				world_pos[6+2+v*6] = gl_in[v].gl_Position + n;"
			"				tex_coord[6+2+v*6] = vec3(vertTexCoord[v], 1.0);"
			"			}"

			"			k = 3+2*v;"
			"			if(((ft == k) && first) || (((ft != k) && !first)))"
			"			{"
			"				world_pos[6+3+v*6] = gl_in[w].gl_Position;"
			"				tex_coord[6+3+v*6] = vec3(vertTexCoord[w], 0.0);"
			"				world_pos[6+4+v*6] = gl_in[w].gl_Position + n;"
			"				tex_coord[6+4+v*6] = vec3(vertTexCoord[w], 1.0);"
			"				world_pos[6+5+v*6] = gl_in[v].gl_Position + n;"
			"				tex_coord[6+5+v*6] = vec3(vertTexCoord[v], 1.0);"
			"			}"
			"		}"

			"		for(int t=first?ft:0; t!=8; ++t)"
			"		{"
			"			if(!first && (t == ft)) continue;"
			"			int o = t*3;"
			"			for(int v=0; v!=3; ++v)"
			"			{"
			"				int w = o+v;"
			"				view_pos[w] = Matrix * world_pos[w];"
			"				screen_pos[w] = view_pos[w].xyz/view_pos[w].w;"
			"			}"
			"			front_facing[t] = cross("
			"				screen_pos[o+1]-screen_pos[o+0],"
			"				screen_pos[o+2]-screen_pos[o+0] "
			"			).z < 0.0;"
			"			if(first) break;"
			"		}"
			"		if(first && !front_facing[ft]) return;"
			"	}"

			"	int o = ft*3;"
			"	vec4 clip_plane[3];"
			"	for(int v=0; v!=3; ++v)"
			"	{"
			"		int w = (v+1)%3;"
			"		vec3 p0 = world_pos[o+v].xyz;"
			"		vec3 p1 = world_pos[o+w].xyz;"
			"		vec3 p2 = CameraPosition;"
			"		vec3 pv = normalize(cross(p1-p0, p2-p0));"
			"		clip_plane[v] = vec4(pv, -dot(pv, p0));"
			"	}"
			"	vec3 lo = CameraPosition;"
			"	vec3 p0 = world_pos[o+0].xyz;"
			"	vec3 pu = world_pos[o+1].xyz-p0;"
			"	vec3 pv = world_pos[o+2].xyz-p0;"
			"	vec3 lp = lo-p0;"

			"	float w0 = view_pos[o+0].w;"
			"	float wu = view_pos[o+1].w-w0;"
			"	float wv = view_pos[o+2].w-w0;"

			"	vec3 t0 = tex_coord[o+0];"
			"	vec3 tu = tex_coord[o+1]-t0;"
			"	vec3 tv = tex_coord[o+2]-t0;"

			"	for(int bt=0; bt!=8; ++bt)"
			"	{"
			"		int k = bt*3;"
			"		if((ft != bt) && !front_facing[bt])"
			"		{"
			"			for(int v=0; v!=3; ++v)"
			"			{"
			"				vec3 lt = world_pos[k+v].xyz;"
			"				mat3 im = mat3(lo-lt, pu, pv);"
			"				vec3 ic = inverse(im)*lp;"
			"				float s = ic.y;"
			"				float t = ic.z;"

			"				geomPositionFront[v] = p0+pu*s+pv*t;"
			"				geomTexCoordFront[v] = t0+tu*s+tv*t;"
			"				geomWFront[v] = w0+wu*s+wv*t;"
			"			}"
			"			for(int v=0; v!=3; ++v)"
			"			{"
			"				int w = k+v;"
			"				gl_Position = view_pos[w];"
			"				for(int c=0; c!=3; ++c)"
			"				{"
			"					gl_ClipDistance[c] = dot("
			"						clip_plane[c],"
			"						world_pos[w]"
			"					);"
			"				}"
			"				geomPosition = world_pos[w].xyz;"
			"				geomTexCoord = tex_coord[w];"
			"				geomBarycentric = vec3(0.0);"
			"				geomBarycentric[v] = 1.0;"

			"				EmitVertex();"
			"			}"
			"			EndPrimitive();"
			"		}"
			"	}"
			"}"
		)).Compile();
		prog.AttachShader(gs);

		FragmentShader fs;
		fs.Source(StrCRef(
			"#version 330\n"

			"uniform float Time;"
			"uniform sampler2D ColorMap;"
			"uniform sampler2D BumpMap;"
			"uniform vec3 LightPosition;"

			"flat in mat3 geomPositionFront;"
			"flat in mat3 geomTexCoordFront;"
			"flat in vec3 geomWFront;"
			"noperspective in vec3 geomBarycentric;"
			"in vec3 geomPosition;"
			"in vec3 geomTexCoord;"

			"out vec3 fragColor;"

			"vec3 vcdiv(vec3 a, vec3 b)"
			"{"
			"	return vec3(a.x/b.x, a.y/b.y, a.z/b.z);"
			"}"

			"void main(void)"
			"{"
			"	const vec3 one = vec3(1.0, 1.0, 1.0);"

			"	vec3 bzfv = vcdiv(geomBarycentric,geomWFront);"

			"	vec3 p0 = geomPosition;"
			"	vec3 p1 = (geomPositionFront*bzfv)/dot(one,bzfv);"
			"	vec3 tc0 = geomTexCoord;"
			"	vec3 tc1 = (geomTexCoordFront*bzfv)/dot(one,bzfv);"
			"	ivec2 ts = textureSize(BumpMap, 0);"
			"	int mts = max(ts.x, ts.y);"
			"	vec2 dtc = tc1.xy - tc0.xy;"
			"	float mdtc = max(abs(dtc.x), abs(dtc.y));"

			"	int nsam = max(min(int(mdtc*mts), mts/2), 1);"
			"	float step = 1.0 / nsam;"
			"	for(int s=0; s<=nsam; ++s)"
			"	{"
			"		vec3 tc = mix(tc1, tc0, s*step);"
			"		vec4 bm = texture(BumpMap, tc.xy);"
			"		if(tc.z <= bm.w)"
			"		{"
			"			vec3 p = mix(p1, p0, s*step);"
			"			vec3 ldir = normalize(LightPosition - p);"
			"			float l = max(dot(ldir, bm.xzy), 0.0)*1.3;"
			"			fragColor = texture(ColorMap, tc.xy).rgb*l;"
			"			return;"
			"		}"
			"	}"
			"	discard;"
			"}"
		)).Compile();
		prog.AttachShader(fs);

		prog.Link();
		prog.Use();

		return prog;
	}