running ok
This commit is contained in:
parent
c6d6f787f7
commit
8e30b7692f
8 changed files with 371 additions and 356 deletions
47
WORKDOC.md
47
WORKDOC.md
|
|
@ -14,7 +14,7 @@ Affichage : **VGA Mode 13h** — 320×200, 256 couleurs, rendu Gouraud en virgul
|
|||
src/
|
||||
main/main.c Point d'entrée, scène, boucle principale
|
||||
part3D/
|
||||
defines.h Types, macros fixed-point, prototypes, externs
|
||||
defines.h Types, macros fixed-point, constantes écran, prototypes, externs
|
||||
engine.c Maths (sin/cos), matrices, pipeline de rendu
|
||||
geometry.c Génération de meshes (sphère, cylindre) + I/O mesh
|
||||
graph.c VGA init, palette, backbuffer/zbuffer
|
||||
|
|
@ -33,11 +33,11 @@ Makefile Build via WSL + wcc386 Windows natif
|
|||
init_engine_math() Précalcul sin/cos (tables entières 16.16)
|
||||
add_sphere / add_cylinder Génération mesh en espace local (0,0,0)
|
||||
─── Boucle principale ───
|
||||
kbhit / getch Gestion clavier
|
||||
kbhit / getch Gestion clavier (touches étendues consommées en deux appels)
|
||||
mat3_rotate_x/y Construction matrices de rotation
|
||||
mat3_mul (orbite) Composition de la matrice d'orbite
|
||||
mat3_mul (orbite) Composition de la matrice d'orbite (sûre contre l'aliasing)
|
||||
→ obj.rot = orbit Application uniforme à tous les objets
|
||||
→ obj.pos = orbit × base_pos + center Rotation des positions
|
||||
→ obj.pos = orbit × base_pos + center Rotation 3D complète des positions
|
||||
clear_buffers Effacement backbuffer + zbuffer (0xFFFF)
|
||||
render_universe Transformation + projection + Gouraud fill
|
||||
flip memcpy backbuffer → 0xA0000 (VGA)
|
||||
|
|
@ -56,6 +56,20 @@ add_sphere / add_cylinder Génération mesh en espace local (0,0,0)
|
|||
|
||||
---
|
||||
|
||||
## Constantes écran
|
||||
|
||||
Définies dans `defines.h` :
|
||||
|
||||
```c
|
||||
#define SCREEN_W 320
|
||||
#define SCREEN_H 200
|
||||
#define SCREEN_PIXELS (SCREEN_W * SCREEN_H) /* 64 000 */
|
||||
```
|
||||
|
||||
Utilisées partout dans `graph.c` et `raster.c` à la place du littéral `64000`.
|
||||
|
||||
---
|
||||
|
||||
## Palette VGA
|
||||
|
||||
256 entrées organisées en **16 couleurs × 16 niveaux d'intensité**.
|
||||
|
|
@ -98,16 +112,19 @@ La lumière est assimilée à la direction de vue (−Z monde). Le dot product d
|
|||
|
||||
```c
|
||||
nz = f_mul(n->x, rot.m[0][2]) + f_mul(n->y, rot.m[1][2]) + f_mul(n->z, rot.m[2][2]);
|
||||
intensity = (nz >= 0) ? int_to_f(1) : ((-nz) * 14) + int_to_f(1);
|
||||
intensity = (nz >= 0) ? int_to_f(1) : f_mul(-nz, int_to_f(14)) + int_to_f(1);
|
||||
```
|
||||
|
||||
`f_mul(-nz, int_to_f(14))` est une multiplication en virgule fixe 16.16 (≠ multiplication entière).
|
||||
|
||||
| nz | Signification | Intensité (shade) |
|
||||
|---|---|---|
|
||||
| −1.0 | Face directement vers caméra | 15 (max) |
|
||||
| 0 | Face tangentielle | 1 (ambiant) |
|
||||
| > 0 | Face opposée à la caméra | 1 (ambiant, face culléé) |
|
||||
|
||||
L'intensité est interpolée en virgule fixe 16.16 entre les sommets du triangle.
|
||||
L'intensité est interpolée en virgule fixe 16.16 entre les sommets du triangle.
|
||||
Le shade final est clampé dans [0, 15] — y compris vers le bas (intensité négative → 0).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -149,15 +166,17 @@ Les objets ont des positions de base fixes dans l'espace scène, définies par r
|
|||
| Sphère (universe[0]) | (+60, 0, 0) |
|
||||
| Cylindre (universe[1]) | (−60, 0, 0) |
|
||||
|
||||
Chaque frame, la matrice d'orbite `orbit = rotX(anglex) × rotY(angley)` est calculée et appliquée uniformément :
|
||||
Chaque frame, la matrice d'orbite `orbit = rotX(anglex) × rotY(angley)` est calculée et appliquée uniformément à chaque objet (transform 3D complet sur `base_pos`) :
|
||||
|
||||
```c
|
||||
universe[o].rot = orbit;
|
||||
universe[o].pos.x = f_mul(base_x, orbit.m[0][0]);
|
||||
universe[o].pos.y = f_mul(base_x, orbit.m[0][1]);
|
||||
universe[o].pos.z = int_to_f(300) + f_mul(base_x, orbit.m[0][2]);
|
||||
obj->rot = orbit;
|
||||
obj->pos.x = f_mul(bx, orbit.m[0][0]) + f_mul(by, orbit.m[1][0]) + f_mul(bz, orbit.m[2][0]);
|
||||
obj->pos.y = f_mul(bx, orbit.m[0][1]) + f_mul(by, orbit.m[1][1]) + f_mul(bz, orbit.m[2][1]);
|
||||
obj->pos.z = int_to_f(300) + f_mul(bx, orbit.m[0][2]) + f_mul(by, orbit.m[1][2]) + f_mul(bz, orbit.m[2][2]);
|
||||
```
|
||||
|
||||
Les trois composantes de `base_pos` (bx, by, bz) sont toutes prises en compte — les objets à `base_pos.y != 0` ou `base_pos.z != 0` sont correctement transformés.
|
||||
|
||||
La caméra reste à l'origine (+ translations clavier). L'effet visuel est celui d'un observateur qui orbite autour de la scène.
|
||||
|
||||
---
|
||||
|
|
@ -171,9 +190,12 @@ La caméra reste à l'origine (+ translations clavier). L'effet visuel est celui
|
|||
| A / E | Caméra haut / bas (axe Y) |
|
||||
| + / − | Orbite vertical (anglex ±3°) |
|
||||
| / / * | Orbite horizontal (angley ±3°) |
|
||||
| 1 / 2 / 3 | Mode fil-de-fer / caché / solide |
|
||||
| R | Reset caméra + angles |
|
||||
| Esc | Quitter |
|
||||
|
||||
Les touches étendues (F1–F12, flèches…) retournent `0` depuis `getch()` ; le scan code suivant est consommé sans effet.
|
||||
|
||||
---
|
||||
|
||||
## Points de vigilance
|
||||
|
|
@ -184,4 +206,7 @@ La caméra reste à l'origine (+ translations clavier). L'effet visuel est celui
|
|||
| Caméra sans rotation | La caméra n'a pas de matrice de vue — elle regarde toujours en +Z. L'orbite est simulée en faisant tourner la scène. Ajouter une matrice de vue si un vrai look-around est nécessaire. |
|
||||
| Clamp pz | pz clampé à int_to_f(20). Si un objet passe derrière la caméra (pz < 0 avant clamp), il sera projeté incorrectement. |
|
||||
| Modes fil-de-fer | MODE_WIRE, MODE_HIDDEN opérationnels. Le champ `face.force_wire` permet de forcer le fil-de-fer face par face en MODE_SOLID. |
|
||||
| Z-test | `scanline_gouraud_c` et `draw_line_z` utilisent tous les deux `zv < zbuf` (strict), garantissant un comportement cohérent. |
|
||||
| mat3_mul | Sûre contre l'aliasing (res peut être identique à a ou b). |
|
||||
| I/O mesh | `save_mesh` / `load_mesh` / `free_mesh` disponibles dans `geometry.c` mais non utilisées depuis `main.c`. |
|
||||
| Face.color | Le champ `face.color` a été supprimé : la couleur est portée par `obj->color`. `face.force_wire` reste le seul flag par-face. |
|
||||
|
|
|
|||
Loading…
Reference in a new issue