From 5daf101be3aad564b3511009bc6f78bea7fd1d27 Mon Sep 17 00:00:00 2001 From: Rod Kay Date: Sun, 7 May 2023 06:46:45 +1000 Subject: [PATCH] opengl.shader: Allow shaders to be built from snippets. --- .../opengl/assets/shader/lit_textured_x2.frag | 32 +--- .../opengl-geometry-lit_textured_x2.adb | 4 +- .../source/lean/shader/opengl-shader.adb | 144 ++++++++++++++---- .../source/lean/shader/opengl-shader.ads | 5 +- 4 files changed, 128 insertions(+), 57 deletions(-) diff --git a/3-mid/opengl/assets/shader/lit_textured_x2.frag b/3-mid/opengl/assets/shader/lit_textured_x2.frag index 23a6454..528fdc5 100644 --- a/3-mid/opengl/assets/shader/lit_textured_x2.frag +++ b/3-mid/opengl/assets/shader/lit_textured_x2.frag @@ -1,5 +1,3 @@ -#version 140 - struct light { vec4 Site; @@ -16,10 +14,6 @@ uniform mat3 inverse_model_Rotation; uniform vec3 camera_Site; uniform vec3 specular_Color; // The materials specular color. -uniform int texture_Count; -uniform sampler2D Textures [32]; -uniform float Fade [32]; - uniform int light_Count; uniform light Lights [10]; @@ -32,6 +26,8 @@ in float frag_Shine; out vec4 final_Color; + + vec3 apply_Light (light Light, vec3 surface_Color, @@ -95,33 +91,16 @@ apply_Light (light Light, + void main() { vec3 surface_Site = vec3 ( model_Transform * vec4 (frag_Site, 1)); - - vec4 surface_Color = vec4 (0); - - for (int i = 0; i < texture_Count; ++i) - { -// surface_Color += texture (Textures [i], -// frag_Coords); - - surface_Color.rgb += texture (Textures [i],frag_Coords).rgb - * texture (Textures [i],frag_Coords).a - * (1.0 - Fade [i]); - - surface_Color.a = max (surface_Color.a, texture (Textures [i], - frag_Coords).a); - } - - surface_Color = surface_Color; // / texture_Count; - + vec4 surface_Color = apply_Texturing (frag_Coords); vec3 Surface_to_Camera = normalize (camera_Site - surface_Site); vec3 Normal = normalize ( frag_Normal * inverse_model_Rotation); - // Combine color from all the lights. // vec3 linear_Color = vec3 (0); @@ -135,8 +114,7 @@ main() Surface_to_Camera); } - vec3 Gamma = vec3 (1.0 / 2.2); - + vec3 Gamma = vec3 (1.0 / 2.2); final_Color = vec4 (pow (linear_Color, // Final color (after gamma correction). Gamma), surface_Color.a); diff --git a/3-mid/opengl/source/lean/geometry/opengl-geometry-lit_textured_x2.adb b/3-mid/opengl/source/lean/geometry/opengl-geometry-lit_textured_x2.adb index 80c3c0f..c9f6c52 100644 --- a/3-mid/opengl/source/lean/geometry/opengl-geometry-lit_textured_x2.adb +++ b/3-mid/opengl/source/lean/geometry/opengl-geometry-lit_textured_x2.adb @@ -87,8 +87,10 @@ is white_Texture := openGL.Texture.Forge.to_Texture (white_Image); vertex_Shader .define (Shader.Vertex, "assets/opengl/shader/lit_textured_x2.vert"); - fragment_Shader.define (Shader.Fragment, "assets/opengl/shader/lit_textured_x2.frag"); + fragment_Shader.define (Shader.Fragment, (asset_Names' (1 => to_Asset ("assets/opengl/shader/version.header"), + 2 => to_Asset ("assets/opengl/shader/texturing.frag"), + 3 => to_Asset ("assets/opengl/shader/lit_textured_x2.frag")))); the_Program := new openGL.Program.lit.item; the_Program.define ( vertex_Shader'Access, fragment_Shader'Access); diff --git a/3-mid/opengl/source/lean/shader/opengl-shader.adb b/3-mid/opengl/source/lean/shader/opengl-shader.adb index e6387f9..b032316 100644 --- a/3-mid/opengl/source/lean/shader/opengl-shader.adb +++ b/3-mid/opengl/source/lean/shader/opengl-shader.adb @@ -11,6 +11,9 @@ with interfaces.C.Strings; +-- use ada.Text_IO; + + package body openGL.Shader is use GL.lean, @@ -22,23 +25,71 @@ is function read_text_File (Filename : in String) return C.char_array; + + --------- -- Forge -- - procedure define (Self : in out Item; Kind : in shader.Kind; - source_Filename : in String) + function to_C_char_array (shader_Filename : in String) return C.char_array + is + use type interfaces.C.char_array; + begin + return read_text_File (shader_Filename) + & (1 => C.char (ada.Characters.Latin_1.NUL)); + end to_C_char_array; + + + + + function to_C_char_array (shader_Snippets : in asset_Names) return C.char_array + is + use type interfaces.C.char_array; + + snippet_Id : Natural := 0; + + function combine_Snippets return C.char_array + is + begin + snippet_Id := snippet_Id + 1; + + if snippet_Id < shader_Snippets'Last + then + return read_text_File (to_String (shader_Snippets (snippet_Id))) & combine_Snippets; + else + return read_text_File (to_String (shader_Snippets (snippet_Id))); + end if; + end combine_Snippets; + + begin + return combine_Snippets + & (1 => C.char (ada.Characters.Latin_1.NUL)); + end to_C_char_array; + + + + + procedure create_Shader (Self : in out Item; Kind : in Shader.Kind; + Source : in C.char_array) is use GL.Pointers, C.Strings; - the_Source : aliased C.char_array := read_text_File (source_Filename); - the_Source_ptr : aliased - constant chars_ptr := to_chars_ptr (the_Source'unchecked_Access); - the_Source_Array : aliased chars_ptr_array := [1 => the_Source_ptr]; + use type interfaces.C.char_array; + + the_Source : aliased C.char_array := Source; + the_Source_ptr : aliased constant chars_ptr := to_chars_ptr (the_Source'unchecked_Access); + the_Source_Array : aliased chars_ptr_array := [1 => the_Source_ptr]; + begin Tasks.check; + -- for i in the_Source'Range + -- loop + -- put (Character (the_Source (i))); + -- end loop; + + Self.Kind := Kind; if Kind = Vertex @@ -58,7 +109,7 @@ is Errors.log; declare - use type C.int; + use interfaces.C; Status : aliased gl.glInt; begin glGetShaderiv (self.gl_Shader, @@ -70,14 +121,37 @@ is compile_Log : constant String := Self.shader_info_Log; begin Self.destroy; - raise Error with "'" & source_Filename & "' compilation failed ~ " & compile_Log; + raise Error with "'" & to_Ada (the_Source) & "' compilation failed ~ " & compile_Log; end; end if; end; + end create_Shader; + + + + + procedure define (Self : in out Item; Kind : in Shader.Kind; + shader_Filename : in String) + is + the_Source : aliased constant C.char_array := to_C_char_array (shader_Filename); + begin + create_Shader (Self, Kind, the_Source); end define; + + procedure define (Self : in out Item; Kind : in Shader.Kind; + shader_Snippets : in asset_Names) + is + the_Source : aliased constant C.char_array := to_C_char_array (shader_Snippets); + begin + create_Shader (Self, Kind, the_Source); + end define; + + + + procedure destroy (Self : in out Item) is begin @@ -86,6 +160,7 @@ is end destroy; + -------------- -- Attributes -- @@ -123,6 +198,8 @@ is end shader_info_Log; + + ---------- -- Privvy -- @@ -134,44 +211,55 @@ is end gl_Shader; + + ----------- -- Utility -- - NL : constant String := "" & ada.characters.latin_1.LF; - function read_text_File (Filename : in String) return C.char_array is use ada.Text_IO, ada.Strings.unbounded; + use type interfaces.C.size_t; + + NL : constant String := "" & ada.characters.latin_1.LF; the_File : ada.Text_IO.File_type; Pad : unbounded_String; begin - open (the_File, in_File, Filename); + if Filename = "" + then + return C.char_array' (1 .. 0 => <>); + else + open (the_File, in_File, Filename); - while not end_of_File (the_File) - loop - append (Pad, get_Line (the_File) & NL); - end loop; - - close (the_File); - - declare - use type Interfaces.C.size_t; - - the_Data : C.char_array (1 .. C.size_t (Length (Pad)) + 1); - begin - for i in 1 .. the_Data'Last - 1 + while not end_of_File (the_File) loop - the_Data (i) := C.char (Element (Pad, Integer (i))); + append (Pad, get_Line (the_File) & NL); end loop; - the_Data (the_Data'Last) := C.char'Val (0); + close (the_File); - return the_Data; - end; + if Length (Pad) = 0 + then + return C.char_array' (1 .. 0 => <>); + else + declare + the_Data : C.char_array (0 .. C.size_t (Length (Pad) - 1)); + begin + for i in the_Data'Range + loop + the_Data (i) := C.char (Element (Pad, Integer (i) + 1)); + end loop; + + -- the_Data (the_Data'Last) := C.char'Val (0); + + return the_Data; + end; + end if; + end if; exception when ada.IO_Exceptions.name_Error => diff --git a/3-mid/opengl/source/lean/shader/opengl-shader.ads b/3-mid/opengl/source/lean/shader/opengl-shader.ads index deb3bb7..c75f305 100644 --- a/3-mid/opengl/source/lean/shader/opengl-shader.ads +++ b/3-mid/opengl/source/lean/shader/opengl-shader.ads @@ -19,7 +19,10 @@ is -- Forge -- procedure define (Self : in out Item; Kind : in Shader.Kind; - source_Filename : in String); + shader_Filename : in String); + + procedure define (Self : in out Item; Kind : in Shader.Kind; + shader_Snippets : in asset_Names); procedure destroy (Self : in out Item);