void Render(double time) { namespace se = oglplus::smart_enums; gl.Clear().ColorBuffer().DepthBuffer().StencilBuffer(); // make the camera matrix orbiting around the origin // at radius of 3.5 with elevation between 15 and 90 degrees Mat4f camera = CamMatrixf::Orbiting( Vec3f(), 6.5, Degrees(time * 135), Degrees(15 + (-SineWave(0.25+time/12.5)+1.0)*0.5*75) ); ModelMatrixf model = ModelMatrixf::Translation(0.0f, 1.5f, 0.0); ModelMatrixf identity; // SetProgramUniform(prog_norm, "CameraMatrix", camera); SetProgramUniform(prog_refl, "CameraMatrix", camera); // draw the plane into the stencil buffer prog_norm.Use(); gl.Disable(se::Blend()); gl.Disable(se::DepthTest()); gl.Enable(se::StencilTest()); gl.ColorMask(false, false, false, false); gl.StencilFunc(se::Always(), 1, 1); gl.StencilOp(se::Keep(), se::Keep(), se::Replace()); Uniform<Mat4f> model_matrix_norm(prog_norm, "ModelMatrix"); model_matrix_norm.Set(identity); plane.Bind(); gl.DrawArrays(se::TriangleStrip(), 0, 4); gl.ColorMask(true, true, true, true); gl.Enable(se::DepthTest()); gl.StencilFunc(se::Equal(), 1, 1); gl.StencilOp(se::Keep(), se::Keep(), se::Keep()); // draw the torus using the reflection program prog_refl.Use(); Uniform<Mat4f>(prog_refl, "ModelMatrix").Set(model); torus.Bind(); torus_instr.Draw(torus_indices); gl.Disable(se::StencilTest()); prog_norm.Use(); // draw the torus using the normal object program model_matrix_norm.Set(model); torus_instr.Draw(torus_indices); // blend-in the plane gl.Enable(se::Blend()); gl.BlendEquation(se::Max()); model_matrix_norm.Set(identity); plane.Bind(); gl.DrawArrays(se::TriangleStrip(), 0, 4); }
void Reshape(GLuint width, GLuint height) { gl.Viewport(width, height); Mat4f perspective = CamMatrixf::PerspectiveX( Degrees(65), double(width)/height, 1, 40 ); SetProgramUniform(cloud_prog, "ProjectionMatrix", perspective); SetProgramUniform(light_prog, "ProjectionMatrix", perspective); }
void Reshape(GLuint width, GLuint height) { gl.Viewport(width, height); Mat4f projection = CamMatrixf::PerspectiveX( Degrees(65), double(width)/height, 1, 40 ); SetProgramUniform(prog_norm, "ProjectionMatrix", projection); SetProgramUniform(prog_refl, "ProjectionMatrix", projection); }
void Reshape(GLuint width, GLuint height) { gl.Viewport(width, height); Mat4f projection = CamMatrixf::PerspectiveX( Degrees(70), double(width)/height, 1, 30 ); SetProgramUniform(object_prog, "ProjectionMatrix", projection); SetProgramUniform(shadow_prog, "ProjectionMatrix", projection); }
void Reshape(GLuint vp_width, GLuint vp_height) { width = vp_width; height = vp_height; Mat4f proj = CamMatrixf::PerspectiveX( Degrees(60), double(width)/height, 1, 60 ); SetProgramUniform(shape_prog, "ProjectionMatrix", proj); SetProgramUniform(light_prog, "ProjectionMatrix", proj); }
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 330\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 330\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 330\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 330\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 330\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 330\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 330\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(VertexAttribArray::QueryCommonLocation( "Position", location ).In(shape_prog).And(halo_prog)) { VertexAttribArray attr(location); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } else assert(!"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(); VertexAttribArray 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(); VertexAttribArray 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(); VertexAttribArray attr(plane_prog, "Normal"); attr.Setup<Vec3f>(); attr.Enable(); } Vec3f lightPos(2.0f, 2.5f, 9.0f); SetProgramUniform(shape_prog, "LightPos", lightPos); SetProgramUniform(plane_prog, "LightPos", 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); }
void Render(double time) { // // the camera matrix Mat4f camera = CamMatrixf::Orbiting( Vec3f(), 6.5 + SineWave(time / 16.0) * 1.5, FullCircles(time / 12.0), Degrees(SineWave(time / 30.0) * 90) ); // // the model matrix Mat4f model = ModelMatrixf::RotationA( Vec3f(1.0f, 1.0f, 1.0f), FullCircles(time / 10.0) ); // the light position Vec3f lightPos(0.0f, SineWave(time / 7.0) * 0.5, 0.0f); // SetProgramUniform(shape_prog, "LightPos", lightPos); SetProgramUniform(depth_prog, "LightPos", lightPos); SetProgramUniform(light_prog, "LightPos", lightPos); // SetProgramUniform(shape_prog, "CameraMatrix", camera); SetProgramUniform(light_prog, "CameraMatrix", camera); SetProgramUniform(shape_prog, "ModelMatrix", model); SetProgramUniform(depth_prog, "ModelMatrix", model); // render the shadow map depth_fbo.Bind(Framebuffer::Target::Draw); gl.DrawBuffer(ColorBuffer::None); gl.Viewport(tex_side, tex_side); gl.Clear().DepthBuffer(); depth_prog.Use(); shape.Bind(); shape_instr.Draw(shape_indices); // render the output frame Framebuffer::BindDefault(Framebuffer::Target::Draw); gl.DrawBuffer(ColorBuffer::Back); gl.Viewport(width, height); gl.Clear().ColorBuffer().DepthBuffer(); shape_prog.Use(); shape.Bind(); shape_instr.Draw(shape_indices); gl.Enable(Capability::Blend); light_prog.Use(); SetUniform(light_prog, "ViewX", camera.Row(0).xyz()); SetUniform(light_prog, "ViewY", camera.Row(1).xyz()); SetUniform(light_prog, "ViewZ", camera.Row(2).xyz()); light.Bind(); gl.DrawArraysInstanced( PrimitiveType::Points, 0, 1, sample_count ); gl.Disable(Capability::Blend); }
ShadowExample(void) : make_torus(1.0, 0.7, 72, 48) , torus_indices(make_torus.Indices()) , torus_instr(make_torus.Instructions()) , object_camera_matrix(object_prog, "CameraMatrix") , object_model_matrix(object_prog, "ModelMatrix") , shadow_camera_matrix(shadow_prog, "CameraMatrix") , shadow_model_matrix(shadow_prog, "ModelMatrix") , object_color(object_prog, "Color") , object_light_mult(object_prog, "LightMult") { vs_object.Source( "#version 330\n" "in vec4 Position;" "in vec3 Normal;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec3 LightPos;" "out vec3 vertNormal;" "out vec3 vertLight;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLight = LightPos - gl_Position.xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); vs_object.Compile(); fs_object.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertLight;" "uniform vec3 Color;" "uniform float LightMult;" "out vec4 fragColor;" "void main(void)" "{" " float l = sqrt(length(vertLight));" " float d = l > 0.0 ?" " dot(" " vertNormal," " normalize(vertLight)" " ) / l : 0.0;" " float i = 0.3 + max(d, 0.0) * LightMult;" " fragColor = vec4(Color*i, 1.0);" "}" ); fs_object.Compile(); object_prog.AttachShader(vs_object); object_prog.AttachShader(fs_object); object_prog.Link(); vs_shadow.Source( "#version 330\n" "in vec4 Position;" "in vec3 Normal;" "uniform mat4 ModelMatrix;" "uniform vec3 LightPos;" "out float ld;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vec3 geomNormal = mat3(ModelMatrix)*Normal;" " vec3 lightDir = LightPos - gl_Position.xyz;" " ld = dot(geomNormal, normalize(lightDir));" "}" ); vs_shadow.Compile(); gs_shadow.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 12) out;" "in float ld[];" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 LightPos;" "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;" " if(ld[a] == 0.0 && ld[b] == 0.0)" " {" " px = pa;" " py = pb;" " }" " else if(ld[a] > 0.0 && ld[b] < 0.0)" " {" " float x = ld[a]/(ld[a]-ld[b]);" " float y;" " px = mix(pa, pb, x);" " if(ld[c] < 0.0)" " {" " y = ld[a]/(ld[a]-ld[c]);" " py = mix(pa, pc, y);" " }" " else" " {" " y = ld[c]/(ld[c]-ld[b]);" " py = mix(pc, pb, y);" " }" " }" " else continue;" " vec3 vx = px.xyz - LightPos;" " vec3 vy = py.xyz - LightPos;" " vec4 sx = vec4(px.xyz + vx*10.0, 1.0);" " vec4 sy = vec4(py.xyz + vy*10.0, 1.0);" " vec4 cpx = CameraMatrix * px;" " vec4 cpy = CameraMatrix * py;" " vec4 csx = CameraMatrix * sx;" " vec4 csy = CameraMatrix * sy;" " gl_Position = ProjectionMatrix * cpy;" " EmitVertex();" " gl_Position = ProjectionMatrix * cpx;" " EmitVertex();" " gl_Position = ProjectionMatrix * csy;" " EmitVertex();" " gl_Position = ProjectionMatrix * csx;" " EmitVertex();" " EndPrimitive();" " break;" " }" "}" ); gs_shadow.Compile(); fs_shadow.Source( "#version 330\n" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(0.0, 0.0, 0.0, 1.0);" "}" ); fs_shadow.Compile(); shadow_prog.AttachShader(vs_shadow); shadow_prog.AttachShader(gs_shadow); shadow_prog.AttachShader(fs_shadow); shadow_prog.Link(); // bind the VAO for the torus torus.Bind(); // bind the VBO for the torus vertices torus_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr( VertexAttribArray::GetCommonLocation( "Position", object_prog, shadow_prog ) ); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // bind the VBO for the torus normals torus_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); Buffer::Data(Buffer::Target::Array, data); object_prog.Use(); VertexAttribArray attr(object_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); object_prog.Use(); VertexAttribArray attr(object_prog, "Position"); attr.Setup<GLfloat>(3); attr.Enable(); } // bind the VBO for the torus 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); object_prog.Use(); VertexAttribArray attr(object_prog, "Normal"); attr.Setup<GLfloat>(3); attr.Enable(); } Vec3f lightPos(2.0f, 9.0f, 3.0f); SetProgramUniform(object_prog, "LightPos", lightPos); SetProgramUniform(shadow_prog, "LightPos", lightPos); gl.ClearColor(0.2f, 0.2f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.ClearStencil(0); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_torus.FaceWinding()); }