From 25669bf7362645d1c0fee9d7cb07f4a6b0b34903 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Mon, 3 Oct 2016 07:41:39 +0300 Subject: [PATCH] added lighting --- src/3dgfx.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/3dgfx.h | 15 +++++++- src/polytest.c | 6 +++ 3 files changed, 134 insertions(+), 2 deletions(-) diff --git a/src/3dgfx.c b/src/3dgfx.c index 41b3959..30721c8 100644 --- a/src/3dgfx.c +++ b/src/3dgfx.c @@ -11,6 +11,18 @@ typedef float g3d_matrix[16]; #define MAX_VBUF_SIZE 256 +#define MAX_LIGHTS 4 + +struct light { + float x, y, z; + float r, g, b; +}; + +struct material { + float kd[3]; + float ks[3]; + float shin; +}; struct g3d_state { unsigned int opt; @@ -23,6 +35,10 @@ struct g3d_state { g3d_matrix norm_mat; + float ambient[3]; + struct light lt[MAX_LIGHTS]; + struct material mtl; + int width, height; void *pixels; }; @@ -53,6 +69,13 @@ int g3d_init(void) g3d_matrix_mode(i); g3d_load_identity(); } + + for(i=0; imat[which][top]; } +void g3d_light_pos(int idx, float x, float y, float z) +{ + int mvtop = st->mtop[G3D_MODELVIEW]; + + st->lt[idx].x = x; + st->lt[idx].y = y; + st->lt[idx].z = z; + + xform4_vec3(st->mat[G3D_MODELVIEW][mvtop], &st->lt[idx].x); +} + +void g3d_light_color(int idx, float r, float g, float b) +{ + st->lt[idx].r = r; + st->lt[idx].g = g; + st->lt[idx].b = b; +} + +void g3d_light_ambient(float r, float g, float b) +{ + st->ambient[0] = r; + st->ambient[1] = g; + st->ambient[2] = b; +} + +void g3d_mtl_diffuse(float r, float g, float b) +{ + st->mtl.kd[0] = r; + st->mtl.kd[1] = g; + st->mtl.kd[2] = b; +} + +void g3d_mtl_specular(float r, float g, float b) +{ + st->mtl.ks[0] = r; + st->mtl.ks[1] = g; + st->mtl.ks[2] = b; +} + +void g3d_mtl_shininess(float shin) +{ + st->mtl.shin = shin; +} + void g3d_draw(int prim, const struct g3d_vertex *varr, int varr_size) { g3d_draw_indexed(prim, varr, varr_size, 0, 0); @@ -374,7 +441,53 @@ static void xform3_vec3(const float *mat, float *vec) vec[2] = z; } +#define NORMALIZE(v) \ + do { \ + float len = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); \ + if(len != 0.0) { \ + float s = 1.0 / len; \ + v[0] *= s; \ + v[1] *= s; \ + v[2] *= s; \ + } \ + } while(0) + static void shade(struct g3d_vertex *v) { - v->r = v->g = v->b = 255; + int i, r, g, b; + float color[3]; + + color[0] = st->ambient[0] * st->mtl.kd[0]; + color[1] = st->ambient[1] * st->mtl.kd[1]; + color[2] = st->ambient[2] * st->mtl.kd[2]; + + for(i=0; iopt & (G3D_LIGHT0 << i))) { + continue; + } + + ldir[0] = st->lt[i].x - v->x; + ldir[1] = st->lt[i].y - v->y; + ldir[2] = st->lt[i].z - v->z; + NORMALIZE(ldir); + + if((ndotl = v->nx * ldir[0] + v->ny * ldir[1] + v->nz * ldir[2]) < 0.0f) { + ndotl = 0.0f; + } + + color[0] += st->mtl.kd[0] * st->lt[i].r * ndotl; + color[1] += st->mtl.kd[1] * st->lt[i].g * ndotl; + color[2] += st->mtl.kd[2] * st->lt[i].b * ndotl; + } + + r = color[0] * 255.0; + g = color[1] * 255.0; + b = color[2] * 255.0; + + v->r = r > 255 ? 255 : r; + v->g = g > 255 ? 255 : g; + v->b = b > 255 ? 255 : b; } diff --git a/src/3dgfx.h b/src/3dgfx.h index 4a3cde5..ee9de63 100644 --- a/src/3dgfx.h +++ b/src/3dgfx.h @@ -22,7 +22,11 @@ enum { G3D_CULL_FACE = 1, G3D_DEPTH_TEST = 2, /* XXX not implemented */ G3D_LIGHTING = 4, - G3D_TEXTURE = 8, + G3D_LIGHT0 = 8, + G3D_LIGHT1 = 16, + G3D_LIGHT2 = 32, + G3D_LIGHT3 = 64, + G3D_TEXTURE = 128, G3D_ALL = 0x7fffffff }; @@ -74,6 +78,15 @@ void g3d_perspective(float vfov, float aspect, float znear, float zfar); const float *g3d_get_matrix(int which, float *m); +void g3d_light_pos(int idx, float x, float y, float z); +void g3d_light_color(int idx, float r, float g, float b); + +void g3d_light_ambient(float r, float g, float b); + +void g3d_mtl_diffuse(float r, float g, float b); +void g3d_mtl_specular(float r, float g, float b); +void g3d_mtl_shininess(float shin); + void g3d_draw(int prim, const struct g3d_vertex *varr, int varr_size); void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size, const int16_t *iarr, int iarr_size); diff --git a/src/polytest.c b/src/polytest.c index 826b0b0..58fdb41 100644 --- a/src/polytest.c +++ b/src/polytest.c @@ -74,6 +74,8 @@ static void start(long trans_time) g3d_perspective(50.0, 1.3333333, 0.5, 100.0); g3d_enable(G3D_CULL_FACE); + g3d_enable(G3D_LIGHTING); + g3d_enable(G3D_LIGHT0); } static void update(void) @@ -113,7 +115,11 @@ static void draw(void) g3d_rotate(phi, 1, 0, 0); g3d_rotate(theta, 0, 1, 0); + g3d_light_pos(0, -10, 10, 20); + zsort(&torus); + + g3d_mtl_diffuse(0.3, 0.6, 1.0); draw_mesh(&torus); /*draw_mesh(&cube);*/ -- 1.7.10.4