add flat & flat shading render
This commit is contained in:
parent
a89bea929a
commit
0d98a2077b
6 changed files with 139 additions and 2 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
# Moteur 3D DOS (TESTING)
|
# Moteur 3D DOS (TESTING)
|
||||||
|
|
||||||
|
**Version : 0.15**
|
||||||
|
|
||||||
## Vue d'ensemble
|
## Vue d'ensemble
|
||||||
|
|
||||||
Moteur 3D software en C ciblant le DOS 32-bit via l'extender **CauseWay** (ou DOS/4GW).
|
Moteur 3D software en C ciblant le DOS 32-bit via l'extender **CauseWay** (ou DOS/4GW).
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
# Moteur 3D DOS (TESTING)
|
# Moteur 3D DOS (TESTING)
|
||||||
|
|
||||||
|
**Version : 0.15**
|
||||||
|
|
||||||
## Vue d'ensemble
|
## Vue d'ensemble
|
||||||
|
|
||||||
Moteur 3D software en C ciblant le DOS 32-bit via l'extender **CauseWay** (ou DOS/4GW).
|
Moteur 3D software en C ciblant le DOS 32-bit via l'extender **CauseWay** (ou DOS/4GW).
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,11 @@ int main(void) {
|
||||||
int anglex, angley, key, render, o;
|
int anglex, angley, key, render, o;
|
||||||
fixed bx, by, bz, distance;
|
fixed bx, by, bz, distance;
|
||||||
|
|
||||||
|
printf("Moteur 3D DOS (TESTING) - Version 0.15\n");
|
||||||
|
printf("Compile le %s a %s\n\n", __DATE__, __TIME__);
|
||||||
|
printf("Appuyez sur une touche pour demarrer le rendu...\n");
|
||||||
|
getch();
|
||||||
|
|
||||||
anglex = angley = key = 0;
|
anglex = angley = key = 0;
|
||||||
render = MODE_SOLID;
|
render = MODE_SOLID;
|
||||||
distance = int_to_f(300);
|
distance = int_to_f(300);
|
||||||
|
|
@ -122,7 +127,9 @@ int main(void) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 59: render = MODE_WIRE; break; /* F1 */
|
case 59: render = MODE_WIRE; break; /* F1 */
|
||||||
case 60: render = MODE_HIDDEN; break; /* F2 */
|
case 60: render = MODE_HIDDEN; break; /* F2 */
|
||||||
case 61: render = MODE_SOLID; break; /* F3 */
|
case 61: render = MODE_FLAT; break; /* F3 */
|
||||||
|
case 62: render = MODE_FLAT_SHADING; break; /* F4 */
|
||||||
|
case 63: render = MODE_SOLID; break; /* F5 */
|
||||||
case 71: distance -= int_to_f(10); break; /* Home : Rapprocher le centre */
|
case 71: distance -= int_to_f(10); break; /* Home : Rapprocher le centre */
|
||||||
case 79: distance += int_to_f(10); break; /* End : Eloigner le centre */
|
case 79: distance += int_to_f(10); break; /* End : Eloigner le centre */
|
||||||
case 72: anglex = ((anglex - 3) % 360 + 360) % 360; break; /* Flèche Haut */
|
case 72: anglex = ((anglex - 3) % 360 + 360) % 360; break; /* Flèche Haut */
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,9 @@
|
||||||
|
|
||||||
#define MODE_WIRE 0
|
#define MODE_WIRE 0
|
||||||
#define MODE_HIDDEN 1
|
#define MODE_HIDDEN 1
|
||||||
#define MODE_SOLID 2
|
#define MODE_FLAT 2
|
||||||
|
#define MODE_FLAT_SHADING 3
|
||||||
|
#define MODE_SOLID 4
|
||||||
|
|
||||||
#define SCREEN_W 320
|
#define SCREEN_W 320
|
||||||
#define SCREEN_H 200
|
#define SCREEN_H 200
|
||||||
|
|
@ -141,6 +143,7 @@ void flip(void);
|
||||||
void close_vga(void);
|
void close_vga(void);
|
||||||
|
|
||||||
void fill_triangle_gouraud(Point2D *p1, Point2D *p2, Point2D *p3, uint8_t base_color);
|
void fill_triangle_gouraud(Point2D *p1, Point2D *p2, Point2D *p3, uint8_t base_color);
|
||||||
|
void fill_triangle_flat(Point2D *p1, Point2D *p2, Point2D *p3, uint8_t color);
|
||||||
void draw_line_z(Point2D *p1, Point2D *p2, uint8_t col, int z_test);
|
void draw_line_z(Point2D *p1, Point2D *p2, uint8_t col, int z_test);
|
||||||
|
|
||||||
void save_mesh(Mesh *m, const char *fn);
|
void save_mesh(Mesh *m, const char *fn);
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,9 @@ void render_universe(Universe *uni, Camera *cam, int mode) {
|
||||||
Object3D *obj;
|
Object3D *obj;
|
||||||
Face *f;
|
Face *f;
|
||||||
Point2D *p1, *p2, *p3;
|
Point2D *p1, *p2, *p3;
|
||||||
|
fixed avg_i;
|
||||||
|
int s;
|
||||||
|
uint8_t shade;
|
||||||
|
|
||||||
for (o = 0; o < uni->num_objects; o++) {
|
for (o = 0; o < uni->num_objects; o++) {
|
||||||
obj = &uni->objects[o];
|
obj = &uni->objects[o];
|
||||||
|
|
@ -156,6 +159,33 @@ void render_universe(Universe *uni, Camera *cam, int mode) {
|
||||||
draw_line_z(p3, p1, wire_col, 1);
|
draw_line_z(p3, p1, wire_col, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MODE_FLAT:
|
||||||
|
if (front) {
|
||||||
|
if (f->force_wire) {
|
||||||
|
draw_line_z(p1, p2, wire_col, 1);
|
||||||
|
draw_line_z(p2, p3, wire_col, 1);
|
||||||
|
draw_line_z(p3, p1, wire_col, 1);
|
||||||
|
} else {
|
||||||
|
fill_triangle_flat(p1, p2, p3, wire_col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MODE_FLAT_SHADING:
|
||||||
|
if (front) {
|
||||||
|
if (f->force_wire) {
|
||||||
|
draw_line_z(p1, p2, wire_col, 1);
|
||||||
|
draw_line_z(p2, p3, wire_col, 1);
|
||||||
|
draw_line_z(p3, p1, wire_col, 1);
|
||||||
|
} else {
|
||||||
|
avg_i = (p1->intensity + p2->intensity + p3->intensity) / 3;
|
||||||
|
s = f_to_int(avg_i);
|
||||||
|
if (s < 0) shade = 0;
|
||||||
|
else if (s > 15) shade = 15;
|
||||||
|
else shade = (uint8_t)s;
|
||||||
|
fill_triangle_flat(p1, p2, p3, (uint8_t)((obj->color << 4) | shade));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MODE_SOLID:
|
case MODE_SOLID:
|
||||||
default:
|
default:
|
||||||
if (front) {
|
if (front) {
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,99 @@ void fill_triangle_gouraud(Point2D *p1, Point2D *p2, Point2D *p3, uint8_t base_c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Rendu d'une scanline avec z-buffer (couleur unie) */
|
||||||
|
void scanline_flat_c(int width, uint8_t *dest, uint16_t *zbuf,
|
||||||
|
fixed z, fixed dz_step, uint8_t color) {
|
||||||
|
int i;
|
||||||
|
uint16_t zv;
|
||||||
|
|
||||||
|
for (i = 0; i < width; i++) {
|
||||||
|
zv = (uint16_t)(z >> 16);
|
||||||
|
if (zv < zbuf[i]) {
|
||||||
|
zbuf[i] = zv;
|
||||||
|
dest[i] = color;
|
||||||
|
}
|
||||||
|
z += dz_step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_triangle_flat(Point2D *p1, Point2D *p2, Point2D *p3, uint8_t color) {
|
||||||
|
int y, width, start_x, end_x, clip_x, w, second_half, total_height;
|
||||||
|
fixed dx13, dz13, xA, zA, xB, zB, dx12, dz12, dx23, dz23;
|
||||||
|
fixed cx1, cz1, cx2, cz2, tx, tz;
|
||||||
|
fixed dz_step, start_z;
|
||||||
|
uint8_t *dest;
|
||||||
|
uint16_t *zbuf;
|
||||||
|
|
||||||
|
/* Tri des points par ordonnée (Y) */
|
||||||
|
if (p1->y > p2->y) swap_pt(&p1, &p2);
|
||||||
|
if (p1->y > p3->y) swap_pt(&p1, &p3);
|
||||||
|
if (p2->y > p3->y) swap_pt(&p2, &p3);
|
||||||
|
|
||||||
|
total_height = p3->y - p1->y;
|
||||||
|
if (total_height == 0) return;
|
||||||
|
|
||||||
|
/* Gradients pour le côté long (p1 vers p3) */
|
||||||
|
dx13 = ((p3->x - p1->x) << 16) / total_height;
|
||||||
|
dz13 = (p3->z - p1->z) / total_height;
|
||||||
|
|
||||||
|
xA = int_to_f(p1->x); zA = p1->z;
|
||||||
|
if (p1->y == p2->y) {
|
||||||
|
xB = int_to_f(p2->x); zB = p2->z;
|
||||||
|
} else {
|
||||||
|
xB = xA; zB = zA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gradients pour les côtés courts */
|
||||||
|
dx12 = (p2->y > p1->y) ? ((p2->x - p1->x) << 16) / (p2->y - p1->y) : 0;
|
||||||
|
dz12 = (p2->y > p1->y) ? (p2->z - p1->z) / (p2->y - p1->y) : 0;
|
||||||
|
|
||||||
|
dx23 = (p3->y > p2->y) ? ((p3->x - p2->x) << 16) / (p3->y - p2->y) : 0;
|
||||||
|
dz23 = (p3->y > p2->y) ? (p3->z - p2->z) / (p3->y - p2->y) : 0;
|
||||||
|
|
||||||
|
for (y = p1->y; y < p3->y; y++) {
|
||||||
|
second_half = (y >= p2->y);
|
||||||
|
cx1 = xA; cz1 = zA;
|
||||||
|
cx2 = xB; cz2 = zB;
|
||||||
|
|
||||||
|
/* Tri horizontal */
|
||||||
|
if (cx1 > cx2) {
|
||||||
|
tx = cx1; cx1 = cx2; cx2 = tx;
|
||||||
|
tz = cz1; cz1 = cz2; cz2 = tz;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_x = f_to_int(cx1);
|
||||||
|
end_x = f_to_int(cx2) + 1;
|
||||||
|
width = end_x - start_x;
|
||||||
|
|
||||||
|
if (y >= 0 && y < SCREEN_H && width > 0) {
|
||||||
|
dz_step = (cz2 - cz1) / width;
|
||||||
|
|
||||||
|
clip_x = (start_x < 0) ? 0 : start_x;
|
||||||
|
w = width - (clip_x - start_x);
|
||||||
|
if (clip_x + w > SCREEN_W) w = SCREEN_W - clip_x;
|
||||||
|
|
||||||
|
if (w > 0) {
|
||||||
|
start_z = cz1 + (clip_x - start_x) * dz_step;
|
||||||
|
dest = backbuffer + (y * SCREEN_W) + clip_x;
|
||||||
|
zbuf = zbuffer + (y * SCREEN_W) + clip_x;
|
||||||
|
|
||||||
|
scanline_flat_c(w, dest, zbuf, start_z, dz_step, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xA += dx13; zA += dz13;
|
||||||
|
if (!second_half) {
|
||||||
|
xB += dx12; zB += dz12;
|
||||||
|
} else {
|
||||||
|
if (y == p2->y) {
|
||||||
|
xB = int_to_f(p2->x); zB = p2->z;
|
||||||
|
}
|
||||||
|
xB += dx23; zB += dz23;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void draw_line_z(Point2D *p1, Point2D *p2, uint8_t col, int z_test) {
|
void draw_line_z(Point2D *p1, Point2D *p2, uint8_t col, int z_test) {
|
||||||
int dx, dy, sx, sy, err, steps, x, y, e2;
|
int dx, dy, sx, sy, err, steps, x, y, e2;
|
||||||
fixed z_step, cz;
|
fixed z_step, cz;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue