Example #1
0
	static Program make(void)
	{
		Program prog;

		VertexShader vs;
		vs.Source(
			"#version 330\n"
			"in vec4 Position;"
			"in ivec3 TexCoord;"
			"out ivec3 vertTexCoord;"

			"void main(void)"
			"{"
			"	gl_Position = Position;"
			"	vertTexCoord = TexCoord;"
			"}"
		).Compile();
		prog.AttachShader(vs);

		GeometryShader gs;
		gs.Source(
			"#version 330\n"
			"layout (points) in;"
			"layout (triangle_strip, max_vertices=24) out;"

			"uniform float FadeCoef;"
			"uniform sampler3D Pattern, FadeMap;"
			"uniform mat4 ProjectionMatrix, CameraMatrix;"
			"mat4 Matrix = ProjectionMatrix*CameraMatrix;"
			"uniform vec3 LightPosition = vec3(100, 120, 150);"

			"in ivec3 vertTexCoord[1];"

			"out vec3 geomNormal;"
			"out vec3 geomLightDir;"
			"out vec3 geomTexCoord;"
			"out float geomShadow;"

			"float get_cell(ivec3 offs)"
			"{"
			"	ivec3 coord = vertTexCoord[0]+offs;"
			"	float patt = texelFetch(Pattern, coord, 0).r;"
			"	float fade = texelFetch(FadeMap, coord, 0).r;"
			"	return clamp("
			"		(patt != 0.0)?"
			"		(FadeCoef-fade)*256.0:"
			"		0.0, 0.0, 1.0"
			"	);"
			"}"

			"const ivec3 coffs[6] = ivec3[6]("
			"	ivec3(+1, 0, 0),"
			"	ivec3(-1, 0, 0),"
			"	ivec3( 0,+1, 0),"
			"	ivec3( 0,-1, 0),"
			"	ivec3( 0, 0,+1),"
			"	ivec3( 0, 0,-1) "
			");"

			"const mat3 tmats[6] = mat3[6]("
			"	mat3( 0, 0, 1,  0,-1, 0,  1, 0, 0),"
			"	mat3( 0, 0,-1,  0,-1, 0, -1, 0, 0),"
			"	mat3(-1, 0, 0,  0, 0, 1,  0, 1, 0),"
			"	mat3(-1, 0, 0,  0, 0,-1,  0,-1, 0),"
			"	mat3( 1, 0, 0,  0, 1, 0,  0, 0, 1),"
			"	mat3(-1, 0, 0,  0, 1, 0,  0, 0,-1) "
			");"

			"const vec3[8] nvec = vec3[8]("
			"	vec3( 0,-1,+1),"
			"	vec3(+1,-1,+1),"
			"	vec3(+1, 0,+1),"
			"	vec3(+1,+1,+1),"
			"	vec3( 0,+1,+1),"
			"	vec3(-1,+1,+1),"
			"	vec3(-1, 0,+1),"
			"	vec3(-1,-1,+1) "
			");"

			"void main(void)"
			"{"
			"	float cc = get_cell(ivec3(0,0,0));"
			"	if(cc > 0.0)"
			"	{"
			"		float c05 = 0.5*cc;"
			"		float c0 = 0.5-c05;"
			"		float c1 = 0.5+c05;"

			"		for(int f=0; f!=6; ++f)"
			"		if(get_cell(coffs[f]) < 1.0)"
			"		{"
			"			int config = 0x0;"
			"			vec3 noffs[8];"
			"			vec3 nml = tmats[f][2];"
			"			float aoc = get_cell(ivec3(nml*2));"
			"			aoc += 0.8*get_cell(ivec3(nml*3));"
			"			for(int n=0; n!=8; ++n)"
			"			{"
			"				noffs[n] = nvec[n]*tmats[f];"
			"				float nc = get_cell(ivec3(noffs[n]));"
			"				aoc += 0.2*get_cell(ivec3(noffs[n]+nml));"
			"				aoc += 0.1*get_cell(ivec3(noffs[n]+nml*2));"
			"				config |= (nc>0.0)?0x1<<n:0x0;"
			"			}"
			"			float aom = float(config);"

			"			geomNormal = tmats[f][2];"

			"			geomShadow = max(1.0-sqrt(aoc), 0.0);"

			"			vec3 cpos = gl_in[0].gl_Position.xyz;"

			"			gl_Position = vec4(cpos+noffs[7]*c05, 1.0);"
			"			geomLightDir = LightPosition - gl_Position.xyz;"
			"			gl_Position = Matrix * gl_Position;"
			"			geomTexCoord = vec3(c0, c1, aom);"
			"			EmitVertex();"

			"			gl_Position = vec4(cpos+noffs[1]*c05, 1.0);"
			"			geomLightDir = LightPosition - gl_Position.xyz;"
			"			gl_Position = Matrix * gl_Position;"
			"			geomTexCoord = vec3(c1, c1, aom);"
			"			EmitVertex();"

			"			gl_Position = vec4(cpos+noffs[5]*c05, 1.0);"
			"			geomLightDir = LightPosition - gl_Position.xyz;"
			"			gl_Position = Matrix * gl_Position;"
			"			geomTexCoord = vec3(c0, c0, aom);"
			"			EmitVertex();"

			"			gl_Position = vec4(cpos+noffs[3]*c05, 1.0);"
			"			geomLightDir = LightPosition - gl_Position.xyz;"
			"			gl_Position = Matrix * gl_Position;"
			"			geomTexCoord = vec3(c1, c0, aom);"
			"			EmitVertex();"

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

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

			"uniform sampler2DArray AmbiOcclMaps;"

			"in vec3 geomNormal;"
			"in vec3 geomLightDir;"
			"in vec3 geomTexCoord;"
			"in float geomShadow;"

			"out vec3 fragColor;"
			"void main(void)"
			"{"
			"	float amoc = texture(AmbiOcclMaps, geomTexCoord).r;"
			"	float shdw = sqrt(0.5*(1.0+geomShadow));"
			"	float ambi = 0.5;"
			"	float diff = max(dot(geomNormal, normalize(geomLightDir)), 0)*0.6;"
			"	float light = ambi*amoc*shdw + (0.8*amoc*shdw+0.2)*diff;"
			"	fragColor = vec3(1,1,1)*light;"
			"}"
		).Compile();
		prog.AttachShader(fs);

		prog.Link().Use();

		return std::move(prog);
	}
	static Program make(void)
	{
		VertexShader vs;
		vs.Source(
			"#version 330\n"
			"uniform mat4  ProjectionMatrix,CameraMatrix,ModelMatrix;"
			"mat3 RotMatrix = mat3(ModelMatrix);"

			"const vec3 LightPosition = vec3(12.0, 11.0, 17.0);"

			"in vec4 Position;"
			"in vec3 Normal;"

			"out vec3 vertLightDir;"
			"out vec3 vertNormal;"
			"out vec3 vertColor;"
			"void main(void)"
			"{"
			"	gl_Position = ModelMatrix * Position;"
			"	vertLightDir = LightPosition - gl_Position.xyz;"
			"	vertNormal = RotMatrix * Normal;"
			"	vertColor = normalize("
			"		vec3(1, 1, 1) - "
			"		mix(vertNormal, Position.xyz, 0.5)"
			"	);"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		).Compile();

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

			"uniform sampler2DRect DepthTex;"

			"in vec4 gl_FragCoord;"

			"in vec3 vertLightDir;"
			"in vec3 vertNormal;"
			"in vec3 vertColor;"

			"out vec3 fragColor;"
			"void main(void)"
			"{"
			"	float w = gl_FragCoord.w;"
			"	float sum_bz = 0.0;"
			"	const int nd = 2;"
			"	float ns = 0.0;"
			"	for(int dy=-nd; dy!=(nd+1); ++dy)"
			"	for(int dx=-nd; dx!=(nd+1); ++dx)"
			"	{"
			"		ivec2 TexelCoord = ivec2(gl_FragCoord.xy)+ivec2(dx, dy);"
			"		float bz = texelFetch(DepthTex, TexelCoord).x;"
			"		if(bz < 1.0)"
			"		{"
			"			sum_bz += bz;"
			"			ns += 1.0;"
			"		}"
			"	}"
			"	float DepthDiff = (sum_bz/ns)/w - gl_FragCoord.z/w;"
			"	DepthDiff =  clamp(pow(mix(1.0, 0.0, DepthDiff*4.0), 3.0), 0.0, 1.0);"
			"	vec3 Normal = normalize(vertNormal);"
			"	vec3 LightDir = normalize(vertLightDir);"
			"	float Ambi = 0.2;"
			"	float Diff  = 0.4*max(dot(LightDir, Normal)+0.1, 0.0);"
			"	fragColor = (Ambi + Diff + DepthDiff) * vertColor;"
			"}"
		).Compile();

		Program prog;
		prog.AttachShader(vs).AttachShader(fs).Link().Use();
		return std::move(prog);
	}
Example #3
0
	CubeExample(void)
	 : cube_instr(make_cube.Instructions())
	 , cube_indices(make_cube.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	{
		// Set the vertex shader source
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix;"
			"in vec4 Position;"
			"out vec3 vertColor;"
			"void main(void)"
			"{"
			"	float angle = gl_InstanceID * 10 * 2 * 3.14159 / 360.0;"
			"	float cx = cos(angle);"
			"	float sx = sin(angle);"
			"	mat4 ModelMatrix = mat4("
			"		 cx, 0.0,  sx, 0.0,"
			"		0.0, 1.0, 0.0, 0.0,"
			"		-sx, 0.0,  cx, 0.0,"
			"		0.0, 0.0, 0.0, 1.0 "
			"	) * 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,"
			"		12.0, 0.0, 0.0, 1.0 "
			"	);"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		ModelMatrix *"
			"		Position;"
			"	vertColor = abs(normalize((ModelMatrix*Position).xyz));"
			"}"
		);
		// compile it
		vs.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"in vec3 vertColor;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	fragColor = vec4(vertColor, 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();
		}

		//
		gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
	}
Example #4
0
    SkyBoxExample()
      : sky_box(List("Position").Get(), shapes::SkyBox())
      , shape(List("Position")("Normal").Get(), shapes::WickerTorus())
      , sky_box_prog()
      , sky_box_projection_matrix(sky_box_prog, "ProjectionMatrix")
      , sky_box_camera_matrix(sky_box_prog, "CameraMatrix")
      , shape_projection_matrix(shape_prog, "ProjectionMatrix")
      , shape_camera_matrix(shape_prog, "CameraMatrix")
      , shape_model_matrix(shape_prog, "ModelMatrix")
      , sky_box_sun_position(sky_box_prog, "SunPosition")
      , shape_sun_position(shape_prog, "SunPosition")
      , shape_camera_position(shape_prog, "CameraPosition") {
        VertexShader sky_box_vs;
        sky_box_vs.Source(
          "#version 140\n"
          "uniform mat4 ProjectionMatrix, CameraMatrix;"
          "mat4 Matrix = ProjectionMatrix*CameraMatrix;"

          "in vec3 Position;"
          "out vec3 vertTexCoord;"
          "void main()"
          "{"
          "	gl_Position = Matrix * vec4(Position * 100.0, 1.0);"
          "	vertTexCoord = Position;"
          "}");
        sky_box_vs.Compile();
        sky_box_prog.AttachShader(sky_box_vs);

        VertexShader shape_vs;
        shape_vs.Source(
          "#version 140\n"

          "uniform vec3 SunPosition;"
          "uniform vec3 CameraPosition;"
          "uniform mat4  ProjectionMatrix,CameraMatrix,ModelMatrix;"

          "in vec4 Position;"
          "in vec3 Normal;"

          "out vec3 vertNormal, vertViewRefl, vertLightDir;"

          "void main()"
          "{"
          "	gl_Position = ModelMatrix * Position;"
          "	vertNormal = mat3(ModelMatrix)*Normal;"
          "	vertViewRefl = reflect("
          "		gl_Position.xyz - CameraPosition,"
          "		vertNormal"
          "	);"
          "	vertLightDir = SunPosition - gl_Position.xyz;"
          "	gl_Position = ProjectionMatrix*CameraMatrix*gl_Position;"
          "}");
        shape_vs.Compile();
        shape_prog.AttachShader(shape_vs);

        FragmentShader sky_box_fs;
        sky_box_fs.Source(
          "#version 140\n"

          "in vec3 vertTexCoord;"

          "out vec3 fragColor;"

          "vec3 sky_color(vec3 vd);"

          "void main()"
          "{"
          "	fragColor = sky_color(normalize(vertTexCoord));"
          "}");
        sky_box_fs.Compile();
        sky_box_prog.AttachShader(sky_box_fs);

        FragmentShader shape_fs;
        shape_fs.Source(
          "#version 140\n"

          "in vec3 vertNormal, vertViewRefl, vertLightDir;"

          "out vec3 fragColor;"

          "vec3 sky_color(vec3 vd);"

          "void main()"
          "{"
          "	float l = max(dot(normalize(vertNormal), "
          "normalize(vertLightDir))+0.1, 0.0);"
          "	float a = 0.1;"
          "	fragColor = "
          "		0.1*vec3(1.0, 1.0, 1.0)*(a+l)+"
          "		0.9*sky_color(normalize(vertViewRefl));"
          "}");
        shape_fs.Compile();
        shape_prog.AttachShader(shape_fs);

        FragmentShader sky_fs;
        sky_fs.Source(
          "#version 140\n"

          "const float WorldRadius = 6371000;"
          "const float AtmThickness = 50000;"
          "const vec3 AirColor = vec3(0.32, 0.36, 0.45);"
          "const vec3 LightColor = vec3(1.0, 1.0, 1.0);"

          "uniform vec3 SunPosition;"

          "uniform samplerCube EnvMap;"

          "float atm_intersection(vec3 v)"
          "{"
          "	const vec3 c = vec3(0.0, -WorldRadius, 0.0);"
          "	const float r = WorldRadius + AtmThickness;"
          "	const float c_c = dot(-c, -c);"
          "	float v_c = dot( v, -c);"
          "	return (-v_c + sqrt(v_c*v_c - c_c + r*r))/AtmThickness;"
          "}"

          "vec3 sky_color(vec3 vd)"
          "{"
          "	vec3 up = vec3(0.0, 1.0, 0.0);"
          "	vec3 ld = normalize(SunPosition);"
          "	vec4 cl = texture(EnvMap, vd);"
          "	float ai = atm_intersection(vd);"
          "	float al = max(dot(ld, up) + 0.12, 0.0);"
          "	float vl = max(dot(vd, ld), 0.0);"
          "	float ct = (1.0-cl.a)*cl.b;"
          "	vec3 ac = max(LightColor-AirColor*pow(ai, 0.33), vec3(0.0, 0.0, "
          "0.0));"

          "	vec3 Sun = "
          "		ac*(vl>0.995+0.004*al ? 1.0:0.0);"

          "	vec3 Air = "
          "		min(AirColor*sqrt(pow(al,0.25)*ai), vec3(al, al, al)*1.5)+"
          "		ac*pow(min(vl+0.001*ai, 1.0), 1024.0/pow(ai, 2.0))+"
          "		ac*(vl/(1.0+pow(3.0*al, 8.0)))*pow(ai, 0.6)*0.5;"

          "	vec3 Clouds ="
          "		ac*pow(min(vl*(cl.g+cl.b), 1.015), 64.0)*pow(ct, 2.0)+"
          "		ac*pow(min(vl*cl.g+cl.b, 1.020), 32.0)*ct+"
          "		ac*pow(min(vl*cl.g*cl.b, 1.010), 16.0)*pow(ct, 0.5)+"
          "		ac*0.7*min(cl.g + cl.b*0.5, 1.0)*al+"
          "		ac*(cl.g*(1.0-cl.b*0.2)*5.0)*pow(1.0-al, 2.0)*(al)+"
          "		LightColor*0.5*min(al + cl.g*0.4+cl.b*0.1, 1.0)*sqrt(al);"

          "	return mix(Air, Clouds, cl.a*(1.0-cl.r*0.8))+Sun*(1.0-cl.a);"
          "}");
        sky_fs.Compile();
        sky_box_prog.AttachShader(sky_fs);
        shape_prog.AttachShader(sky_fs);

        sky_box_prog.Link();
        sky_box.UseInProgram(sky_box_prog);

        shape_prog.Link();
        shape.UseInProgram(shape_prog);

        {
            ProgramUniformSampler(sky_box_prog, "EnvMap").Set(0);
            ProgramUniformSampler(shape_prog, "EnvMap").Set(0);
            Texture::Active(0);

            gl.Bound(Texture::Target::CubeMap, env_map)
              .MinFilter(TextureMinFilter::Linear)
              .MagFilter(TextureMagFilter::Linear)
              .WrapS(TextureWrap::ClampToEdge)
              .WrapT(TextureWrap::ClampToEdge)
              .WrapR(TextureWrap::ClampToEdge);

            Texture::ImageCM(
              0, images::LoadTexture("clouds01-cm_0", false, false));
            Texture::ImageCM(
              1, images::LoadTexture("clouds01-cm_1", false, false));
            Texture::ImageCM(
              2, images::LoadTexture("clouds01-cm_2", false, false));
            Texture::ImageCM(
              3, images::LoadTexture("clouds01-cm_3", false, false));
            Texture::ImageCM(
              4, images::LoadTexture("clouds01-cm_4", false, false));
            Texture::ImageCM(
              5, images::LoadTexture("clouds01-cm_5", false, false));
        }

        gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.ClearDepth(1.0f);
        gl.Enable(Capability::DepthTest);
    }
Example #5
0
	ShadowVolExample(const ExampleParams& params)
	 : shape_instr(make_shape.Instructions())
	 , shape_indices(make_shape.Indices())
	 , shape_vs(ShaderType::Vertex, ObjectDesc("Shape vertex"))
	 , depth_vs(ShaderType::Vertex, ObjectDesc("Depth vertex"))
	 , light_vs(ShaderType::Vertex, ObjectDesc("Light vertex"))
	 , depth_gs(ShaderType::Geometry, ObjectDesc("Depth geometry"))
	 , light_gs(ShaderType::Geometry, ObjectDesc("Light geometry"))
	 , shape_fs(ShaderType::Fragment, ObjectDesc("Shape fragment"))
	 , depth_fs(ShaderType::Fragment, ObjectDesc("Depthfragment"))
	 , light_fs(ShaderType::Fragment, ObjectDesc("Light fragment"))
	 , shape_prog(ObjectDesc("Shape"))
	 , depth_prog(ObjectDesc("Depth"))
	 , light_prog(ObjectDesc("Light"))
	 , tex_side(128)
	 , sample_count(params.HighQuality()?1024:128)
	{
		shape_vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"in vec2 TexCoord;"
			"out vec3 vertNormal;"
			"out vec3 vertLightDir;"
			"out vec3 vertLightRefl;"
			"out vec3 vertViewDir;"
			"out vec3 vertViewRefl;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	gl_Position = ModelMatrix * Position;"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	vertLightDir = LightPos - gl_Position.xyz;"
			"	vertLightRefl = reflect("
			"		-normalize(vertLightDir),"
			"		normalize(vertNormal)"
			"	);"
			"	vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)* CameraMatrix).xyz;"
			"	vertViewRefl = reflect("
			"		normalize(vertViewDir),"
			"		normalize(vertNormal)"
			"	);"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		shape_vs.Compile();

		shape_fs.Source(
			"#version 330\n"
			"in vec3 vertNormal;"
			"in vec3 vertLightDir;"
			"in vec3 vertLightRefl;"
			"in vec3 vertViewDir;"
			"in vec3 vertViewRefl;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float l = length(vertLightDir);"
			"	float d = dot("
			"		normalize(vertNormal), "
			"		normalize(vertLightDir)"
			"	) / l;"
			"	float s = dot("
			"		normalize(vertLightRefl),"
			"		normalize(vertViewDir)"
			"	);"
			"	vec3 ambi = vec3(0.6, 0.3, 0.5);"
			"	vec3 diff = vec3(0.9, 0.7, 0.8);"
			"	vec3 spec = vec3(1.0, 0.9, 0.95);"
			"	fragColor = vec4("
			"		ambi * 0.3 + "
			"		diff * 0.7 * max(d, 0.0) + "
			"		spec * pow(max(s, 0.0), 64), "
			"		1.0"
			"	);"
			"}"
		);
		shape_fs.Compile();

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

		depth_vs.Source(
			"#version 330\n"
			"uniform mat4 ModelMatrix;"
			"uniform vec3 LightPos;"
			"in vec4 Position;"
			"void main(void)"
			"{"
			"	gl_Position = "
			"		mat4("
			"			1.0, 0.0, 0.0, -LightPos.x,"
			"			0.0, 1.0, 0.0, -LightPos.y,"
			"			0.0, 0.0, 1.0, -LightPos.z,"
			"			0.0, 0.0, 0.0,  1.0"
			"		)*"
			"		ModelMatrix *"
			"		mat4("
			"			10.0,  0.0,  0.0,  0.0,"
			"			 0.0, 10.0,  0.0,  0.0,"
			"			 0.0,  0.0, 10.0,  0.0,"
			"			 0.0,  0.0,  0.0,  1.0 "
			"		)*"
			"		Position;"
			"}"
		);
		depth_vs.Compile();

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

			"uniform mat4 ProjectionMatrix;"

			"const mat4 CubeFaceMatrix[6] = mat4[6]("
			"	mat4("
			"		 0.0,  0.0, -1.0,  0.0,"
			"		 0.0, -1.0,  0.0,  0.0,"
			"		-1.0,  0.0,  0.0,  0.0,"
			"		 0.0,  0.0,  0.0,  1.0 "
			"	), mat4("
			"		 0.0,  0.0,  1.0,  0.0,"
			"		 0.0, -1.0,  0.0,  0.0,"
			"		 1.0,  0.0,  0.0,  0.0,"
			"		 0.0,  0.0,  0.0,  1.0 "
			"	), mat4("
			"		 1.0,  0.0,  0.0,  0.0,"
			"		 0.0,  0.0, -1.0,  0.0,"
			"		 0.0,  1.0,  0.0,  0.0,"
			"		 0.0,  0.0,  0.0,  1.0 "
			"	), mat4("
			"		 1.0,  0.0,  0.0,  0.0,"
			"		 0.0,  0.0,  1.0,  0.0,"
			"		 0.0, -1.0,  0.0,  0.0,"
			"		 0.0,  0.0,  0.0,  1.0 "
			"	), 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 "
			"	), 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(gl_Layer=0; gl_Layer!=6; ++gl_Layer)"
			"	{"
			"		for(int i=0; i!=3; ++i)"
			"		{"
			"			gl_Position = "
			"				ProjectionMatrix *"
			"				CubeFaceMatrix[gl_Layer]*"
			"				gl_in[i].gl_Position;"
			"			EmitVertex();"
			"		}"
			"		EndPrimitive();"
			"	}"
			"}"
		);
		depth_gs.Compile();

		depth_fs.Source(
			"#version 330\n"
			"void main(void)"
			"{"
			"	gl_FragDepth = gl_FragCoord.z;"
			"}"
		);
		depth_fs.Compile();

		depth_prog.AttachShader(depth_vs);
		depth_prog.AttachShader(depth_gs);
		depth_prog.AttachShader(depth_fs);
		depth_prog.Link();
		depth_prog.Use();

		Uniform<Mat4f>(depth_prog, "ProjectionMatrix").Set(
			CamMatrixf::PerspectiveX(
				RightAngles(1.0),
				1.0,
				0.1,
				10.0
			)
		);

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

		shape_positions.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(VertexAttribArray::QueryCommonLocation(
				"Position",
				location,
				shape_prog,
				depth_prog
			))
			{
				VertexAttribArray shape_attr(location);
				shape_attr.Setup(n_per_vertex, DataType::Float);
				shape_attr.Enable();
			}
			else assert(!"Inconsistent 'Position' location");
		}

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

		light_vs.Source(
			"#version 330\n"
			"in vec3 Position;"
			"out float vertZOffs;"
			"uniform vec3 LightPos;"
			"uniform int SampleCount;"
			"void main(void)"
			"{"
			"	float hp = (SampleCount-1) * 0.5;"
			"	vertZOffs = (gl_InstanceID - hp)/hp;"
			"	gl_Position = vec4(Position + LightPos, 1.0);"
			"}"
		);
		light_vs.Compile();

		light_gs.Source(
			"#version 330\n"
			"layout(points) in;"
			"layout(triangle_strip, max_vertices = 4) out;"
			"in float vertZOffs[];"
			"out vec4 geomPosition;"
			"uniform mat4 CameraMatrix, ProjectionMatrix;"
			"uniform vec3 ViewX, ViewY, ViewZ;"
			"uniform float LightVolSize;"
			"void main(void)"
			"{"
			"	float zo = vertZOffs[0];"
			"	float yo[2] = float[2](-1.0, 1.0);"
			"	float xo[2] = float[2](-1.0, 1.0);"
			"	for(int j=0;j!=2;++j)"
			"	for(int i=0;i!=2;++i)"
			"	{"
			"		geomPosition = vec4("
			"			gl_in[0].gl_Position.xyz+"
			"			ViewX * xo[i] * LightVolSize+"
			"			ViewY * yo[j] * LightVolSize+"
			"			ViewZ * zo    * LightVolSize,"
			"			1.0"
			"		);"
			"		gl_Position = "
			"			ProjectionMatrix *"
			"			CameraMatrix *"
			"			geomPosition;"
			"		EmitVertex();"
			"	}"
			"	EndPrimitive();"
			"}"
		);
		light_gs.Compile();

		light_fs.Source(
			"#version 330\n"
			"in vec4 geomPosition;"
			"out vec4 fragColor;"
			"uniform samplerCubeShadow ShadowMap;"
			"uniform int SampleCount;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	vec3 LightDir = geomPosition.xyz - LightPos;"
			"	vec4 ShadowCoord = vec4("
			"		normalize(LightDir),"
			"		length(LightDir)"
			"	);"
			"	float s = texture(ShadowMap, ShadowCoord);"
			"	float alpha = s / (SampleCount * pow(length(LightDir), 2));"
			"	fragColor = vec4(1.0, 1.0, 1.0, alpha);"
			"}"
		);
		light_fs.Compile();

		light_prog.AttachShader(light_vs);
		light_prog.AttachShader(light_gs);
		light_prog.AttachShader(light_fs);
		light_prog.Link();
		light_prog.Use();

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

		// bind the VBO for the light volume plane positions
		light_positions.Bind(Buffer::Target::Array);
		{
			GLfloat position[3] = {0.0, 0.0, 0.0};
			Buffer::Data(Buffer::Target::Array, 3, position);
			VertexAttribArray attr(light_prog, "Position");
			attr.Setup(3, DataType::Float);
			attr.Enable();
		}

		Uniform<GLint>(light_prog, "SampleCount").Set(sample_count);
		Uniform<GLfloat>(light_prog, "LightVolSize").Set(4);
		UniformSampler(light_prog, "ShadowMap").Set(0);

		// Setup the texture and the offscreen FBO
		Texture::Active(0);
		{
			auto bound_tex = Bind(depth_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);
			bound_tex.CompareFunc(CompareFunction::LEqual);
			bound_tex.CompareMode(
				TextureCompareMode::CompareRefToTexture
			);

			for(int i=0; i!=6; ++i)
			{
				Texture::Image2D(
					Texture::CubeMapFace(i),
					0,
					PixelDataInternalFormat::DepthComponent,
					tex_side, tex_side,
					0,
					PixelDataFormat::DepthComponent,
					PixelDataType::Float,
					nullptr
				);
			}

			auto bound_fbo = Bind(
				depth_fbo,
				Framebuffer::Target::Draw
			);
			bound_fbo.AttachTexture(
				FramebufferAttachment::Depth,
				depth_tex,
				0
			);
		}
		//
		gl.ClearColor(0.2f, 0.05f, 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);

		gl.BlendFunc(BlendFunction::SrcAlpha, BlendFunction::One);
	}
    PoolTilesExample()
      : make_plane(
          Vec3f(), Vec3f(7.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, -7.0f), 48, 48)
      , 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_camera_matrix(plane_prog, "CameraMatrix")
      , shape_camera_matrix(shape_prog, "CameraMatrix")
      , plane_camera_position(plane_prog, "CameraPosition")
      , width(800)
      , height(600)
      , refl_tex_side(width > height ? height : width)
      , tile_tex_side(64) {
        gl.RequireAtLeast(LimitQuery::MaxCombinedTextureImageUnits, 5);

        plane_vs.Source(
          "#version 140\n"
          "uniform vec3 LightPosition;"
          "uniform vec3 CameraPosition;"
          "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
          "in vec4 Position;"
          "in vec2 TexCoord;"
          "out vec3 vertLightDir;"
          "out vec3 vertViewDir;"
          "out vec4 vertReflTexCoord;"
          "out vec2 vertTileTexCoord;"
          "void main()"
          "{"
          "	gl_Position = ModelMatrix* Position;"
          "	vertLightDir = normalize(LightPosition - gl_Position.xyz);"
          "	vertViewDir = normalize(CameraPosition - gl_Position.xyz);"
          "	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
          "	vertReflTexCoord = gl_Position;"
          "	vertTileTexCoord = TexCoord;"
          "}");
        plane_vs.Compile();

        plane_fs.Source(
          "#version 140\n"
          "uniform sampler2D RandTex, PictTex, TileTex, NormTex;"
          "uniform sampler2D ReflectTex;"
          "uniform uint TileCount;"
          "uniform float Aspect;"
          "in vec3 vertLightDir;"
          "in vec3 vertViewDir;"
          "in vec4 vertReflTexCoord;"
          "in vec2 vertTileTexCoord;"
          "out vec4 fragColor;"
          "void main()"
          "{"
          "	vec3 Normal = texture("
          "		NormTex, "
          "		vertTileTexCoord * TileCount"
          "	).rgb;"
          "	vec3 LightRefl = reflect("
          "		-normalize(vertLightDir),"
          "		normalize(Normal)"
          "	);"
          "	float Diffuse = max(dot("
          "		Normal, "
          "		vertLightDir"
          "	), 0.0);"
          "	float Specular = max(dot("
          "		LightRefl,"
          "		vertViewDir"
          "	), 0.0);"
          "	float PlasterLight = 0.3 + max(Diffuse, 0.0);"
          "	float TileLight = 0.3 + pow(Diffuse, 2.0)*0.9 + pow(Specular, "
          "4.0)*2.5;"
          "	vec2 ReflCoord = vertReflTexCoord.xy;"
          "	ReflCoord /= vertReflTexCoord.w;"
          "	ReflCoord *= 0.5;"
          "	ReflCoord += vec2(Aspect*0.5, 0.5);"
          "	ReflCoord += vec2(Normal.x, Normal.z)*0.5;"
          "	vec3 ReflColor = texture("
          "		ReflectTex, "
          "		ReflCoord"
          "	).rgb;"
          "	vec3 TileProps = texture("
          "		TileTex, "
          "		vertTileTexCoord * TileCount"
          "	).rgb;"
          "	float Pict = texture(PictTex, vertTileTexCoord).r;"
          "	float Rand = texture(RandTex, vertTileTexCoord).r;"
          "	float LightVsDark = "
          "		mix( 0.1, 0.9, Pict)+"
          "		mix(-0.1, 0.1, Rand);"
          "	vec3 TileColor = mix("
          "		vec3(0.1, 0.1, 0.5),"
          "		vec3(0.4, 0.4, 0.9),"
          "		LightVsDark "
          "	);"
          "	vec3 PlasterColor = vec3(0.9, 0.9, 0.9);"
          "	fragColor = vec4("
          "		mix("
          "			PlasterColor * PlasterLight,"
          "			TileColor * TileLight, "
          "			TileProps.b"
          "		) +"
          "		ReflColor * TileProps.g * 0.6,"
          "		1.0"
          "	);"
          "}");
        plane_fs.Compile();

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

        Vec3f lightPos(3.0f, 2.5f, 2.0f);
        Uniform<Vec3f>(plane_prog, "LightPosition").Set(lightPos);
        Uniform<GLuint>(plane_prog, "TileCount").Set(tile_tex_side);
        Uniform<Mat4f>(plane_prog, "ModelMatrix")
          .Set(ModelMatrixf::Translation(0.0f, -0.5f, 0.0f));

        std::vector<GLfloat> data;
        GLuint n_per_vertex;

        n_per_vertex = make_plane.Positions(data);
        plane_verts.Data(data);
        DSAVertexArrayAttribEXT(plane, plane_prog, "Position")
          .Setup<GLfloat>(plane_verts, n_per_vertex)
          .Enable();

        n_per_vertex = make_plane.TexCoordinates(data);
        plane_texcoords.Data(data);
        DSAVertexArrayAttribEXT(plane, plane_prog, "TexCoord")
          .Setup<GLfloat>(plane_texcoords, n_per_vertex)
          .Enable();

        //
        rand_tex.target = Texture::Target::_2D;
        rand_tex.Image2D(images::RandomRedUByte(tile_tex_side, tile_tex_side));
        rand_tex.Filter(TextureFilter::Nearest);
        rand_tex.Wrap(TextureWrap::Repeat);
        Texture::Active(0);
        UniformSampler(plane_prog, "RandTex").Set(0);
        rand_tex.Bind();

        //
        pict_tex.target = Texture::Target::_2D;
        pict_tex.Image2D(images::LoadTexture("pool_pictogram"));
        pict_tex.Filter(TextureFilter::Linear);
        pict_tex.Wrap(TextureWrap::Repeat);
        Texture::Active(1);
        UniformSampler(plane_prog, "PictTex").Set(1);
        pict_tex.Bind();
        //
        auto tile_image = images::LoadTexture("small_tile");
        //
        tile_tex.target = Texture::Target::_2D;
        tile_tex.Image2D(tile_image);
        tile_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
        tile_tex.MagFilter(TextureMagFilter::Linear);
        tile_tex.Wrap(TextureWrap::Repeat);
        tile_tex.GenerateMipmap();
        Texture::Active(2);
        UniformSampler(plane_prog, "TileTex").Set(2);
        tile_tex.Bind();
        //
        norm_tex.target = Texture::Target::_2D;
        norm_tex.Image2D(images::TransformComponents<GLfloat, 3>(
          images::NormalMap(tile_image),
          Mat4d(
            Vec4d(1.0, 0.0, 0.0, 0.0),
            Vec4d(0.0, 0.0, 1.0, 0.0),
            Vec4d(0.0, -1.0, 0.0, 0.0),
            Vec4d(0.0, 0.0, 0.0, 1.0))));
        norm_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
        norm_tex.MagFilter(TextureMagFilter::Linear);
        norm_tex.Wrap(TextureWrap::Repeat);
        norm_tex.GenerateMipmap();
        Texture::Active(3);
        UniformSampler(plane_prog, "NormTex").Set(3);
        norm_tex.Bind();
        //
        reflect_tex.target = Texture::Target::_2D;
        reflect_tex.Image2D(
          0,
          PixelDataInternalFormat::RGB,
          refl_tex_side,
          refl_tex_side,
          0,
          PixelDataFormat::RGB,
          PixelDataType::UnsignedByte,
          nullptr);
        reflect_tex.Filter(TextureFilter::Linear);
        reflect_tex.Wrap(TextureWrap::ClampToEdge);
        Texture::Active(4);
        UniformSampler(plane_prog, "ReflectTex").Set(4);
        reflect_tex.Bind();

        rbo.Storage(
          PixelDataInternalFormat::DepthComponent,
          refl_tex_side,
          refl_tex_side);
        fbo.target = Framebuffer::Target::Draw;
        fbo.AttachTexture(FramebufferAttachment::Color, reflect_tex, 0);
        fbo.AttachRenderbuffer(FramebufferAttachment::Depth, rbo);

        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 vertViewRefl;"
          "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;"
          "	vertViewRefl = reflect("
          "		-normalize(vertViewDir),"
          "		normalize(vertNormal)"
          "	);"
          "	vertColor = vec3(0.3, 0.3, 0.7);"
          "	gl_Position = "
          "		ProjectionMatrix *"
          "		CameraMatrix *"
          "		gl_Position;"
          "}");
        shape_vs.Compile();

        shape_fs.Source(
          "#version 140\n"
          "uniform sampler2D PictTex, TileTex;"
          "uniform uint TileCount;"
          "in vec3 vertNormal;"
          "in vec3 vertLightDir;"
          "in vec3 vertLightRefl;"
          "in vec3 vertViewDir;"
          "in vec3 vertViewRefl;"
          "in vec3 vertColor;"
          "out vec4 fragColor;"

          "void main()"
          "{"
          "	float LtDist = length(vertLightDir);"
          "	float Diffuse = dot("
          "		normalize(vertNormal), "
          "		normalize(vertLightDir)"
          "	) / LtDist;"
          "	float Specular = dot("
          "		normalize(vertLightRefl),"
          "		normalize(vertViewDir)"
          "	);"
          "	vec3 LightColor = vec3(1.0, 1.0, 1.0);"
          "	vec2 ReflTexCoord = -vec2("
          "		vertViewRefl.x,"
          "		vertViewRefl.z "
          "	);"
          "	ReflTexCoord *= 0.25;"
          "	ReflTexCoord += vec2(0.5, 0.5);"
          "	float Pict = texture(PictTex, ReflTexCoord).r;"
          "	float LightVsDark = mix( 0.1, 0.9, Pict);"
          "	vec3 TileColor = mix("
          "		vec3(0.2, 0.2, 0.6),"
          "		vec3(0.5, 0.5, 0.9),"
          "		LightVsDark"
          "	);"
          "	vec3 PlasterColor = vec3(0.7, 0.7, 0.7);"
          "	vec3 FloorColor = mix("
          "		PlasterColor, "
          "		TileColor, "
          "		texture(TileTex, ReflTexCoord*TileCount).b"
          "	);"
          "	vec3 ReflColor = mix("
          "		vec3(0.5, 0.5, 0.4), "
          "		FloorColor, "
          "		pow(max((-vertViewRefl.y-0.5)*2.0, 0.0), 2.0)"
          "	);"
          "	fragColor = vec4("
          "		vertColor * 0.4 + "
          "		ReflColor * 0.3 + "
          "		(LightColor + vertColor)*pow(max(2.5*Diffuse, 0.0), 3) + "
          "		LightColor * pow(max(Specular, 0.0), 64), "
          "		1.0"
          "	);"
          "}");
        shape_fs.Compile();

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

        Uniform<Vec3f>(shape_prog, "LightPosition").Set(lightPos);
        Uniform<Mat4f>(shape_prog, "ModelMatrix")
          .Set(ModelMatrixf::Translation(0.0f, 0.6f, 0.0f));
        UniformSampler(shape_prog, "PictTex").Set(0);
        UniformSampler(shape_prog, "TileTex").Set(1);
        Uniform<GLuint>(shape_prog, "TileCount").Set(tile_tex_side);

        n_per_vertex = make_shape.Positions(data);
        shape_verts.Data(data);
        DSAVertexArrayAttribEXT(shape, shape_prog, "Position")
          .Setup<GLfloat>(shape_verts, n_per_vertex)
          .Enable();

        n_per_vertex = make_shape.Normals(data);
        shape_normals.Data(data);
        DSAVertexArrayAttribEXT(shape, shape_prog, "Normal")
          .Setup<GLfloat>(shape_normals, n_per_vertex)
          .Enable();
        //
        gl.ClearColor(0.5f, 0.5f, 0.4f, 0.0f);
        gl.ClearDepth(1.0f);
        gl.Enable(Capability::DepthTest);
    }
Example #7
0
	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 410\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 410\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 410\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 410\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 410\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(n_per_vertex, DataType::Float);
			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 #8
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;"
			"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(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();
		}

		// 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(n_per_vertex, DataType::Float);
			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);
	}
Example #9
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);
			VertexArrayAttrib 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
			VertexArrayAttrib 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
			VertexArrayAttrib 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 #10
0
	CubeMapExample(void)
	 : shape_instr(make_shape.Instructions())
	 , shape_indices(make_shape.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	{
		// Set the vertex shader source
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"in vec2 TexCoord;"
			"out vec3 vertNormal;"
			"out vec3 vertLightDir;"
			"out vec3 vertLightRefl;"
			"out vec3 vertViewDir;"
			"out vec3 vertViewRefl;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	gl_Position = ModelMatrix * Position;"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	vertLightDir = LightPos - gl_Position.xyz;"
			"	vertLightRefl = reflect("
			"		-normalize(vertLightDir),"
			"		normalize(vertNormal)"
			"	);"
			"	vertViewDir = ("
			"		vec4(0.0, 0.0, 1.0, 1.0)*"
			"		CameraMatrix"
			"	).xyz;"
			"	vertViewRefl = reflect("
			"		normalize(vertViewDir),"
			"		normalize(vertNormal)"
			"	);"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		// compile it
		vs.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"uniform samplerCube TexUnit;"
			"in vec3 vertNormal;"
			"in vec3 vertLightDir;"
			"in vec3 vertLightRefl;"
			"in vec3 vertViewDir;"
			"in vec3 vertViewRefl;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	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);"
			"	vec3 env = texture(TexUnit, vertViewRefl).rgb;"
			"	fragColor = vec4("
			"		env * 0.4 + "
			"		(lt + env) * 1.5 * max(d, 0.0) + "
			"		lt * pow(max(s, 0.0), 64), "
			"		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 shape
		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();
		}

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

		// setup the texture
		{
			GLuint tex_side = 256;
			auto image = images::NewtonFractal(
				tex_side, tex_side,
				Vec3f(0.3f, 0.1f, 0.2f),
				Vec3f(1.0f, 0.8f, 0.9f),
				Vec2f(-1.0f, -1.0f),
				Vec2f( 1.0f,  1.0f),
				images::NewtonFractal::X4Minus1(),
				images::NewtonFractal::DefaultMixer()
			);
			auto tex_target = Texture::Target::CubeMap;
			// texture syntax sugar
			tex << tex_target;
			tex_target << TextureMinFilter::Linear;
			tex_target << TextureMagFilter::Linear;
			tex_target << TextureWrap::ClampToEdge;

			for(int i=0; i!=6; ++i)
			{
				Texture::CubeMapFace(i) << image;
			}
		}
		// typechecked uniform with the exact sampler type
		// on compilers supporting strongly typed enums
		// you can use:
		//Typechecked<Uniform<SLtoCpp<SLDataType::SamplerCube>>>(prog, "TexUnit").Set(0);
		// without strongly typed enums you need to do:
		typedef SLtoCpp<OGLPLUS_CONST_ENUM_VALUE(SLDataType::SamplerCube)> GLSLsamplerCube;
		Typechecked<Uniform<GLSLsamplerCube>>(prog, "TexUnit").Set(0);

		//
		Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(3.0f, 5.0f, 4.0f));
		//
		gl.ClearColor(0.2f, 0.05f, 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 #11
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);
	}
Example #12
0
	static Program make(void)
	{
		Program result;

		VertexShader vs;
		vs.Source(
			"#version 330\n"
			"#define side 128\n"

			"uniform mat4 ProjectionMatrix, CameraMatrix, LightProjMatrix, LightMatrix;"
			"uniform vec3 CameraPos, LightPos;"
			"uniform float Fade;"
			"uniform sampler2D Offsets;"
			"uniform sampler2D Heights;"

			"in vec4 Position;"
			"in vec3 Normal;"

			"out vec4 vertShadowCoord;"
			"out vec3 vertViewDir;"
			"out vec3 vertLightDir;"
			"out vec3 vertNormal;"
			"out float vertLight;"

			"void main(void)"
			"{"
			"	ivec2 Coord = ivec2(gl_InstanceID%side, gl_InstanceID/side);"
			"	vec2 Offs = texelFetch(Offsets, Coord, 0).xy;"
			"	float Depth = texelFetch(Heights, Coord, 0).r;"
			"	float Height = 1.0-Depth;"
			"	gl_Position = Position;"
			"	gl_Position.xz += Offs;"
			"	float l = (1.0-dot(Normal, vec3(0,1,0))*0.5)*0.8;"
			"	vertLight = (1.0-gl_Position.y*l)*sign(Height)*Fade;"
			"	gl_Position.y  *= max(Height*Fade*side/2, 0.5);"
			"	vertViewDir = CameraPos - gl_Position.xyz;"
			"	vertLightDir = LightPos - gl_Position.xyz;"
			"	vertShadowCoord = LightProjMatrix * LightMatrix * gl_Position;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"	vertNormal = Normal;"
			"}"
		).Compile();

		FragmentShader fs;
		fs.Source(
			"#version 330\n"
			"uniform sampler2DShadow Shadows;"

			"const vec3 LightDir = normalize(vec3(1, 0.3, 1));"
			"const vec3 BarColor = vec3(0.4, 0.4, 0.4);"

			"in vec4 vertShadowCoord;"
			"in vec3 vertViewDir;"
			"in vec3 vertLightDir;"
			"in vec3 vertNormal;"
			"in float vertLight;"

			"out vec3 fragColor;"

			"void main(void)"
			"{"
			"	vec3 Normal = normalize(vertNormal);"
			"	vec3 ViewDir = normalize(vertViewDir);"
			"	vec3 LightDir = normalize(vertLightDir);"
			"	vec3 LightRefl = reflect(-LightDir, Normal);"
			"	vec3 ShadowCoord = (vertShadowCoord.xyz/vertShadowCoord.w)*0.5 + 0.5;"
			"	float shdw = texture(Shadows, ShadowCoord);"
			"	float ambi = 0.15;"
			"	float diff = pow(max(dot(Normal, LightDir)+0.1, 0.0),2.0)*0.9;"
			"	float spec = pow(max(dot(ViewDir, LightRefl), 0.0), 32.0)*0.4;"
			"	float emis = pow(vertLight, 2.0)*0.7;"
			"	fragColor = "
			"		BarColor * (diff*shdw+ambi)+"
			"		vec3(1.0, 1.0, 1.0)*spec*shdw+"
			"		vec3(0.1, 1.0, 0.3)*emis;"
			"}"
		).Compile();

		result.AttachShader(vs).AttachShader(fs);
		result.Link().Validate().Use();
		return std::move(result);
	}
    static Program make() {
        Shader vs(ShaderType::Vertex);
        vs.Source(
            "#version 140\n"
            "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
            "uniform vec3 LightPos;"
            "in vec4 Position;"
            "in vec3 Normal;"
            "in vec3 Tangent;"
            "in vec2 TexCoord;"
            "out vec3 vertEye;"
            "out vec3 vertLight;"
            "out vec3 vertNormal;"
            "out vec2 vertTexCoord;"
            "out vec3 vertViewTangent;"
            "out mat3 NormalMatrix;"
            "void main()"
            "{"
            "	vec4 EyePos = "
            "		CameraMatrix *"
            "		ModelMatrix *"
            "		Position;"
            "	vertEye = EyePos.xyz;"
            "	vec3 fragTangent = ("
            "		CameraMatrix *"
            "		ModelMatrix *"
            "		vec4(Tangent, 0.0)"
            "	).xyz;"
            "	vertNormal = ("
            "		CameraMatrix *"
            "		ModelMatrix *"
            "		vec4(Normal, 0.0)"
            "	).xyz;"
            "	vertLight = ("
            "		CameraMatrix *"
            "		vec4(LightPos-vertEye, 1.0)"
            "	).xyz;"
            "	NormalMatrix = mat3("
            "		fragTangent,"
            "		cross(vertNormal, fragTangent),"
            "		vertNormal"
            "	);"
            "	vertViewTangent = vec3("
            "		dot(NormalMatrix[0], vertEye),"
            "		dot(NormalMatrix[1], vertEye),"
            "		dot(NormalMatrix[2], vertEye) "
            "	);"
            "	vertTexCoord = TexCoord;"
            "	gl_Position = ProjectionMatrix *"
            "		EyePos;"
            "}")
          .Compile();

        Shader fs(ShaderType::Fragment);
        fs.Source(
            "#version 140\n"
            "uniform sampler2D BumpTex;"
            "uniform int BumpTexWidth;"
            "uniform int BumpTexHeight;"
            "float DepthMult = 0.1;"
            "in vec3 vertEye;"
            "in vec3 vertLight;"
            "in vec3 vertNormal;"
            "in vec2 vertTexCoord;"
            "in vec3 vertViewTangent;"
            "in mat3 NormalMatrix;"
            "out vec4 fragColor;"
            "void main()"
            "{"
            "	vec3 ViewTangent = normalize(vertViewTangent);"
            "	float perp = -dot(normalize(vertEye), vertNormal);"
            "	float sampleInterval = 1.0/length("
            "		vec2(BumpTexWidth, BumpTexHeight)"
            "	);"
            "	vec3 sampleStep = ViewTangent*sampleInterval;"
            "	float prevD = 0.0;"
            "	float depth = texture(BumpTex, vertTexCoord).w;"
            "	float maxOffs = min((depth*DepthMult)/(-ViewTangent.z), 1.0);"
            "	vec3 viewOffs = vec3(0.0, 0.0, 0.0);"
            "	vec2 offsTexC = vertTexCoord + viewOffs.xy;"
            "	while(length(viewOffs) < maxOffs)"
            "	{"
            "		if(offsTexC.x <= 0.0 || offsTexC.x >= 1.0)"
            "			break;"
            "		if(offsTexC.y <= 0.0 || offsTexC.y >= 1.0)"
            "			break;"
            "		if(depth*DepthMult*perp <= -viewOffs.z)"
            "			break;"
            "		viewOffs += sampleStep;"
            "		offsTexC = vertTexCoord + viewOffs.xy;"
            "		prevD = depth;"
            "		depth = texture(BumpTex, offsTexC).w;"
            "	}"
            "	offsTexC = vec2("
            "		clamp(offsTexC.x, 0.0, 1.0),"
            "		clamp(offsTexC.y, 0.0, 1.0) "
            "	);"
            "	float b = ("
            "		1 +"
            "		int(offsTexC.x*16) % 2+"
            "		int(offsTexC.y*16) % 2"
            "	) % 2;"
            "	vec3 c = vec3(b, b, b);"
            "	vec3 n = texture(BumpTex, offsTexC).xyz;"
            "	vec3 finalNormal = NormalMatrix * n;"
            "	float l = length(vertLight);"
            "	float d = (l > 0.0) ? dot("
            "		normalize(vertLight), "
            "		finalNormal"
            "	) / l : 0.0;"
            "	float i = 0.1 + 2.5*max(d, 0.0);"
            "	fragColor = vec4(c*i, 1.0);"
            "}")
          .Compile();

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

        return prog;
    }
    static Program make_prog() {
        Program prog;
        VertexShader vs;
        vs.Source(StrCRef("#version 150\n"
                          "in vec3 Position;"
                          "in vec2 TexCoord;"
                          "out vec2 vertTexCoord;"
                          "void main()"
                          "{"
                          "	gl_Position = vec4(Position, 1.0);"
                          "	vertTexCoord = TexCoord;"
                          "}"))
          .Compile();
        prog.AttachShader(vs);

        GeometryShader gs;
        gs
          .Source(StrCRef(
            "#version 150\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()"
            "{"
            "	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 150\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()"
                          "{"
                          "	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;
    }
Example #15
0
    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<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);

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

            VertexAttribArray attr(transf_prog, "TexCoord");
            attr.Setup<GLfloat>(n_per_vertex);
            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());
    }
Example #16
0
	ParticlesExample(void)
	 : projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , particle_count(100)
	 , prev_time(0.0)
	 , prev_spawn(0.0)
	{
		// Set the vertex shader source
		vs.Source(
			"#version 330\n"
			"uniform mat4 ModelMatrix, CameraMatrix;"
			"in vec4 Position;"
			"in float Age;"
			"out float vertAge;"
			"void main(void)"
			"{"
			"	gl_Position = "
			"		CameraMatrix *"
			"		ModelMatrix *"
			"		Position;"
			"	vertAge = Age;"
			"}"
		);
		// compile it
		vs.Compile();

		// Set the geometry shader source
		gs.Source(
			"#version 330\n"
			"layout(points) in;"
			"layout(triangle_strip, max_vertices = 4) out;"
			"uniform mat4 ProjectionMatrix;"
			"in float vertAge[];"
			"out float geomAge;"
			"void main(void)"
			"{"
			"	float s = 0.5;"
			"	float yo[2] = float[2](-1.0, 1.0);"
			"	float xo[2] = float[2](-1.0, 1.0);"
			"	for(int j=0;j!=2;++j)"
			"	for(int i=0;i!=2;++i)"
			"	{"
			"		float xoffs = xo[i]*(1.0+vertAge[0])*s;"
			"		float yoffs = yo[j]*(1.0+vertAge[0])*s;"
			"		gl_Position = ProjectionMatrix * vec4("
			"			gl_in[0].gl_Position.x-xoffs,"
			"			gl_in[0].gl_Position.y-yoffs,"
			"			gl_in[0].gl_Position.z,"
			"			1.0"
			"		);"
			"		geomAge = vertAge[0];"
			"		EmitVertex();"
			"	}"
			"	EndPrimitive();"
			"}"
		);
		// compile it
		gs.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"in float geomAge;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	vec3 Color1 = vec3(1.0, 0.5, 0.5);"
			"	vec3 Color2 = vec3(0.3, 0.1, 0.1);"
			"	fragColor = vec4("
			"		mix(Color1, Color2, geomAge),"
			"		1.0 - geomAge"
			"	);"
			"}"
		);
		// compile it
		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 particles
		particles.Bind();

		// bind the VBO for the particle positions
		pos_buf.Bind(Buffer::Target::Array);
		{
			Buffer::Data(Buffer::Target::Array, positions);
			VertexAttribArray attr(prog, "Position");
			attr.Setup(3, DataType::Float);
			attr.Enable();
		}
		positions.reserve(particle_count);
		directions.reserve(particle_count);

		// bind the VBO for the particle ages
		age_buf.Bind(Buffer::Target::Array);
		{
			Buffer::Data(Buffer::Target::Array, ages);
			VertexAttribArray attr(prog, "Age");
			attr.Setup(1, DataType::Float);
			attr.Enable();
		}
		ages.reserve(particle_count);

		Uniform<Mat4f>(prog, "ModelMatrix").Set(
			ModelMatrixf::Translation(0.0f, -10.0f, 0.0f)
		);
		//
		gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::Blend);
		gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha);
	}
Example #17
0
	RectangleExample(void)
	 : vs(ShaderType::Vertex)
	 , fs(ShaderType::Fragment)
	{
		// this could be any istream
		std::stringstream vs_source(
			"#version 330\n"
			"in vec2 Position;"
			"in vec3 Color;"
			"out vec3 vertColor;"
			"void main(void)"
			"{"
			"	vertColor = Color;"
			"	gl_Position = vec4(Position, 0.0, 1.0);"
			"}"
		);
		// set the vertex shader source
		vs.Source(GLSLSource::FromStream(vs_source));
		// compile it
		vs.Compile();

		std::stringstream fs_source(
			"#version 330\n"
			"in vec3 vertColor;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	fragColor = vec4(vertColor, 1.0);"
			"}"
		);
		// set the fragment shader source
		fs.Source(GLSLSource::FromStream(fs_source));
		// 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 rectangle
		rectangle.Bind();

		GLfloat rectangle_verts[8] = {
			-1.0f, -1.0f,
			-1.0f,  1.0f,
			 1.0f, -1.0f,
			 1.0f,  1.0f
		};
		// bind the VBO for the rectangle vertices
		verts.Bind(Buffer::Target::Array);
		// upload the data
		Buffer::Data(Buffer::Target::Array, 8, rectangle_verts);
		// setup the vertex attribs array for the vertices
		VertexAttribArray vert_attr(prog, "Position");
		vert_attr.Setup<Vec2f>().Enable();

		GLfloat rectangle_colors[12] = {
			1.0f, 1.0f, 1.0f,
			1.0f, 0.0f, 0.0f,
			0.0f, 1.0f, 0.0f,
			0.0f, 0.0f, 1.0f,
		};
		// bind the VBO for the rectangle colors
		colors.Bind(Buffer::Target::Array);
		// upload the data
		Buffer::Data(Buffer::Target::Array, 12, rectangle_colors);
		// setup the vertex attribs array for the vertices
		VertexAttribArray color_attr(prog, "Color");
		color_attr.Setup<Vec3f>().Enable();
		//
		gl.Disable(Capability::DepthTest);
	}
Example #18
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")
	{
		// Set the vertex shader source
		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 * 6.0;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		// compile it
		vs.Compile();

		// set the fragment shader source
		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 = dot(vertLight, vertLight);"
			"	float d = l != 0.0 ? dot("
			"		vertNormal, "
			"		normalize(vertLight)"
			"	) / l : 0.0;"
			"	vec3 c = vec3(0.9, 0.8, 0.2);"
			"	vec4 t  = texture(TexUnit, vertTexCoord);"
			"	float a = 1.0 - sqrt(abs(d)), e;"
			"	if(gl_FrontFacing)"
			"	{"
			"		e = d >= 0.0 ?"
			"		d * mix(0.5, 1.0, t.a):"
			"		(-0.9*d) * (1.0 - t.a);"
			"	}"
			"	else"
			"	{"
			"		e = d >= 0.0 ?"
			"		(0.6*d) * (1.0 - t.a):"
			"		(-0.7*d) * mix(0.5, 1.0, t.a);"
			"	}"
			"	float i = 0.1 + 9.0*e;"
			"	fragColor = vec4("
			"		t.r*c.r*i, "
			"		t.g*c.g*i, "
			"		t.b*c.b*i, "
			"		clamp(pow(t.a,2) + a*0.4, 0.0, 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();

		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(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_cube.Normals(data);
			Buffer::Data(Buffer::Target::Array, data);
			VertexAttribArray attr(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_cube.TexCoordinates(data);
			Buffer::Data(Buffer::Target::Array, data);
			VertexAttribArray attr(prog, "TexCoord");
			attr.Setup(n_per_vertex, DataType::Float);
			attr.Enable();
		}

		// setup the texture
		{
			auto bound_tex = Bind(tex, Texture::Target::_2D);
			bound_tex.Image2D(images::LoadTexture("honeycomb"));
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::MirroredRepeat);
			bound_tex.WrapT(TextureWrap::MirroredRepeat);
		}
		//
		UniformSampler(prog, "TexUnit").Set(0);
		Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(1.0f, 2.0f, 3.0f));
		//
		gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::Blend);
		gl.BlendFunc(
			BlendFn::SrcAlpha,
			BlendFn::OneMinusSrcAlpha
		);

		gl.Enable(Capability::CullFace);
		gl.FrontFace(make_cube.FaceWinding());
	}
Example #19
0
int main(int argc, char** argv)
{
	int width = 800;
	int height = 600;
	SDL_Window* window = SDL_CreateWindow("Demo: A Modern OpenGL Application in Modern C++", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
	if(window == nullptr)
	{
		std::cerr << SDL_GetError() << std::endl;
		return 0;
	}

	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);

	SDL_GLContext context = SDL_GL_CreateContext(window);
	if(context == nullptr)
	{
		SDL_DestroyWindow(window);
		std::cerr << SDL_GetError() << std::endl;
		return 0;
	}

	glewInit();

	// OpenGL initialization
	using namespace Render::OpenGL;
	Program program;
	Shader vertex("../shaders/simple.vert");
	program.AttachShader(vertex);
	vertex.Compile();
	vertex.PrintInfoLog();
	Shader fragment("../shaders/simple.frag");
	program.AttachShader(fragment);
	fragment.Compile();
	fragment.PrintInfoLog();
	program.BindFragDataLocation(0, "FragColor");
	program.Link();
	program.PrintInfoLog();
	program.Use();
	program.PrintInfoLog();
	PrintError();

	glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 1.0f, 100.f);
	program.UniformMatrix("Projection", Projection);
	glm::mat4 Modelview = glm::translate(glm::mat4(1.0f), glm::vec3(0.f,0.f,-4.0f));
	program.UniformMatrix("Modelview", Modelview);
	glViewport(0,0,800,600);



	for(int i = 0; i < 3000; i++)
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glBegin(GL_TRIANGLES);
		program.VertexAttrib("Vertex", 0.f, 0.f, 0.f);
		program.VertexAttrib("Vertex", 0.f, .5f, 0.f);
		program.VertexAttrib("Vertex", .5f, .5f, 0.f);
		glEnd();
		SDL_GL_SwapWindow(window);
		SDL_Delay(1);
	}

	SDL_GL_DeleteContext(context);
	SDL_DestroyWindow(window);

	return 0;
}