# Nitload.GenerateGL `Nitload.GenerateGL` generates the Nitload desktop OpenGL C# bindings from the Khronos `gl.xml` registry. The current target is OpenGL 4.6 Core. The generator does not emit OpenGL ES or mix extension entry points into the core API. `gl.xml` is the authoritative generation input; the retained `gl.h` is reference material only. ## Namespace migration The project and directory are named `Nitload.GenerateGL`, but the implementation namespace and generated-source templates still contain `StgSharp.*`. Update the templates in `Generation/OpenGlGenerator.cs` to emit `Nitload.Graphics.OpenGL` and import `Nitload.Mathematics.Numeric.Graphics` before regenerating the renamed graphics library. The CLI commands below use the current project paths; they do not automatically migrate generated namespaces. ## Usage Start the interactive CLI: ```powershell dotnet run --project tools/Nitload.GenerateGL/Nitload.GenerateGL.csproj ``` Common commands: ```text summary find glBindBuffer show command glBindBuffer target summary families list Vertex families show VertexAttributeP generate all list files preview OpenGLFunction.v4_1.g.cs ``` Generate directly into an existing directory: ```powershell dotnet run --project tools/Nitload.GenerateGL/Nitload.GenerateGL.csproj -- generate all src/Nitload.Graphics/OpenGL/Generated ``` Generation targets are explicit: ```text generate api [output-directory] # function tables and managed forwarding APIs generate enum [output-directory] # glConst and strongly typed enum groups generate all [output-directory] # both sets ``` The API files reference the generated enum types. Use `generate all` for a clean output directory; use `generate api` when refreshing an output tree that already contains the enum files. Without a directory, `generate` retains its output in the current CLI session. With a directory: - the directory must already exist and be writable; - each file is staged in the destination directory before replacing its target; - an existing file is replaced only when its first line is `// `; - unrelated and obsolete generated files are not deleted. Use a directory dedicated to generated source files. ## Pipeline ```text gl.xml -> lossless XML and registry models -> desktop OpenGL 4.6 Core projection -> GLenum/GLbitfield semantic group projection -> function-family and scalar/vector relation analysis -> managed API filters -> C# naming and signature validation -> in-memory generated file set -> preview or directory output ``` The target projection removes GLES and ARB/NV/EXT extension entry points. It retains only commands and constants present in the target Core Profile. Generated files: - `glconst.cs`: core constants; - `GlEnums.g.cs`: strongly typed enum groups referenced by Core Profile parameters and return values; - `OpenglContext.g.cs`: the function-pointer table with native names and ABI types; - `glContextShadow.g.cs`: an identically ordered `nint` table used while loading native entry points; - `OpenGLFunction.Base.g.cs`: APIs introduced through OpenGL 3.2 and retained in the target profile; - `OpenGLFunction.v3_3.g.cs` through `OpenGLFunction.v4_6.g.cs`: APIs introduced by each later core version. `OpenglContext` intentionally remains close to the C ABI. Overloads, `Span`, `GlHandle`, and managed naming exist only in the `OpenGLFunction` layer. ## Overload rules The generator merges a family only when it can validate the resulting signatures. Every managed method retains a reference to its original `gl*` command. | Native C API | Generated API | | --- | --- | | `glUniform1f` through `glUniform4f` | Scalar `Uniform(...)` overloads | | `glUniform*i`, `glUniform*ui`, and `glUniform*d` | Merged into `Uniform(...)` by C# parameter type | | `glProgramUniform*` | Merged into `ProgramUniform(...)` by the same rules | | `glUniform1*v` | `Uniform(..., ReadOnlySpan)` | | `glUniform4*v` | `Uniform(..., ReadOnlySpan>)` | | `glUniform2*v` and `glUniform3*v` | Omitted because `Vec2` and `Vec3` storage is not a tightly packed C array | | `glUniformMatrix4fv` | `Uniform(..., GMatrix44)` and matrix-span overloads | | Other matrix sizes and double matrices | Omitted because only the graphics-oriented 4x4 float layout is defined | | `glGetBooleanv`, `glGetFloatv`, `glGetIntegerv`, and related queries | `GetValue(..., Span)` | | `glVertexAttrib1f/2f/3f/4f` and equivalent scalar forms | `VertexAttribute(...)`; component count is expressed by the parameter list | | `glVertexAttrib*fv/*iv/...` with a scalar equivalent | Omitted instead of exposing a duplicate C-style pointer entry point | | `glVertexAttrib4N*` | `VertexAttributeNormalized(...)` | | `glVertexAttribI*` | `VertexAttributeInteger(...)` | | `glVertexAttribL*` | `VertexAttributeDouble(...)`; `L` does not mean C# `long` | | `glVertexAttribP1ui` through `P4ui` | `VertexAttributePacked1(...)` through `Packed4(...)`; the width prevents signature collisions | | `glGetVertexAttribI*` and `L*` | `GetVertexAttributeInteger(...)` and `GetVertexAttributeDouble(...)` | | `glScissorIndexed` and `glScissorIndexedv` | `ScissorIndexed(...)` overloads | Function families are inferred from common name prefixes, shape suffixes, type suffixes, and vector forms. Candidates are checked against: - the `gl.xml` `` relation; - parameter `len`, `kind`, and native types; - scalar `T` versus `const T*` relationships; - uniqueness of the final C# signature. If incomplete type mapping causes two methods to collapse to the same C# signature, the generator conservatively restores their normalized native names instead of emitting uncompilable overloads. ## Renaming rules Safe lexical normalization applies to all public methods: | OpenGL spelling | C# spelling | | --- | --- | | `Framebuffer` / `framebuffer` | `FrameBuffer` / `frameBuffer` | | `Renderbuffer` / `renderbuffer` | `RenderBuffer` / `renderBuffer` | | `Internalformat` / `internalformat` | `InternalFormat` / `internalFormat` | | `Attrib` / `attrib` | `Attribute` / `attribute` | | `Frag` | `Fragment` | | `attribindex` | `attributeIndex` | | `bindingindex` | `bindingIndex` | | `relativeoffset` | `relativeOffset` | | `pname` | `pName` | | `xoffset` / `yoffset` / `zoffset` | `xOffset` / `yOffset` / `zOffset` | | `vaobj` | `vertexArray` | Families that represent distinct semantics receive explicit names: | Native family | Managed family | | --- | --- | | `TexParameter*` | `TextureParameter(...)` | | DSA `TextureParameter*` | `NamedTextureParameter(...)` | | `TexParameterI*` | `TextureParameterInteger(...)` | | DSA `TextureParameterI*` | `NamedTextureParameterInteger(...)` | | `SamplerParameterI*` | `SamplerParameterInteger(...)` | | `GetnUniform*` | Merged into `GetUniform(...)` when signatures permit | | `VertexAttribI/L/P/N` | Expanded to `Integer/Double/Packed/Normalized` | Renaming never changes the native target. For example, `VertexAttributeInteger(...)` still calls `__context->glVertexAttribI*`. ## Type rules - `gl.xml` typedefs map to equivalent C# ABI types; the generator does not emit separate type aliases; - `GLenum` and `GLbitfield` declarations with one unambiguous registry group use the generated enum type in public APIs; - enum pointers preserve their pointer shape (for example, `GLenum*` becomes `DebugSource*`) and are cast back to the native `uint*` representation at the forwarding boundary; - enum return values are converted from the native `uint` representation before being returned; - declarations with missing or conflicting enum group metadata remain on their ABI type; - a `GLuint` is converted to `GlHandle` only when object class and parameter semantics identify it as an object handle; - handle arrays use `Span` or `ReadOnlySpan`; - `OpenGLFunction` stores an `OpenglContext*` and forwards through `__context->glFunction(...)`; - unknown-length arrays, complex outputs, multiple indirection, and `void*` remain pointers. A `T*` alone does not determine whether a managed API should use `Span`, `ReadOnlySpan`, `out T`, or a return value. Future pointer improvements should be implemented as family-specific filters validated with `len`, parameter direction, and OpenGL state semantics. Raw managed forwards are omitted when a safer handwritten public API owns the command. In particular, `glShaderSource` remains in `OpenglContext` for ABI loading, while `OpenGLFunction` exposes the handwritten `ReadOnlySpan` and `string` overloads instead of a generated `byte**` signature. ## Documentation comments Every generated public method contains: - its original C API declaration; - a `` link to the corresponding docs.gl OpenGL 4 page or family page. The generator does not emit `` or `` elements and does not copy docs.gl content. ## Source layout - `Registry/`: the `gl.xml` object model and Core Profile projection; - `Analysis/`: function families, name shapes, and scalar/vector relations; - `Generation/`: type mapping, API filters, signature planning, and file generation; - `Naming/`: C# identifier and semantic-family naming policies; - `XmlCli.cs`, `RegistryCli.cs`, and `FunctionFamilyCli.cs`: interactive inspection; - `GenerateCli.cs`: in-memory preview and protected directory output.