Example #1
0
	FlowMapHolder(
		GLuint flow_tex_size,
		GLuint tex_unit,
		const images::Image& flow_map_image
	): first_tex_unit(tex_unit)
	 , nhm(3)
	 , height_maps(nhm, Texture::Target::_2D, first_tex_unit)
	 , curr(0)
	{
		std::vector<GLfloat> v(flow_tex_size*flow_tex_size, 0.0f);
		for(GLuint i=0; i!=nhm; ++i)
		{
			height_maps[i].Image2D(
				0,
				PixelDataInternalFormat::Red,
				flow_tex_size, flow_tex_size,
				0,
				PixelDataFormat::Red,
				PixelDataType::Float,
				v.data()
			);
			height_maps[i].MinFilter(TextureMinFilter::Linear);
			height_maps[i].MagFilter(TextureMagFilter::Linear);
			height_maps[i].WrapS(TextureWrap::ClampToBorder);
			height_maps[i].WrapT(TextureWrap::ClampToBorder);
		}

		Texture::Active(BumpMapUnit());
		{
			auto bound_tex = Bind(bump_map, Texture::Target::_2D);
			bound_tex.Image2D(
				0,
				PixelDataInternalFormat::RGBA,
				flow_tex_size, flow_tex_size,
				0,
				PixelDataFormat::RGBA,
				PixelDataType::UnsignedByte,
				nullptr
			);
			bound_tex.MinFilter(TextureMinFilter::Linear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::ClampToEdge);
			bound_tex.WrapT(TextureWrap::ClampToEdge);
		}

		Texture::Active(FlowMapUnit());
		{
			auto bound_tex = Bind(flow_map, Texture::Target::_2D);
			bound_tex.Image2D(flow_map_image);
			bound_tex.MinFilter(TextureMinFilter::Linear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::Repeat);
			bound_tex.WrapT(TextureWrap::Repeat);
		}
	}
Example #2
0
	FlowExample(void)
	 : gl()
	 , flow(images::LoadTexture("flow_map"), 1)
	 , screen(
		List("Position")("TexCoord").Get(),
		shapes::Screen(),
		screen_prog
	)
	{
		Texture::Active(0);
		{
			auto bound_tex = Bind(background, Texture::Target::_2D);
			bound_tex.Image2D(images::LoadTexture("flower_glass"));
			bound_tex.MinFilter(TextureMinFilter::Linear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::MirroredRepeat);
			bound_tex.WrapT(TextureWrap::MirroredRepeat);
		}

		screen_prog.background.Set(0);
		screen_prog.normal_map.Set(flow.TexUnit());

		gl.ClearColor(0.4f, 0.4f, 0.4f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
	}
Example #3
0
	LiquidExample(const ExampleParams& params)
	 : liquid_prog()
	 , grid(liquid_prog, params.quality)
	 , grid_repeat(int(1 + params.quality*2))
	{
		Texture::Active(1);
		{
			auto image = images::Squares(512, 512, 0.9f, 8, 8);
			auto bound_tex = gl.Bound(Texture::Target::CubeMap, env_map);
			for(int i=0; i!=6; ++i)
				Texture::ImageCM(i, image);
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::ClampToEdge);
			bound_tex.WrapT(TextureWrap::ClampToEdge);
			bound_tex.WrapR(TextureWrap::ClampToEdge);
			bound_tex.SwizzleG(TextureSwizzle::Red);
			bound_tex.SwizzleB(TextureSwizzle::Red);
		}
		ProgramUniformSampler(liquid_prog, "EnvMap").Set(1);

		const Vec3f light_position(12.0, 1.0, 8.0);
		liquid_prog.light_position.Set(light_position);

		gl.ClearColor(0.7f, 0.65f, 0.55f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);

		gl.Enable(Capability::CullFace);
		gl.FrontFace(FaceOrientation::CW);
		gl.CullFace(Face::Back);
	}
Example #4
0
	RippleTexHolder(GLuint ripple_tex_size, GLuint tex_unit)
	 : first_tex_unit(tex_unit)
	 , nhm(3)
	 , height_maps(nhm)
	 , curr(0)
	{
		std::vector<GLfloat> v(ripple_tex_size*ripple_tex_size, 0.0f);
		for(GLuint i=0; i!=nhm; ++i)
		{
			Texture::Active(first_tex_unit+i);
			auto bound_tex = Bind(height_maps[i], Texture::Target::_2D);
			bound_tex.Image2D(
				0,
				PixelDataInternalFormat::Red,
				ripple_tex_size, ripple_tex_size,
				0,
				PixelDataFormat::Red,
				PixelDataType::Float,
				v.data()
			);
			bound_tex.MinFilter(TextureMinFilter::Nearest);
			bound_tex.MagFilter(TextureMagFilter::Nearest);
			bound_tex.WrapS(TextureWrap::Repeat);
			bound_tex.WrapT(TextureWrap::Repeat);
		}

		Texture::Active(first_tex_unit+nhm);
		auto bound_tex = Bind(bump_map, Texture::Target::_2D);
		bound_tex.Image2D(
			0,
			PixelDataInternalFormat::RGBA,
			ripple_tex_size, ripple_tex_size,
			0,
			PixelDataFormat::RGBA,
			PixelDataType::UnsignedByte,
			nullptr
		);
		bound_tex.MinFilter(TextureMinFilter::Linear);
		bound_tex.MagFilter(TextureMagFilter::Linear);
		bound_tex.WrapS(TextureWrap::Repeat);
		bound_tex.WrapT(TextureWrap::Repeat);
	}
Example #5
0
void
WebGLTexture::GenerateMipmap(TexTarget texTarget)
{
    const TexImageTarget imageTarget = (texTarget == LOCAL_GL_TEXTURE_2D)
                                                  ? LOCAL_GL_TEXTURE_2D
                                                  : LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
    if (!IsMipmapRangeValid())
    {
        return mContext->ErrorInvalidOperation("generateMipmap: Texture does not have a valid mipmap range.");
    }
    if (!HasImageInfoAt(imageTarget, EffectiveBaseMipmapLevel()))
    {
        return mContext->ErrorInvalidOperation("generateMipmap: Level zero of texture is not defined.");
    }

    if (!mContext->IsWebGL2() && !IsFirstImagePowerOfTwo())
        return mContext->ErrorInvalidOperation("generateMipmap: Level zero of texture does not have power-of-two width and height.");

    TexInternalFormat internalformat = ImageInfoAt(imageTarget, 0).EffectiveInternalFormat();
    if (IsTextureFormatCompressed(internalformat))
        return mContext->ErrorInvalidOperation("generateMipmap: Texture data at level zero is compressed.");

    if (mContext->IsExtensionEnabled(WebGLExtensionID::WEBGL_depth_texture) &&
        (IsGLDepthFormat(internalformat) || IsGLDepthStencilFormat(internalformat)))
    {
        return mContext->ErrorInvalidOperation("generateMipmap: "
                                     "A texture that has a base internal format of "
                                     "DEPTH_COMPONENT or DEPTH_STENCIL isn't supported");
    }

    if (!AreAllLevel0ImageInfosEqual())
        return mContext->ErrorInvalidOperation("generateMipmap: The six faces of this cube map have different dimensions, format, or type.");

    SetGeneratedMipmap();

    mContext->MakeContextCurrent();
    gl::GLContext* gl = mContext->gl;

    if (gl->WorkAroundDriverBugs()) {
        // bug 696495 - to work around failures in the texture-mips.html test on various drivers, we
        // set the minification filter before calling glGenerateMipmap. This should not carry a significant performance
        // overhead so we do it unconditionally.
        //
        // note that the choice of GL_NEAREST_MIPMAP_NEAREST really matters. See Chromium bug 101105.
        gl->fTexParameteri(texTarget.get(), LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST_MIPMAP_NEAREST);
        gl->fGenerateMipmap(texTarget.get());
        gl->fTexParameteri(texTarget.get(), LOCAL_GL_TEXTURE_MIN_FILTER, MinFilter().get());
    } else {
        gl->fGenerateMipmap(texTarget.get());
    }
}
	FBTexThread(FBTexExample& example)
	 : gl()
	 , prog(make_prog(example))
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	 , shape(List("Position")("Normal")("TexCoord").Get(), shapes::TwistedTorus(), prog)
	 , tex_side(512)
	 , parent_ready(example.parent_ready)
	{
		example.thread_ready = &thread_ready;

		Uniform<Vec3f>(prog, "LightPos").Set(20.0f, 30.0f, 40.0f);

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

		{
			auto bound_fbo = Bind(fbo, Framebuffer::Target::Draw);
			auto bound_rbo = Bind(rbo, Renderbuffer::Target::Renderbuffer);

 			bound_rbo.Storage(
				PixelDataInternalFormat::DepthComponent,
				tex_side,
				tex_side
			);
			bound_fbo.AttachTexture(FramebufferAttachment::Color, example.tex, 0);
			bound_fbo.AttachRenderbuffer(FramebufferAttachment::Depth, rbo);
		}

		Use();
	}
Example #7
0
	LiquidExample(const ExampleParams& params)
	 : liquid_prog()
	 , grid(liquid_prog, params.quality)
	 , grid_repeat(1 + params.quality*2)
	{
		Texture::Active(0);
		{
			auto image = images::NewtonFractal(
				256, 256,
				Vec3f(0.1f, 0.1f, 0.1f),
				Vec3f(1.0f, 1.0f, 1.0f),
				Vec2f(-1.0f, -1.0f),
				Vec2f( 1.0f,  1.0f),
				images::NewtonFractal::X4Minus1(),
				images::NewtonFractal::DefaultMixer()
			);
			auto bound_tex = oglplus::Context::Bound(
				Texture::Target::CubeMap,
				env_map
			);
			for(int i=0; i!=6; ++i)
				Texture::ImageCM(i, image);
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::ClampToEdge);
			bound_tex.WrapT(TextureWrap::ClampToEdge);
			bound_tex.WrapR(TextureWrap::ClampToEdge);
		}
		ProgramUniformSampler(liquid_prog, "EnvMap").Set(0);

		const Vec3f light_position(12.0, 1.0, 8.0);
		liquid_prog.light_position.Set(light_position);

		gl.ClearColor(0.7f, 0.65f, 0.55f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);

		gl.Enable(Capability::CullFace);
		gl.FrontFace(FaceOrientation::CW);
		gl.CullFace(Face::Back);
	}
Example #8
0
	CubeExample(void)
	 : cube(
		List("Position")("Normal")("TexCoord").Get(),
		shapes::Cube(),
		cube_prog
	)
	{
		// setup the texture
		{
			GLuint tex_side = 512;
			auto image = images::NewtonFractal(
				tex_side, tex_side,
				Vec3f(0.2f, 0.1f, 0.4f),
				Vec3f(0.8f, 0.8f, 1.0f),
				Vec2f(-1.0f, -1.0f),
				Vec2f( 1.0f,  1.0f),
				images::NewtonFractal::X4Minus1(),
				images::NewtonFractal::DefaultMixer()
			);
			auto bound_tex = Bind(cube_tex, Texture::Target::_2D);

			bound_tex.Image2D(image);
			bound_tex.GenerateMipmap();
			bound_tex.BorderColor(Vec4f(0.8f, 0.8f, 1.0f, 1.0f));
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::Repeat);
			bound_tex.WrapT(TextureWrap::Repeat);
		}

		cube_prog.cube_tex = 0;
		cube_prog.light_position.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.CullFace(Face::Back);
	}
Example #9
0
	EnvMap(GLuint tex_unit)
	 : _tex_unit(tex_unit)
	{
		Texture::Active(_tex_unit);
		auto bound_tex = oglplus::Bind(*this, 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);

		Texture::Image2D(
			Texture::CubeMapFace(0),
			images::LoadTexture("cloudy_day-cm_0", false, false)
		);
		Texture::Image2D(
			Texture::CubeMapFace(1),
			images::LoadTexture("cloudy_day-cm_1", false, false)
		);
		Texture::Image2D(
			Texture::CubeMapFace(2),
			images::LoadTexture("cloudy_day-cm_2", false, false)
		);
		Texture::Image2D(
			Texture::CubeMapFace(3),
			images::LoadTexture("cloudy_day-cm_3", false, false)
		);
		Texture::Image2D(
			Texture::CubeMapFace(4),
			images::LoadTexture("cloudy_day-cm_4", false, false)
		);
		Texture::Image2D(
			Texture::CubeMapFace(5),
			images::LoadTexture("cloudy_day-cm_5", false, false)
		);
	}
Example #10
0
	ReflectionExample(void)
	 : make_plane(
		Vec3f(),
		Vec3f(3.0f, 0.0f, 0.0f),
		Vec3f(0.0f, 0.0f, -3.0f),
		15,
		15
	), plane_instr(make_plane.Instructions())
	 , plane_indices(make_plane.Indices())
	 , make_shape()
	 , shape_instr(make_shape.Instructions())
	 , shape_indices(make_shape.Indices())
	 , plane_vs(ObjectDesc("Plane vertex"))
	 , shape_vs(ObjectDesc("Shape vertex"))
	 , plane_fs(ObjectDesc("Plane fragment"))
	 , shape_fs(ObjectDesc("Shape fragment"))
	 , plane_projection_matrix(plane_prog, "ProjectionMatrix")
	 , plane_camera_matrix(plane_prog, "CameraMatrix")
	 , plane_model_matrix(plane_prog, "ModelMatrix")
	 , shape_projection_matrix(shape_prog, "ProjectionMatrix")
	 , shape_camera_matrix(shape_prog, "CameraMatrix")
	 , shape_model_matrix(shape_prog, "ModelMatrix")
	 , width(800)
	 , height(600)
	 , tex_size_div(2)
	{
		plane_vs.Source(
			"#version 330\n"
			"uniform vec3 LightPosition;"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"out vec3 vertLightDir;"
			"out vec4 vertTexCoord;"
			"void main(void)"
			"{"
			"	gl_Position = ModelMatrix*Position;"
			"	vertLightDir = LightPosition - gl_Position.xyz;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"	vertTexCoord = gl_Position;"
			"}"
		);
		plane_vs.Compile();

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

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

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

		plane.Bind();

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

		Texture::Active(0);
		ProgramUniformSampler(plane_prog, "ReflectTex").Set(0);
		{
			auto bound_tex = Bind(reflect_tex, Texture::Target::Rectangle);
			bound_tex.MinFilter(TextureMinFilter::Linear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::ClampToEdge);
			bound_tex.WrapT(TextureWrap::ClampToEdge);
		}

		{
			auto bound_fbo = Bind(
				fbo,
				Framebuffer::Target::Draw
			);
			bound_fbo.AttachTexture(
				FramebufferAttachment::Color,
				reflect_tex,
				0
			);
			bound_fbo.AttachTexture(
				FramebufferAttachment::Depth,
				depth_tex,
				0
			);
		}

		shape_vs.Source(
			"#version 330\n"
			"uniform vec3 LightPosition;"
			"uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"out vec3 vertNormal;"
			"out vec3 vertLightDir;"
			"out vec3 vertLightRefl;"
			"out vec3 vertViewDir;"
			"out vec3 vertColor;"
			"void main(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;"
			"	vertColor = vec3(1, 1, 1) - 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 vertColor;"
			"out vec3 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);"
			"	fragColor = "
			"		vertColor * 0.4 + "
			"		(lt + vertColor)*pow(max(2.5*d, 0.0), 3) + "
			"		lt * pow(max(s, 0.0), 64);"
			"}"
		);
		shape_fs.Compile();

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

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

		shape.Bind();

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

		shape_normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_shape.Normals(data);
			Buffer::Data(Buffer::Target::Array, data);
			VertexAttribArray attr(shape_prog, "Normal");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}
		//
		gl.ClearColor(0.5f, 0.5f, 0.4f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
	}
Example #11
0
	FBTexExample(void)
	 : make_cube()
	 , cube_instr(make_cube.Instructions())
	 , cube_indices(make_cube.Indices())
	 , make_torus(1.0, 0.5, 72, 48)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	 , cube_fs(ObjectDesc("Cube fragment"))
	 , torus_fs(ObjectDesc("Torus fragment"))
	 , torus_projection_matrix(torus_prog, "ProjectionMatrix")
	 , torus_camera_matrix(torus_prog, "CameraMatrix")
	 , torus_model_matrix(torus_prog, "ModelMatrix")
	 , cube_projection_matrix(cube_prog, "ProjectionMatrix")
	 , cube_camera_matrix(cube_prog, "CameraMatrix")
	 , cube_model_matrix(cube_prog, "ModelMatrix")
	 , tex_side(512)
	 , width(tex_side)
	 , height(tex_side)
	{
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"in vec2 TexCoord;"
			"out vec3 vertNormal;"
			"out vec3 vertLight;"
			"out vec2 vertTexCoord;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	gl_Position = ModelMatrix * Position;"
			"	vertLight = LightPos-gl_Position.xyz;"
			"	vertTexCoord = TexCoord;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		vs.Compile();

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

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

		cube.Bind();

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

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

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

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

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

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

		torus.Bind();

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

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

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

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

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

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

		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
		gl.CullFace(Face::Back);
	}
Example #12
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(n_per_vertex, DataType::Float);
			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(n_per_vertex, DataType::Float);
			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 bound_tex = Bind(tex, Texture::Target::CubeMap);
			bound_tex.MinFilter(TextureMinFilter::Linear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::ClampToEdge);
			bound_tex.WrapT(TextureWrap::ClampToEdge);
			bound_tex.WrapR(TextureWrap::ClampToEdge);

			for(int i=0; i!=6; ++i)
				Texture::Image2D(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 #13
0
	TriangleExample(void)
	 : projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , camera_position(prog, "CameraPosition")
	 , light_position(prog, "LightPosition")
	 , shape(
		List("Position")("TexCoord").Get(),
		shapes::Plane(
			Vec3f(),
			Vec3f(1.0f, 0.0f, 0.0f),
			Vec3f(0.0f, 0.0f,-1.0f),
			32, 32
		)
	)
	{
		VertexShader vs;
		vs.Source(StrLit(
			"#version 330\n"
			"in vec3 Position;"
			"in vec2 TexCoord;"
			"out vec2 vertTexCoord;"
			"void main(void)"
			"{"
			"	gl_Position = vec4(Position, 1.0);"
			"	vertTexCoord = TexCoord;"
			"}"
		)).Compile();
		prog.AttachShader(vs);

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

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

			"in vec2 vertTexCoord[3];"

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

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

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

			"	int ft = gl_InvocationID+1;"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			"out vec3 fragColor;"

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

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

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

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

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

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

		shape.UseInProgram(prog);

		auto tex_image = images::LoadTexture("stones_color_hmap");

		Texture::Active(0);
		try
		{
			UniformSampler(prog, "ColorMap").Set(0);
			auto bound_tex = Bind(color_tex, Texture::Target::_2D);
			bound_tex.Image2D(tex_image);
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::Repeat);
			bound_tex.WrapT(TextureWrap::Repeat);
		}
		catch(Error&){ }

		Texture::Active(1);
		try
		{
			UniformSampler(prog, "BumpMap").Set(1);
			auto bound_tex = Bind(bump_tex, Texture::Target::_2D);
			bound_tex.Image2D(
				images::NormalMap(
					tex_image,
					images::NormalMap::FromAlpha()
				)
			);
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::Repeat);
			bound_tex.WrapT(TextureWrap::Repeat);
		}
		catch(Error&){ }

		gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Disable(Capability::CullFace);

		gl.Enable(Functionality::ClipDistance, 0);
		gl.Enable(Functionality::ClipDistance, 1);
		gl.Enable(Functionality::ClipDistance, 2);
	}
Example #14
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")
	 , light_pos(prog, "LightPos")
	{
		namespace se = oglplus::smart_enums;
		// Set the vertex shader source
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"in vec3 Tangent;"
			"in vec2 TexCoord;"
			"out vec3 vertLight;"
			"out vec2 vertTexCoord;"
			"out mat3 NormalMatrix;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	vec3 fragNormal = mat3(ModelMatrix) * Normal;"
			"	vec3 fragTangent = mat3(ModelMatrix) * Tangent;"
			"	NormalMatrix[0] = fragTangent;"
			"	NormalMatrix[1] = cross(fragNormal, fragTangent);"
			"	NormalMatrix[2] = fragNormal;"

			"	gl_Position = ModelMatrix * Position;"
			"	vertLight = LightPos - gl_Position.xyz;"
			"	vertTexCoord = TexCoord;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		// compile it
		vs.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"uniform sampler2D ColorTex, NormalTex;"
			"in mat3 NormalMatrix;"
			"in vec3 vertLight;"
			"in vec2 vertTexCoord;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float l = dot(vertLight, vertLight);"
			"	vec3 n = texture(NormalTex, vertTexCoord).xyz;"
			"	vec3 finalNormal = NormalMatrix * n;"
			"	float d = (l > 0.0) ? dot("
			"		normalize(vertLight), "
			"		finalNormal"
			"	) / l : 0.0;"
			"	float i = 0.2 + 4.5*max(d, 0.0);"
			"	vec4 t  = texture(ColorTex, vertTexCoord);"
			"	fragColor = vec4(t.rgb*i, 1.0);"
			"}"
		);
		// compile it
		fs.Compile();

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

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

		verts.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.Positions(data);
			Buffer::Data(se::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_cube.Normals(data);
			Buffer::Data(se::Array(), data);
			VertexAttribArray attr(prog, "Normal");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		tangents.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.Tangents(data);
			Buffer::Data(se::Array(), data);
			VertexAttribArray attr(prog, "Tangent");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

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

		// setup the textures
		{
			Texture::Active(0);
			UniformSampler(prog, "ColorTex").Set(0);
			auto bound_tex = Bind(colorTex, se::_2D());
			bound_tex.Image2D(images::LoadTexture("wooden_crate"));
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(se::LinearMipmapLinear());
			bound_tex.MagFilter(se::Linear());
			bound_tex.WrapS(se::Repeat());
			bound_tex.WrapT(se::Repeat());
		}
		{
			Texture::Active(1);
			UniformSampler(prog, "NormalTex").Set(1);
			auto bound_tex = Bind(normalTex, se::_2D());
			bound_tex.Image2D(
				images::NormalMap(
					images::LoadTexture("wooden_crate-hmap"),
					images::NormalMap::FromRed()
				)
			);
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(se::LinearMipmapLinear());
			bound_tex.MagFilter(se::Linear());
			bound_tex.WrapS(se::Repeat());
			bound_tex.WrapT(se::Repeat());
		}
		//
		gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(se::DepthTest());

		gl.Enable(se::CullFace());
		gl.FrontFace(make_cube.FaceWinding());
	}
	CubeExample(void)
	 : cube_instr(make_cube.Instructions())
	 , cube_indices(make_cube.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	{
		namespace se = oglplus::smart_enums;
		VertexShader vs;
		vs.Source(
			"#version 120\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"attribute vec4 Position;"
			"attribute vec3 Normal;"
			"attribute vec2 TexCoord;"
			"varying vec3 vertNormal;"
			"varying vec3 vertLight;"
			"varying vec2 vertTexCoord;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	gl_Position = ModelMatrix * Position;"
			"	vertLight = LightPos - gl_Position.xyz;"
			"	vertTexCoord = TexCoord;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		).Compile();

		FragmentShader fs;
		fs.Source(
			"#version 120\n"
			"uniform sampler2D TexUnit;"
			"varying vec3 vertNormal;"
			"varying vec3 vertLight;"
			"varying vec2 vertTexCoord;"
			"void main(void)"
			"{"
			"	float l = length(vertLight);"
			"	float d = l > 0 ? dot(vertNormal, normalize(vertLight)) / l : 0.0;"
			"	float i = 0.3 + 2.0*max(d, 0.0);"
			"	vec4 t = texture2D(TexUnit, vertTexCoord);"
			"	gl_FragColor = vec4(t.rgb*i, 1.0);"
			"}"
		).Compile();

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

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

		verts.Bind(se::Array());
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.Positions(data);
			Buffer::Data(se::Array(), data);
			(prog|"Position").Setup(n_per_vertex, se::Float()).Enable();
		}

		normals.Bind(se::Array());
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.Normals(data);
			Buffer::Data(se::Array(), data);
			(prog|"Normal").Setup(n_per_vertex, se::Float()).Enable();
		}

		texcoords.Bind(se::Array());
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.TexCoordinates(data);
			Buffer::Data(se::Array(), data);
			(prog|"TexCoord").Setup(n_per_vertex, se::Float()).Enable();
		}

		// setup the texture
		{
			auto bound_tex = Bind(tex, se::_2D());
			auto image = images::NewtonFractal(
				512, 512,
				Vec3f(1.0f, 1.4f, 1.3f),
				Vec3f(0.2f, 0.3f, 0.1f),
				Vec2f(-1.0f, -1.0f),
				Vec2f( 1.0f,  1.0f),
				images::NewtonFractal::X4Minus1(),
				[](double x) -> double
				{
					return pow(SineWave(pow(x,0.5)), 4.0);
				}
			);
			bound_tex.Image2D(image);
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(se::LinearMipmapLinear());
			bound_tex.MagFilter(se::Linear());
			bound_tex.WrapS(se::Repeat());
			bound_tex.WrapT(se::Repeat());
		}
		// set the uniform values
		(prog/"TexUnit") = 0;
		(prog/"LightPos") = Vec3f(1.0f, 2.0f, 3.0f);
		//
		gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(se::DepthTest());

		gl.Enable(se::CullFace());
		gl.FrontFace(make_cube.FaceWinding());
	}
Example #16
0
	Test01(void)
	{
		// Set the vertex shader source
		vs.Source(
			"#version 330\n"
			"uniform mat4 projectionMatrix, cameraMatrix, modelMatrix;"
			"in vec4 vertex;"
			"in vec3 normal;"
			"in vec3 tangent;"
			"in vec2 texcoord;"
			"out vec3 fragLight;"
			"out vec2 fragTex;"
			"out mat3 normalMatrix;"
			"uniform vec3 lightPos;"
			"void main(void)"
			"{"
			"	vec3 fragNormal = ("
			"		modelMatrix *"
			"		vec4(normal, 0.0)"
			"	).xyz;"
			"	vec3 fragTangent = ("
			"		modelMatrix *"
			"		vec4(tangent, 0.0)"
			"	).xyz;"
			"	normalMatrix[0] = fragTangent;"
			"	normalMatrix[1] = cross(fragNormal, fragTangent);"
			"	normalMatrix[2] = fragNormal;"
			"	fragLight = ("
			"		vec4(lightPos, 0.0)-"
			"		modelMatrix*vertex"
			"	).xyz;"
			"	fragTex = texcoord;"
			"	gl_Position = "
			"		projectionMatrix *"
			"		cameraMatrix *"
			"		modelMatrix *"
			"		vertex;"
			"}"
		);
		// compile it
		vs.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"uniform sampler2D colorTex, normalTex;"
			"in vec3 fragLight;"
			"in vec2 fragTex;"
			"in mat3 normalMatrix;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float s = 5.0;"
			"	float l = length(fragLight);"
			"	vec3 n = texture2D(normalTex, fragTex*s).xyz;"
			"	vec3 finalNormal = normalMatrix * n;"
			"	float d = (l != 0.0)?"
			"		dot(fragLight, finalNormal)/l:"
			"		0.0;"
			"	float i = 0.1 + 2.5*clamp(d, 0.0, 1.0);"
			"	vec4 t  = texture2D(colorTex, fragTex*s);"
			"	fragColor = vec4(t.rgb*i, 1.0);"
			"}"
		);
		// compile it
		fs.Compile();

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

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

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

		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = shape.Normals(data);
			Bind(normals, Buffer::Target::Array).Data(data);
			// setup the vertex attribs array for the normals
			VertexAttribArray attr(prog, "normal");
			attr.Setup(n_per_vertex, DataType::Float);
			attr.Enable();
		}

		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = shape.Tangents(data);
			Bind(tangents, Buffer::Target::Array).Data(data);
			VertexAttribArray attr(prog, "tangent");
			attr.Setup(n_per_vertex, DataType::Float);
			attr.Enable();
		}

		// bind the VBO for the shape tex-coords
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = shape.TexCoordinates(data);
			Bind(texcoords, Buffer::Target::Array).Data(data);
			//
			VertexAttribArray attr(prog, "texcoord");
			attr.Setup(n_per_vertex, DataType::Float);
			attr.Enable();
		}

		// setup the textures
		{
			Texture::Active(0);
			UniformSampler(prog, "colorTex").Set(0);
			auto bound_tex = Bind(color_tex, Texture::Target::_2D);
			bound_tex.Image2D(images::LoadTexture("stones"));
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::Repeat);
			bound_tex.WrapT(TextureWrap::Repeat);
		}
		{
			Texture::Active(1);
			UniformSampler(prog, "normalTex").Set(1);
			auto bound_tex = Bind(normal_tex, Texture::Target::_2D);
			bound_tex.Image2D(
				images::NormalMap(images::LoadTexture("stones-hmap"))
			);
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::Repeat);
			bound_tex.WrapT(TextureWrap::Repeat);
		}

		Uniform<Mat4f>(prog, "projectionMatrix").Set(
			CamMatrixf::Perspective(Degrees(24), 1.25, 1, 100)
		);
		//
		VertexArray::Unbind();
		gl.ClearColor(0.3f, 0.3f, 0.3f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		//
		gl.FrontFace(shape.FaceWinding());
		gl.CullFace(Face::Back);
		gl.Enable(Capability::CullFace);
	}
Example #17
0
	MetaballExample(void)
	{
		for(GLuint i=0; i!=64; ++i)
		{
			GLuint j = 0, n = 3+std::rand()%3;
			std::vector<Vec4f> points(n);
			while(j != n)
			{
				points[j] = Vec4f(
					1.4*std::rand()/GLdouble(RAND_MAX) - 0.7,
					1.4*std::rand()/GLdouble(RAND_MAX) - 0.7,
					0.0,
					0.1*std::rand()/GLdouble(RAND_MAX) + 0.1
				);
				++j;
			}
			ball_paths.push_back(CubicBezierLoop<Vec4f, double>(points));
			++i;
		}

		// Set the vertex shader source
		vs.Source(StrLit(
			"#version 330\n"
			"in vec2 Position;"
			"out vec3 vertPosition;"
			"void main(void)"
			"{"
			"	vertPosition = vec3(Position, 0.0);"
			"	gl_Position = vec4(vertPosition, 1.0);"
			"}"
		));
		// compile it
		vs.Compile();

		// set the fragment shader source
		fs.Source(StrLit(
			"#version 330\n"
			"uniform sampler1D Metaballs;"
			"in vec3 vertPosition;"
			"out vec3 fragColor;"

			"const vec3 AmbientColor = vec3(0.3, 0.4, 0.9);"
			"const vec3 DiffuseColor = vec3(0.5, 0.6, 1.0);"
			"const vec3 LightDir = normalize(vec3(1.0, 1.0, 1.0));"

			"void main(void)"
			"{"
			"	int i = 0, n = textureSize(Metaballs, 0);"

			"	float InvN = 1.0/n;"
			"	float Value = 0.0;"
			"	vec3 Normal = vec3(0.0, 0.0, 0.0);"
			"	while(i != n)"
			"	{"
			"		vec4 Metaball = texelFetch(Metaballs, i, 0);"
			"		float Radius = Metaball.w;"
			"		vec3 Vect = vertPosition - Metaball.xyz;"
			"		float Tmp = pow(Radius,2.0)/dot(Vect, Vect)-0.25;"
			"		Value += Tmp;"
			"		float Mul = max(Tmp, 0.0);"
			"		Normal += Mul*vec3(Vect.xy, Mul*InvN/Radius);"
			"		++i;"
			"	}"
			"	if(Value > 0.0)"
			"	{"
			"		float Diffuse = 1.4*max(dot("
			"			LightDir,"
			"			normalize(Normal)"
			"		), 0.0);"
			"		float Ambient = 0.3;"
			"		fragColor = "
			"			Ambient*AmbientColor+"
			"			Diffuse*DiffuseColor;"
			"	}"
			"	else fragColor = vec3(0.4, 0.4, 0.4);"
			"}"
		));
		// compile it
		fs.Compile();

		// attach the shaders to the program
		prog << vs << fs;
		// link and use it
		prog.Link().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, rectangle_verts);
		// setup the vertex attribs array for the vertices
		VertexAttribArray vert_attr(prog, "Position");
		vert_attr.Setup(2, DataType::Float).Enable();
		//
		Texture::Active(0);
		UniformSampler(prog, "Metaballs").Set(0);

		{
			auto bound_tex = Bind(metaballs_tex, Texture::Target::_1D);
			bound_tex.Image1D(
				0,
				PixelDataInternalFormat::RGBA32F,
				ball_paths.size(),
				0,
				PixelDataFormat::RGBA,
				PixelDataType::Float,
				nullptr
			);
			bound_tex.MinFilter(TextureMinFilter::Nearest);
			bound_tex.MagFilter(TextureMagFilter::Nearest);
			bound_tex.WrapS(TextureWrap::MirroredRepeat);
		}

		gl.ClearDepth(1.0f);
	}
Example #18
0
	SkyBoxExample(void)
	 : prog()
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	{
		VertexShader vs;
		vs.Source(StrLit(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix;"
			"mat4 Matrix = ProjectionMatrix*CameraMatrix;"

			"in vec3 Corner;"
			"out vec3 vertTexCoord;"
			"void main(void)"
			"{"
			"	gl_Position = Matrix * vec4(Corner * 10.0, 1.0);"
			"	vertTexCoord = Corner;"
			"}"
		));
		vs.Compile();
		prog.AttachShader(vs);

		FragmentShader fs;
		fs.Source(StrLit(
			"#version 330\n"
			"uniform samplerCube EnvMap;"
			"in vec3 vertTexCoord;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	fragColor = vec4(texture(EnvMap, normalize(vertTexCoord)).rgb, 1.0);"
			"}"
		));
		fs.Compile();
		prog.AttachShader(fs);

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

		sky_box.Bind();

		GLfloat sky_box_corners[8*3] = {
			-1.0f,-1.0f,-1.0f,
			+1.0f,-1.0f,-1.0f,
			-1.0f,+1.0f,-1.0f,
			+1.0f,+1.0f,-1.0f,
			-1.0f,-1.0f,+1.0f,
			+1.0f,-1.0f,+1.0f,
			-1.0f,+1.0f,+1.0f,
			+1.0f,+1.0f,+1.0f
		};
		corners.Bind(Buffer::Target::Array);
		Buffer::Data(Buffer::Target::Array, sky_box_corners);
		VertexAttribArray vert_attr(prog, "Corner");
		vert_attr.Setup(3, DataType::Float).Enable();

		GLuint sky_box_indices[6*5] = {
			1, 3, 5, 7, 9,
			4, 6, 0, 2, 9,
			2, 6, 3, 7, 9,
			4, 0, 5, 1, 9,
			5, 7, 4, 6, 9,
			0, 2, 1, 3, 9
		};
		indices.Bind(Buffer::Target::ElementArray);
		Buffer::Data(Buffer::Target::ElementArray, 6*5, sky_box_indices);

		gl.Enable(Capability::PrimitiveRestart);
		gl.PrimitiveRestartIndex(9);

		{
			UniformSampler(prog, "EnvMap").Set(0);
			Texture::Active(0);

			auto bound_tex = oglplus::Bind(env_map, 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);

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

		gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		gl.ClearDepth(1.0f);
	}
Example #19
0
	DOFExample(const ExampleParams& params)
	 : face_instr(make_cube.Instructions())
	 , edge_instr(make_cube.EdgeInstructions())
	 , face_indices(make_cube.Indices())
	 , edge_indices(make_cube.EdgeIndices())
	 , cube_matrices(MakeCubeMatrices(100, 10.0))
	 , viewport_width(dof_prog, "ViewportWidth")
	 , viewport_height(dof_prog, "ViewportHeight")
	 , projection_matrix(main_prog, "ProjectionMatrix")
	 , camera_matrix(main_prog, "CameraMatrix")
	 , model_matrix(main_prog, "ModelMatrix")
	 , ambient_color(main_prog, "AmbientColor")
	 , diffuse_color(main_prog, "DiffuseColor")
	 , focus_depth(dof_prog, "FocusDepth")
	 , color_tex(Texture::Target::Rectangle)
	 , depth_tex(Texture::Target::Rectangle)
	 , width(800)
	 , height(600)
	{
		main_vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"uniform vec3 LightPos;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"out vec3 vertLightDir;"
			"out vec3 vertNormal;"
			"void main(void)"
			"{"
			"	gl_Position = ModelMatrix * Position;"
			"	vertLightDir = normalize(LightPos - gl_Position.xyz);"
			"	vertNormal = normalize(mat3(ModelMatrix)*Normal);"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		// compile it
		main_vs.Compile();

		// set the fragment shader source
		main_fs.Source(
			"#version 330\n"
			"uniform vec3 AmbientColor, DiffuseColor;"
			"in vec3 vertLightDir;"
			"in vec3 vertNormal;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float d = max(dot(vertLightDir,vertNormal),0.0);"
			"	float e = sin("
			"		10.0*vertLightDir.x + "
			"		20.0*vertLightDir.y + "
			"		25.0*vertLightDir.z   "
			"	)*0.9;"
			"	fragColor = vec4("
			"		mix(AmbientColor, DiffuseColor, d+e),"
			"		1.0"
			"	);"
			"}"
		);
		// compile it
		main_fs.Compile();

		// attach the shaders to the program
		main_prog.AttachShader(main_vs);
		main_prog.AttachShader(main_fs);
		// link and use it
		main_prog.Link();
		main_prog.Use();

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

		// bind the VBO for the cube vertices
		positions.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(main_prog, "Position");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		// bind the VBO for the cube normals
		normals.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.Normals(data);
			Buffer::Data(Buffer::Target::Array, data);
			VertexAttribArray attr(main_prog, "Normal");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}

		Uniform<Vec3f>(main_prog, "LightPos").Set(30.0, 50.0, 20.0);

		dof_vs.Source(
			"#version 330\n"
			"uniform uint ViewportWidth, ViewportHeight;"
			"in vec4 Position;"
			"out vec2 vertTexCoord;"
			"void main(void)"
			"{"
			"	gl_Position = Position;"
			"	vertTexCoord = vec2("
			"		(Position.x*0.5 + 0.5)*ViewportWidth,"
			"		(Position.y*0.5 + 0.5)*ViewportHeight"
			"	);"
			"}"
		);
		dof_vs.Compile();

		dof_fs.Source(
			"#version 330\n"
			"uniform sampler2DRect ColorTex;"
			"uniform sampler2DRect DepthTex;"
			"uniform float FocusDepth;"
			"uniform uint SampleMult;"
			"in vec2 vertTexCoord;"
			"out vec4 fragColor;"
			"const float strength = 16.0;"
			"void main(void)"
			"{"
			"	float fragDepth = texture(DepthTex, vertTexCoord).r;"
			"	vec3 color = texture(ColorTex, vertTexCoord).rgb;"
			"	float of = abs(fragDepth - FocusDepth);"
			"	int nsam = int(of*SampleMult);"
			"	float inv_nsam = 1.0 / (1.0 + nsam);"
			"	float astep = (3.14151*4.0)/nsam;"
			"	for(int i=0; i!=nsam; ++i)"
			"	{"
			"		float a = i*astep;"
			"		float d = sqrt(i*inv_nsam);"
			"		float sx = cos(a)*of*strength*d;"
			"		float sy = sin(a)*of*strength*d;"
			"		vec2 samTexCoord = vertTexCoord + vec2(sx, sy) + noise2(vec2(sx, sy));"
			"		color += texture(ColorTex, samTexCoord).rgb;"
			"	}"
			"	fragColor = vec4(color * inv_nsam , 1.0);"
			"}"
		);
		dof_fs.Compile();

		dof_prog.AttachShader(dof_vs);
		dof_prog.AttachShader(dof_fs);
		dof_prog.Link();
		dof_prog.Use();

		GLuint sample_mult = params.HighQuality()?512:128;
		Uniform<GLuint>(dof_prog, "SampleMult") = sample_mult;

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

		corners.Bind(Buffer::Target::Array);
		{
			GLfloat screen_verts[8] = {
				-1.0f, -1.0f,
				-1.0f,  1.0f,
				 1.0f, -1.0f,
				 1.0f,  1.0f
			};
			Buffer::Data(Buffer::Target::Array, 8, screen_verts);
			VertexAttribArray attr(dof_prog, "Position");
			attr.Setup<Vec2f>();
			attr.Enable();
		}

		Texture::Active(0);
		UniformSampler(dof_prog, "ColorTex").Set(0);
		{
			auto bound_tex = Bind(color_tex, Texture::Target::Rectangle);
			bound_tex.MinFilter(TextureMinFilter::Linear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::ClampToEdge);
			bound_tex.WrapT(TextureWrap::ClampToEdge);
			bound_tex.Image2D(
				0,
				PixelDataInternalFormat::RGB,
				width, height,
				0,
				PixelDataFormat::RGB,
				PixelDataType::UnsignedByte,
				nullptr
			);
		}

		Texture::Active(1);
		UniformSampler(dof_prog, "DepthTex").Set(1);
		{
			auto bound_tex = Bind(depth_tex, Texture::Target::Rectangle);
			bound_tex.MinFilter(TextureMinFilter::Linear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::ClampToEdge);
			bound_tex.WrapT(TextureWrap::ClampToEdge);
			bound_tex.Image2D(
				0,
				PixelDataInternalFormat::DepthComponent,
				width, height,
				0,
				PixelDataFormat::DepthComponent,
				PixelDataType::Float,
				nullptr
			);
		}

		{
			auto bound_fbo = Bind(
				fbo,
				Framebuffer::Target::Draw
			);
			bound_fbo.AttachTexture(
				FramebufferAttachment::Color,
				color_tex,
				0
			);
			bound_fbo.AttachTexture(
				FramebufferAttachment::Depth,
				depth_tex,
				0
			);
		}

		//
		gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.DepthFunc(CompareFn::LEqual);
		gl.Enable(Capability::LineSmooth);
		gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha);
	}
Example #20
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);
	}
Example #21
0
	SketchExample(void)
	 : transf_prog()
	 , sketch_prog()
	 , plane(
		transf_prog,
		shapes::Plane(
			Vec3f(0, 0, 0),
			Vec3f(9, 0, 0),
			Vec3f(0, 0,-9),
			9, 9
		)
	), torus(transf_prog, shapes::WickerTorus())
	 , sketch_tex_layers(8)
	 , shadow_tex_side(1024)
	{

		NoProgram().Use();

		shadow_pp.Bind();
		shadow_pp.UseStages(transf_prog).Vertex();
		shadow_pp.UseStages(shadow_prog).Fragment();

		sketch_pp.Bind();
		sketch_pp.UseStages(transf_prog).Vertex();
		sketch_pp.UseStages(sketch_prog).Fragment();

		line_pp.Bind();
		line_pp.UseStages(transf_prog).Vertex();
		line_pp.UseStages(line_prog).Geometry().Fragment();

		Texture::Active(0);
		sketch_prog.sketch_tex.Set(0);
		{
			auto bound_tex = gl.Bound(Texture::Target::_3D, sketch_texture);

			for(GLuint i=0; i<sketch_tex_layers; ++i)
			{
				auto image = images::BrushedMetalUByte(
					512, 512,
					64 + i*128,
					-(2+i*4), +(2+i*4),
					64, 256-i*4
				);
				if(i == 0)
				{
					bound_tex.Image3D(
						0,
						PixelDataInternalFormat::RGB,
						image.Width(),
						image.Height(),
						sketch_tex_layers,
						0,
						image.Format(),
						image.Type(),
						nullptr
					);
				}
				bound_tex.SubImage3D(
					0,
					0, 0, i,
					image.Width(),
					image.Height(),
					1,
					image.Format(),
					image.Type(),
					image.RawData()
				);
			}
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::Repeat);
			bound_tex.WrapT(TextureWrap::Repeat);
			bound_tex.WrapR(TextureWrap::ClampToEdge);
		}

		Texture::Active(1);
		sketch_prog.shadow_tex.Set(1);

		gl.Bound(Texture::Target::_2D, shadow_tex)
			.MinFilter(TextureMinFilter::Linear)
			.MagFilter(TextureMagFilter::Linear)
			.WrapS(TextureWrap::ClampToEdge)
			.WrapT(TextureWrap::ClampToEdge)
			.CompareMode(TextureCompareMode::CompareRefToTexture)
			.Image2D(
				0,
				PixelDataInternalFormat::DepthComponent32,
				shadow_tex_side, shadow_tex_side,
				0,
				PixelDataFormat::DepthComponent,
				PixelDataType::Float,
				nullptr
			);

		gl.Bound(Framebuffer::Target::Draw, frame_shadow_fbo)
			.AttachTexture(
				FramebufferAttachment::Depth,
				shadow_tex,
				0
			);

		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);

		gl.DepthFunc(CompareFn::LEqual);
		gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha);

		gl.PolygonOffset(1.0, 1.0);
		gl.LineWidth(1.5);

	}
Example #22
0
	LiquidGeomShader(void)
	 : GeometryShader(
		ObjectDesc("Liquid geometry shader"),
		StrLit("#version 330\n"
		"layout(triangles_adjacency) in;"
		"layout(triangle_strip, max_vertices = 4) out;"

		"uniform isampler1D Configurations;"
		"uniform mat4 CameraMatrix;"
		"uniform vec3 CameraPosition, LightPosition;"

		"in vec3 vertNormal[];"
		"in float vertValue[];"
		"flat in int vertSign[];"

		"out vec3 geomNormal, geomLightDir, geomViewDir;"

		"void make_vertex(int i1, int i2)"
		"{"
		"	float t = vertValue[i1]/(vertValue[i1] - vertValue[i2]);"
		"	gl_Position = mix("
		"		gl_in[i1].gl_Position,"
		"		gl_in[i2].gl_Position,"
		"		t"
		"	);"
		"	geomNormal = mix("
		"		vertNormal[i1],"
		"		vertNormal[i2],"
		"		t"
		"	);"
		"	geomLightDir = LightPosition - gl_Position.xyz;"
		"	geomViewDir = CameraPosition - gl_Position.xyz;"
		"	gl_Position = CameraMatrix * gl_Position;"
		"	EmitVertex();"
		"}"

		"void make_triangle(const ivec4 v1, const ivec4 v2)"
		"{"
		"	make_vertex(v1.x, v2.x);"
		"	make_vertex(v1.y, v2.y);"
		"	make_vertex(v1.z, v2.z);"
		"	EndPrimitive();"
		"}"

		"void make_quad(const ivec4 v1, const ivec4 v2)"
		"{"
		"	make_vertex(v1.x, v2.x);"
		"	make_vertex(v1.y, v2.y);"
		"	make_vertex(v1.z, v2.z);"
		"	make_vertex(v1.w, v2.w);"
		"	EndPrimitive();"
		"}"

		"void process_tetrahedron(int a, int b, int c, int d)"
		"{"
		"	ivec4 i = ivec4(vertSign[a],vertSign[b],vertSign[c],vertSign[d]);"
		"	int si = int(dot(i, ivec4(1, 1, 1, 1))) % 4;"
		"	if(si != 0)"
		"	{"
		"		int iv = int(dot(i, ivec4(16, 8, 4, 2)));"
		"		ivec4 v1 = texelFetch(Configurations, iv+0, 0);"
		"		ivec4 v2 = texelFetch(Configurations, iv+1, 0);"
		"		if(si % 2 == 0) make_quad(v1, v2);"
		"		else make_triangle(v1, v2);"
		"	}"
		"}"

		"void main(void)"
		"{"
		"	process_tetrahedron(0, 2, 4, 1);"
		"}")
	)
	{
		Texture::Active(0);
		{
			const GLubyte a = 0x0, b = 0x2, c = 0x4, d = 0x1, x = 0xFF;
			const GLubyte  tex_data[] = {
				x, x, x, x,   x, x, x, x,
				a, c, b, x,   d, d, d, x,
				b, d, a, x,   c, c, c, x,
				b, b, a, a,   c, d, c, d,
				a, d, c, x,   b, b, b, x,
				a, a, c, c,   b, d, b, d,
				a, a, d, d,   c, b, c, b,
				a, a, a, x,   b, d, c, x,
				c, d, b, x,   a, a, a, x,
				c, c, b, b,   a, d, a, d,
				b, d, b, d,   c, c, a, a,
				b, b, b, x,   c, d, a, x,
				c, d, c, d,   a, a, b, b,
				c, c, c, x,   a, d, b, x,
				d, d, d, x,   a, b, c, x,
				x, x, x, x,   x, x, x, x
			};
			auto bound_tex = Bind(_configurations, Texture::Target::_1D);
			bound_tex.Image1D(
				0,
				PixelDataInternalFormat::RGBA8UI,
				sizeof(tex_data),
				0,
				PixelDataFormat::RGBAInteger,
				PixelDataType::UnsignedByte,
				tex_data
			);
			bound_tex.MinFilter(TextureMinFilter::Nearest);
			bound_tex.MagFilter(TextureMagFilter::Nearest);
			bound_tex.WrapS(TextureWrap::ClampToEdge);
		}
	}
Example #23
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")
	{
		namespace se = oglplus::smart_enums;
		// 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;"
			"	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 = length(vertLight);"
			"	float d = l > 0 ? dot(vertNormal, normalize(vertLight)) / l : 0.0;"
			"	float i = 0.3 + 2.0*max(d, 0.0);"
			"	vec4 t  = texture(TexUnit, vertTexCoord);"
			"	fragColor = vec4(t.rgb*i, 1.0);"
			"}"
		);
		// compile it
		fs.Compile();

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

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

		verts.Bind(se::Array());
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.Positions(data);
			Buffer::Data(se::Array(), data);
			(prog|"Position").Setup(n_per_vertex, se::Float()).Enable();
		}

		normals.Bind(se::Array());
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.Normals(data);
			Buffer::Data(se::Array(), data);
			(prog|"Normal").Setup(n_per_vertex, se::Float()).Enable();
		}

		texcoords.Bind(se::Array());
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_cube.TexCoordinates(data);
			Buffer::Data(se::Array(), data);
			(prog|"TexCoord").Setup(n_per_vertex, se::Float()).Enable();
		}

		// setup the texture
		{
			auto bound_tex = Bind(tex, se::_2D());
			bound_tex.Image2D(images::LoadTexture("concrete_block"));
			bound_tex.MinFilter(se::Linear());
			bound_tex.MagFilter(se::Linear());
			bound_tex.WrapS(se::Repeat());
			bound_tex.WrapT(se::Repeat());
		}
		// set the uniform values
		(prog/"TexUnit") = 0;
		(prog/"LightPos") = Vec3f(1.0f, 2.0f, 3.0f);
		//
		gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(se::DepthTest());

		gl.Enable(se::CullFace());
		gl.FrontFace(make_cube.FaceWinding());
	}
Example #24
0
	WavesExample(void)
	 : make_plane(
		Vec3f(  0.0f,   0.0f,   0.0f),
		Vec3f(100.0f,   0.0f,   0.0f),
		Vec3f(  0.0f,   0.0f,-100.0f),
		50, 50
	), plane_instr(make_plane.PatchInstructions())
	 , plane_indices(make_plane.PatchIndices())
	 , camera_matrix(prog, "CameraMatrix")
	 , camera_position(prog, "CameraPosition")
	 , anim_time(prog, "Time")
	 , prev_period(-1)
	{
		VertexShader vs(ObjectDesc("Vertex"));
		vs.Source(StrLit(
			"#version 410\n"

			"uniform vec3 CameraPosition;"

			"in vec3 Position;"

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

			"void main(void)"
			"{"
			"	vertPosition = Position;"
			"	vertDistance = distance(CameraPosition, Position);"
			"}"
		));
		vs.Compile();
		prog.AttachShader(vs);

		TessControlShader cs(ObjectDesc("TessControl"));
		cs.Source(
			"#version 410\n"

			"layout(vertices = 3) out;"

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

			"out vec3 tecoPosition[];"

			"int tessLevel(float dist)"
			"{"
			"	return clamp(int(150.0 / (dist+0.1)), 1, 10);"
			"}"

			"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();
		prog.AttachShader(cs);

		TessEvaluationShader es(ObjectDesc("TessEvaluation"));
		es.Source(
			"#version 410\n"
			"#define MaxWaves 5\n"

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

			"uniform mat4 ProjectionMatrix, CameraMatrix;"
			"uniform vec3 LightPosition;"
			"uniform vec3 CameraPosition;"

			"uniform float Time;"

			"uniform int WaveCount;"
			"uniform vec3 WaveDirections[MaxWaves];"
			"uniform vec3 WaveDimensions[MaxWaves];"

			"in vec3 tecoPosition[];"

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

			"out float teevDistance;"

			"void main(void)"
			"{"
			"	const vec3 Up = vec3(0.0, 1.0, 0.0);"
			"	vec3 Position ="
			"		gl_TessCoord.x * tecoPosition[0]+"
			"		gl_TessCoord.y * tecoPosition[1]+"
			"		gl_TessCoord.z * tecoPosition[2];"

			"	vec3 Pos = Position;"
			"	vec3 Nml = Up;"
			"	for(int w=0; w!=WaveCount; ++w)"
			"	{"
			"		vec3 Dir = WaveDirections[w];"
			"		vec3 Dim = WaveDimensions[w];"
			"		float Dist = dot(Position, Dir);"

			"		float u = Dim.y*sin(Dist/Dim.x + Time*Dim.z);"
			"		Pos += Up * u;"

			"		float w = (Dim.y/Dim.x)*cos(Dist/Dim.x + Time*Dim.z);"
			"		Nml -= Dir * w;"

			"		float d = -0.125*Dim.x*sin(2.0*Dist/Dim.x + Time*Dim.z);"
			"		Pos += Dir * d;"
			"	}"

			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		vec4(Pos, 1.0);"

			"	teevNormal = normalize(Nml);"
			"	teevLightDir = normalize(LightPosition - Pos);"
			"	teevViewDir = normalize(CameraPosition - Pos);"
			"	teevDistance = distance(CameraPosition, Pos);"
			"}"
		);
		es.Compile();
		prog.AttachShader(es);

		FragmentShader fs(ObjectDesc("Fragment"));
		fs.Source(StrLit(
			"#version 410\n"

			"uniform samplerCube EnvMap;"

			"in vec3 teevNormal;"
			"in vec3 teevLightDir;"
			"in vec3 teevViewDir;"
			"in float teevDistance;"

			"out vec3 fragColor;"

			"void main(void)"
			"{"
			"	float Dim = clamp(30.0/teevDistance, 0.0, 1.0);"
			"	float LightRefl = dot(reflect(-teevLightDir, teevNormal), teevViewDir);"
			"	float LightHit = dot(teevNormal, teevLightDir);"

			"	float Diffuse = clamp(LightHit+0.1, 0.0, 1.0);"
			"	float Specular = pow(clamp(LightRefl, 0.0, 0.91), 32);"

			"	vec3 Environ=texture(EnvMap,reflect(-teevViewDir, teevNormal)).rgb;"
			"	vec3 WaterColor = vec3(0.4, 0.5, 0.5);"
			"	vec3 LightColor = vec3(1.0, 1.0, 1.0);"
			"	vec3 FogColor = vec3(0.9, 0.9, 0.9);"

			"	vec3 WaveColor ="
			"		LightColor*Specular+"
			"		WaterColor*Diffuse+"
			"		Environ*0.02;"

			"	fragColor = mix(WaveColor, FogColor, 1.0-Dim);"
			"}"
		));
		fs.Compile();
		prog.AttachShader(fs);

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

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

		Uniform<Vec3f>(prog, "LightPosition").Set(-100.0, 100.0, 20.0);

		Uniform<Vec3f> wave_directions(prog, "WaveDirections");
		Uniform<Vec3f> wave_dimensions(prog, "WaveDimensions");
		Uniform<GLint>(prog, "WaveCount").Set(5);

		wave_directions[0] = Normalized(Vec3f(1.0f, 0.0f, 1.0f));
		wave_dimensions[0] = Vec3f(5.0f, 1.5f, 1.2f);

		wave_directions[1] = Normalized(Vec3f(1.0f, 0.0f, 0.5f));
		wave_dimensions[1] = Vec3f(4.0f, 0.8f, 1.2f);

		wave_directions[2] = Normalized(Vec3f(1.0f, 0.0f, 0.1f));
		wave_dimensions[2] = Vec3f(2.0f, 0.5f, 2.4f);

		wave_directions[3] = Normalized(Vec3f(1.0f, 0.0f,-0.1f));
		wave_dimensions[3] = Vec3f(1.5f, 0.2f, 3.7f);

		wave_directions[4] = Normalized(Vec3f(1.0f, 0.0f, 0.4f));
		wave_dimensions[4] = Vec3f(1.1f, 0.2f, 4.7f);

		Texture::Active(0);
		{
			auto image = images::Squares(512, 512, 0.9f, 16, 16);
			auto bound_tex = Bind(env_map, Texture::Target::CubeMap);
			for(int i=0; i!=6; ++i)
				Texture::Image2D(Texture::CubeMapFace(i), image);
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::ClampToEdge);
			bound_tex.WrapT(TextureWrap::ClampToEdge);
			bound_tex.WrapR(TextureWrap::ClampToEdge);
			bound_tex.SwizzleG(TextureSwizzle::Red);
			bound_tex.SwizzleB(TextureSwizzle::Red);
		}
		UniformSampler(prog, "EnvMap").Set(0);

		gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
	}
Example #25
0
	CloudExample(void)
	 : projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	{
		// Set the vertex shader source

		vs.Source(
			"#version 330\n"
			"in vec4 Position;"
			"uniform mat4 CameraMatrix;"
			"void main(void)"
			"{"
			"	gl_Position = "
			"		CameraMatrix *"
			"		Position;"
			"}"
		);
		// compile it
		vs.Compile();

		// Set the geometry shader source
		gs.Source(
			"#version 330\n"
			"layout(points) in;"
			"layout(triangle_strip, max_vertices = 100) out;"
			"const int p = 25;"
			"const float hp = (p-1)*0.5;"
			"uniform vec3 LightPos;"
			"uniform mat4 CameraMatrix, ProjectionMatrix;"
			"out vec3 geomTexCoord;"
			"out vec3 geomLightDir;"
			"void main(void)"
			"{"
			"	float s = 0.6;"
			"	float yo[2] = float[2](-1.0, 1.0);"
			"	float xo[2] = float[2](-1.0, 1.0);"
			"	vec3 cx = vec3("
			"		CameraMatrix[0][0],"
			"		CameraMatrix[1][0],"
			"		CameraMatrix[2][0] "
			"	);"
			"	vec3 cy = vec3("
			"		CameraMatrix[0][1],"
			"		CameraMatrix[1][1],"
			"		CameraMatrix[2][1] "
			"	);"
			"	vec3 cz = vec3("
			"		CameraMatrix[0][2],"
			"		CameraMatrix[1][2],"
			"		CameraMatrix[2][2] "
			"	);"
			"	for(int k=0;k!=p;++k)"
			"	{"
			"		for(int j=0;j!=2;++j)"
			"		for(int i=0;i!=2;++i)"
			"		{"
			"			float zo = ((k - hp) / hp);"
			"			float xoffs = xo[i]*s;"
			"			float yoffs = yo[j]*s;"
			"			float zoffs = zo   *s;"
			"			vec4 v = vec4("
			"				gl_in[0].gl_Position.x+xoffs,"
			"				gl_in[0].gl_Position.y+yoffs,"
			"				gl_in[0].gl_Position.z+zoffs,"
			"				1.0"
			"			);"
			"			gl_Position = ProjectionMatrix * v;"
			"			geomLightDir = LightPos - v.xyz;"
			"			geomTexCoord = "
			"				vec3(0.5, 0.5, 0.5)+"
			"				cx*(xo[i])*0.707+"
			"				cy*(yo[j])*0.707+"
			"				cz*(zo   )*0.707;"
			"			EmitVertex();"
			"		}"
			"		EndPrimitive();"
			"	}"
			"}"
		);
		// compile it
		gs.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"uniform sampler3D cloudTex;"
			"in vec3 geomTexCoord;"
			"in vec3 geomLightDir;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float d = texture(cloudTex, geomTexCoord).r;"
			"	float o = 1.0;"
			"	float s = 2.0/128.0;"
			"	float r = s * 8.0;"
			"	vec3 sampleOffs = normalize(geomLightDir) * s;"
			"	vec3 samplePos = geomTexCoord;"
			"	if(d > 0.01) while(o > 0.0)"
			"	{"
			"		if(samplePos.x<0.0 || samplePos.x>1.0)"
			"			break;"
			"		if(samplePos.y<0.0 || samplePos.y>1.0)"
			"			break;"
			"		if(samplePos.z<0.0 || samplePos.z>1.0)"
			"			break;"
			"		o -= texture(cloudTex, samplePos).r*r;"
			"		samplePos += sampleOffs;"
			"	}"
			"	float a = 0.2 * d;"
			"	float i = mix(0.4, 1.0, o);"
			"	fragColor = vec4(i, i, i, a);"
			"}"
		);
		// 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 clouds
		clouds.Bind();

		// bind the VBO for the cloud positions
		buffer.Bind(Buffer::Target::Array);
		{
			GLfloat positions[3] = {0.5f, 0.1f, 0.2f};
			Buffer::Data(Buffer::Target::Array, 3, positions);
			VertexAttribArray attr(prog, "Position");
			attr.Setup(3, DataType::Float);
			attr.Enable();
		}

		{
			Texture::Active(0);
			UniformSampler(prog, "cloudTex").Set(0);
			auto bound_tex = Bind(cloud_tex, Texture::Target::_3D);
			bound_tex.Image3D(images::Cloud(128, 128, 128));
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.BorderColor(Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
			bound_tex.WrapS(TextureWrap::ClampToBorder);
			bound_tex.WrapT(TextureWrap::ClampToBorder);
			bound_tex.WrapR(TextureWrap::ClampToBorder);
		}

		Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(10.0f, 1.0f, 5.0f));

		gl.ClearColor(0.2f, 0.3f, 0.4f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::Blend);
		gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha);
	}
Example #26
0
    CloudExample(const ExampleParams& params)
        : sphere_instr(make_sphere.Instructions())
        , sphere_indices(make_sphere.Indices())
        , samples(25 + params.quality*params.quality*100)
        , positions(make_positions())
        , sizes(make_sizes())
        , cloud_tex(positions.size())
        , light_path(make_light_path_cps())
    {
        assert(positions.size() == sizes.size());
        std::srand(123456);

        light_vs.Source(
            "#version 330\n"
            "in vec3 Position;"
            "uniform vec3 LightPos;"
            "uniform mat4 CameraMatrix, ProjectionMatrix;"
            "void main(void)"
            "{"
            "	float s = 0.1;"
            "	gl_Position = "
            "		ProjectionMatrix*"
            "		CameraMatrix*"
            "		vec4(Position*s + LightPos, 1.0);"
            "}"
        ).Compile();

        light_fs.Source(
            "#version 330\n"
            "out vec4 fragLight;"
            "void main(void)"
            "{"
            "	fragLight = vec4(1.0, 1.0, 1.0, 1.0);"
            "}"
        ).Compile();

        light_prog << light_vs << light_fs;
        light_prog.Link().Use();

        light.Bind();

        buffer.Bind(Buffer::Target::Array);
        {
            std::vector<GLfloat> data;
            GLuint n_per_vertex = make_sphere.Positions(data);
            Buffer::Data(Buffer::Target::Array, data);
            (light_prog|"Position").Setup(n_per_vertex, DataType::Float).Enable();
        }

        cloud_vs.Source(
            "#version 330\n"
            "in vec4 Position;"
            "in float Size;"
            "uniform int SampleCount;"
            "uniform mat4 CameraMatrix;"
            "uniform vec4 ViewZ;"
            "out float vertZOffs;"
            "out float vertSize;"
            "void main(void)"
            "{"
            "	float hp = (SampleCount-1) * 0.5;"
            "	vertZOffs = (gl_InstanceID - hp)/hp;"
            "	vertSize = Size;"
            "	gl_Position = vec4("
            "		Position.xyz +"
            "		ViewZ.xyz*vertZOffs*Size*0.5,"
            "		1.0"
            "	);"
            "}"
        ).Compile();

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

        cloud_fs.Source(
            "#version 330\n"
            "uniform sampler3D CloudTex;"
            "in vec3 geomTexCoord;"
            "in vec3 geomLightDir;"
            "out vec4 fragColor;"
            "void main(void)"
            "{"
            "	float d = texture(CloudTex, geomTexCoord).r;"
            "	float o = 1.0;"
            "	float s = 2.0/128.0;"
            "	float r = s * 8.0;"
            "	vec3 sampleOffs = normalize(geomLightDir) * s;"
            "	vec3 samplePos = geomTexCoord;"
            "	if(d > 0.01) while(o > 0.0)"
            "	{"
            "		if(samplePos.x<0.0 || samplePos.x>1.0)"
            "			break;"
            "		if(samplePos.y<0.0 || samplePos.y>1.0)"
            "			break;"
            "		if(samplePos.z<0.0 || samplePos.z>1.0)"
            "			break;"
            "		o -= texture(CloudTex, samplePos).r*r;"
            "		samplePos += sampleOffs;"
            "	}"
            "	float a = 0.4 * d;"
            "	float i = mix(0.2, 1.0, o);"
            "	fragColor = vec4(i, i, i, a);"
            "}"
        ).Compile();

        cloud_prog << cloud_vs << cloud_gs << cloud_fs;
        cloud_prog.Link().Use();

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

        // bind the VBO for the cloud positions
        pos_buffer.Bind(Buffer::Target::Array);
        {
            Buffer::Data(Buffer::Target::Array, positions);
            (cloud_prog|"Position").Setup(3, DataType::Float).Enable();
        }

        // bind the VBO for the cloud sizes
        size_buffer.Bind(Buffer::Target::Array);
        {
            Buffer::Data(Buffer::Target::Array, sizes);
            (cloud_prog|"Size").Setup(1, DataType::Float).Enable();
        }

        // set the number of samples
        cloud_prog/"SampleCount" = GLint(samples);

        Texture::Active(0);
        cloud_prog/"CloudTex" = 0;
        for(std::size_t i=0, n=positions.size(); i!=n; ++i)
        {
            auto bound_tex = Bind(cloud_tex[i], Texture::Target::_3D);
            bound_tex.Image3D(
                images::Cloud(
                    128, 128, 128,
                    Vec3f(0.1f, -0.5f, 0.3f),
                    0.5f
                )
            );
            bound_tex.GenerateMipmap();
            bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
            bound_tex.MagFilter(TextureMagFilter::Linear);
            bound_tex.BorderColor(Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
            bound_tex.WrapS(TextureWrap::ClampToBorder);
            bound_tex.WrapT(TextureWrap::ClampToBorder);
            bound_tex.WrapR(TextureWrap::ClampToBorder);
        }

        gl.ClearColor(0.0f, 0.1f, 0.2f, 0.0f);
        gl.ClearDepth(1.0f);
        gl.Disable(Capability::DepthTest);
        gl.Enable(Capability::Blend);
        gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha);
    }
	MultiViewportExample(void)
	 : make_shape(1.0, 0.1, 8, 4, 48)
	 , shape_instr(make_shape.Instructions())
	 , shape_indices(make_shape.Indices())
	 , camera_position_3(prog, "CameraPosition[3]")
	 , camera_matrix_0(prog, "CameraMatrix[0]")
	 , camera_matrix_1(prog, "CameraMatrix[1]")
	 , camera_matrix_2(prog, "CameraMatrix[2]")
	 , camera_matrix_3(prog, "CameraMatrix[3]")
	 , model_matrix(prog, "ModelMatrix")
	{
		VertexShader vs;
		// Set the vertex shader source
		vs.Source(
			"#version 330\n"
			"uniform mat4 ModelMatrix;"
			"uniform vec3 LightPos;"

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

			"out vec3 vertNormal;"
			"out vec3 vertTexCoord;"
			"out vec3 vertLightDir;"
			"out vec3 vertLightRefl;"

			"void main(void)"
			"{"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	vertTexCoord = Normal;"
			"	gl_Position = ModelMatrix * Position;"
			"	vertLightDir = LightPos-gl_Position.xyz;"
			"	vertLightRefl = reflect(-vertLightDir, vertNormal);"
			"}"
		);
		vs.Compile();

		GeometryShader gs;
		// Set the geometry shader source
		gs.Source(
			"#version 330\n"
			"#extension GL_ARB_viewport_array : enable\n"
			"layout(triangles) in;"
			"layout(triangle_strip, max_vertices = 12) out;"

			"uniform mat4 CameraMatrix[4];"
			"uniform vec3 CameraPosition[4];"

			"in vec3 vertNormal[];"
			"in vec3 vertTexCoord[];"
			"in vec3 vertLightDir[];"
			"in vec3 vertLightRefl[];"

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

			"void main(void)"
			"{"
			"	for(int vp=0; vp!=4; ++vp)"
			"	{"
			"		gl_ViewportIndex = vp;"
			"		for(int v=0; v!=3; ++v)"
			"		{"
			"			geomNormal = vertNormal[v];"
			"			geomTexCoord = vertTexCoord[v];"
			"			geomLightDir = vertLightDir[v];"
			"			geomLightRefl = vertLightRefl[v];"
			"			geomViewDir = "
			"				CameraPosition[vp] - "
			"				gl_in[v].gl_Position.xyz;"
			"			geomViewRefl = reflect("
			"				-geomViewDir,"
			"				geomNormal"
			"			);"
			"			gl_Position = "
			"				CameraMatrix[vp] *"
			"				gl_in[v].gl_Position;"
			"			EmitVertex();"
			"		}"
			"		EndPrimitive();"
			"	}"
			"}"
		);
		gs.Compile();

		FragmentShader fs;
		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"uniform samplerCube TexUnit;"
			"in vec3 geomNormal;"
			"in vec3 geomTexCoord;"
			"in vec3 geomLightDir;"
			"in vec3 geomLightRefl;"
			"in vec3 geomViewDir;"
			"in vec3 geomViewRefl;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	float l = length(geomLightDir);"
			"	float d = dot("
			"		normalize(geomNormal), "
			"		normalize(geomLightDir)"
			"	) / l;"
			"	float s = dot("
			"		normalize(geomLightRefl),"
			"		normalize(geomViewDir)"
			"	);"
			"	vec3 lt = vec3(1.0, 1.0, 1.0);"
			"	vec3 tex = texture(TexUnit, geomTexCoord).rgb;"
			"	fragColor = vec4("
			"		tex * 0.4 + "
			"		(lt + tex) * 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(gs);
		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 = 512;
			auto image = images::NewtonFractal(
				tex_side, tex_side,
				Vec3f(0.8f, 0.8f, 1.0f),
				Vec3f(0.1f, 0.0f, 0.2f),
				Vec2f(-0.707f, -0.707f),
				Vec2f( 0.707f,  0.707f),
				images::NewtonFractal::X4Minus1(),
				[](double x) -> double
				{
					return pow(SineWave(pow(x,0.5)), 4.0);
				}
			);
			auto bound_tex = Bind(tex, Texture::Target::CubeMap);
			bound_tex.MinFilter(TextureMinFilter::Linear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.WrapS(TextureWrap::ClampToEdge);
			bound_tex.WrapT(TextureWrap::ClampToEdge);
			bound_tex.WrapR(TextureWrap::ClampToEdge);

			for(int i=0; i!=6; ++i)
				Texture::Image2D(Texture::CubeMapFace(i), image);
		}
		//
		UniformSampler(prog, "TexUnit").Set(0);
		Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(3.0f, 5.0f, 4.0f));
		//
		gl.ClearColor(0.1f, 0.05f, 0.2f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);

		gl.Enable(Capability::CullFace);
		gl.FrontFace(make_shape.FaceWinding());
		gl.CullFace(Face::Back);

		Uniform<Vec3f> camera_position(prog, "CameraPosition");
		camera_position[0].Set(Vec3f(2, 0, 0));
		camera_position[1].Set(Vec3f(0, 2, 0));
		camera_position[2].Set(Vec3f(0, 0, 2));
	}
	SmokeExample(void)
	 : emitters(
		{
			{
				{
					{-20.0f, -10.0f,  10.0f},
					{ 20.0f,   0.0f, -20.0f},
					{ 20.0f,  10.0f,  20.0f},
					{-20.0f,   0.0f, -10.0f}
				}, 15.0, 200.0
			},
			{
				{
					{ 30.0f,   0.0f,   5.0f},
					{-30.0f,   0.0f,  -5.0f},
					{-20.0f,  20.0f,   5.0f},
					{ 20.0f, -10.0f,  -5.0f}
				}, 17.0, 200.0
			},
		}
	), vs(ShaderType::Vertex, "Vertex")
	 , gs(ShaderType::Geometry, "Geometry")
	 , fs(ShaderType::Fragment, "Fragment")
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , light_cam_pos(prog, "LightCamPos")
	{
		// Set the vertex shader source
		vs.Source(
			"#version 330\n"
			"uniform mat4 CameraMatrix;"
			"in vec4 Position;"
			"in float Age;"
			"in int Id;"
			"out float vertAge;"
			"out int vertId;"
			"void main(void)"
			"{"
			"	gl_Position = CameraMatrix * Position;"
			"	vertAge = Age;"
			"	vertId = Id;"
			"}"
		);
		// 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 vec3 LightCamPos;"
			"uniform mat4 ProjectionMatrix;"
			"in float vertAge[];"
			"in int vertId[];"
			"out vec2 geomTexCoord;"
			"out float geomAge;"
			"out float geomLightVal;"
			"out float geomLightBias;"
			"void main(void)"
			"{"
			"	if(vertAge[0] > 1.0) return;"
			"	vec3 pos = gl_in[0].gl_Position.xyz;"
			"	vec3 lightDir = normalize(LightCamPos - pos);"
			"	float s = 0.8, g = 3.0;"
			"	float yo[2] = float[2](-1.0, 1.0);"
			"	float xo[2] = float[2](-1.0, 1.0);"
			"	float angle = vertId[0];"
			"	float cx = cos(angle), sx = sin(angle);"
			"	mat2 rot = mat2(cx, sx, -sx, cx);"
			"	for(int j=0;j!=2;++j)"
			"	for(int i=0;i!=2;++i)"
			"	{"
			"		float xoffs = xo[i]*(1.0+vertAge[0]*g)*s;"
			"		float yoffs = yo[j]*(1.0+vertAge[0]*g)*s;"
			"		vec2 offs = rot*vec2(xoffs, yoffs);"
			"		gl_Position = ProjectionMatrix * vec4("
			"			pos.x-offs.x,"
			"			pos.y-offs.y,"
			"			pos.z,"
			"			1.0"
			"		);"
			"		geomTexCoord = vec2(float(i), float(j));"
			"		geomAge = vertAge[0];"
			"		geomLightVal = lightDir.z;"
			"		geomLightBias = -dot("
			"			normalize(vec3(offs, 0.0)),"
			"			lightDir"
			"		);"
			"		EmitVertex();"
			"	}"
			"	EndPrimitive();"
			"}"
		);
		// compile it
		gs.Compile();

		// set the fragment shader source
		fs.Source(
			"#version 330\n"
			"uniform sampler2D SmokeTex;"
			"in vec2 geomTexCoord;"
			"in float geomAge;"
			"in float geomLightVal;"
			"in float geomLightBias;"
			"out vec4 fragColor;"
			"void main(void)"
			"{"
			"	vec3 c = texture(SmokeTex, geomTexCoord).rgb;"
			"	float depth = c.g - c.r;"
			"	if(depth == 0.0) discard;"
			"	float density = min(depth * c.b * 2.0, 1.0);"
			"	float intensity = min("
			"		max("
			"			geomLightVal*0.5+"
			"			geomLightBias,"
			"			0.0"
			"		)+max("
			"			-geomLightVal*"
			"			(1.0 - density)*"
			"			geomLightBias * 5.0,"
			"			0.0"
			"		),"
			"		1.0"
			"	) + 0.1;"
			"	fragColor = vec4("
			"		intensity,"
			"		intensity,"
			"		intensity,"
			"		(1.0 - geomAge)*density"
			"	);"
			"}"
		);
		// 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<Vec3f>();
			attr.Enable();
		}

		// 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<GLfloat>();
			attr.Enable();
		}

		// bind the VBO for the particle identifiers
		id_buf.Bind(Buffer::Target::Array);
		{
			Buffer::Data(Buffer::Target::Array, ids);
			VertexAttribArray attr(prog, "Id");
			attr.Setup<GLint>();
			attr.Enable();
		}

		Texture::Active(0);
		UniformSampler(prog, "SmokeTex").Set(0);
		{
			auto bound_tex = Bind(smoke_tex, Texture::Target::_2D);
			bound_tex.Image2D(
				images::Cloud2D(
					images::Cloud(
						128, 128, 128,
						Vec3f(0.1f, -0.5f, 0.3f),
						0.5f
					)
				)
			);
			bound_tex.GenerateMipmap();
			bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear);
			bound_tex.MagFilter(TextureMagFilter::Linear);
			bound_tex.BorderColor(Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
			bound_tex.WrapS(TextureWrap::ClampToBorder);
			bound_tex.WrapT(TextureWrap::ClampToBorder);
		}
		//
		gl.ClearColor(0.0f, 0.1f, 0.2f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::Blend);
		gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha);
	}
	CubeMapExample(void)
	 : make_shape(4)
	 , shape_instr(make_shape.Instructions())
	 , shape_indices(make_shape.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	{
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"out vec3 vertNormal;"
			"out vec3 vertTexCoord;"
			"out vec3 vertLightDir;"
			"out vec3 vertViewDir;"
			"uniform vec3 LightPos;"
			"void main(void)"
			"{"
			"	vec3 Normal = Position.xyz;"
			"	gl_Position = ModelMatrix * Position;"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	vertTexCoord = Normal;"
			"	vertLightDir = LightPos - gl_Position.xyz;"
			"	vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)*CameraMatrix).xyz;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		vs.Compile();

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

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

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

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

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

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

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

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

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

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

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

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

		gl.Enable(Capability::CullFace);
		gl.FrontFace(make_shape.FaceWinding());
		gl.CullFace(Face::Back);
	}
Example #30
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());
	}