#include #include #include #include #include "globals.h" #include "states.h" #include "util.h" #include "lights.h" /* creates and binds an ambient light with rgb color r, g, b and attenuation factors of k0, k1, and k2 also specifies two sided lighting calculations with twoside */ void make_ambient_light(float r, float g, float b, float k0, float k1, float k2, float twoside) { float props[14]; /* AMBIENT LIGHT */ props[0] = AMBIENT; props[1] = r; /* red */ props[2] = g; /* green */ props[3] = b; /* blue */ props[4] = ATTENUATION; props[5] = k0; props[6] = k1; props[7] = ATTENUATION2; props[8] = k2; props[9] = LOCALVIEWER; props[10] = 0.0; props[11] = TWOSIDE; props[12] = twoside; props[13] = LMNULL; lmdef(DEFLMODEL, 1, 14, props); lmbind(LMODEL, 1); } /* creates and binds a directional light with rgb color r, g, b, and ambient rgb color ar, ag, ab, at a direction (x, y, z) NOTE: gl does light direction in the opposite sense, so I change direction to negative, so the direction specified is exactly the direction in world coordinates */ void make_directional_light(float r, float g, float b, float ar, float ag, float ab, float x, float y, float z) { float props[14]; if (gstate.num_lights > MAXLIGHTS) return; else gstate.num_lights++; /* DIRECTIONAL LIGHT */ props[0] = AMBIENT; props[1] = ar; props[2] = ag; props[3] = ab; props[4] = LCOLOR; props[5] = r; /* red */ props[6] = g; /* green */ props[7] = b; /* blue */ props[8] = POSITION; props[9] = -x; /* x */ props[10] = -y; /* y */ props[11] = -z; /* z */ props[12] = 0.0; /* at infinity */ props[13] = LMNULL; lmdef(DEFLIGHT, gstate.num_lights, 14, props); lmbind(LIGHT0+gstate.num_lights, gstate.num_lights); } /* creates and binds a point light of rgb color r, g, b and ambient color ar, ag, ab, at point (x, y, z) */ void make_point_light(float r, float g, float b, float ar, float ag, float ab, float x, float y, float z) { float props[14]; if (gstate.num_lights > MAXLIGHTS) return; else gstate.num_lights++; /* POINT LIGHTS */ props[0] = AMBIENT; props[1] = ar; props[2] = ag; props[3] = ab; props[4] = LCOLOR; props[5] = r; /* red */ props[6] = g; /* green */ props[7] = b; /* blue */ props[8] = POSITION; props[9] = x; /* x */ props[10] = y; /* y */ props[11] = z; /* z */ props[12] = 1.0; /* local */ props[13] = LMNULL; lmdef(DEFLIGHT, gstate.num_lights, 14, props); lmbind(LIGHT0+gstate.num_lights, gstate.num_lights); } /* creates and binds a spot light with rgb color r, g, b, and ambient color ar, ag, ab, at position (posx, posy, posz) going at a direction (dirx, diry, dirz) with an exponent factor exp and angle of ang (angle is the angle of the spot light emitted) NOTE: gl does light direction in the opposite sense, so I change direction to negative, so the direction specified is exactly the direction in world coordinates */ void make_spot_light(float r, float g, float b, float ar, float ag, float ab, float posx, float posy, float posz, float dirx, float diry, float dirz, float exp, float ang) { float props[21]; if (gstate.num_lights > MAXLIGHTS) return; else gstate.num_lights++; /* SPOT LIGHTS */ props[0] = AMBIENT; props[1] = ar; props[2] = ag; props[3] = ab; props[4] = LCOLOR; props[5] = r; /* red */ props[6] = g; /* green */ props[7] = b; /* blue */ props[8] = POSITION; props[9] = posx; /* x */ props[10] = posy; /* y */ props[11] = posz; /* z */ props[12] = 1.0; props[13] = SPOTDIRECTION; props[14] = dirx; /* x */ props[15] = diry; /* y */ props[16] = dirz; /* z */ props[17] = SPOTLIGHT; props[18] = exp; /* exp: 0.0 - 128.0 */ props[19] = ang; /* ang: 0.0 - 90.0 */ props[20] = LMNULL; lmdef(DEFLIGHT, gstate.num_lights, 21, props); lmbind(LIGHT0+gstate.num_lights, gstate.num_lights); } /* creates a material with the given parameters */ void make_material(int id, float r, float g, float b, float ambient, float diffuse, float specular, float shininess, float emission, float alpha) { float props[30]; props[0] = ALPHA; /* 0.0 - 1.0; transparency */ props[1] = alpha; props[2] = AMBIENT; /* 0.0 - 1.0 */ props[3] = ambient * r; props[4] = ambient * g; props[5] = ambient * b; props[6] = COLORINDEXES; /* 0.0 - 1.0 */ props[7] = ambient; props[8] = diffuse; props[9] = specular; props[10] = DIFFUSE; /* 0.0 - 1.0 */ props[11] = diffuse * r; props[12] = diffuse * g; props[13] = diffuse * b; props[14] = EMISSION; /* 0.0 - 1.0 */ props[15] = emission * r; props[16] = emission * g; props[17] = emission * b; props[18] = SHININESS; props[19] = shininess; /* 0.0 - 128.0 */ props[20] = SPECULAR; /* 0.0 - 1.0 */ props[21] = specular * r; props[22] = specular * g; props[23] = specular * b; props[24] = LMNULL; lmdef(DEFMATERIAL, id, 25, props); } void load_texture(int id, char *texfile) { int xsize, ysize; unsigned long *data; float texprops[] = {TX_MINFILTER, TX_POINT, TX_MAGFILTER, TX_POINT, TX_WRAP, TX_REPEAT, TX_NULL}; sizeofimage(texfile, &xsize, &ysize); data = longimagedata(texfile); texdef2d(id, 4, xsize, ysize, data, 0, texprops); } /* creates a few texture arrays by reading a few rgb files */ void define_texture() { float tevprops[] = {TV_MODULATE, TV_NULL}; if (getgdesc(GD_TEXTURE) == 0) { fprintf(stderr, "texture mapping not available on this machine\n"); return; } /* texture environment */ tevdef(1, 0, tevprops); } /* defines a fog scene if density is zero, it uses the start and end of fog to interpolate the fog density at a distance from the viewer (simulates depthcue) otherwise it has a constant density of fog the fog has rgb color r, g, b */ void define_fog(float density, float start_fog, float end_fog, float r, float g, float b) { float params[5]; if (density == 0.0) { params[0] = start_fog; params[1] = end_fog; params[2] = r; params[3] = g; params[4] = b; fogvertex(FG_VTX_LIN, params); } else { params[0] = density; params[1] = r; params[2] = g; params[3] = b; fogvertex(FG_VTX_EXP2, params); } } long get_bytes(FILE *imgfile) { long pixel_bytes; int i; char c; pixel_bytes = 0; for (i=0; i<4; i++) { c = fgetc(imgfile); pixel_bytes += ((c<<24)-(8*i)); printf("%x ", c); } return pixel_bytes; }