Skip to main content

forge-procedural-geometry

Generate procedural 3D geometry using forge_shapes.h — parametric surfaces (sphere, icosphere, cylinder, cone, torus, plane, cube, capsule) with struct-of-arrays layout for GPU upload

Aller à l'installation

Informations de source

Dépôt
Nebulavenus/forge-gpu
Dernière activité de la source
8 mars 2026 à 11:52
Langue détectée de SKILL.md
anglais
Étoiles
38
Forks
7

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
forge-procedural-geometry
description
Generate procedural 3D geometry using forge_shapes.h — parametric surfaces (sphere, icosphere, cylinder, cone, torus, plane, cube, capsule) with struct-of-arrays layout for GPU upload
Generate and render procedural geometry using the `forge_shapes.h` header-only library. Shapes are unit-scale, centred at origin, Y-up, CCW winding. ## Include pattern One `.c` file defines the implementation; all others get declarations only: ```c /* In exactly ONE .c file: */ #define FORGE_SHAPES_IMPLEMENTATION #include "shapes/forge_shapes.h" /* In all other files: */ #include "shapes/forge_shapes.h" ``` ## Generate and upload a shape ```c /* Generate a 32-slice, 16-stack UV sphere */ ForgeShape sphere = forge_shapes_sphere(32, 16); /* Create GPU buffers for struct-of-arrays layout */ SDL_GPUBuffer *pos_buf = upload_gpu_buffer(device, sphere.positions, sphere.vertex_count * sizeof(vec3)); SDL_GPUBuffer *nor_buf = upload_gpu_buffer(device, sphere.normals, sphere.vertex_count * sizeof(vec3)); SDL_GPUBuffer *idx_buf = upload_gpu_buffer_index(device, sphere.indices, sphere.index_count * sizeof(uint32_t)); /* Free CPU-side data after upload */ int index_count = sphere.index_count; forge_shapes_free(&sphere); ``` ## Bind and draw (struct-of-arrays) ```c /* Bind position buffer at vertex slot 0 */ SDL_GPUBufferBinding pos_bind = { .buffer = pos_buf, .offset = 0 }; SDL_BindGPUVertexBuffers(rpass, 0, &pos_bind, 1); /* Bind normal buffer at vertex slot 1 */ SDL_GPUBufferBinding nor_bind = { .buffer = nor_buf, .offset = 0 }; SDL_BindGPUVertexBuffers(rpass, 1, &nor_bind, 1); /* Bind index buffer */ SDL_GPUBufferBinding idx_bind = { .buffer = idx_buf, .offset = 0 }; SDL_BindGPUIndexBuffer(rpass, &idx_bind, SDL_GPU_INDEXELEMENTSIZE_32BIT); /* Draw */ SDL_DrawGPUIndexedPrimitives(rpass, index_count, 1, 0, 0, 0); ``` ## Pipeline vertex attributes Configure two vertex buffer slots matching the struct-of-arrays layout: ```c SDL_GPUVertexBufferDescription vbufs[] = { { .slot = 0, .pitch = sizeof(vec3), .input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX }, { .slot = 1, .pitch = sizeof(vec3), .input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX }, }; SDL_GPUVertexAttribute attrs[] = { { .location = 0, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, .offset = 0 }, { .location = 1, .buffer_slot = 1, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, .offset = 0 }, }; ``` ## Multiple shapes in one scene ```c /* Generate all shapes */ ForgeShape shapes[] = { forge_shapes_sphere(32, 16), forge_shapes_torus(24, 12, 1.0f, 0.4f), forge_shapes_plane(4, 4), }; int shape_count = sizeof(shapes) / sizeof(shapes[0]); /* Upload each to GPU, store buffers and counts */ for (int i = 0; i < shape_count; i++) { upload_shape_to_gpu(device, &shapes[i], &gpu_shapes[i]); forge_shapes_free(&shapes[i]); } /* In render loop: draw each with its own model matrix */ for (int i = 0; i < shape_count; i++) { set_push_uniforms(rpass, model_matrices[i]); bind_and_draw(rpass, &gpu_shapes[i]); } ``` ## Available generators | Function | Description | Default params | |---|---|---| | `forge_shapes_sphere(slices, stacks)` | UV sphere, radius 1 | 32, 16 | | `forge_shapes_icosphere(subdivisions)` | Even triangle distribution | 2 | | `forge_shapes_cylinder(slices, stacks)` | No caps, height 2 | 32, 1 | | `forge_shapes_cone(slices, stacks)` | Apex at Y=+1, no base | 32, 1 | | `forge_shapes_torus(slices, stacks, major, tube)` | Donut in XZ plane | 32, 16, 1.0, 0.4 | | `forge_shapes_plane(slices, stacks)` | XZ plane, Y=0 | 4, 4 | | `forge_shapes_cube(slices, stacks)` | 6 faces, per-face normals | 1, 1 | | `forge_shapes_capsule(slices, stacks, cap_stacks, half_h)` | Cylinder + hemisphere caps | 32, 4, 4, 1.0 | ## Common mistakes 1. **Forgetting to free** — always call `forge_shapes_free()` after GPU upload 2. **Wrong vertex slot** — positions go to slot 0, normals to slot 1; swapping them produces garbled lighting 3. **Using interleaved vertex layout** — `ForgeShape` uses struct-of-arrays; bind separate buffers per attribute, not one interleaved buffer 4. **Missing seam at U=0/U=1** — the sphere has `(slices+1)` columns to handle the texture seam; this is intentional, not a bug ## References - Library: [`common/shapes/forge_shapes.h`](../../../common/shapes/forge_shapes.h) - API docs: [`common/shapes/README.md`](../../../common/shapes/README.md) - Lesson: [`lessons/assets/04-procedural-geometry/`](../../../lessons/assets/04-procedural-geometry/) - Tests: [`tests/shapes/test_shapes.c`](../../../tests/shapes/test_shapes.c)
Voir sur GitHub