TorusExample(void)
	 : make_torus(1.0, 0.5, 36, 24)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	 , prog(make_prog())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	{
		Uniform<Vec4f>(prog, "ClipPlane").Set(0.f, 0.f, 1.f, 0.f);

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

		// bind the VBO for the torus vertices
		verts.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.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 torus UV-coordinates
		texcoords.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.TexCoordinates(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			// setup the vertex attribs array for the vertices
			VertexArrayAttrib attr(prog, "TexCoord");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}
		//
		gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.FrontFace(make_torus.FaceWinding());
		gl.Enable(Capability::DepthTest);
		gl.Enable(Functionality::ClipDistance, 0);
	}
	TorusExample(void)
	 : make_torus(1.0, 0.5, 72, 48)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	{
		// Set the vertex shader source and compile it
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"out vec3 vertNormal;"
			"void main(void)"
			"{"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		ModelMatrix *"
			"		Position;"
			"}"
		).Compile();

		// set the fragment shader source and compile it
		fs.Source(
			"#version 330\n"
			"in vec3 vertNormal;"
			"out vec4 fragColor;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	float intensity = 2.0 * max("
			"		dot(vertNormal,  LightPos)/"
			"		length(LightPos),"
			"		0.0"
			"	);"
			"	if(!gl_FrontFacing)"
			"		fragColor = vec4(0.0, 0.0, 0.0, 1.0);"
			"	else if(intensity > 0.9)"
			"		fragColor = vec4(1.0, 0.9, 0.8, 1.0);"
			"	else if(intensity > 0.1)"
			"		fragColor = vec4(0.7, 0.6, 0.4, 1.0);"
			"	else"
			"		fragColor = vec4(0.3, 0.2, 0.1, 1.0);"
			"}"
		).Compile();

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

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

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

		// bind the VBO for the torus normals
		normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.Normals(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			// setup the vertex attribs array for the vertices
			(prog|"Normal").Setup(n_per_vertex, DataType::Float).Enable();
		}
		//
		// set the light position
		(prog/"LightPos").Set(Vec3f(4.0f, 4.0f, -8.0f));

		gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
		gl.FrontFace(make_torus.FaceWinding());
		gl.CullFace(Face::Back);
		glLineWidth(4.0f);
	}
	TorusExample(void)
	 : make_torus(1.0, 0.5, 72, 48)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	{
		// Set the vertex shader source and compile it
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"in vec2 TexCoord;"
			"out vec3 vertNormal;"
			"out vec3 vertLight;"
			"out vec2 vertTexCoord;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	gl_Position = ModelMatrix * Position;"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	vertLight = LightPos - gl_Position.xyz;"
			"	vertTexCoord = TexCoord;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		).Compile();

		// set the fragment shader source and compile it
		fs.Source(
			"#version 330\n"
			"uniform sampler2D TexUnit;"
			"in vec3 vertNormal;"
			"in vec3 vertLight;"
			"in vec2 vertTexCoord;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float l = sqrt(length(vertLight));"
			"	float d = l > 0? dot("
			"		vertNormal, "
			"		normalize(vertLight)"
			"	) / l : 0.0;"
			"	float i = 0.2 + 3.2*max(d, 0.0);"
			"	fragColor = texture(TexUnit, vertTexCoord)*i;"
			"}"
		).Compile();

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

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

		// bind the VBO for the torus vertices
		verts.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.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 torus normals
		normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.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();
		}

		// bind the VBO for the torus texture coordinates
		texcoords.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.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<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		// setup the texture
		Texture::Target tex_tgt = Texture::Target::_2D;
		tex.Bind(tex_tgt);
		{
			GLuint s = 256;
			std::vector<GLubyte> tex_data(s*s);
			for(GLuint v=0;v!=s;++v)
				for(GLuint u=0;u!=s;++u)
					tex_data[v*s+u] = rand() % 0x100;
			Texture::Image2D(
				tex_tgt,
				0,
				PixelDataInternalFormat::Red,
				s, s,
				0,
				PixelDataFormat::Red,
				PixelDataType::UnsignedByte,
				tex_data.data()
			);
			Texture::MinFilter(tex_tgt, TextureMinFilter::Linear);
			Texture::MagFilter(tex_tgt, TextureMagFilter::Linear);
			Texture::WrapS(tex_tgt, TextureWrap::Repeat);
			Texture::WrapT(tex_tgt, TextureWrap::Repeat);
			Texture::SwizzleG(tex_tgt, TextureSwizzle::Red);
			Texture::SwizzleB(tex_tgt, TextureSwizzle::Red);
		}
		// typechecked uniform with exact data type
		// on compilers supporting strongly typed enums
		// you can use:
		//Typechecked<Uniform<SLtoCpp<SLDataType::Sampler2D>>>(prog, "TexUnit").Set(0);
		// without strongly typed enums you need to do:
		typedef SLtoCpp<OGLPLUS_CONST_ENUM_VALUE(SLDataType::Sampler2D)> GLSLsampler2D;
		Typechecked<Uniform<GLSLsampler2D>>(prog, "TexUnit").Set(0);

		//
		Uniform<Vec3f>(prog, "LightPos").Set(4.0f, 4.0f, -8.0f);

		gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
		gl.FrontFace(make_torus.FaceWinding());
		gl.CullFace(Face::Back);
	}
	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());
	}
Beispiel #5
0
	TorusExample(void)
	 : make_torus(1.0, 0.5, 72, 48)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	{
		// Set the vertex shader source and compile it
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"out vec3 vertNormal;"
			"void main(void)"
			"{"
			"	vertNormal = mat3(CameraMatrix)*mat3(ModelMatrix)*Normal;"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		ModelMatrix *"
			"		Position;"
			"}"
		).Compile();

		// set the fragment shader source and compile it
		fs.Source(
			"#version 330\n"
			"uniform int ColorCount;"
			"uniform vec4 Color[8];"
			"in vec3 vertNormal;"
			"vec3 ViewDir = vec3(0.0, 0.0, 1.0);"
			"vec3 TopDir = vec3(0.0, 1.0, 0.0);"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float k = dot(vertNormal, ViewDir);"
			"	vec3 reflDir = 2.0*k*vertNormal - ViewDir;"
			"	float a = dot(reflDir, TopDir);"
			"	vec3 reflColor;"
			"	for(int i = 0; i != (ColorCount - 1); ++i)"
			"	{"
			"		if(a<Color[i].a && a>=Color[i+1].a)"
			"		{"
			"			float m = "
			"				(a - Color[i].a)/"
			"				(Color[i+1].a-Color[i].a);"
			"			reflColor = mix("
			"				Color[i].rgb,"
			"				Color[i+1].rgb,"
			"				m"
			"			);"
			"			break;"
			"		}"
			"	}"
			"	float i = max(dot(vertNormal, TopDir), 0.0);"
			"	vec3 diffColor = vec3(i, i, i);"
			"	fragColor = vec4("
			"		mix(reflColor, diffColor, 0.3 + i*0.7),"
			"		1.0"
			"	);"
			"}"
		).Compile();

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

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

		// bind the VBO for the torus vertices
		verts.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.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).Enable();
		}

		// bind the VBO for the torus normals
		normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.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(n_per_vertex, DataType::Float).Enable();
		}

		// setup the color gradient
		Uniform<GLint>(prog, "ColorCount").Set(8);
		Uniform<Vec4f> color(prog, "Color");
		color[0].Set(1.0f, 1.0f, 0.9f, 1.00f);
		color[1].Set(1.0f, 0.9f, 0.8f, 0.97f);
		color[2].Set(0.9f, 0.7f, 0.5f, 0.95f);
		color[3].Set(0.5f, 0.5f, 1.0f, 0.95f);
		color[4].Set(0.2f, 0.2f, 0.7f, 0.00f);
		color[5].Set(0.1f, 0.1f, 0.1f, 0.00f);
		color[6].Set(0.2f, 0.2f, 0.2f,-0.10f);
		color[7].Set(0.5f, 0.5f, 0.5f,-1.00f);

		gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
		gl.FrontFace(make_torus.FaceWinding());
		gl.CullFace(Face::Back);
	}
    ShadowExample()
      : make_torus(1.0, 0.7, 72, 48)
      , torus_indices(make_torus.Indices())
      , torus_instr(make_torus.Instructions())
      , object_projection_matrix(object_prog)
      , object_camera_matrix(object_prog)
      , object_model_matrix(object_prog)
      , shadow_projection_matrix(shadow_prog)
      , shadow_camera_matrix(shadow_prog)
      , shadow_model_matrix(shadow_prog)
      , object_color(object_prog)
      , object_light_mult(object_prog) {
        vs_object.Source(
          "#version 140\n"
          "in vec4 Position;"
          "in vec3 Normal;"
          "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
          "uniform vec3 LightPos;"
          "out vec3 vertNormal;"
          "out vec3 vertLight;"
          "void main()"
          "{"
          "	gl_Position = ModelMatrix * Position;"
          "	vertNormal = mat3(ModelMatrix)*Normal;"
          "	vertLight = LightPos - gl_Position.xyz;"
          "	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
          "}");
        vs_object.Compile();

        fs_object.Source(
          "#version 140\n"
          "in vec3 vertNormal;"
          "in vec3 vertLight;"
          "uniform vec3 Color;"
          "uniform float LightMult;"
          "out vec4 fragColor;"
          "void main()"
          "{"
          "	float l = sqrt(length(vertLight));"
          "	float d = l > 0.0 ?"
          "		dot("
          "			vertNormal,"
          "			normalize(vertLight)"
          "		) / l : 0.0;"
          "	float i = 0.3 + max(d, 0.0) * LightMult;"
          "	fragColor = vec4(Color*i, 1.0);"
          "}");
        fs_object.Compile();

        object_prog.AttachShader(vs_object);
        object_prog.AttachShader(fs_object);
        object_prog.Link().Use();

        object_projection_matrix.BindTo("ProjectionMatrix");
        object_camera_matrix.BindTo("CameraMatrix");
        object_model_matrix.BindTo("ModelMatrix");
        object_color.BindTo("Color");
        object_light_mult.BindTo("LightMult");

        vs_shadow.Source(
          "#version 150\n"
          "in vec4 Position;"
          "in vec3 Normal;"
          "uniform mat4 ModelMatrix;"
          "uniform vec3 LightPos;"
          "out float ld;"
          "void main()"
          "{"
          "	gl_Position = ModelMatrix * Position;"
          "	vec3 geomNormal = mat3(ModelMatrix)*Normal;"
          "	vec3 lightDir = LightPos - gl_Position.xyz;"
          "	ld = dot(geomNormal, normalize(lightDir));"
          "}");
        vs_shadow.Compile();

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

          "in float ld[];"

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

          "void main()"
          "{"
          "	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;"
          "		if(ld[a] == 0.0 && ld[b] == 0.0)"
          "		{"
          "			px = pa;"
          "			py = pb;"
          "		}"
          "		else if(ld[a] > 0.0 && ld[b] < 0.0)"
          "		{"
          "			float x = ld[a]/(ld[a]-ld[b]);"
          "			float y;"
          "			px = mix(pa, pb, x);"
          "			if(ld[c] < 0.0)"
          "			{"
          "				y = ld[a]/(ld[a]-ld[c]);"
          "				py = mix(pa, pc, y);"
          "			}"
          "			else"
          "			{"
          "				y = ld[c]/(ld[c]-ld[b]);"
          "				py = mix(pc, pb, y);"
          "			}"
          "		}"
          "		else continue;"
          "		vec3 vx = px.xyz - LightPos;"
          "		vec3 vy = py.xyz - LightPos;"
          "		vec4 sx = vec4(px.xyz + vx*10.0, 1.0);"
          "		vec4 sy = vec4(py.xyz + vy*10.0, 1.0);"
          "		vec4 cpx = CameraMatrix * px;"
          "		vec4 cpy = CameraMatrix * py;"
          "		vec4 csx = CameraMatrix * sx;"
          "		vec4 csy = CameraMatrix * sy;"
          "		gl_Position = ProjectionMatrix * cpy;"
          "		EmitVertex();"
          "		gl_Position = ProjectionMatrix * cpx;"
          "		EmitVertex();"
          "		gl_Position = ProjectionMatrix * csy;"
          "		EmitVertex();"
          "		gl_Position = ProjectionMatrix * csx;"
          "		EmitVertex();"
          "		EndPrimitive();"
          "		break;"
          "	}"
          "}");
        gs_shadow.Compile();

        fs_shadow.Source(
          "#version 150\n"
          "out vec4 fragColor;"
          "void main()"
          "{"
          "	fragColor = vec4(0.0, 0.0, 0.0, 1.0);"
          "}");
        fs_shadow.Compile();

        shadow_prog.AttachShader(vs_shadow);
        shadow_prog.AttachShader(gs_shadow);
        shadow_prog.AttachShader(fs_shadow);
        shadow_prog.Link().Use();

        shadow_projection_matrix.BindTo("ProjectionMatrix");
        shadow_camera_matrix.BindTo("CameraMatrix");
        shadow_model_matrix.BindTo("ModelMatrix");

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

        // bind the VBO for the torus vertices
        torus_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(VertexArrayAttrib::GetCommonLocation(
              MakeGroup(object_prog, shadow_prog), "Position"));
            attr.Setup<GLfloat>(n_per_vertex);
            attr.Enable();
        }

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

            object_prog.Use();
            VertexArrayAttrib attr(object_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);
            object_prog.Use();
            VertexArrayAttrib attr(object_prog, "Position");
            attr.Setup<GLfloat>(3);
            attr.Enable();
        }

        // bind the VBO for the torus 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);
            object_prog.Use();
            VertexArrayAttrib attr(object_prog, "Normal");
            attr.Setup<GLfloat>(3);
            attr.Enable();
        }

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

        ProgramUniform<Vec3f>(object_prog, "LightPos").Set(lightPos);
        ProgramUniform<Vec3f>(shadow_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.Enable(Capability::CullFace);
        gl.FrontFace(make_torus.FaceWinding());
    }
	FBTexExample(void)
	 : make_cube()
	 , cube_instr(make_cube.Instructions())
	 , cube_indices(make_cube.Indices())
	 , make_torus(1.0, 0.5, 72, 48)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	 , cube_fs(ObjectDesc("Cube fragment"))
	 , torus_fs(ObjectDesc("Torus fragment"))
	 , torus_projection_matrix(torus_prog, "ProjectionMatrix")
	 , torus_camera_matrix(torus_prog, "CameraMatrix")
	 , torus_model_matrix(torus_prog, "ModelMatrix")
	 , cube_projection_matrix(cube_prog, "ProjectionMatrix")
	 , cube_camera_matrix(cube_prog, "CameraMatrix")
	 , cube_model_matrix(cube_prog, "ModelMatrix")
	 , tex_side(512)
	 , width(tex_side)
	 , height(tex_side)
	{
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"in vec2 TexCoord;"
			"out vec3 vertNormal;"
			"out vec3 vertLight;"
			"out vec2 vertTexCoord;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	gl_Position = ModelMatrix * Position;"
			"	vertLight = LightPos-gl_Position.xyz;"
			"	vertTexCoord = TexCoord;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		vs.Compile();

		cube_fs.Source(
			"#version 330\n"
			"uniform sampler2D TexUnit;"
			"in vec3 vertNormal;"
			"in vec3 vertLight;"
			"in vec2 vertTexCoord;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float l = sqrt(length(vertLight));"
			"	float d = l > 0? dot(vertNormal, normalize(vertLight)) / l : 0.0;"
			"	float i = 0.6 + max(d, 0.0);"
			"	fragColor = texture(TexUnit, vertTexCoord)*i;"
			"}"
		);
		cube_fs.Compile();

		cube_prog.AttachShader(vs);
		cube_prog.AttachShader(cube_fs);
		cube_prog.Link();
		cube_prog.Use();

		cube.Bind();

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

		cube_normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.Normals(data);
			Buffer::Data(Buffer::Target::Array, data);
			VertexAttribArray attr(cube_prog, "Normal");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		cube_texcoords.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.TexCoordinates(data);
			Buffer::Data(Buffer::Target::Array, data);
			VertexAttribArray attr(cube_prog, "TexCoord");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		UniformSampler(cube_prog, "TexUnit").Set(0);
		Uniform<Vec3f>(cube_prog, "LightPos").Set(4.0f, 4.0f, -8.0f);

		torus_fs.Source(
			"#version 330\n"
			"in vec3 vertNormal;"
			"in vec3 vertLight;"
			"in vec2 vertTexCoord;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float d = dot("
			"		vertNormal, "
			"		normalize(vertLight)"
			"	);"
			"	float i = ("
			"		int(vertTexCoord.x*18) % 2+"
			"		int(vertTexCoord.y*14) % 2"
			"	) % 2;"
			"	float c = (0.4 + max(d, 0.0))*(1-i/2);"
			"	fragColor = vec4(c, c, c, 1.0);"
			"}"
		);
		torus_fs.Compile();

		torus_prog.AttachShader(vs);
		torus_prog.AttachShader(torus_fs);
		torus_prog.Link();
		torus_prog.Use();

		torus.Bind();

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

		torus_normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.Normals(data);
			Buffer::Data(Buffer::Target::Array, data);
			VertexAttribArray attr(torus_prog, "Normal");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		torus_texcoords.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.TexCoordinates(data);
			Buffer::Data(Buffer::Target::Array, data);
			VertexAttribArray attr(torus_prog, "TexCoord");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		Uniform<Vec3f>(torus_prog, "LightPos").Set(2.0f, 3.0f, 4.0f);

		{
			auto bound_tex = Bind(tex, Texture::Target::_2D);
			bound_tex.Image2D(
				0,
				PixelDataInternalFormat::RGBA,
				tex_side, tex_side,
				0,
				PixelDataFormat::RGBA,
				PixelDataType::UnsignedByte,
				nullptr
			);
			bound_tex.MinFilter(TextureMinFilter::Linear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::Repeat);
			bound_tex.WrapT(TextureWrap::Repeat);
		}

		{
			auto bound_fbo = Bind(
				fbo,
				Framebuffer::Target::Draw
			);
			auto bound_rbo = Bind(
				rbo,
				Renderbuffer::Target::Renderbuffer
			);
			bound_rbo.Storage(
				PixelDataInternalFormat::DepthComponent,
				tex_side,
				tex_side
			);
			bound_fbo.AttachTexture(
				FramebufferAttachment::Color,
				tex,
				0
			);
			bound_fbo.AttachRenderbuffer(
				FramebufferAttachment::Depth,
				rbo
			);
		}

		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
		gl.CullFace(Face::Back);
	}
	void Render(double time)
	{
		// render into the texture
		fbo.Bind(Framebuffer::Target::Draw);
		gl.Viewport(tex_side, tex_side);
		gl.ClearDepth(1.0f);
		gl.ClearColor(0.4f, 0.9f, 0.4f, 1.0f);
		gl.Clear().ColorBuffer().DepthBuffer();
		torus_prog.Use();

		torus_projection_matrix.Set(
			CamMatrixf::PerspectiveX(Degrees(60), 1.0, 1, 30)
		);

		torus_camera_matrix.Set(
			CamMatrixf::Orbiting(
				Vec3f(),
				3.5,
				Degrees(time * 25),
				Degrees(SineWave(time / 30.0) * 90)
			)
		);

		torus_model_matrix.Set(
			ModelMatrixf::RotationA(
				Vec3f(1.0f, 1.0f, 1.0f),
				FullCircles(time * 0.5)
			)
		);

		torus.Bind();
		gl.FrontFace(make_torus.FaceWinding());
		torus_instr.Draw(torus_indices);

		// render the textured cube
		Framebuffer::BindDefault(Framebuffer::Target::Draw);
		gl.Viewport(width, height);
		gl.ClearDepth(1.0f);
		gl.ClearColor(0.8f, 0.8f, 0.8f, 0.0f);
		gl.Clear().ColorBuffer().DepthBuffer();
		cube_prog.Use();

		cube_projection_matrix.Set(
			CamMatrixf::PerspectiveX(
				Degrees(70),
				double(width)/height,
				1, 30
			)
		);

		cube_camera_matrix.Set(
			CamMatrixf::Orbiting(
				Vec3f(),
				3.0,
				Degrees(time * 35),
				Degrees(SineWave(time / 20.0) * 60)
			)
		);

		cube_model_matrix.Set(
			ModelMatrixf::RotationX(FullCircles(time * 0.25))
		);

		cube.Bind();
		gl.FrontFace(make_cube.FaceWinding());
		cube_instr.Draw(cube_indices);
	}
Beispiel #9
0
	TorusExample(void)
	 : make_torus(1.0, 0.5, 36, 24)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	 , make_plane(make_plane_builders())
	 , plane_instr(make_plane[0].Instructions())
	 , plane_indices(make_plane[0].Indices())
	 , torus_vs(ShaderType::Vertex, ObjectDesc("Torus vertex"))
	 , plane_vs(ShaderType::Vertex, ObjectDesc("Plane vertex"))
	 , torus_fs(ShaderType::Fragment, ObjectDesc("Torus fragment"))
	 , plane_fs(ShaderType::Fragment, ObjectDesc("Plane fragment"))
	 , torus_prog(ObjectDesc("Torus"))
	 , plane_prog(ObjectDesc("Plane"))
	 , plane_normal(plane_prog, "Normal")
	 , plane_camera_matrix(plane_prog, "CameraMatrix")
	 , torus_camera_matrix(torus_prog, "CameraMatrix")
	 , torus_model_matrix(torus_prog, "ModelMatrix")
	 , plane(make_plane.size())
	 , plane_positions(make_plane.size())
	{
		std::stringstream plane_count_def;
		plane_count_def <<"#define PlaneCount "<<plane.size()<<'\n';

		const GLchar* torus_vs_source[3] = {
			"#version 330\n",
			plane_count_def.str().c_str(),
			"uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;"
			"uniform float ClipSign[PlaneCount];"
			"uniform vec4 ClipPlane[PlaneCount];"
			"in vec4 Position;"
			"in vec2 TexCoord;"
			"out vec2 vertTexCoord;"
			"void main(void)"
			"{"
			"	vertTexCoord = TexCoord;"
			"	gl_Position = "
			"		ModelMatrix *"
			"		Position;"
			"	for(int p=0; p!=PlaneCount; ++p)"
			"	{"
			"		gl_ClipDistance[p] = "
			"			ClipSign[p]* "
			"			dot(ClipPlane[p], gl_Position);"
			"	}"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		gl_Position;"
			"}"
		};
		torus_vs.Source(torus_vs_source, 3);
		torus_vs.Compile();

		torus_fs.Source(
			"#version 330\n"
			"in vec2 vertTexCoord;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float i = ("
			"		int(vertTexCoord.x*36) % 2+"
			"		int(vertTexCoord.y*24) % 2"
			"	) % 2;"
			"	fragColor = vec4(1-i/2, 1-i/2, 1-i/2, 1.0);"
			"}"
		);
		torus_fs.Compile();

		torus_prog.AttachShader(torus_vs);
		torus_prog.AttachShader(torus_fs);
		torus_prog.Link();
		torus_prog.Use();

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

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

		// bind the VBO for the torus UV-coordinates
		torus_texcoords.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.TexCoordinates(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			// setup the vertex attribs array for the vertices
			VertexAttribArray attr(torus_prog, "TexCoord");
			attr.Setup(n_per_vertex, DataType::Float);
			attr.Enable();
		}

		const GLchar* plane_vs_source[3] = {
			"#version 330\n",
			plane_count_def.str().c_str(),
			"uniform mat4 ProjectionMatrix, CameraMatrix;"
			"uniform float ClipSign[PlaneCount];"
			"uniform vec4 ClipPlane[PlaneCount];"
			"uniform vec3 Normal;"
			"in vec4 Position;"
			"out vec3 vertColor;"
			"void main(void)"
			"{"
			"	gl_Position = Position;"
			"	for(int p=0; p!=PlaneCount; ++p)"
			"	{"
			"		gl_ClipDistance[p] = "
			"			ClipSign[p]* "
			"			dot(ClipPlane[p], gl_Position);"
			"	}"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		gl_Position;"
			"	vertColor = normalize("
			"		abs(Normal) + "
			"		0.4*Position.xyz"
			"	);"
			"}"
		};
		plane_vs.Source(plane_vs_source, 3);
		plane_vs.Compile();

		plane_fs.Source(
			"#version 330\n"
			"in vec3 vertColor;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	fragColor = vec4(vertColor, 0.7);"
			"}"
		);
		plane_fs.Compile();

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


		ProgramUniform<Vec4f> torus_clip_plane(torus_prog, "ClipPlane");
		ProgramUniform<Vec4f> plane_clip_plane(plane_prog, "ClipPlane");
		ProgramUniform<GLfloat> torus_clip_sign(torus_prog, "ClipSign");
		ProgramUniform<GLfloat> plane_clip_sign(plane_prog, "ClipSign");
		for(std::size_t p=0; p!=plane.size(); ++p)
		{
			plane[p].Bind();

			plane_positions[p].Bind(Buffer::Target::Array);
			{
				std::vector<GLfloat> data;
				GLuint n = make_plane[p].Positions(data);
				// upload the data
				Buffer::Data(Buffer::Target::Array, data);
				VertexAttribArray attr(plane_prog, "Position");
				attr.Setup(n, DataType::Float);
				attr.Enable();
			}
			{
				auto eq = make_plane[p].Equation();
				torus_clip_plane[p].Set(eq);
				plane_clip_plane[p].Set(eq);
			}
			{
				torus_clip_signs.push_back(torus_clip_sign[p]);
				plane_clip_signs.push_back(plane_clip_sign[p]);
			}
		}

		//
		gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.FrontFace(make_torus.FaceWinding());
		gl.Enable(Capability::DepthTest);
		gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha);
	}
	TorusExample(void)
	 : make_torus(1.0, 0.5, 18, 36)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	 , vs(ObjectDesc("Vertex"))
	 , gs(ObjectDesc("Geometry"))
	 , face_fs(ObjectDesc("Face fragment"))
	 , frame_fs(ObjectDesc("Frame fragment"))
	 , transf_prog(ObjectDesc("Transformation"))
	 , face_prog(ObjectDesc("Face"))
	 , frame_prog(ObjectDesc("Frame"))
	 , projection_matrix(transf_prog, "ProjectionMatrix")
	 , camera_matrix(transf_prog, "CameraMatrix")
	 , model_matrix(transf_prog, "ModelMatrix")
	 , transf_time(transf_prog, "Time")
	{
		vs.Source(
			"#version 330\n"
			"uniform mat4 ModelMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"in vec2 TexCoord;"
			"out gl_PerVertex {"
			"	vec4 gl_Position;"
			"};"
			"out vec3 vertNormal;"
			"out vec2 vertTexCoord;"
			"void main(void)"
			"{"
			"	gl_Position = ModelMatrix * Position;"
			"	vertNormal = (ModelMatrix*vec4(Normal,0.0)).xyz;"
			"	vertTexCoord = TexCoord;"
			"}"
		);
		vs.Compile();

		gs.Source(
			"#version 330\n"
			"layout(triangles) in;"
			"layout(triangle_strip, max_vertices = 15) out;"
			"uniform mat4 CameraMatrix, ProjectionMatrix;"
			"uniform vec3 LightPos;"
			"uniform float Time;"
			"in gl_PerVertex {"
			"	vec4 gl_Position;"
			"} gl_in[];"
			"in vec3 vertNormal[];"
			"in vec2 vertTexCoord[];"
			"out gl_PerVertex {"
			"	vec4 gl_Position;"
			"};"
			"out vec3 geomNormal;"
			"out vec3 geomLight;"
			"out float geomGlow;"
			"flat out int geomTop;"
			"void main(void)"
			"{"
			"	vec3 FaceNormal = normalize("
			"		vertNormal[0]+"
			"		vertNormal[1]+"
			"		vertNormal[2] "
			"	);"
			"	vec2 FaceCoord = 0.33333 * ("
			"		vertTexCoord[0]+"
			"		vertTexCoord[1]+"
			"		vertTexCoord[2] "
			"	);"
			"	float Offs = (sin((FaceCoord.s + Time/10.0)* 3.14 * 2.0 * 10)*0.5 + 0.5)*0.4;"
			"	Offs *= cos(FaceCoord.t * 3.1415 * 2.0)*0.5 + 0.51;"

			"	vec3 pos[3], norm[3];"
			"	for(int i=0; i!=3; ++i)"
			"		pos[i] = gl_in[i].gl_Position.xyz;"
			"	for(int i=0; i!=3; ++i)"
			"		norm[i] = cross("
			"			FaceNormal, "
			"			normalize(pos[(i+1)%3] - pos[i])"
			"		);"
			"	vec3 pofs = FaceNormal * Offs;"

			"	geomTop = 0;"
			"	for(int i=0; i!=3; ++i)"
			"	{"
			"		geomNormal = norm[i];"
			"		for(int j=0; j!=2; ++j)"
			"		{"
			"			vec3 tpos = pos[(i+j)%3];"
			"			geomLight = LightPos-tpos;"
			"			geomGlow = 1.0;"
			"			gl_Position = "
			"				ProjectionMatrix *"
			"				CameraMatrix *"
			"				vec4(tpos, 1.0);"
			"			EmitVertex();"
			"			geomGlow = 0.7;"
			"			geomLight = LightPos-tpos+pofs;"
			"			gl_Position = "
			"				ProjectionMatrix *"
			"				CameraMatrix *"
			"				vec4(tpos + pofs, 1.0);"
			"			EmitVertex();"
			"		}"
			"		EndPrimitive();"
			"	}"

			"	geomGlow = 0.0;"
			"	geomTop = 1;"
			"	for(int i=0; i!=3; ++i)"
			"	{"
			"		geomLight = LightPos - (pos[i]+pofs);"
			"		geomNormal = vertNormal[i];"
			"		gl_Position = "
			"			ProjectionMatrix *"
			"			CameraMatrix *"
			"			vec4(pos[i] + pofs, 1.0);"
			"		EmitVertex();"
			"	}"
			"	EndPrimitive();"
			"}"
		);
		gs.Compile();

		transf_prog.AttachShader(vs);
		transf_prog.AttachShader(gs);
		transf_prog.MakeSeparable();
		transf_prog.Link();
		transf_prog.Use();

		ProgramUniform<Vec3f>(transf_prog, "LightPos").Set(4, 4, -8);

		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);

			VertexAttribArray attr(transf_prog, "Position");
			attr.Setup(n_per_vertex, DataType::Float);
			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);

			VertexAttribArray attr(transf_prog, "Normal");
			attr.Setup(n_per_vertex, DataType::Float);
			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);

			VertexAttribArray attr(transf_prog, "TexCoord");
			attr.Setup(n_per_vertex, DataType::Float);
			attr.Enable();
		}

		face_fs.Source(
			"#version 330\n"
			"in vec3 geomNormal;"
			"in vec3 geomLight;"
			"in float geomGlow;"
			"flat in int geomTop;"
			"uniform vec3 TopColor, SideColor;"
			"const vec3 LightColor = vec3(1.0, 1.0, 1.0);"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float d = max(dot("
			"		normalize(geomLight),"
			"		normalize(geomNormal)"
			"	), 0.0);"
			"	vec3 color;"
			"	if(geomTop != 0)"
			"	{"
			"		color = TopColor * d +"
			"			LightColor * pow(d, 8.0);"
			"	}"
			"	else"
			"	{"
			"		color = SideColor * geomGlow +"
			"			LightColor *"
			"			pow(d, 2.0) * 0.2;"
			"	}"
			"	fragColor = vec4(color, 1.0);"
			"}"
		);
		face_fs.Compile();

		face_prog.AttachShader(face_fs);
		face_prog.MakeSeparable();
		face_prog.Link();

		ProgramUniform<Vec3f>(face_prog, "TopColor").Set(0.2f, 0.2f, 0.2f);
		ProgramUniform<Vec3f>(face_prog, "SideColor").Set(0.9f, 0.9f, 0.2f);

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


		frame_fs.Source(
			"#version 330\n"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	fragColor = vec4(0.2, 0.1, 0.0, 1.0);"
			"}"
		);
		frame_fs.Compile();

		frame_prog.AttachShader(frame_fs);
		frame_prog.MakeSeparable();
		frame_prog.Link();

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

		ProgramPipeline::Unbind();
		Program::UseNone();

		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());
	}
Beispiel #11
0
	TorusExample(void)
	 : make_torus(1.0, 0.5, 12, 12)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	 , light_pos_cam(prog, "LightPosCam")
	 , front_color(prog, "FrontColor")
	 , back_color(prog, "BackColor")
	{
		vs.Source(
			"#version 330\n"
			"uniform mat4 ModelMatrix, CameraMatrix;"
			"in vec4 Position;"
			"void main(void)"
			"{"
			"	gl_Position = CameraMatrix *"
			"		ModelMatrix * Position;"
			"}"
		);
		vs.Compile();

		gs.Source(
			"#version 330\n"
			"layout(triangles) in;"
			"layout(triangle_strip, max_vertices = 8) out;"
			"uniform mat4 ProjectionMatrix;"
			"uniform vec4 LightPosCam;"
			"out vec3 geomLightDir;"
			"out float geomOpacity;"
			"void main(void)"
			"{"
			"	vec4 c = vec4(("
			"		gl_in[0].gl_Position.xyz+"
			"		gl_in[1].gl_Position.xyz+"
			"		gl_in[2].gl_Position.xyz "
			"	) * 0.333333, 1.0);"
			"	for(int v = 0; v != 4; ++v)"
			"	{"
			"		vec4 b = gl_in[v%3].gl_Position;"
			"		vec4 a = vec4("
			"			b.xyz + (c.xyz - b.xyz)*0.3,"
			"			1.0"
			"		);"

			"		gl_Position = ProjectionMatrix * a;"
			"		geomLightDir = (LightPosCam - a).xyz;"
			"		geomOpacity = 1.0;"
			"		EmitVertex();"
			"		gl_Position = ProjectionMatrix * b;"
			"		geomLightDir = (LightPosCam - b).xyz;"
			"		geomOpacity = 0.0;"
			"		EmitVertex();"
			"	}"
			"	EndPrimitive();"
			"}"
		);
		gs.Compile();

		fs.Source(
			"#version 330\n"
			"in vec3 geomLightDir;"
			"in float geomOpacity;"
			"uniform vec3 FrontColor, BackColor;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float l = length(geomLightDir);"
			"	vec3 color = gl_FrontFacing?"
			"		FrontColor:"
			"		BackColor;"
			"	fragColor = vec4(color*(4.0/l), geomOpacity);"
			"}"
		);
		fs.Compile();

		prog.AttachShader(vs);
		prog.AttachShader(gs);
		prog.AttachShader(fs);
		prog.Link();

		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);

			prog.Use();
			VertexAttribArray attr(prog, "Position");
			attr.Setup(n_per_vertex, DataType::Float);
			attr.Enable();
		}

		gl.ClearColor(0.8f, 0.7f, 0.6f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.DepthFunc(CompareFn::LEqual);
		gl.FrontFace(make_torus.FaceWinding());
	}
Beispiel #12
0
	TorusExample(void)
	 : make_torus(1.0, 0.5, 72, 48)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	{
		// Set the vertex shader source
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"out vec3 vertNormal;"
			"out vec3 vertViewDir;"
			"void main(void)"
			"{"
			"	vertNormal = Normal;"
			"	vertViewDir = ("
			"		vec4(0.0, 0.0, 1.0, 1.0)*"
			"		CameraMatrix"
			"	).xyz;"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		Position;"
			"}"
		);
		// compile it
		vs.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"in vec3 vertNormal;"
			"in vec3 vertViewDir;"
			"out vec4 fragColor;"
			"uniform vec3 LightPos[3];"
			"void main(void)"
			"{"
			"	float amb = 0.2;"
			"	float diff = 0.0;"
			"	float spec = 0.0;"
			"	for(int i=0;i!=3;++i)"
			"	{"
			"		diff += max("
			"			dot(vertNormal,  LightPos[i])/"
			"			dot(LightPos[i], LightPos[i]),"
			"			0.0"
			"		);"
			"		float k = dot(vertNormal, LightPos[i]);"
			"		vec3 r = 2.0*k*vertNormal - LightPos[i];"
			"		spec += pow(max("
			"			dot(normalize(r), vertViewDir),"
			"			0.0"
			"		), 32.0 * dot(r, r));"
			"	}"
			"	fragColor = "
			"		vec4(1.0, 0.1, 0.3, 1.0)*(amb+diff)+"
			"		vec4(1.0, 1.0, 1.0, 1.0)*spec;"
			"}"
		);
		// 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 torus
		torus.Bind();

		// bind the VBO for the torus vertices
		verts.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.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 torus normals
		normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.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(n_per_vertex, DataType::Float);
			attr.Enable();
		}

		// set the light positions
		Uniform<Vec3f> light_pos(prog, "LightPos");
		light_pos[0].Set(Vec3f(2.0f,-1.0f, 0.0f));
		light_pos[1].Set(Vec3f(0.0f, 3.0f, 0.0f));
		light_pos[2].Set(Vec3f(0.0f,-1.0f, 4.0f));
		//
		gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
		gl.FrontFace(make_torus.FaceWinding());
		gl.CullFace(Face::Back);
	}