Example #1
0
	PoolTilesExample(void)
	 : 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(void)"
			"{"
			"	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(void)"
			"{"
			"	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(void)"
			"{"
			"	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(void)"
			"{"
			"	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 #2
0
	Field(const images::Image& map, const Program& prog)
	 : gl()
	{
		const GLuint w = map.Width();
		const GLuint h = map.Height();
		const GLuint d = map.Depth();
		const GLuint c = 3;

		radius = std::sqrt(GLfloat(w*w+h*h+d*d))*0.5f;

		vert_count = w*h*d;

		std::vector<GLfloat> pos_data(w*h*d*c);
		std::vector<GLuint>  tec_data(w*h*d*c);

		GLfloat xo = w * 0.5f;
		GLfloat yo = h * 0.5f;
		GLfloat zo = d * 0.5f;

		for(GLuint z=0; z!=d; ++z)
		{
			for(GLuint y=0; y!=h; ++y)
			{
				for(GLuint x=0; x!=w; ++x)
				{
					GLuint k = z*w*h*c+y*w*c+x*c;
					pos_data[k+0] = x-xo;
					pos_data[k+1] = y-yo;
					pos_data[k+2] = z-zo;

					tec_data[k+0] = x;
					tec_data[k+1] = y;
					tec_data[k+2] = z;
				}
			}
		}

		positions.Data(pos_data);
		texcoords.Data(tec_data);

		DSAVertexArrayAttribEXT(vao, prog, "Position")
			.Setup<Vector<GLfloat, 3>>(positions)
			.Enable();

		DSAVertexArrayAttribEXT(vao, prog, "TexCoord")
			.Setup<Vector<GLuint, 3>>(texcoords)
			.Enable();


		ProgramUniformSampler(prog, "Pattern").Set(1);
		pattern.BindMulti(1, Texture::Target::_3D);
		pattern.Image3D(map);
		pattern.MinFilter(TextureMinFilter::Nearest);
		pattern.MagFilter(TextureMagFilter::Nearest);
		pattern.WrapS(TextureWrap::ClampToBorder);
		pattern.WrapT(TextureWrap::ClampToBorder);
		pattern.WrapR(TextureWrap::ClampToBorder);
		pattern.BorderColor(Vec4f(0,0,0,1));


		ProgramUniformSampler(prog, "FadeMap").Set(2);
		fademap.BindMulti(2, Texture::Target::_3D);
		fademap.Image3D(images::RandomRedUByte(
			map.Width(),
			map.Height(),
			map.Depth()
		));
		fademap.MinFilter(TextureMinFilter::Nearest);
		fademap.MagFilter(TextureMagFilter::Nearest);
		fademap.WrapS(TextureWrap::ClampToBorder);
		fademap.WrapT(TextureWrap::ClampToBorder);
		fademap.WrapR(TextureWrap::ClampToBorder);
		fademap.BorderColor(Vec4f(0,0,0,1));
	}