public DepthPeeling(Mesh mesh) { gl.create_shader_program(null, meshVertexShader, meshFragmentShader, out scene_p_id); gl.create_shader_program(null, tex_v_shader, tex_f_shader, out tex_p_id); var aabb = mesh.GetAxisAlignedBoundingBox(); mesh.Translate(-aabb.Center); mesh.Transform(Matrix4X4.CreateRotation(new Vector3(23, 51, 12))); mesh.Transform(Matrix4X4.CreateScale(1 / Math.Max(aabb.XSize, Math.Max(aabb.YSize, aabb.ZSize)) / 2)); var screenQuad = new Mesh(); screenQuad.CreateFace(new Vector3[] { new Vector3(-1, -1, 0), new Vector3(1, -1, 0), new Vector3(1, 1, 0), new Vector3(-1, 1, 0) }); screenQuadVao = GLMeshVertexArrayObjectPlugin.Get(screenQuad); }
// Main display routine public void glutDisplayFunc(WorldView worldView, IObject3D item) { var mesh = item.Mesh; var meshVao = GLMeshVertexArrayObjectPlugin.Get(mesh); GL.PushAttrib(AttribMask.EnableBit | AttribMask.ViewportBit | AttribMask.TransformBit); // Projection and modelview matrices float near = 0.01f; float far = 20; var top = Math.Tan(35.0 / 360.0 * Math.PI) * near; var right = top * w / h; var proj = Matrix4X4.Frustum(-right, right, -top, top, near, far); // spin around var model = Matrix4X4.CreateRotationY(Math.PI / 180.0 * count++) * Matrix4X4.CreateTranslation(0, 0, -1.5); //proj = worldView.ProjectionMatrix; //model = worldView.ModelviewMatrix; gl.Enable(GL.DEPTH_TEST); gl.Viewport(0, 0, w, h); // select program and attach uniforms gl.UseProgram(scene_p_id); int proj_loc = gl.GetUniformLocation(scene_p_id, "proj"); gl.UniformMatrix4fv(proj_loc, 1, GL.FALSE, proj.GetAsFloatArray()); int model_loc = gl.GetUniformLocation(scene_p_id, "model"); gl.UniformMatrix4fv(model_loc, 1, GL.FALSE, model.GetAsFloatArray()); gl.Uniform1f(gl.GetUniformLocation(scene_p_id, "width"), w); gl.Uniform1f(gl.GetUniformLocation(scene_p_id, "height"), h); gl.BindVertexArray(meshVao.Vao); gl.Disable(GL.BLEND); for (int pass = 0; pass < renderPasses; pass++) { int first_pass = pass == 0 ? 1 : 0; gl.Uniform1i(gl.GetUniformLocation(scene_p_id, "first_pass"), first_pass); if (first_pass == 0) { gl.Uniform1i(gl.GetUniformLocation(scene_p_id, "depth_texture"), 0); gl.ActiveTexture(GL.TEXTURE0 + 0); GL.BindTexture(TextureTarget.Texture2D, depthTexture[pass - 1]); } gl.BindFramebuffer(GL.FRAMEBUFFER, frameBufferObject[pass]); gl.ClearColor(0.0, 0.4, 0.7, 0.0); gl.Clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT); gl.DrawElements(GL.TRIANGLES, mesh.Faces.Count * 3, GL.UNSIGNED_INT, IntPtr.Zero); } // clean up and set to render to screen gl.BindVertexArray(0); gl.BindFramebuffer(GL.FRAMEBUFFER, 0); gl.ActiveTexture(GL.TEXTURE0 + 0); GL.BindTexture(TextureTarget.Texture2D, 0); gl.ClearColor(0.0, 0.4, 0.7, 0.0); gl.Clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT); for (int pass = 0; pass < renderPasses; pass++) { RenderLayer(pass); } RenderFinal(); gl.DepthFunc(GL.LESS); GL.PopAttrib(); gl.BindVertexArray(0); GL.BindTexture(TextureTarget.Texture2D, 0); gl.UseProgram(0); }