LightRayExample(void)
	 : gl()
	 , mesh_loader(
		mesh_input.stream,
		shapes::ObjMesh::LoadingOptions(false).Normals()
	), meshes(List("Position")("Normal").Get(), mesh_loader)
	 , fan_index(mesh_loader.GetMeshIndex("Fan"))
	 , light_position(0.0, 0.0, -100.0)
	 , vert_shader()
	 , mask_prog(vert_shader)
	 , mask_vao(meshes.VAOForProgram(mask_prog))
	 , draw_prog(vert_shader)
	 , draw_vao(meshes.VAOForProgram(draw_prog))
	 , shadow_tex_unit(0)
	 , light_tex_unit(1)
	{
		mesh_input.stream.close();

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

		RenderShadowMap(512);

		SetupLightMask();

		mask_prog.Use();
		mask_prog.light_position.Set(light_position);

		draw_prog.Use();
		draw_prog.light_position.Set(light_position);

		gl.ClearColor(1.0f, 1.0f, 1.0f, 0.0f);
	}
	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);
	}
Exemple #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);
	}
Exemple #4
0
	CubeExample(void)
	 : n(16)
	 , screen_prog()
	 , draw_prog()
	 , screen(List("Position")("TexCoord").Get(), shapes::Screen(), screen_prog)
	 , cube(List("Position").Get(), shapes::Cube(), draw_prog)
	{

		draw_prog.Use();

		UniformBlock(draw_prog, "OffsetBlock").Binding(0);
		cube_pos<< BufferIndexedTarget::Uniform << 0
			<< BufferUsage::StaticDraw
			<< OffsetData(n);

		ProgramUniformSampler(screen_prog, "Palette").Set(0);
		Texture::Active(0);
		palette	<< Texture::Target::_1D
			<< TextureFilter::Nearest
			<< TextureWrap::ClampToEdge
			<< images::LinearGradient(
				16,
				Vec3f(0, 0, 0),
				std::map<GLfloat, Vec3f>({
					{  0.0/16.0, Vec3f(0.0, 0.0, 0.0)},
					{  1.0/16.0, Vec3f(0.5, 0.0, 1.0)},
					{  3.0/16.0, Vec3f(0.0, 0.0, 1.0)},
					{  6.0/16.0, Vec3f(0.0, 0.6, 0.6)},
					{  8.0/16.0, Vec3f(0.0, 1.0, 0.0)},
					{ 11.0/16.0, Vec3f(0.6, 0.6, 0.0)},
					{ 13.0/16.0, Vec3f(1.0, 0.1, 0.0)},
					{ 16.0/16.0, Vec3f(0.7, 0.0, 0.0)}
				})
			);

		ProgramUniformSampler(screen_prog, "Tex").Set(1);
		Texture::Active(1);
		tex	<< Texture::Target::Rectangle
			<< TextureMinFilter::Nearest
			<< TextureMagFilter::Nearest
			<< TextureWrap::ClampToEdge
			<< images::ImageSpec(
				64, 64,
				Format::Red,
				InternalFormat::R8,
				DataType::UnsignedByte
			);

		rbo	<< Renderbuffer::Target::Renderbuffer
			<< images::ImageSpec(64, 64, InternalFormat::DepthComponent);

		fbo	<< Framebuffer::Target::Draw
			<< FramebufferAttachment::Color << tex
			<< FramebufferAttachment::Depth << rbo
			<< FramebufferComplete();

		gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::CullFace);
	}
	CubeExample(void)
	 : gl()
	 , prog()
	 , field(
		images::FlipImageAxes<GLubyte, 1>(
			images::LoadTexture("suzanne_vol"),
			0, 2,-1
		),
		prog
	), shadowmaps(
		images::LoadTexture("oglcraft_ao"),
		prog
	)
	{
		gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);

		gl.Enable(Capability::CullFace);
		gl.FrontFace(FaceOrientation::CCW);
		gl.CullFace(Face::Back);

		prog.Use();
		field.Use();
	}
Exemple #6
0
    BlobExample(const ExampleParams& params)
      : blob_prog()
      , metal_prog()
      , grid(blob_prog, params.quality)
      , plane(metal_prog) {
        std::srand(234);
        for(GLuint i = 0; i != 24; ++i) {
            GLuint j = 0, n = 3 + std::rand() % 3;
            std::vector<Vec4f> points(n);
            GLfloat ball_size = 0.15f * std::rand() / GLfloat(RAND_MAX) + 0.25f;

            while(j != n) {
                points[j] = Vec4f(
                  1.2f * std::rand() / GLfloat(RAND_MAX) - 0.6f,
                  1.2f * std::rand() / GLfloat(RAND_MAX) - 0.6f,
                  1.2f * std::rand() / GLfloat(RAND_MAX) - 0.6f,
                  ball_size);
                ++j;
            }
            ball_paths.push_back(CubicBezierLoop<Vec4f, double>(points));
        }
        //
        Texture::Active(1);
        blob_prog.metaballs.Set(1);
        gl.Bound(Texture::Target::_1D, metaballs_tex)
          .Filter(TextureFilter::Nearest)
          .Wrap(TextureWrap::ClampToEdge)
          .Image1D(
            0,
            PixelDataInternalFormat::RGBA32F,
            ball_paths.size(),
            0,
            PixelDataFormat::RGBA,
            PixelDataType::Float,
            nullptr);

        Texture::Active(2);
        metal_prog.metal_tex.Set(2);
        gl.Bound(Texture::Target::_2D, metal_tex)
          .MinFilter(TextureMinFilter::LinearMipmapLinear)
          .MagFilter(TextureMagFilter::Linear)
          .Wrap(TextureWrap::Repeat)
          .Image2D(images::BrushedMetalUByte(512, 512, 5120, -3, +3, 32, 128))
          .GenerateMipmap();

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

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

        gl.Enable(Capability::CullFace);
        gl.FrontFace(FaceOrientation::CW);
        gl.CullFace(Face::Back);
    }
Exemple #7
0
	SphereExample(void)
	 : vs(make_vs())
	 , proton(vs,make_fs(fs_proton()))
	 , neutron(vs,make_fs(fs_neutron()))
	 , electron(vs,make_fs(fs_electron()))
	{
		gl.ClearColor(0.3f, 0.3f, 0.3f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
	}
    ParallaxExample()
      : prog(make_prog())
      , 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)) {
        shape.UseInProgram(prog);

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

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

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

        gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f);
        gl.ClearDepth(1.0f);

        (Capability::DepthTest) << true;
        (Capability::CullFace) << false;

        (Functionality::ClipDistance | 0) << true;
        (Functionality::ClipDistance | 1) << true;
        (Functionality::ClipDistance | 2) << true;
    }
	SortingExample(void)
	 : gl()
	 , particles(4096)
	 , dist_proc(particles)
	 , sort_proc(particles)
	 , draw_proc(particles)
	{
		gl.ClearColor(0.3f, 0.3f, 0.3f, 0.0f);
		gl.Enable(Capability::DepthTest);
		gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha);
	}
Exemple #10
0
	SubsurfExample(void)
	 : gl()
	 , shape("stanford_dragon", data_prog)
	 , screen(List("Position").Get(), shapes::Screen(), draw_prog)
	 , data_buffer(draw_prog, 0, 800, 600)
	{
		gl.Enable(Capability::CullFace);
		gl.CullFace(Face::Back);
		gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		gl.ClearDepth(1.0f);
	}
    MorphingExample()
      : shape(point_prog)
      , status(0.0) {
        point_prog.color_1 = Vec3f(1.0f, 0.5f, 0.4f);
        point_prog.color_2 = Vec3f(1.0f, 0.8f, 0.7f);

        gl.ClearColor(0.2f, 0.2f, 0.2f, 0.0f);
        gl.ClearDepth(1.0f);
        gl.Enable(Capability::DepthTest);
        gl.Enable(Capability::ProgramPointSize);
        gl.Enable(Capability::Blend);
    }
	ShapeExample(void)
	 : vs(make_vs())
	 , sphere(vs,make_fs(fs_yb_strips(), "Y/B strips"))
	 , cubeX(vs, make_fs(fs_bw_checker(), "B/W checker"))
	 , cubeY(vs, make_fs(fs_br_circles(), "B/R circles"))
	 , cubeZ(vs, make_fs(fs_wg_spirals(), "W/G spirals"))
	 , torus(vs, make_fs(fs_wo_vstrips(), "W/O vstrips"))
	{
		gl.ClearColor(0.5f, 0.5f, 0.5f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
	}
Exemple #13
0
int main() {
	sf::ContextSettings set;
	set.antialiasingLevel = 8;
	sf::Window w(sf::VideoMode(700, 700), "ogl", sf::Style::Default, set);
	glewExperimental = true;
	glewInit();
	Context gl;
	gl.ClearColor(0.0, 0.0, 0.0, 1.0);
	gl.Enable(Capability::DepthTest);
	gl.Enable(Capability::CullFace);
	gl.Enable(Capability::Blend);
	w.setMouseCursorVisible(false);

	Pyramid pyramid { w };

	bool running = true;
	while(running) {
		sf::Event e;
		while(w.pollEvent(e)){
			if(e.type == sf::Event::Closed){ running = false; }
			if(e.type == sf::Event::KeyPressed) {
				switch(e.key.code) {
				case sf::Keyboard::Escape:
					running = false;
					break;
				case sf::Keyboard::W: case sf::Keyboard::Up:
					camera.forward();
					break;
				case sf::Keyboard::A: case sf::Keyboard::Left:
					camera.left();
					break;
				case sf::Keyboard::S: case sf::Keyboard::Down:
					camera.back();
					break;
				case sf::Keyboard::D: case sf::Keyboard::Right:
					camera.right();
					break;
				default:
					break;
				}
				}
			if(e.type == sf::Event::MouseMoved) {
					//idk
			}
		}

		pyramid.update();
		pyramid.draw(gl);
		gl.Clear().ColorBuffer().DepthBuffer();
		w.display();
	}
	return 0;
}
Exemple #14
0
	CubeExample(void)
	{
		scene.AddShape(shapes::Cage());
		scene.AddShape(shapes::WickerTorus(1.0, 0.5, 0.02, 12, 12));
		scene.AddShape(shapes::SpiralSphere());
		scene.AddShape(shapes::TwistedTorus(0.9, 0.5, 0.02, 8, 48, 7));
		scene.AddShape(shapes::Icosahedron());

		gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
	}
    ParallaxMapExample()
      : prog(make())
      , projection_matrix(prog, "ProjectionMatrix")
      , camera_matrix(prog, "CameraMatrix")
      , model_matrix(prog, "ModelMatrix")
      , camera_position(prog, "CameraPosition")
      , light_position(prog, "LightPosition")
      , shape(
          List("Position")("Normal")("Tangent")("TexCoord").Get(),
          shapes::Torus(1.0f, 0.5, 72, 48)) {
        shape.UseInProgram(prog);

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

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

        Texture::Active(1);
        try {
            UniformSampler(prog, "BumpMap").Set(1);
            gl.Bound(Texture::Target::_2D, bump_tex)
              .MinFilter(TextureMinFilter::LinearMipmapLinear)
              .MagFilter(TextureMagFilter::Linear)
              .WrapS(TextureWrap::Repeat)
              .WrapT(TextureWrap::Repeat)
              .Image2D(
                images::NormalMap(tex_image, images::NormalMap::FromAlpha()))
              .GenerateMipmap();
        } 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);
    }
	ObjMeshExample(void)
	 : gl()
	 , objects(load_objects())
	 , depth_prog()
	 , draw_prog()
	 , depth_vao(objects.VAOForProgram(depth_prog))
	 , draw_vao(objects.VAOForProgram(draw_prog))
	{
		UniformSampler(draw_prog, "DepthTex").Set(0);
		Texture::Active(0);
		depth_tex.Bind(Texture::Target::Rectangle);

		gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
	}
Exemple #17
0
	RainExample(void)
	 : env_map(0)
	 , ripples(1)
	 , water_prog()
	 , water(water_prog, shapes::Plane(Vec3f(40,0,0), Vec3f(0,0,-40)))
	{
		water_prog.light_position.Set(2.0, 10.0, -4.0);

		water_prog.ripple_tex.Set(ripples.TexUnit());
		water_prog.env_tex.Set(env_map.TexUnit());


		gl.ClearColor(0.4f, 0.4f, 0.4f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
	}
	void Use(void)
	{
		gl.ClearDepth(1.0f);
		gl.ClearColor(0.8f, 0.8f, 0.8f, 0.0f);

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

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

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

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

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

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

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

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

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

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

		// bind the VBO for the torus UV-coordinates
		texcoords.Bind(Buffer::Target::Array);
		{
			std::vector<GLfloat> data;
			GLuint n_per_vertex = make_torus.TexCoordinates(data);
			// upload the data
			Buffer::Data(Buffer::Target::Array, data);
			// setup the vertex attribs array for the vertices
			VertexArrayAttrib attr(prog, "TexCoord");
			attr.Setup<GLfloat>(n_per_vertex);
			attr.Enable();
		}
		//
		gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.FrontFace(make_torus.FaceWinding());
		gl.Enable(Capability::DepthTest);
		gl.Enable(Functionality::ClipDistance, 0);
	}
void GIDeferredRenderer::Render()
{
    using namespace oglplus;
    static Context gl;
    static auto &camera = Camera::Active();
    static auto &scene = Scene::Active();
    static auto &info = Window().Info();

    if (!camera || !scene || !scene->IsLoaded() || VoxelizerRenderer::ShowVoxels)
    {
        return;
    }

    SetAsActive();
    // bind g buffer for writing
    geometryBuffer.Bind(FramebufferTarget::Draw);
    gl.ColorMask(true, true, true, true);
    gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    gl.Viewport(info.framebufferWidth, info.framebufferHeight);
    gl.Clear().ColorBuffer().DepthBuffer();
    // activate geometry pass shader program
    CurrentProgram<GeometryProgram>(GeometryPass());
    // rendering and GL flags
    gl.ClearDepth(1.0f);
    gl.Enable(Capability::DepthTest);
    gl.Disable(Capability::Blend);
    gl.Enable(Capability::CullFace);
    gl.FrontFace(FaceOrientation::CCW);
    gl.CullFace(Face::Back);
    camera->DoFrustumCulling(true);
    // draw whole scene tree from root node
    scene->rootNode->DrawList();
    // start light pass
    DefaultFramebuffer().Bind(FramebufferTarget::Draw);
    gl.ColorMask(true, true, true, true);
    gl.Viewport(info.framebufferWidth, info.framebufferHeight);
    gl.Clear().ColorBuffer().DepthBuffer();
    CurrentProgram<LightingProgram>(LightingPass());
    // pass light info and texture locations for final light pass
    SetLightPassUniforms();
    // draw the result onto a fullscreen quad
    fsQuad.DrawElements();
}
Exemple #22
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);
	}
Exemple #23
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()
			);

			gl.Bound(Texture::Target::_2D, cube_tex)
				.Image2D(image)
				.GenerateMipmap()
				.BorderColor(Vec4f(0.8f, 0.8f, 1.0f, 1.0f))
				.MinFilter(TextureMinFilter::LinearMipmapLinear)
				.MagFilter(TextureMagFilter::Linear)
				.WrapS(TextureWrap::Repeat)
				.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);
	}
	TorusExample(void)
	 : make_torus(1.0, 0.5, 72, 48)
	 , torus_instr(make_torus.Instructions())
	 , torus_indices(make_torus.Indices())
	 , projection_matrix(prog, "ProjectionMatrix")
	 , camera_matrix(prog, "CameraMatrix")
	 , model_matrix(prog, "ModelMatrix")
	{
		// Set the vertex shader source and compile it
		vs.Source(
			"#version 330\n"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"in vec4 Position;"
			"in vec3 Normal;"
			"out vec3 vertNormal;"
			"void main(void)"
			"{"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	gl_Position = "
			"		ProjectionMatrix *"
			"		CameraMatrix *"
			"		ModelMatrix *"
			"		Position;"
			"}"
		).Compile();

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

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

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

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

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

		gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
		gl.Enable(Capability::CullFace);
		gl.FrontFace(make_torus.FaceWinding());
		gl.CullFace(Face::Back);
		glLineWidth(4.0f);
	}
	HaloExample(void)
	 : make_shape()
	 , shape_indices(make_shape.Indices())
	 , shape_instr(make_shape.Instructions())
	 , vs_shape(ObjectDesc("Shape VS"))
	 , vs_plane(ObjectDesc("Plane VS"))
	 , fs_shape(ObjectDesc("Shape FS"))
	 , fs_plane(ObjectDesc("Plane FS"))
	 , vs_halo(ObjectDesc("Halo VS"))
	 , gs_halo(ObjectDesc("Halo GS"))
	 , fs_halo(ObjectDesc("Halo FS"))
	 , shape_projection_matrix(shape_prog, "ProjectionMatrix")
	 , shape_camera_matrix(shape_prog, "CameraMatrix")
	 , shape_model_matrix(shape_prog, "ModelMatrix")
	 , plane_projection_matrix(plane_prog, "ProjectionMatrix")
	 , plane_camera_matrix(plane_prog, "CameraMatrix")
	 , halo_projection_matrix(halo_prog, "ProjectionMatrix")
	 , halo_camera_matrix(halo_prog, "CameraMatrix")
	 , halo_model_matrix(halo_prog, "ModelMatrix")
	{
		vs_shape.Source(
			"#version 140\n"
			"in vec4 Position;"
			"in vec3 Normal;"
			"uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
			"uniform vec3 LightPos;"
			"out vec3 vertNormal;"
			"out vec3 vertViewNormal;"
			"out vec3 vertLight;"
			"void main(void)"
			"{"
			"	gl_Position = ModelMatrix * Position;"
			"	vertNormal = mat3(ModelMatrix)*Normal;"
			"	vertViewNormal = mat3(CameraMatrix)*vertNormal;"
			"	vertLight = LightPos - gl_Position.xyz;"
			"	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
			"}"
		);
		vs_shape.Compile();

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

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

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

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

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

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

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

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

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

			"out float geomAlpha;"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			"in vec3 vertNormal[];"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			"in vec4 Position;"

			"out vec3 vertColor;"

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

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

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

			"in vec3 vertColor[3];"

			"out vec3 geomColor;"

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

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

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

			"in vec3 geomColor;"

			"out vec3 fragColor;"

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

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

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

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

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

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

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

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

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

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

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

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

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

		diameter.Set(hole_diameter);

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

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

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

		gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.Enable(Capability::DepthTest);
	}
void ShadowMapRenderer::Render()
{
    using namespace oglplus;
    static Context gl;
    static Scene * scenePtr = nullptr;
    static auto &scene = Scene::Active();
    auto camera = Camera::Active().get();

    if (!camera || !scene || !scene->IsLoaded() || !shadowCaster)
    {
        return;
    }

    // initially assign invalid direction
    static auto &changes = Transform::TransformChangedMap();
    static bool updateShadowMap = true;

    // any node transformation happened
    for (auto &c : changes)
    {
        auto &type = typeid(*c.first);

        if (type == typeid(Node))
        {
            updateShadowMap = true; break;
        }
    }

    // shadow caster change
    if (shadowCaster->TransformChanged()) { updateShadowMap = true; }

    // scene change
    if (scenePtr != scene.get())
    {
        scenePtr = scene.get();
        updateShadowMap = true;
    }

    if (!updateShadowMap) { return; }

    updateShadowMap = false;
    // update shadow map
    SetAsActive();
    lightView.SetAsActive();
    shadowFramebuffer.Bind(FramebufferTarget::Draw);
    gl.Viewport(0, 0, shadowMapSize.x, shadowMapSize.y);
    gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    gl.Clear().DepthBuffer().ColorBuffer();
    // activate geometry pass shader program
    auto &prog = DepthShader();
    CurrentProgram<DepthProgram>(prog);
    // rendering flags
    gl.Disable(Capability::Blend);
    gl.Enable(Capability::DepthTest);
    gl.Disable(Capability::CullFace);
    // unneded since directional light cover the whole scene
    // can be useful for view frustum aware light frustum later
    lightView.DoFrustumCulling(false);
    // scene spatial cues
    auto sceneBB = scene->rootNode->boundaries;
    auto &center = sceneBB.Center();
    auto radius = distance(center, sceneBB.MaxPoint());
    // fix light frustum to fit scene bounding sphere
    lightView.OrthoRect(glm::vec4(-radius, radius, -radius, radius));
    lightView.ClipPlaneNear(-radius);
    lightView.ClipPlaneFar(2.0f * radius);
    lightView.Projection(Camera::ProjectionMode::Orthographic);
    lightView.transform.Position(center + shadowCaster->Direction() * radius);
    lightView.transform.Forward(-shadowCaster->Direction());
    // update lightview matrix
    LightSpaceMatrix();
    // uniforms
    prog.exponents.Set(exponents);
    // draw whole scene tree from root node
    scene->rootNode->DrawList();
    // recover original render camera
    camera->SetAsActive();

    // blur the result evsm map
    if(blurScale > 0)
    {
        BlurShadowMap();
    }

    // recover
    DefaultFramebuffer().Bind(FramebufferTarget::Draw);

    // no trilinear filtering
    if (filtering < 2) return;

    // mip map shadow map
    shadowMap.Bind(TextureTarget::_2D);
    shadowMap.GenerateMipmap(TextureTarget::_2D);
}