185 lines
9.1 KiB
Markdown
185 lines
9.1 KiB
Markdown
# 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 `// <auto-generated>`;
|
|
- 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<T>`, `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<T>)` |
|
|
| `glUniform4*v` | `Uniform(..., ReadOnlySpan<Vec4<T>>)` |
|
|
| `glUniform2*v` and `glUniform3*v` | Omitted because `Vec2` and `Vec3` storage is not a tightly packed C array |
|
|
| `glUniformMatrix4fv` | `Uniform(..., GMatrix44<float>)` 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<T>)` |
|
|
| `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` `<vecequiv>` 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<GlHandle>` or `ReadOnlySpan<GlHandle>`;
|
|
- `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<T>`, `ReadOnlySpan<T>`, `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<byte>` and `string` overloads instead of a generated `byte**` signature.
|
|
|
|
## Documentation comments
|
|
|
|
Every generated public method contains:
|
|
|
|
- its original C API declaration;
|
|
- a `<seealso>` link to the corresponding docs.gl OpenGL 4 page or family page.
|
|
|
|
The generator does not emit `<param>` or `<returns>` 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.
|