diff options
Diffstat (limited to 'examples/demos/n00bdemo/lightdemo.c')
| -rw-r--r-- | examples/demos/n00bdemo/lightdemo.c | 326 |
1 files changed, 163 insertions, 163 deletions
diff --git a/examples/demos/n00bdemo/lightdemo.c b/examples/demos/n00bdemo/lightdemo.c index 5afd5c8..26da9ef 100644 --- a/examples/demos/n00bdemo/lightdemo.c +++ b/examples/demos/n00bdemo/lightdemo.c @@ -3,8 +3,8 @@ #include <psxgte.h> #include <psxgpu.h> #include <inline_c.h> +#include <smd/smd.h> #include "disp.h" -#include "smd.h" extern MATRIX lgt_colmtx; @@ -14,227 +14,227 @@ extern SMD *o_lightbulb; void sort_overlay(int showlotl); void lightdemo() { - + /* The point lighting demo is perhaps the most impressive part of n00bDEMO. A more streamlined version of this demo where you control various attributes of the light source such as position, intensity and color might be made as a dedicated example program in the future. - + The point lighting trick is actually not that too complicated. You basically calculate the distance and direction vector of two points which are the light source and the vertex of a polygon. - + Calculating the normal whose result can later be used to calculate the distance between two points is achieved with: - + vec_dir.vx = lgt_point.vx - pri_vert.vx; vec_dir.vy = lgt_point.vy - pri_vert.vy; vec_dir.vz = lgt_point.vz - pri_vert.vz; - + The intensity is calculated with (this might not be accurate but this is faster than applying a square root): - + i = 4096 - ( ( - (vec_dir.vx*vec_dir.vx) + - (vec_dir.vy*vec_dir.vy) + + (vec_dir.vx*vec_dir.vx) + + (vec_dir.vy*vec_dir.vy) + (vec_dir.vz*vec_dir.vz) ) >> 7 ); - + // Clip minimum intensity if( i < 0 ) i = 0; - + This intensity value is then used to set the color of the light source through the light color matrix. - + col_mtx.m[0][0] = i; col_mtx.m[1][0] = i; col_mtx.m[2][0] = i; gte_SetColorMatrix( &col_mtx ); - + The direction vector can then be used as the direction of the light source. It is recommended to normalize it first to prevent possible overflow related issues. - + VectorNormalS( &vec_dir, &vec_norm ); - + lgt_mtx.m[0][0] = vec_norm.vx; lgt_mtx.m[0][1] = vec_norm.vy; lgt_mtx.m[0][2] = vec_norm.vz; - + gte_SetLightMatrix( &lgt_mtx ); - + This operation is then performed for each point of a polygon to achieve a nice smooth shaded point lighting effect. The macros used are still the same as doing light source calculation with the GTE the normal way. - + 3D geometry still requires normal data as with most lighting processing operations. 'Flat' normals (faces with a single normal vector) work best on flat surfaces while 'smooth' normals (faces with normals on each point) work best on round or curved surfaces. - + */ - + int i,p_ang; - + SC_OT s_ot; - + SVECTOR rot; VECTOR pos; SMD_PRIM s_pri; - + VECTOR l_point; SVECTOR nrm; - + MATRIX lmtx,llmtx,omtx; - + SVECTOR orot = { 0 }; - + int timeout = SCENE_TIME; - + // Set clear color to black setRGB0( &draw, 0, 0, 0 ); - + // Base values for the environment geometry setVector( &pos, 0, 0, 600 ); setVector( &rot, 512, 0, 0 ); - + // Set base tpage value for the SMD drawing routines smdSetBaseTPage( 0x200 ); - + // Set back or ambient color to black for pure darkness gte_SetBackColor( 0, 0, 0 ); - + memset( &llmtx, 0, sizeof(MATRIX) ); - - + + // demo loop while( 1 ) { - + char buff[32]; - + RotMatrix( &rot, &mtx ); TransMatrix( &mtx, &pos ); - + rot.vy += 4; - + gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - - + + setVector( &l_point, (icos( p_ang )>>2)>>2, -350+(icos( p_ang<<1 )>>4), (isin( p_ang )>>2)>>2 ); p_ang += 16; - - + + // Begin parsing the SMD data of the environment OpenSMD( o_world ); - + // Prototype point lighting renderer while( ReadSMD( &s_pri ) ) { - + VECTOR v_dir; SVECTOR v_nrm; VECTOR v_sqr; - + int flg; - + if( s_pri.prim_id.texture ) { - + POLY_GT4 *pri; - + // Perform standard rotate, translate and perspective // transformation of the geometry pri = (POLY_GT4*)nextpri; - - gte_ldv3( + + gte_ldv3( &o_world->p_verts[s_pri.v0], &o_world->p_verts[s_pri.v1], &o_world->p_verts[s_pri.v2] ); - + gte_rtpt(); - + gte_nclip(); // Backface culling - + gte_stopz( &flg ); - + if( flg < 0 ) continue; - + gte_stsxy3( &pri->x0, &pri->x1, &pri->x2 ); - + gte_ldv0( &o_world->p_verts[s_pri.v3] ); gte_rtps(); - + gte_avsz4(); // Depth sort gte_stotz( &flg ); - + if( (flg>>2) >= OT_LEN ) continue; - + gte_stsxy( &pri->x3 ); - - + + // Load base color of polygon to GTE gte_ldrgb( &s_pri.r0 ); - + // Load normal of polygon gte_ldv0( &o_world->p_norms[s_pri.n0] ); - + // Calculate the direction between the vertex of the // polygon and the light source v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v0].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v0].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v0].vz; - + // Calculate distance and light intensity using square i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + // Clip minimum intensity if( i < 0 ) i = 0; - + // Set intensity to color matrix llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; gte_SetColorMatrix( &llmtx ); - + // Normalize light direction and set it to light matrix VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; lmtx.m[0][1] = v_nrm.vy; lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); - + // Calculate (output is retrieved through gte_strgb) gte_nccs(); - - + + // Repeat process for the next 3 vertices v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v1].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v1].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v1].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - - + + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r0 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -242,25 +242,25 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v2].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v2].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v2].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r1 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -268,25 +268,25 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v3].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v3].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v3].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r2 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -294,70 +294,70 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - - setUV4( pri, + + setUV4( pri, s_pri.tu0, s_pri.tv0, - s_pri.tu1, s_pri.tv1, + s_pri.tu1, s_pri.tv1, s_pri.tu2, s_pri.tv2, s_pri.tu3, s_pri.tv3 ); - + pri->tpage = s_pri.tpage; pri->clut = s_pri.clut; - + setPolyGT4( pri ); addPrim( ot[db]+(flg>>2), pri ); nextpri += sizeof(POLY_GT4); - + gte_strgb( &pri->r3 ); - + } else { - + POLY_G4 *pri; - + pri = (POLY_G4*)nextpri; - - gte_ldv3( + + gte_ldv3( &o_world->p_verts[s_pri.v0], &o_world->p_verts[s_pri.v1], &o_world->p_verts[s_pri.v2] ); - + gte_rtpt(); - + gte_nclip(); - + gte_stopz( &flg ); - + if( flg < 0 ) continue; - + gte_stsxy3( &pri->x0, &pri->x1, &pri->x2 ); - + gte_ldv0( &o_world->p_verts[s_pri.v3] ); gte_rtps(); - + gte_avsz4(); gte_stotz( &flg ); - + if( (flg>>2) >= OT_LEN ) continue; - + gte_stsxy( &pri->x3 ); - + gte_ldrgb( &s_pri.r0 ); gte_ldv0( &o_world->p_norms[s_pri.n0] ); - + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v0].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v0].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v0].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; @@ -368,26 +368,26 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - - + + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v1].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v1].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v1].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r0 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -395,25 +395,25 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v2].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v2].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v2].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r1 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -421,25 +421,25 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v3].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v3].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v3].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r2 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -447,49 +447,49 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - + setPolyG4( pri ); addPrim( ot[db]+(flg>>2), pri ); - + nextpri += sizeof(POLY_G4); - + gte_strgb( &pri->r3 ); - + } - + } - - + + // Sort the light bulb to represent the position of the light source orot.vx += 32; orot.vy += 32; orot.vz += 32; - + RotMatrix( &orot, &omtx ); TransMatrix( &omtx, &l_point ); - + CompMatrixLV( &mtx, &omtx, &mtx ); gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - + s_ot.ot = ot[db]; s_ot.otlen = OT_LEN; s_ot.zdiv = 2; s_ot.zoff = 0; - + nextpri = smdSortModel( &s_ot, nextpri, o_lightbulb ); - + // Sort overlay and display sort_overlay( 1 ); - + display(); - + timeout--; if( timeout < 0 ) break; - + } - + }
\ No newline at end of file |
