/// <summary> /// GetShader loads a shader resource from disk /// </summary> private RhGLShaderProgram GetShader(string baseName) { for (int i = 0; i < Shaders.Count; i++) { var shader = Shaders [i]; if (shader.Name.Equals(baseName, StringComparison.InvariantCultureIgnoreCase)) { SetupShader(shader, Model, Viewport); return(shader); } } String vertex_shader = GetResourceAsString(baseName, "vsh"); String fragment_shader = GetResourceAsString(baseName, "fsh"); var new_shader = RhGLShaderProgram.BuildProgram(baseName, vertex_shader, fragment_shader); if (new_shader != null) { Shaders.Add(new_shader); } SetupShader(new_shader, Model, Viewport); return(new_shader); }
/// <summary> /// Creates a default light and enables the active shader /// </summary> private void SetupShader(RhGLShaderProgram shader, RMModel model, ViewportInfo viewport) { // Check to make sure we actually have an active shader... if (shader != null) { // Enable... shader.Enable(); // Now setup and initialize frustum and lighting... int near, far; viewport.GetScreenPort(out near, out far); viewport.SetScreenPort((int)Frame.Left, (int)Frame.Right, (int)Frame.Bottom, (int)Frame.Top, near, far); shader.SetupViewport(viewport); Rhino.Geometry.Light light = CreateDefaultLight(); shader.SetupLight(light); light.Dispose(); } }
/// <summary> /// For derived class implementers. /// <para>This method is called with argument true when class user calls Dispose(), while with argument false when /// the Garbage Collector invokes the finalizer, or Finalize() method.</para> /// <para>You must reclaim all used unmanaged resources in both cases, and can use this chance to call Dispose on disposable fields if the argument is true.</para> /// <para>Also, you must call the base virtual method within your overriding method.</para> /// </summary> /// <param name="disposing">true if the call comes from the Dispose() method; false if it comes from the Garbage Collector finalizer.</param> protected virtual void Dispose(bool disposing) { // Free unmanaged resources... // Free managed resources...but only if called from Dispose // (If called from Finalize then the objects might not exist anymore) if (disposing) { if (Model != null) { Model.Dispose(); Model = null; } Frame = System.Drawing.RectangleF.Empty; if (Viewport != null) { Viewport.Dispose(); Viewport = null; } CurrentMaterial = null; if (ActiveShader != null) { GL.DeleteProgram(ActiveShader.Handle); ActiveShader.Disable(); m_activeShader = null; } if (Shaders != null) { Shaders.Clear(); Shaders = null; } } }
/// <summary> /// Creates a default light and enables the active shader /// </summary> private void SetupShader(RhGLShaderProgram shader, RMModel model, ViewportInfo viewport) { // Check to make sure we actually have an active shader... if (shader != null) { // Enable... shader.Enable (); // Now setup and initialize frustum and lighting... int near, far; viewport.GetScreenPort (out near, out far); viewport.SetScreenPort ((int)Frame.Left, (int)Frame.Right, (int)Frame.Bottom, (int)Frame.Top, near, far); shader.SetupViewport (viewport); Rhino.Geometry.Light light = CreateDefaultLight (); shader.SetupLight (light); light.Dispose (); } }
/// <summary> /// For derived class implementers. /// <para>This method is called with argument true when class user calls Dispose(), while with argument false when /// the Garbage Collector invokes the finalizer, or Finalize() method.</para> /// <para>You must reclaim all used unmanaged resources in both cases, and can use this chance to call Dispose on disposable fields if the argument is true.</para> /// <para>Also, you must call the base virtual method within your overriding method.</para> /// </summary> /// <param name="disposing">true if the call comes from the Dispose() method; false if it comes from the Garbage Collector finalizer.</param> protected virtual void Dispose(bool disposing) { // Free unmanaged resources... // Free managed resources...but only if called from Dispose // (If called from Finalize then the objects might not exist anymore) if (disposing) { if (Model != null) { Model.Dispose (); Model = null; } Frame = System.Drawing.RectangleF.Empty; if (Viewport != null) { Viewport.Dispose (); Viewport = null; } CurrentMaterial = null; if (ActiveShader != null) { GL.DeleteProgram (ActiveShader.Handle); ActiveShader.Disable (); m_activeShader = null; } if (Shaders != null) { Shaders.Clear (); Shaders = null; } } }
/// <summary> /// Builds both the vertex and the fragment shaders /// Shaders MUST consist of both a vertex AND a fragment shader in 2.0. /// </summary> public static RhGLShaderProgram BuildProgram(string name, string vertexShader, string fragmentShader) { if (String.IsNullOrWhiteSpace (vertexShader) || String.IsNullOrWhiteSpace (fragmentShader)) return null; int hVsh = BuildShader (vertexShader, ShaderType.VertexShader); int hFsh = BuildShader (fragmentShader, ShaderType.FragmentShader); if (hVsh == 0 || hFsh == 0) return null; int program_handle = GL.CreateProgram (); if (program_handle == 0 ) return null; GL.AttachShader (program_handle, hVsh); GL.AttachShader (program_handle, hFsh); // These bindings are forced here so that mesh drawing can enable the // appropriate vertex array based on the same binding values. // Note: These must be done before we attempt to link the program... // Note2: Rhino supports multiple textures but for now we'll only // provide for a single set of texture coordinates. GL.BindAttribLocation (program_handle, (int)VertexAttributes.AttribVertex, "rglVertex"); GL.BindAttribLocation (program_handle, (int)VertexAttributes.AttribNormal, "rglNormal"); GL.BindAttribLocation (program_handle, (int)VertexAttributes.AttribTexcoord0, "rglTexCoord0"); GL.BindAttribLocation (program_handle, (int)VertexAttributes.AttribColor, "rglColor"); GL.LinkProgram (program_handle); int success; GL.GetProgram(program_handle, ProgramParameter.LinkStatus, out success); if (success == 0) { #if DEBUG int logLength; GL.GetProgram (program_handle, ProgramParameter.InfoLogLength, out logLength); if (logLength > 0) { string log = GL.GetProgramInfoLog (program_handle); System.Diagnostics.Debug.WriteLine (log); } #endif GL.DetachShader (program_handle, hVsh); GL.DetachShader (program_handle, hFsh); GL.DeleteProgram (program_handle); program_handle = 0; } GL.DeleteShader (hVsh); GL.DeleteShader (hFsh); if (program_handle == 0) return null; RhGLShaderProgram program = new RhGLShaderProgram (name, program_handle); program.ResolvePredefines (); return program; }
/// <summary> /// Builds both the vertex and the fragment shaders /// Shaders MUST consist of both a vertex AND a fragment shader in 2.0. /// </summary> public static RhGLShaderProgram BuildProgram(string name, string vertexShader, string fragmentShader) { if (String.IsNullOrWhiteSpace(vertexShader) || String.IsNullOrWhiteSpace(fragmentShader)) { return(null); } int hVsh = BuildShader(vertexShader, ShaderType.VertexShader); int hFsh = BuildShader(fragmentShader, ShaderType.FragmentShader); if (hVsh == 0 || hFsh == 0) { return(null); } int program_handle = GL.CreateProgram(); if (program_handle == 0) { return(null); } GL.AttachShader(program_handle, hVsh); GL.AttachShader(program_handle, hFsh); // These bindings are forced here so that mesh drawing can enable the // appropriate vertex array based on the same binding values. // Note: These must be done before we attempt to link the program... // Note2: Rhino supports multiple textures but for now we'll only // provide for a single set of texture coordinates. GL.BindAttribLocation(program_handle, (int)VertexAttributes.AttribVertex, "rglVertex"); GL.BindAttribLocation(program_handle, (int)VertexAttributes.AttribNormal, "rglNormal"); GL.BindAttribLocation(program_handle, (int)VertexAttributes.AttribTexcoord0, "rglTexCoord0"); GL.BindAttribLocation(program_handle, (int)VertexAttributes.AttribColor, "rglColor"); GL.LinkProgram(program_handle); int success; GL.GetProgram(program_handle, ProgramParameter.LinkStatus, out success); if (success == 0) { #if DEBUG int logLength; GL.GetProgram(program_handle, ProgramParameter.InfoLogLength, out logLength); if (logLength > 0) { string log = GL.GetProgramInfoLog(program_handle); System.Diagnostics.Debug.WriteLine(log); } #endif GL.DetachShader(program_handle, hVsh); GL.DetachShader(program_handle, hFsh); GL.DeleteProgram(program_handle); program_handle = 0; } GL.DeleteShader(hVsh); GL.DeleteShader(hFsh); if (program_handle == 0) { return(null); } RhGLShaderProgram program = new RhGLShaderProgram(name, program_handle); program.ResolvePredefines(); return(program); }