void Render(double time) { gl.ClearDepth(0.0f); gl.Clear().DepthBuffer(); auto camera = CamMatrixf::Orbiting( objects.BoundingSphere().Center(), objects.BoundingSphere().Radius()*2.8, FullCircles(time / 19.0), Degrees(SineWave(time / 17.0) * 90) ); depth_prog.Use(); gl.DepthFunc(CompareFn::Greater); gl.CullFace(Face::Front); depth_prog.camera_matrix.Set(camera); depth_prog.model_matrix.Set(Mat4f()); objects.Draw(); Texture::CopyImage2D( Texture::Target::Rectangle, 0, PixelDataInternalFormat::DepthComponent, 0, 0, width, height, 0 ); gl.ClearDepth(1.0f); gl.Clear().ColorBuffer().DepthBuffer(); draw_prog.Use(); gl.DepthFunc(CompareFn::Less); gl.CullFace(Face::Back); draw_prog.camera_matrix.Set(camera); draw_prog.model_matrix.Set(Mat4f()); objects.Draw(); }
TorusExample(void) : make_torus(1.0, 0.5, 18, 36) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , transf_prog(make_transf_prog()) , face_prog(make_face_prog()) , frame_prog(make_frame_prog()) , projection_matrix(transf_prog, "ProjectionMatrix") , camera_matrix(transf_prog, "CameraMatrix") , model_matrix(transf_prog, "ModelMatrix") , transf_time(transf_prog, "Time") { transf_prog.Use(); torus.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(transf_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(transf_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(transf_prog, "TexCoord"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } face_pp.Bind(); face_prog.Use(); face_pp.UseStages(transf_prog).Vertex().Geometry(); face_pp.UseStages(face_prog).Fragment(); frame_pp.Bind(); frame_prog.Use(); frame_pp.UseStages(transf_prog).Vertex().Geometry(); frame_pp.UseStages(frame_prog).Fragment(); gl.Bind(NoProgramPipeline()); gl.Use(NoProgram()); gl.ClearColor(0.7f, 0.6f, 0.5f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.DepthFunc(CompareFn::Less); gl.FrontFace(make_torus.FaceWinding()); }
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); }
TorusExample(void) : make_torus(1.0, 0.5, 18, 36) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , vs(ObjectDesc("Vertex")) , gs(ObjectDesc("Geometry")) , face_fs(ObjectDesc("Face fragment")) , frame_fs(ObjectDesc("Frame fragment")) , transf_prog(ObjectDesc("Transformation")) , face_prog(ObjectDesc("Face")) , frame_prog(ObjectDesc("Frame")) , projection_matrix(transf_prog, "ProjectionMatrix") , camera_matrix(transf_prog, "CameraMatrix") , model_matrix(transf_prog, "ModelMatrix") , transf_time(transf_prog, "Time") { vs.Source( "#version 330\n" "uniform mat4 ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out gl_PerVertex {" " vec4 gl_Position;" "};" "out vec3 vertNormal;" "out vec2 vertTexCoord;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = (ModelMatrix*vec4(Normal,0.0)).xyz;" " vertTexCoord = TexCoord;" "}" ); vs.Compile(); gs.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 15) out;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 LightPos;" "uniform float Time;" "in gl_PerVertex {" " vec4 gl_Position;" "} gl_in[];" "in vec3 vertNormal[];" "in vec2 vertTexCoord[];" "out gl_PerVertex {" " vec4 gl_Position;" "};" "out vec3 geomNormal;" "out vec3 geomLight;" "out float geomGlow;" "flat out int geomTop;" "void main(void)" "{" " vec3 FaceNormal = normalize(" " vertNormal[0]+" " vertNormal[1]+" " vertNormal[2] " " );" " vec2 FaceCoord = 0.33333 * (" " vertTexCoord[0]+" " vertTexCoord[1]+" " vertTexCoord[2] " " );" " float Offs = (sin((FaceCoord.s + Time/10.0)* 3.14 * 2.0 * 10)*0.5 + 0.5)*0.4;" " Offs *= cos(FaceCoord.t * 3.1415 * 2.0)*0.5 + 0.51;" " vec3 pos[3], norm[3];" " for(int i=0; i!=3; ++i)" " pos[i] = gl_in[i].gl_Position.xyz;" " for(int i=0; i!=3; ++i)" " norm[i] = cross(" " FaceNormal, " " normalize(pos[(i+1)%3] - pos[i])" " );" " vec3 pofs = FaceNormal * Offs;" " geomTop = 0;" " for(int i=0; i!=3; ++i)" " {" " geomNormal = norm[i];" " for(int j=0; j!=2; ++j)" " {" " vec3 tpos = pos[(i+j)%3];" " geomLight = LightPos-tpos;" " geomGlow = 1.0;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(tpos, 1.0);" " EmitVertex();" " geomGlow = 0.7;" " geomLight = LightPos-tpos+pofs;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(tpos + pofs, 1.0);" " EmitVertex();" " }" " EndPrimitive();" " }" " geomGlow = 0.0;" " geomTop = 1;" " for(int i=0; i!=3; ++i)" " {" " geomLight = LightPos - (pos[i]+pofs);" " geomNormal = vertNormal[i];" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " vec4(pos[i] + pofs, 1.0);" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); transf_prog.AttachShader(vs); transf_prog.AttachShader(gs); transf_prog.MakeSeparable(); transf_prog.Link(); transf_prog.Use(); ProgramUniform<Vec3f>(transf_prog, "LightPos").Set(4, 4, -8); torus.Bind(); 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(transf_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_torus.Normals(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(transf_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_torus.TexCoordinates(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(transf_prog, "TexCoord"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } face_fs.Source( "#version 330\n" "in vec3 geomNormal;" "in vec3 geomLight;" "in float geomGlow;" "flat in int geomTop;" "uniform vec3 TopColor, SideColor;" "const vec3 LightColor = vec3(1.0, 1.0, 1.0);" "out vec4 fragColor;" "void main(void)" "{" " float d = max(dot(" " normalize(geomLight)," " normalize(geomNormal)" " ), 0.0);" " vec3 color;" " if(geomTop != 0)" " {" " color = TopColor * d +" " LightColor * pow(d, 8.0);" " }" " else" " {" " color = SideColor * geomGlow +" " LightColor *" " pow(d, 2.0) * 0.2;" " }" " fragColor = vec4(color, 1.0);" "}" ); face_fs.Compile(); face_prog.AttachShader(face_fs); face_prog.MakeSeparable(); face_prog.Link(); ProgramUniform<Vec3f>(face_prog, "TopColor").Set(0.2f, 0.2f, 0.2f); ProgramUniform<Vec3f>(face_prog, "SideColor").Set(0.9f, 0.9f, 0.2f); face_pp.Bind(); face_prog.Use(); face_pp.UseStages(transf_prog).Vertex().Geometry(); face_pp.UseStages(face_prog).Fragment(); frame_fs.Source( "#version 330\n" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(0.2, 0.1, 0.0, 1.0);" "}" ); frame_fs.Compile(); frame_prog.AttachShader(frame_fs); frame_prog.MakeSeparable(); frame_prog.Link(); frame_pp.Bind(); frame_prog.Use(); frame_pp.UseStages(transf_prog).Vertex().Geometry(); frame_pp.UseStages(frame_prog).Fragment(); ProgramPipeline::Unbind(); Program::UseNone(); gl.ClearColor(0.7f, 0.6f, 0.5f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.DepthFunc(CompareFn::Less); gl.FrontFace(make_torus.FaceWinding()); }
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); }
TorusExample(void) : make_torus(1.0, 0.5, 12, 12) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , light_pos_cam(prog, "LightPosCam") , front_color(prog, "FrontColor") , back_color(prog, "BackColor") { vs.Source( "#version 330\n" "uniform mat4 ModelMatrix, CameraMatrix;" "in vec4 Position;" "void main(void)" "{" " gl_Position = CameraMatrix *" " ModelMatrix * Position;" "}" ); vs.Compile(); gs.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 8) out;" "uniform mat4 ProjectionMatrix;" "uniform vec4 LightPosCam;" "out vec3 geomLightDir;" "out float geomOpacity;" "void main(void)" "{" " vec4 c = vec4((" " gl_in[0].gl_Position.xyz+" " gl_in[1].gl_Position.xyz+" " gl_in[2].gl_Position.xyz " " ) * 0.333333, 1.0);" " for(int v = 0; v != 4; ++v)" " {" " vec4 b = gl_in[v%3].gl_Position;" " vec4 a = vec4(" " b.xyz + (c.xyz - b.xyz)*0.3," " 1.0" " );" " gl_Position = ProjectionMatrix * a;" " geomLightDir = (LightPosCam - a).xyz;" " geomOpacity = 1.0;" " EmitVertex();" " gl_Position = ProjectionMatrix * b;" " geomLightDir = (LightPosCam - b).xyz;" " geomOpacity = 0.0;" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); fs.Source( "#version 330\n" "in vec3 geomLightDir;" "in float geomOpacity;" "uniform vec3 FrontColor, BackColor;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(geomLightDir);" " vec3 color = gl_FrontFacing?" " FrontColor:" " BackColor;" " fragColor = vec4(color*(4.0/l), geomOpacity);" "}" ); fs.Compile(); prog.AttachShader(vs); prog.AttachShader(gs); prog.AttachShader(fs); prog.Link(); torus.Bind(); verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); Buffer::Data(Buffer::Target::Array, data); prog.Use(); VertexAttribArray attr(prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } gl.ClearColor(0.8f, 0.7f, 0.6f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.DepthFunc(CompareFn::LEqual); gl.FrontFace(make_torus.FaceWinding()); }