protected override void OnRenderFrame(FrameEventArgs e) { ++serial; GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); float z = 20.0f * (float)(System.Math.Sin(2.0f * Now)); camera.Frame.LocalToParent.Set( Matrix4.CreateLookAt( new Vector3(0.0f, 0.0f, z), // camera location new Vector3(0.0f, 0.0f, -100.0f), // aim point new Vector3(0.0f, 1.0f, 0.0f) // up vector ) ); camera.Frame.UpdateHierarchical(serial); camera.UpdateFrame(); camera.UpdateViewport(viewport); camera.UniformBufferGL.Sync(); int baseVertex = mesh.VertexBufferRange.BaseVertex; IBufferRange indexBufferRange = mesh.IndexBufferRange(MeshMode.PolygonFill); if (RenderStack.Graphics.Configuration.canUseInstancing) { // Instancing code path int i = 0; // index to models uniform block int j = 0; // index to material (changed for each draw call) for (int mi = 0; mi < modelCount; ++mi) { models.Floats("model_to_world_matrix").SetI( i, modelFrame[mi].LocalToWorld.Matrix ); i++; if ( (i == maxInstanceCount) || (mi == modelCount - 1) ) { models.Sync(); Materials[j].Use(); GL.DrawElementsInstanced( indexBufferRange.BeginMode, (int)(indexBufferRange.Count), indexBufferRange.DrawElementsTypeGL, (IntPtr)0, i ); i = 0; ++j; if (j == Materials.Length) { j = 0; } } } } else { int j = 0; // index to material (changed for each draw call) for (int i = 0; i < modelCount; ++i) { Materials[j].Use(); models.Floats("model_to_world_matrix").SetI( 0, modelFrame[i].LocalToWorld.Matrix ); models.Sync(); GL.DrawElements( indexBufferRange.BeginMode, (int)(indexBufferRange.Count), indexBufferRange.DrawElementsTypeGL, (IntPtr)0 ); ++j; if (j == Materials.Length) { j = 0; } } } SwapBuffers(); }
protected override void OnLoad(System.EventArgs e) { mesh = new GeometryMesh( new ColladaGeometry("cube.dae"), NormalStyle.CornerNormals ).GetMesh; viewport = new Viewport(base.Width, base.Height); modelFrame.LocalToParent.Set( Matrix4.CreateTranslation(0.0f, 0.0f, 0.0f) ); camera.Frame.LocalToParent.Set( Matrix4.CreateLookAt( new Vector3(0.0f, 0.0f, -4.0f), // camera location new Vector3(0.0f, 0.0f, 0.0f), // aim point new Vector3(0.0f, 1.0f, 0.0f) // up vector ) ); camera.FovYRadians = RenderStack.Math.Conversions.DegreesToRadians(60.0f); camera.ProjectionType = ProjectionType.PerspectiveVertical; program = new Program(vs, fs); attributeMappings.Add("_position", VertexUsage.Position, 0, 3); attributeMappings.Add("_normal", VertexUsage.Normal, 0, 3); program.AttributeMappings = attributeMappings; /* name in shader uniform */ UniformMappings.Add("_model_to_world_matrix", LogicalUniform.ModelToWorld); UniformMappings.Add("_world_to_model_matrix", LogicalUniform.WorldToModel); UniformMappings.Add("_model_to_clip_matrix", LogicalUniform.ModelToClip); UniformMappings.Add("_clip_to_model_matrix", LogicalUniform.ClipToModel); UniformMappings.Add("_world_to_clip_matrix", LogicalUniform.WorldToClip); UniformMappings.Add("_clip_to_world_matrix", LogicalUniform.ClipToWorld); UniformMappings.Add("_view_position_in_world", LogicalUniform.ViewPositionInWorld); /* type name in shader parameter name */ UniformMappings.Add <Floats>("_light_direction", "light_direction"); UniformMappings.Add <Floats>("_light_color", "light_color"); UniformMappings.Add <Floats>("_surface_color", "surface_color"); parameters["surface_color"] = new Floats(1.0f, 1.0f, 1.0f); parameters["light_direction"] = new Floats(0.0f, 1.0f, 0.0f); parameters["light_color"] = new Floats(1.0f, 1.0f, 1.0f); program.Bind(camera); program.Bind(parameters); // Setup initial GL state { // Since we only use one program, we don't // need to touch this after. program.Use(); program.ApplyUniforms(); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.CullFace); GL.ClearColor(0.5f, 0.5f, 0.5f, 1.0f); // Since we only use one mesh, we don't // need to change this after mesh.ApplyAttributes(program, meshMode); } Resize += new EventHandler <EventArgs>(Application_Resize); Unload += new EventHandler <EventArgs>(Application_Unload); }
private int modelCount; // How many models in scene protected override void OnLoad(System.EventArgs e) { // Check GL features RenderStack.Graphics.Configuration.Initialize(); if (RenderStack.Graphics.Configuration.glslVersion < 150) { throw new System.PlatformNotSupportedException("You need at least GL 3.2"); } AttributeMappings.Global.Add(0, "_position", VertexUsage.Position, 0, 3); AttributeMappings.Global.Add(1, "_normal", VertexUsage.Normal, 0, 3); // Build uniform blocks { System.Text.StringBuilder uniforms = new System.Text.StringBuilder(); CameraUniformBlock.NearFar = "near_far"; CameraUniformBlock.FovXFovYAspect = "fovx_fovy_aspect"; CameraUniformBlock.ViewToClip = "view_to_clip_matrix"; CameraUniformBlock.ClipToView = "view_to_clip_matrix"; CameraUniformBlock.WorldToClip = "world_to_clip_matrix"; CameraUniformBlock.ClipToWorld = "clip_to_world_matrix"; CameraUniformBlock.WorldToView = "world_to_view_matrix"; CameraUniformBlock.ViewToWorld = "view_to_world_matrix"; CameraUniformBlock.Viewport = "viewport"; CameraUniformBlock.ViewPositionInWorld = "view_position_in_world"; CameraUniformBlock.Initialize("camera"); uniforms.Append(CameraUniformBlock.UniformBlockGL.SourceGL); ModelsUB = new UniformBlockGL("models"); ModelsUB.AddMat4("model_to_world_matrix", maxInstanceCount); ModelsUB.Seal(); uniforms.Append(ModelsUB.SourceGL); GlobalUB = new UniformBlockGL("global"); GlobalUB.AddVec4("add_color"); GlobalUB.AddFloat("alpha"); GlobalUB.Seal(); uniforms.Append(GlobalUB.SourceGL); MaterialUB = new UniformBlockGL("material"); MaterialUB.AddVec4("surface_diffuse_reflectance_color"); MaterialUB.AddVec4("surface_specular_reflectance_color"); MaterialUB.AddFloat("surface_roughness"); MaterialUB.Seal(); uniforms.Append(MaterialUB.SourceGL); LightsUB = new UniformBlockGL("lights"); LightsUB.AddVec4("exposure"); LightsUB.AddVec4("color", lightCount); LightsUB.AddVec4("ambient_light_color"); LightsUB.AddVec4("direction", lightCount); LightsUB.AddMat4("world_to_shadow_matrix", lightCount); LightsUB.Seal(); uniforms.Append(LightsUB.SourceGL); ShaderGL3.Replace("UNIFORMS;", uniforms.ToString()); } // Models List <Vector2> positions = UniformPoissonDiskSampler.SampleCircle(Vector2.Zero, poissonRadius, poissonMinDistance); modelCount = positions.Count; System.Diagnostics.Debug.WriteLine("Model count: " + modelCount); modelFrame = new Frame[modelCount]; for (int i = 0; i < modelCount; ++i) { modelFrame[i] = new Frame(); modelFrame[i].LocalToParent.Set( Matrix4.CreateTranslation(positions[i].X, positions[i].Y, -40.0f) ); } // Setup geometry and mesh Geometry geometry = new Sphere(radius, 20, 8); //Matrix4 translate = Matrix4.CreateTranslation(0.0f, 0.0f, -4.0f); //geometry.Transform(translate); mesh = new GeometryMesh(geometry, NormalStyle.PointNormals).GetMesh; // \todo Get rid of this //mesh.VertexBufferRange.Buffer.VertexFormat.Seal(AttributeMappings.Global); // This is where we collect models transformations models = UniformBufferFactory.Create(ModelsUB); global = UniformBufferFactory.Create(GlobalUB); global.Floats("alpha").Set(1.0f); global.Floats("add_color").Set(0.0f, 0.0f, 0.4f); global.Sync(); // Setup lights lights = UniformBufferFactory.Create(LightsUB); lights.Floats("exposure").Set(1.0f); lights.Floats("ambient_light_color").Set(1.0f, 1.0f, 1.0f); for (int i = 0; i < lightCount; ++i) { lights.Floats("direction").SetI(i, 0.0f, 1.0f, 0.0f); lights.Floats("color").SetI(i, 1.0f, 1.0f, 1.0f, 1.0f / (float)lightCount); } lights.Sync(); global.Use(); models.Use(); lights.Use(); // Setup viewport and camera viewport = new Viewport(base.Width, base.Height); camera = new Camera(); camera.Projection.Near = 0.1f; camera.Projection.Far = 300.0f; camera.Frame.LocalToParent.Set( Matrix4.CreateLookAt( new Vector3(0.0f, 0.0f, 4.0f), // camera location new Vector3(0.0f, 0.0f, 0.0f), // aim point new Vector3(0.0f, 1.0f, 0.0f) // up vector ) ); camera.Projection.FovYRadians = RenderStack.Math.Conversions.DegreesToRadians(60.0f); camera.Projection.ProjectionType = ProjectionType.PerspectiveVertical; camera.UniformBufferGL.Use(); // Setup shader program program = (IProgram) new ProgramGL3(vs, fs); // Setup material for (int i = 0; i < Materials.Length; ++i) { var material = UniformBufferFactory.Create(MaterialUB); float h = (float)(i) / (float)(Materials.Length - 1); float r, g, b; Conversions.HSVtoRGB(360.0f * h, 1.0f, 1.0f, out r, out g, out b); float diffuse = 0.2f; float specular = 0.8f; float roughness = 0.1f; material.Floats("surface_diffuse_reflectance_color").Set(diffuse * r, diffuse * g, diffuse * b); material.Floats("surface_specular_reflectance_color").Set(specular * r, specular * r, specular * r); material.Floats("surface_roughness").Set(roughness); material.Sync(); Materials[i] = material; } // Update scene. There is no animation in this scene // so we only need to do it once. camera.Frame.UpdateHierarchical(serial); foreach (var frame in modelFrame) { frame.UpdateHierarchical(serial); } // Setup initial GL state { // Since we only use one program, we don't need to touch this after. camera.UpdateFrame(); camera.UpdateViewport(viewport); camera.UniformBufferGL.Sync(); // Bind program program.Use(0); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.CullFace); float gammaHalf = (float)Math.Pow(0.5, 1.0 / 2.2); GL.ClearColor(gammaHalf, gammaHalf, gammaHalf, 1.0f); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); SwapBuffers(); Visible = true; // Since we only use one mesh, we don't need to change this after SetupAttributeBindings(); // The mesh has not yet been uploaded to GL, do it now IBufferRange vertexBufferRange = mesh.VertexBufferRange; IBufferRange indexBufferRange = mesh.IndexBufferRange(MeshMode.PolygonFill); if (vertexBufferRange.NeedsUploadGL) { vertexBufferRange.UpdateGL(); } if (indexBufferRange.NeedsUploadGL) { indexBufferRange.UpdateGL(); } } Resize += new EventHandler <EventArgs>(Application_Resize); Unload += new EventHandler <EventArgs>(Application_Unload); }
protected override void OnLoad(System.EventArgs e) { // Check GL version and feature capabilities RenderStack.Graphics.Configuration.Initialize(); if (RenderStack.Graphics.Configuration.canUseFramebufferObject == false) { throw new System.PlatformNotSupportedException( "GL version 3.0 or GL_ARB_framebuffer_object extension is needed. Neither was found." ); } if (RenderStack.Graphics.Configuration.canUseBaseVertex == false) { throw new System.PlatformNotSupportedException( "GL version 3.2 or GL_ARB_draw_elements_base_vertex extension is needed. Neither was found." ); } sphereMesh = new GeometryMesh(new Sphere(2.00f, 20, 20), NormalStyle.PointNormals).GetMesh; quadMesh = new GeometryMesh(new QuadXY(1.0f, 1.0f, 0.0f), NormalStyle.PolygonNormals).GetMesh; // Initialize shared resources attributeMappings.Add("_position", VertexUsage.Position, 0, 3); attributeMappings.Add("_normal", VertexUsage.Normal, 0, 3); attributeMappings.Add("_texcoord", VertexUsage.TexCoord, 0, 2); UniformMappings.Add("_model_to_world_matrix", LogicalUniform.ModelToWorld); UniformMappings.Add("_world_to_model_matrix", LogicalUniform.WorldToModel); UniformMappings.Add("_model_to_clip_matrix", LogicalUniform.ModelToClip); UniformMappings.Add("_clip_to_model_matrix", LogicalUniform.ClipToModel); UniformMappings.Add("_world_to_clip_matrix", LogicalUniform.WorldToClip); UniformMappings.Add("_clip_to_world_matrix", LogicalUniform.ClipToWorld); UniformMappings.Add("_view_position_in_world", LogicalUniform.ViewPositionInWorld); UniformMappings.Add <Floats>("_light_direction", "light_direction"); UniformMappings.Add <Floats>("_light_color", "light_color"); UniformMappings.Add <Floats>("_surface_color", "surface_color"); UniformMappings.Add <Texture>("_texture", "texture"); UniformMappings.Add <Floats> ("_t", "t"); parameters["surface_color"] = new Floats(1.0f, 1.0f, 1.0f); parameters["light_direction"] = new Floats(0.0f, 1.0f, 0.0f); parameters["light_color"] = new Floats(1.0f, 1.0f, 1.0f); parameters["t"] = new Floats(0.5f); // Initialize resources used by the first pass (render to texture) framebuffer = new Framebuffer(128, 128); framebuffer.AttachTexture(FramebufferAttachment.ColorAttachment0, PixelFormat.Rgb, PixelInternalFormat.Rgb8); framebuffer.AttachRenderBuffer(FramebufferAttachment.DepthAttachment, PixelFormat.DepthComponent, RenderbufferStorage.DepthComponent32, 0); framebuffer.Begin(); framebuffer.Check(); framebuffer.End(); cameraOne.Frame.LocalToParent.Set( Matrix4.CreateLookAt( new Vector3(0.0f, 0.0f, -4.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f) ) ); cameraOne.FovYRadians = RenderStack.Math.Conversions.DegreesToRadians(60.0f); cameraOne.ProjectionType = ProjectionType.PerspectiveVertical; ulong updateSerial = 1; cameraOne.Frame.UpdateHierarchical(updateSerial); quadFrame.UpdateHierarchical(updateSerial); cameraOne.UpdateFrame(); cameraOne.UpdateViewport(framebuffer); cameraOne.UpdateModelFrame(quadFrame); if (RenderStack.Graphics.Configuration.glslVersion >= 330) { diffuseProgram = new ProgramDeprecated(vsDiffuse330, fsDiffuse330); } else { diffuseProgram = new ProgramDeprecated(vsDiffuse120, fsDiffuse120); } diffuseProgram.AttributeMappings = attributeMappings; diffuseProgram.Bind(cameraOne); diffuseProgram.Bind(parameters); // Initialize resources used by the second pass (render to screen, using texture) windowViewport = new Viewport(base.Width, base.Height); cameraTwo.Frame.LocalToParent.Set( Matrix4.CreateLookAt( new Vector3(0.0f, 0.0f, -2.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f) ) ); cameraTwo.FovYRadians = RenderStack.Math.Conversions.DegreesToRadians(60.0f); cameraTwo.ProjectionType = ProjectionType.PerspectiveVertical; cameraTwo.Frame.UpdateHierarchical(updateSerial); sphereFrame.UpdateHierarchical(updateSerial); cameraTwo.UpdateFrame(); cameraTwo.UpdateViewport(windowViewport); cameraTwo.UpdateModelFrame(sphereFrame); parameters["texture"] = framebuffer[FramebufferAttachment.ColorAttachment0]; if (RenderStack.Graphics.Configuration.glslVersion >= 330) { texturedProgram = new ProgramDeprecated(vsTextured330, fsTextured330); } else { texturedProgram = new ProgramDeprecated(vsTextured120, fsTextured120); } texturedProgram.AttributeMappings = attributeMappings; texturedProgram.Bind(cameraTwo); texturedProgram.Bind(parameters); diffuseProgram.Use(); diffuseProgram.ApplyUniforms(); texturedProgram.Use(); texturedProgram.ApplyUniforms(); EnsureUploaded(sphereMesh); EnsureUploaded(quadMesh); // Setup some GL state GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.CullFace); Resize += new EventHandler <EventArgs>(Application_Resize); Unload += new EventHandler <EventArgs>(Application_Unload); GL.ClearColor(0.5f, 0.5f, 0.5f, 1.0f); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); SwapBuffers(); Visible = true; }