void RenderOffscreen(double time) { fbo.Bind(); gl.Clear().ColorBuffer().DepthBuffer(); gl.BlendFunc(BlendFn::One, BlendFn::One); gl.Enable(Capability::Blend); gl.Enable(Capability::DepthTest); draw_prog.Use(); draw_prog.camera_matrix.Set( CamMatrixf::Orbiting( Vec3f(), 27.0, Degrees(time * 23), Degrees(SineWave(time / 23.0) * 80) ) ); cube.Use(); cube.Draw(n*n*n); gl.Disable(Capability::DepthTest); gl.Disable(Capability::Blend); fbo.Unbind(); }
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); }
SmokeExample(void) : emitters() , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") { emitters.push_back( ParticleSystem( ListOf<Vec3f> (Vec3f(-20.0f, -10.0f, 10.0f)) (Vec3f( 20.0f, 0.0f, -20.0f)) (Vec3f( 20.0f, 10.0f, 20.0f)) (Vec3f(-20.0f, 0.0f, -10.0f)) .As<std::vector<Vec3f>>(), 5.0, 200.0 ) ); emitters.push_back( ParticleSystem( ListOf<Vec3f> (Vec3f( 30.0f, 0.0f, 0.0f)) (Vec3f(-30.0f, 0.0f, 0.0f)) (Vec3f(-20.0f, 20.0f, 0.0f)) (Vec3f( 20.0f, -10.0f, 0.0f)) .As<std::vector<Vec3f>>(), 3.0, 200.0 ) ); emitters.push_back( ParticleSystem( ListOf<Vec3f> (Vec3f( 5.0f, 20.0f, 20.0f)) (Vec3f( -5.0f, 20.0f, -20.0f)) (Vec3f( 5.0f, -20.0f, -20.0f)) (Vec3f( -5.0f, -20.0f, 20.0f)) .As<std::vector<Vec3f>>(), 20.0, 100.0 ) ); // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 CameraMatrix;" "in vec4 Position;" "in float Age;" "out float vertAge;" "void main(void)" "{" " gl_Position = CameraMatrix * Position;" " vertAge = Age;" "}" ); // compile it vs.Compile(); // Set the geometry shader source gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "uniform mat4 ProjectionMatrix;" "in float vertAge[];" "out float geomAge;" "void main(void)" "{" " if(vertAge[0] > 1.0) return;" " float s = 0.5;" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " float xoffs = xo[i]*(1.0+vertAge[0])*s;" " float yoffs = yo[j]*(1.0+vertAge[0])*s;" " gl_Position = ProjectionMatrix * vec4(" " gl_in[0].gl_Position.x-xoffs," " gl_in[0].gl_Position.y-yoffs," " gl_in[0].gl_Position.z," " 1.0" " );" " geomAge = vertAge[0];" " EmitVertex();" " }" " EndPrimitive();" "}" ); // compile it gs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "in float geomAge;" "out vec4 fragColor;" "void main(void)" "{" " vec3 Color1 = vec3(1.0, 0.5, 0.5);" " vec3 Color2 = vec3(0.3, 0.1, 0.1);" " fragColor = vec4(" " mix(Color1, Color2, geomAge)," " 1.0 - geomAge" " );" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(gs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the particles particles.Bind(); // bind the VBO for the particle positions pos_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, positions, BufferUsage::DynamicDraw); VertexAttribArray attr(prog, "Position"); attr.Setup(3, DataType::Float); attr.Enable(); } // bind the VBO for the particle ages age_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, ages, BufferUsage::DynamicDraw); VertexAttribArray attr(prog, "Age"); attr.Setup(1, DataType::Float); attr.Enable(); } // gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
GlassAndMetalExample(void) : transf_prog() , metal_prog() , plane(transf_prog, shapes::Plane(Vec3f(9, 0, 0), Vec3f(0, 0,-9))) , torus(transf_prog, shapes::WickerTorus()) , shadow_tex_side(1024) { NoProgram().Use(); shadow_pp.Bind(); shadow_pp.UseStages(transf_prog).Vertex(); shadow_pp.UseStages(shadow_prog).Fragment(); light_pp.Bind(); light_pp.UseStages(transf_prog).Vertex(); light_pp.UseStages(light_prog).Fragment(); glass_pp.Bind(); glass_pp.UseStages(transf_prog).Vertex(); glass_pp.UseStages(glass_prog).Fragment(); metal_pp.Bind(); metal_pp.UseStages(transf_prog).Vertex(); metal_pp.UseStages(metal_prog).Fragment(); Texture::Active(0); metal_prog.metal_tex.Set(0); gl.Bound(Texture::Target::_2D, metal_texture) .MinFilter(TextureMinFilter::LinearMipmapLinear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::Repeat) .WrapT(TextureWrap::Repeat) .Image2D( images::BrushedMetalUByte( 512, 512, 5120, -3, +3, 32, 128 ) ).GenerateMipmap(); Texture::Active(1); metal_prog.frame_shadow_tex.Set(1); glass_prog.frame_shadow_tex.Set(1); gl.Bound(Texture::Target::_2D, frame_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, frame_shadow_tex, 0 ); Texture::Active(2); metal_prog.glass_shadow_tex.Set(2); gl.Bound(Texture::Target::_2D, glass_shadow_tex) .MinFilter(TextureMinFilter::Linear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::ClampToEdge) .WrapT(TextureWrap::ClampToEdge) .Image2D( 0, PixelDataInternalFormat::RGBA, shadow_tex_side, shadow_tex_side, 0, PixelDataFormat::RGBA, PixelDataType::UnsignedByte, nullptr ); gl.Bound(Framebuffer::Target::Draw, glass_shadow_fbo) .AttachTexture( FramebufferAttachment::Color, glass_shadow_tex, 0 ); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); gl.PolygonOffset(1.0, 1.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); }
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); }
TorusExample(void) : make_torus(1.0, 0.5, 36, 24) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , make_plane(make_plane_builders()) , plane_instr(make_plane[0].Instructions()) , plane_indices(make_plane[0].Indices()) , torus_vs(ShaderType::Vertex, ObjectDesc("Torus vertex")) , plane_vs(ShaderType::Vertex, ObjectDesc("Plane vertex")) , torus_fs(ShaderType::Fragment, ObjectDesc("Torus fragment")) , plane_fs(ShaderType::Fragment, ObjectDesc("Plane fragment")) , torus_prog(ObjectDesc("Torus")) , plane_prog(ObjectDesc("Plane")) , plane_normal(plane_prog, "Normal") , plane_camera_matrix(plane_prog, "CameraMatrix") , torus_camera_matrix(torus_prog, "CameraMatrix") , torus_model_matrix(torus_prog, "ModelMatrix") , plane(make_plane.size()) , plane_positions(make_plane.size()) { std::stringstream plane_count_def; plane_count_def <<"#define PlaneCount "<<plane.size()<<'\n'; const GLchar* torus_vs_source[3] = { "#version 330\n", plane_count_def.str().c_str(), "uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;" "uniform float ClipSign[PlaneCount];" "uniform vec4 ClipPlane[PlaneCount];" "in vec4 Position;" "in vec2 TexCoord;" "out vec2 vertTexCoord;" "void main(void)" "{" " vertTexCoord = TexCoord;" " gl_Position = " " ModelMatrix *" " Position;" " for(int p=0; p!=PlaneCount; ++p)" " {" " gl_ClipDistance[p] = " " ClipSign[p]* " " dot(ClipPlane[p], gl_Position);" " }" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " gl_Position;" "}" }; torus_vs.Source(torus_vs_source, 3); torus_vs.Compile(); torus_fs.Source( "#version 330\n" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float i = (" " int(vertTexCoord.x*36) % 2+" " int(vertTexCoord.y*24) % 2" " ) % 2;" " fragColor = vec4(1-i/2, 1-i/2, 1-i/2, 1.0);" "}" ); torus_fs.Compile(); torus_prog.AttachShader(torus_vs); torus_prog.AttachShader(torus_fs); torus_prog.Link(); torus_prog.Use(); // bind the VAO for the torus torus.Bind(); // bind the VBO for the torus vertices torus_positions.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray attr(torus_prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // bind the VBO for the torus UV-coordinates torus_texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.TexCoordinates(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray attr(torus_prog, "TexCoord"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } const GLchar* plane_vs_source[3] = { "#version 330\n", plane_count_def.str().c_str(), "uniform mat4 ProjectionMatrix, CameraMatrix;" "uniform float ClipSign[PlaneCount];" "uniform vec4 ClipPlane[PlaneCount];" "uniform vec3 Normal;" "in vec4 Position;" "out vec3 vertColor;" "void main(void)" "{" " gl_Position = Position;" " for(int p=0; p!=PlaneCount; ++p)" " {" " gl_ClipDistance[p] = " " ClipSign[p]* " " dot(ClipPlane[p], gl_Position);" " }" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " gl_Position;" " vertColor = normalize(" " abs(Normal) + " " 0.4*Position.xyz" " );" "}" }; plane_vs.Source(plane_vs_source, 3); plane_vs.Compile(); plane_fs.Source( "#version 330\n" "in vec3 vertColor;" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(vertColor, 0.7);" "}" ); plane_fs.Compile(); plane_prog.AttachShader(plane_vs); plane_prog.AttachShader(plane_fs); plane_prog.Link(); plane_prog.Use(); ProgramUniform<Vec4f> torus_clip_plane(torus_prog, "ClipPlane"); ProgramUniform<Vec4f> plane_clip_plane(plane_prog, "ClipPlane"); ProgramUniform<GLfloat> torus_clip_sign(torus_prog, "ClipSign"); ProgramUniform<GLfloat> plane_clip_sign(plane_prog, "ClipSign"); for(std::size_t p=0; p!=plane.size(); ++p) { plane[p].Bind(); plane_positions[p].Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n = make_plane[p].Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(plane_prog, "Position"); attr.Setup(n, DataType::Float); attr.Enable(); } { auto eq = make_plane[p].Equation(); torus_clip_plane[p].Set(eq); plane_clip_plane[p].Set(eq); } { torus_clip_signs.push_back(torus_clip_sign[p]); plane_clip_signs.push_back(plane_clip_sign[p]); } } // gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f); gl.ClearDepth(1.0f); gl.FrontFace(make_torus.FaceWinding()); gl.Enable(Capability::DepthTest); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
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()); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , front_facing(prog, "FrontFacing") , inst_count(32) { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec3 LightPos;" "uniform int InstCount;" "uniform int FrontFacing;" "in vec4 Position;" "in vec3 Normal;" "out float vertMult;" "out vec3 vertColor;" "out vec3 vertWrapNormal;" "out vec3 vertNormal;" "out vec3 vertLight;" "void main(void)" "{" " int inst = (FrontFacing != 0) ? " " (InstCount - gl_InstanceID - 1):" " gl_InstanceID;" " vertMult = float(inst) / float(InstCount-1);" " float sca = 1.0 - 0.3 * pow(vertMult, 2);" " mat4 ScaleMatrix = mat4(" " sca, 0.0, 0.0, 0.0," " 0.0, sca, 0.0, 0.0," " 0.0, 0.0, sca, 0.0," " 0.0, 0.0, 0.0, 1.0 " " );" " gl_Position = ModelMatrix * Position;" " vertColor = Normal;" " vec3 wrap = Position.xyz - Normal;" " vertWrapNormal = " " mat3(ModelMatrix)*" " normalize(mix(" " Normal," " wrap," " mix(0.5, 1.0, vertMult)" " ));" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLight = LightPos-gl_Position.xyz;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " ScaleMatrix *" " gl_Position;" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "in float vertMult;" "in vec3 vertColor;" "in vec3 vertWrapNormal;" "in vec3 vertNormal;" "in vec3 vertLight;" "out vec4 fragColor;" "uniform int InstCount;" "void main(void)" "{" " float l = dot(vertLight, vertLight);" " float d = l > 0.0 ? dot(" " vertNormal, " " normalize(vertLight)" " ) / l : 0.0;" " float s = max(" " dot(vertWrapNormal, vertLight)/l," " 0.0" " );" " float intensity = clamp(" " 0.2 + d * 3.0 + s * 5.5," " 0.0," " 1.0" " );" " fragColor = vec4(" " abs(vertColor) * intensity," " (2.5 + 1.5*d + 1.5*s) / InstCount" " );" "}" ); // 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 VertexArrayAttrib attr(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); // upload the data Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // the light position Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(-3.0f, -2.0f, -3.0f)); // and the instance count Uniform<GLint>(prog, "InstCount").Set(inst_count); // gl.ClearColor(0.5f, 0.6f, 0.5f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_cube.FaceWinding()); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
GraphExample(void) : prog() , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , node_count(512) , edge_count(0) , cam_path(make_cam_path_cps()) , tgt_path(make_tgt_path_cps()) { std::srand(std::time(0)); // Vertex shader VertexShader vs; // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix;" "in vec4 Position;" "void main(void)" "{" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " Position;" " gl_PointSize = 4.0 * gl_Position.w / gl_Position.z;" "}" ); // compile it vs.Compile(); // Fragment shader FragmentShader fs; // set the fragment shader source fs.Source( "#version 330\n" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(0.0, 0.0, 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 graph.Bind(); std::vector<GLfloat> positions(node_count * 3); // bind the VBO for the cube vertices verts.Bind(Buffer::Target::Array); { GLuint k = 0; for(GLuint p=0; p!=node_count; ++p) { positions[k++] = nrand() *120.0; positions[k++] = nrand() * 5.0; positions[k++] = nrand() *120.0; } assert(k == positions.size()); // upload the data Buffer::Data(Buffer::Target::Array, positions); // setup the vertex attribs array for the vertices VertexAttribArray vert_attr(prog, "Position"); vert_attr.Setup(3, DataType::Float).Enable(); } // bind the VBO for cube edge indices edges.Bind(Buffer::Target::ElementArray); { std::vector<GLuint> edge_data; edge_data.reserve(node_count * 6); for(GLuint i=0; i!=node_count; ++i) { Vec3f pi( positions[i*3+0], positions[i*3+1], positions[i*3+2] ); float min_dist = 1000.0f; GLuint m = i; for(GLuint j=i+1; j!=node_count; ++j) { Vec3f pj( positions[j*3+0], positions[j*3+1], positions[j*3+2] ); float dist = Distance(pi, pj); if(min_dist > 1.0 && min_dist > dist) { min_dist = dist; m = j; } } min_dist *= 2.0f; GLuint done = 0; for(GLuint j=i+1; j!=node_count; ++j) { Vec3f pj( positions[j*3+0], positions[j*3+1], positions[j*3+2] ); float dist = Distance(pi, pj); if(min_dist > dist) { float x = dist/min_dist; if(std::pow(nrand(), 2.0) >= x) { edge_data.push_back(i); edge_data.push_back(j); ++done; } } } if(done == 0) { if(i != m) { edge_data.push_back(i); edge_data.push_back(m); } } } Buffer::Data(Buffer::Target::ElementArray, edge_data); assert(edge_data.size() % 2 == 0); edge_count = edge_data.size(); positions.clear(); } // gl.ClearColor(0.9f, 0.9f, 0.8f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::LineSmooth); gl.Enable(Capability::ProgramPointSize); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
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); }
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); }
VolLightExample(void) : volume_vs(ShaderType::Vertex, ObjectDesc("Volume vertex")) , plane_vs(ShaderType::Vertex, ObjectDesc("Plane vertex")) , volume_gs(ShaderType::Geometry, ObjectDesc("Volume geometry")) , volume_fs(ShaderType::Fragment, ObjectDesc("Volume fragment")) , plane_fs(ShaderType::Fragment, ObjectDesc("Plane fragment")) , volume_prog(ObjectDesc("Volume")) , plane_prog(ObjectDesc("Plane")) , samples(150) { volume_vs.Source( "#version 330\n" "in vec4 Position;" "out float vertZOffs;" "uniform int SampleCount;" "uniform mat4 CameraMatrix;" "uniform vec3 ViewZ;" "uniform float Size;" "void main(void)" "{" " float hp = (SampleCount-1) * 0.5;" " vertZOffs = (gl_InstanceID - hp)/hp;" " gl_Position = vec4(" " Position.xyz +" " ViewZ*vertZOffs*Size*0.5," " 1.0" " );" "}" ); volume_vs.Compile(); volume_gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform mat4 TexProjectionMatrix;" "uniform vec3 ViewX, ViewY;" "uniform float Size;" "in float vertZOffs[];" "out vec4 geomTexCoord;" "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)" " {" " vec4 v = vec4(" " gl_in[0].gl_Position.xyz+" " ViewX * xo[i] * Size+" " ViewY * yo[j] * Size," " 1.0" " );" " geomTexCoord = " " TexProjectionMatrix *" " v;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix * v;" " EmitVertex();" " }" " EndPrimitive();" "}" ); volume_gs.Compile(); volume_fs.Source( "#version 330\n" "uniform sampler2D LightTex;" "uniform int SampleCount;" "in vec4 geomTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " vec2 coord = geomTexCoord.st/geomTexCoord.q;" " float depth = geomTexCoord.z;" " if(depth < 0.0) discard;" " vec4 t = texture(LightTex, coord*0.5 + 0.5);" " if(t.a == 0.0) discard;" " float alpha = 10.0*(1.0-t.a)/SampleCount;" " alpha *= (t.r+t.g+t.b)*0.3333;" " alpha /= sqrt(depth);" " fragColor = vec4(t.rgb, alpha);" "}" ); volume_fs.Compile(); volume_prog.AttachShader(volume_vs); volume_prog.AttachShader(volume_gs); volume_prog.AttachShader(volume_fs); volume_prog.Link(); volume_prog.Use(); // bind the VAO for the volumes volume.Bind(); // bind the VBO for the volume positions volume_pos.Bind(Buffer::Target::Array); { GLfloat position[3] = {0.0, 0.0, 0.0}; Buffer::Data(Buffer::Target::Array, 3, position); VertexArrayAttrib attr(volume_prog, "Position"); attr.Setup<Vec3f>(); attr.Enable(); } Vec3f lightPos(2.0f, 4.0f, -3.0f); auto texProjMat = CamMatrixf::PerspectiveX(Degrees(30), 1.0, 0.3, 20.0) * CamMatrixf::LookingAt(lightPos, Vec3f(0, 0, 0)); Uniform<GLint>(volume_prog, "SampleCount").Set(samples); Uniform<GLfloat>(volume_prog, "Size").Set(Length(lightPos)); Uniform<Mat4f>(volume_prog, "TexProjectionMatrix").Set(texProjMat); plane_vs.Source( "#version 330\n" "in vec4 Position;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform mat4 TexProjectionMatrix;" "out vec2 vertChecker;" "out vec4 vertTexCoord;" "void main(void)" "{" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " Position;" " vertTexCoord = " " TexProjectionMatrix *" " Position;" " vertChecker = Position.xz;" "}" ); plane_vs.Compile(); plane_fs.Source( "#version 330\n" "uniform sampler2D LightTex;" "in vec4 vertTexCoord;" "in vec2 vertChecker;" "out vec4 fragColor;" "void main(void)" "{" " vec2 coord = vertTexCoord.st/vertTexCoord.q;" " vec4 t = texture(LightTex, coord*0.5 + 0.5);" " float i = (" " 1 +" " int(vertChecker.x+10) % 2+" " int(vertChecker.y+10) % 2" " ) % 2;" " vec3 color = vec3(0.1, 0.1, 0.1);" " color += t.rgb * (1.0 - t.a);" " color *= mix(" " vec3(0.9, 0.9, 1.0), " " vec3(0.4, 0.4, 0.9), " " i" " );" " fragColor = vec4(color, 1.0);" "}" ); plane_fs.Compile(); plane_prog.AttachShader(plane_vs); plane_prog.AttachShader(plane_fs); plane_prog.Link(); plane_prog.Use(); Uniform<Mat4f>(plane_prog, "TexProjectionMatrix").Set(texProjMat); plane.Bind(); // bind the VBO for the plane vertices plane_pos.Bind(Buffer::Target::Array); { GLfloat data[4*3] = { -9.0f, -4.0f, 9.0f, -9.0f, -4.0f, -9.0f, 9.0f, -4.0f, 9.0f, 9.0f, -4.0f, -9.0f }; Buffer::Data(Buffer::Target::Array, 4*3, data); plane_prog.Use(); VertexArrayAttrib attr(plane_prog, "Position"); attr.Setup<Vec3f>(); attr.Enable(); } Texture::Active(0); ProgramUniformSampler(volume_prog, "LightTex").Set(0); light_tex << Texture::Target::_2D << TextureMinFilter::LinearMipmapLinear << TextureMagFilter::Linear << TextureWrap::ClampToBorder << Vec4f(0.0f, 0.0f, 0.0f, 0.0f) << images::LoadTexture("flower_glass") << TextureMipmap(); gl.ClearColor(0.0f, 0.05f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::One); }
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); }
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); }
FlareExample(void) : shape(shape_prog, shapes::SpiralSphere()) , n_flares(32) , queries(n_flares) { std::vector<Vec3f> light_positions(n_flares); for(GLuint i=0; i!=n_flares; ++i) { const float rand_max = float(RAND_MAX); auto angle = FullCircles(std::rand()/rand_max); light_positions[i] = Vec3f( 7.0f*Cos(angle), 0.2f*(std::rand()/rand_max)-0.1f, 7.0f*Sin(angle) ); } shape_prog.light_position.Set(light_positions); shape_prog.color_1 = Vec3f(0.3f, 0.3f, 0.5f); shape_prog.color_2 = Vec3f(0.8f, 0.8f, 1.0f); Texture::Active(0); shape_prog.metal_tex.Set(0); metal_texture << TextureTarget::_2D << TextureMinFilter::LinearMipmapLinear << TextureMagFilter::Linear << TextureWrap::Repeat << images::BrushedMetalUByte( 512, 512, 5120, -12, +12, 32, 64 ) << TextureMipmap(); Texture::Active(1); UniformSampler(flare_prog, "FlareTex").Set(1); flare_texture << TextureTarget::_2D << TextureMinFilter::LinearMipmapLinear << TextureMagFilter::Linear << images::LoadTexture("flare_1") << TextureMipmap(); (TextureTarget::_2D|0) << TextureWrap::MirroredRepeat; (TextureTarget::_2D|1) << TextureWrap::Repeat; lights.Bind(); try { light_pos.Bind(Buffer::Target::Array); Buffer::Data(Buffer::Target::Array, light_positions); light_prog.Use(); VertexArrayAttrib light_attr(light_prog, "Position"); light_attr.Setup<Vec3f>(); light_attr.Enable(); flare_prog.Use(); VertexArrayAttrib flare_attr(flare_prog, "Position"); flare_attr.Setup<Vec3f>(); flare_attr.Enable(); } catch(Error&) { } gl.ClearColor(0.1f, 0.1f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::ProgramPointSize); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.CullFace(Face::Back); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::One); }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , prog(make_prog()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") { // bind the VAO for the cube gl.Bind(cube); gl.Bind(Buffer::Target::Array, verts); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } gl.Bind(Buffer::Target::Array, normals); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } gl.Bind(Buffer::Target::Array, texcoords); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // setup the texture gl.Bound(Texture::Target::_2D, tex) .Image2D(images::LoadTexture("honeycomb")) .GenerateMipmap() .MinFilter(TextureMinFilter::LinearMipmapLinear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::MirroredRepeat) .WrapT(TextureWrap::MirroredRepeat) .Anisotropy(2); // 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()); }
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); }
ParticlesExample(void) : projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , particle_count(100) , prev_time(0.0) , prev_spawn(0.0) { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ModelMatrix, CameraMatrix;" "in vec4 Position;" "in float Age;" "out float vertAge;" "void main(void)" "{" " gl_Position = " " CameraMatrix *" " ModelMatrix *" " Position;" " vertAge = Age;" "}" ); // compile it vs.Compile(); // Set the geometry shader source gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "uniform mat4 ProjectionMatrix;" "in float vertAge[];" "out float geomAge;" "void main(void)" "{" " float s = 0.5;" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " float xoffs = xo[i]*(1.0+vertAge[0])*s;" " float yoffs = yo[j]*(1.0+vertAge[0])*s;" " gl_Position = ProjectionMatrix * vec4(" " gl_in[0].gl_Position.x-xoffs," " gl_in[0].gl_Position.y-yoffs," " gl_in[0].gl_Position.z," " 1.0" " );" " geomAge = vertAge[0];" " EmitVertex();" " }" " EndPrimitive();" "}" ); // compile it gs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "in float geomAge;" "out vec4 fragColor;" "void main(void)" "{" " vec3 Color1 = vec3(1.0, 0.5, 0.5);" " vec3 Color2 = vec3(0.3, 0.1, 0.1);" " fragColor = vec4(" " mix(Color1, Color2, geomAge)," " 1.0 - geomAge" " );" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(gs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the particles particles.Bind(); // bind the VBO for the particle positions pos_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, positions); VertexAttribArray attr(prog, "Position"); attr.Setup(3, DataType::Float); attr.Enable(); } positions.reserve(particle_count); directions.reserve(particle_count); // bind the VBO for the particle ages age_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, ages); VertexAttribArray attr(prog, "Age"); attr.Setup(1, DataType::Float); attr.Enable(); } ages.reserve(particle_count); Uniform<Mat4f>(prog, "ModelMatrix").Set( ModelMatrixf::Translation(0.0f, -10.0f, 0.0f) ); // gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }