make some changes to opengl api gen, discussing on rewrite of all opengl binding, making it neat and structral

This commit is contained in:
Youmu Liu
2026-08-25 17:33:45 +08:00
parent 708a915549
commit 65041ff8bc
63 changed files with 14404 additions and 8851 deletions
@@ -2,7 +2,7 @@
## 目标与范围
- **输入**:Khronos OpenGL Registry `gl.xml`(Core Profile 为主,版本 3.3→4.6,可选扩展)。
- **输出**:分版本 partial `glContext`(`delegate*` 字段)与 `OpenGLFunction` 包装方法(调用 `Context.glXxx`),以及新增常量/枚举补全文件,写入 `StgSharp.Common\Graphics\OpenGL\Generated\`。不改动现有手写文件。
- **输出**:合并的 partial `OpenglContext`(`delegate*` 字段)、分版本 `OpenGLFunction` 薄包装方法,以及按版本生成的 Uniform 语义重载。生成结果最终对应 `src\StgSharp.Graphics\OpenGL\Generated\`,评审时可以通过命令行参数输出到独立目录。
- **风格**:保持现有函数指针字段 + 薄封装方法模式;兼容现有命名和类型定义(如 `GlHandle`)。
---
@@ -21,27 +21,41 @@
## 阶段 2:类型映射与句柄规则
- 整数:`GLenum`/`GLbitfield`→`uint`;`GLint`/`GLsizei`/`GLfixed`→`int`;`GLuint`→`uint`;`GLboolean`→`byte`(包装层可 bool→byte)。
- 浮点:`GLfloat`→`float`;`GLdouble`→`double`。
- 指针与尺寸:`void*`/`const void*`→`void*`;`GLintptr`→`nint`/`IntPtr`;`GLsizeiptr`/`size_t`→`nuint`/`UIntPtr`;`GLsync`→现有 `GLsync`/`IntPtr` 包装。
- 字符串:`const GLchar*`→`byte*`(UTF-8),包装层可另行提供 string/Span<byte> 重载。
- 指针与尺寸:`void*`/`const void*`→`void*`;`GLintptr`、`GLsizeiptr`→`nint`;`GLsync`→现有 `glSync` 包装。`GLint64`/`GLuint64` 分别映射为 `long`/`ulong`。回调类型 `GLDEBUGPROC` 暂以指针大小的 `IntPtr` 表示。
- 未知 C 类型直接终止生成,不再静默回退为 `IntPtr`。这可以防止 typedef 漏映射后生成 ABI 不兼容的函数指针。
- 字符串:函数表中的 `GLchar*` 保持 `byte*` ABI;包装层的 const 单指针使用 UTF-8 `ReadOnlySpan<byte>`,后续可另行提供 `string` 重载。
- 参数长度:解析并保留 registry `<param len="...">`。包装层以该表达式判断数组方向、固定长度和关联的 `count`/`bufSize` 参数;底层函数表不使用这些托管规则。
- 调用约定:OpenGL APIENTRY 通常 stdcall(Windows);保持与现有 `glContext` 字段一致(`delegate* unmanaged[Stdcall]` 或 `unmanaged[Cdecl]`,需与 loader 对齐)。
- 句柄识别:包含 program/shader/buffer/texture/framebuffer/renderbuffer/vertexarray/query/sampler/transformfeedback 等对象名的 `GLuint` 参数 → 包装层使用 `GlHandle`,内部传 `handle.Value`。
- 句柄识别:包含 program/shader/buffer/texture/framebuffer/renderbuffer/vertexarray/query/sampler/transformfeedback 等对象名的 `GLuint` 参数 → 包装层使用 `GlHandle`,内部传 `handle.Value`。`glCreateProgram`、`glCreateShader` 等明确返回 object name 的命令返回 `GlHandle`。
- `GLenum` 不再仅凭参数名 `type` 推断为 `ShaderType`;低层包装保持 `uint`,避免把像素类型、索引类型等无关参数错误分类。
- glGet* 输出:保留指针签名,或另行生成 unsafe Span/stackalloc 适配器;核心先生成指针版。
---
## 阶段 3:版本分组与文件组织
- 输出目录:`StgSharp.Common\Graphics\OpenGL\Generated\`
- 每个版本生成独立 partial:
- `glContext.v33.cs`, `glContext.v40.cs`, …, `glContext.v46.cs`:`delegate*` 字段。
- `OpenGLFunction.v33.cs`, …:包装方法 `public void Foo(...) => Context.glFoo(...);`
- 目标目录:`src\StgSharp.Graphics\OpenGL\Generated\`
- Context 生成一个合并文件:
- `OpenglContext.g.cs`:所有目标 Core 版本需要的 `delegate*` 字段。
- Raw 包装按版本生成独立 partial:
- `OpenGLFunction.Raw.v3_3.g.cs`, …:包装方法 `public void Foo(...) => Context.glFoo(...);`
- Uniform 重载按首次引入版本生成:
- `OpenGLFunction.Uniform.v3_3.g.cs`、`v4_0`、`v4_1`。
- 不再同时生成分版本 Context 与合并 Context,避免同一字段被 partial struct 重复定义。
- 常量/枚举:`glConst.generated.cs`(或分版本补丁),避免与现有重复,先查已有定义再生成。
- 命名空间:`StgSharp.Graphics.OpenGL`;类声明:`partial struct/partial class glContext`(按现有定义),`partial class OpenGLFunction`。
---
## 阶段 4:生成规则(函数表与包装)
- `glContext` 字段:`internal unsafe delegate*<converted_sig> glFoo;`
- `OpenglContext` 字段:`internal unsafe delegate*<converted_sig> glFoo;`
- `OpenGLFunction` 包装:薄封装直接转发;句柄参数用 `GlHandle`,内部传 `handle.Value`;`bool` 参数按底层 `GLboolean` 需要转换为 `byte/uint`。
- 指针包装:带长度的 `const T*` 生成 `ReadOnlySpan<T>`,输出 `T*` 生成 `Span<T>`,`len="1"` 的输出生成 `out T`。可由单个 Span 唯一决定的 `count`/`n`/`bufSize` 从 `Span.Length` 推导;共享同一长度的输入 Span 会检查长度一致。简单常量、乘法和除法长度表达式会生成下限检查。
- registry 中省略 `len` 的零结尾 const 字符指针仍生成 `ReadOnlySpan<byte>`;省略 `len` 的 `glGet*` 数值单指针按未知长度输出生成 `Span<T>`。`void*`、二级指针、驱动拥有的返回指针以及表示 Buffer 偏移的指针继续保留原始形式。
- 可重载的 C 类型尾缀会折叠为同一 C# 方法名,例如 `TexParameterf/i/fv/iv` → `TexParameter(...)`,`BlendEquation/BlendEquationi` → `BlendEquation(...)`。生成器以最终 C# 参数签名检测冲突;无法区分时保留最少的维度或语义尾缀。
- `glUniform1/2/3/4[f|i|ui|d][v]` 和 `glProgramUniform*` 不再作为一组公开的 C 风格方法生成,而是生成 `SetUniformValue(...)` 重载。location 从 `Uniform<T...>.id.SignedValue` 取得;数组版本接受 `ReadOnlySpan<T>` 并自动计算 count。
- float vector 额外生成 `Vec2`、`Vec3`、`Vec4` 重载,4×4 float matrix 生成 `GraphicsMatrix` 重载。所有 uniform setter(包括 matrix)都不进入 Raw wrapper;项目暂时没有对应托管类型的其他矩阵形状只保留底层 `OpenglContext` 函数指针,待类型齐备后再生成公开重载。
- `glVertexAttribN*v` 若存在对应的标量命令 `glVertexAttribN*`,不再生成重复的 Span wrapper;公开 API 使用 `VertexAttrib(index, x, y, z, w)` 形式的固定分量重载。只有不存在标量等价命令的特殊整数/归一化形式才暂时保留独立入口。
- `FramebufferTexture1D/2D/3D` 表示不同 OpenGL API,不参与维度重载归并。
- 去重:若同名字段/方法已存在,跳过或比对签名避免重复生成。
---
@@ -69,3 +83,11 @@
2. 搭建增量生成器骨架:Parse → Filter → Emit。
3. 先生成 3.3 子集验证编译,再扩展到 4.6。
4. 按需追加扩展(ARB/KHR),保持可配置启用列表。
## 本地评审输出
可把首个命令行参数作为输出目录:
```powershell
dotnet run --project test\StgSharp.GenerateGL\GenerateGL.csproj -- test\StgSharp.GenerateGL\Generated
```