Made lighting code work with actual RGB values and added feature to let certain objects emit colored dynamic light as well as let mine flash red when control center destroyed (OpenGL-only at the moment)

This commit is contained in:
zicodxx 2011-04-07 22:32:47 +02:00
parent 85f7be583f
commit 357e1b0144
23 changed files with 633 additions and 276 deletions

View file

@ -143,10 +143,10 @@ bool g3_check_and_draw_poly(int nv,g3s_point **pointlist,vms_vector *norm,vms_ve
return 255;
}
bool g3_check_and_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,grs_bitmap *bm,vms_vector *norm,vms_vector *pnt)
bool g3_check_and_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,g3s_lrgb *light_rgb,grs_bitmap *bm,vms_vector *norm,vms_vector *pnt)
{
if (do_facing_check(norm,pointlist,pnt))
return g3_draw_tmap(nv,pointlist,uvl_list,bm);
return g3_draw_tmap(nv,pointlist,uvl_list,light_rgb,bm);
else
return 255;
}
@ -246,7 +246,7 @@ bool must_clip_tmap_face(int nv,g3s_codes cc,grs_bitmap *bm);
//draw a texture-mapped face.
//returns 1 if off screen, 0 if drew
bool g3_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,grs_bitmap *bm)
bool g3_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,g3s_lrgb *light_rgb,grs_bitmap *bm)
{
int i;
g3s_point **bufptr;
@ -266,7 +266,7 @@ bool g3_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,grs_bitmap *bm)
p->p3_u = uvl_list[i].u;
p->p3_v = uvl_list[i].v;
p->p3_l = uvl_list[i].l;
p->p3_l = (light_rgb[i].r+light_rgb[i].g+light_rgb[i].b)/3;
p->p3_flags |= PF_UVS + PF_LS;

View file

@ -105,9 +105,59 @@ g3s_point *point_list[MAX_POINTS_PER_POLY];
int glow_num = -1;
// check a polymodel for it's color and return it
int g3_poly_get_color(void *model_ptr)
{
ubyte *p = model_ptr;
int color = 0;
while (w(p) != OP_EOF)
switch (w(p)) {
case OP_DEFPOINTS:
p += w(p+2)*sizeof(struct vms_vector) + 4;
break;
case OP_DEFP_START:
p += w(p+2)*sizeof(struct vms_vector) + 8;
break;
case OP_FLATPOLY: {
int nv = w(p+2);
if (g3_check_normal_facing(vp(p+4),vp(p+16)) > 0)
color = (w(p+28));
p += 30 + ((nv&~1)+1)*2;
break;
}
case OP_TMAPPOLY: {
int nv = w(p+2);
p += 30 + ((nv&~1)+1)*2 + nv*12;
break;
}
case OP_SORTNORM:
if (g3_check_normal_facing(vp(p+16),vp(p+4)) > 0) //facing
color = g3_poly_get_color(p+w(p+28));
else //not facing
color = g3_poly_get_color(p+w(p+30));
p += 32;
break;
case OP_RODBM:
p+=36;
break;
case OP_SUBCALL:
color = g3_poly_get_color(p+w(p+16));
p += 20;
break;
case OP_GLOW:
p += 4;
break;
default:
;
}
return color;
}
//calls the object interpreter to render an object. The object renderer
//is really a seperate pipeline. returns true if drew
bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix model_light,fix *glow_values)
bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,g3s_lrgb model_light,fix *glow_values)
{
ubyte *p = model_ptr;
@ -163,32 +213,40 @@ bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec
Assert( nv < MAX_POINTS_PER_POLY );
if (g3_check_normal_facing(vp(p+4),vp(p+16)) > 0) {
int i;
fix light;
g3s_lrgb light, lrgb_list[nv];
//calculate light from surface normal
if (glow_num < 0) { //no glow
light = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
light = f1_0/4 + (light*3)/4;
light = fixmul(light,model_light);
if (glow_num < 0) //no glow
{
light.r = light.g = light.b = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
light.r = f1_0/4 + (light.r*3)/4;
light.r = fixmul(light.r,model_light.r);
light.g = f1_0/4 + (light.g*3)/4;
light.g = fixmul(light.g,model_light.g);
light.b = f1_0/4 + (light.b*3)/4;
light.b = fixmul(light.b,model_light.b);
}
else { //yes glow
light = glow_values[glow_num];
else //yes glow
{
light.r = light.g = light.b = glow_values[glow_num];
glow_num = -1;
}
//now poke light into l values
uvl_list = (g3s_uvl *) (p+30+((nv&~1)+1)*2);
for (i=0;i<nv;i++)
uvl_list[i].l = light;
{
uvl_list[i].l = (light.r+light.g+light.b)/3;
lrgb_list[i].r = light.r;
lrgb_list[i].g = light.g;
lrgb_list[i].b = light.b;
}
for (i=0;i<nv;i++)
point_list[i] = Interp_point_list + wp(p+30)[i];
g3_draw_tmap(nv,point_list,uvl_list,model_bitmaps[w(p+28)]);
g3_draw_tmap(nv,point_list,uvl_list,lrgb_list,model_bitmaps[w(p+28)]);
}
p += 30 + ((nv&~1)+1)*2 + nv*12;
@ -219,11 +277,12 @@ bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec
case OP_RODBM: {
g3s_point rod_bot_p,rod_top_p;
g3s_lrgb rodbm_light = { f1_0, f1_0, f1_0 };
g3_rotate_point(&rod_bot_p,vp(p+20));
g3_rotate_point(&rod_top_p,vp(p+4));
g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),f1_0);
g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),rodbm_light);
p+=36;
break;
@ -267,7 +326,7 @@ int nest_count;
#endif
//alternate interpreter for morphing object
bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix model_light,vms_vector *new_points)
bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,g3s_lrgb model_light,vms_vector *new_points)
{
ubyte *p = model_ptr;
fix *glow_values = NULL;
@ -301,7 +360,7 @@ bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angve
int nv = w(p+2);
int i,ntris;
gr_setcolor(w(p+28));
gr_setcolor(55/*w(p+28)*/);
for (i=0;i<2;i++)
point_list[i] = Interp_point_list + wp(p+30)[i];
@ -324,29 +383,39 @@ bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angve
case OP_TMAPPOLY: {
int nv = w(p+2);
g3s_uvl *uvl_list;
g3s_lrgb light, lrgb_list[nv];
g3s_uvl morph_uvls[3];
int i,ntris;
fix light;
//calculate light from surface normal
if (glow_num < 0) { //no glow
light = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
light = f1_0/4 + (light*3)/4;
light = fixmul(light,model_light);
if (glow_num < 0) //no glow
{
light.r = light.g = light.b = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
light.r = f1_0/4 + (light.r*3)/4;
light.r = fixmul(light.r,model_light.r);
light.g = f1_0/4 + (light.g*3)/4;
light.g = fixmul(light.g,model_light.g);
light.b = f1_0/4 + (light.b*3)/4;
light.b = fixmul(light.b,model_light.b);
}
else { //yes glow
light = glow_values[glow_num];
else //yes glow
{
light.r = light.g = light.b = glow_values[glow_num];
glow_num = -1;
}
//now poke light into l values
uvl_list = (g3s_uvl *) (p+30+((nv&~1)+1)*2);
for (i=0;i<nv;i++)
{
lrgb_list[i].r = light.r;
lrgb_list[i].g = light.g;
lrgb_list[i].b = light.b;
}
for (i=0;i<3;i++)
morph_uvls[i].l = light;
morph_uvls[i].l = (light.r+light.g+light.b)/3;
for (i=0;i<2;i++) {
point_list[i] = Interp_point_list + wp(p+30)[i];
@ -362,7 +431,7 @@ bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angve
morph_uvls[2].v = uvl_list[i].v;
i++;
g3_check_and_draw_tmap(3,point_list,uvl_list,model_bitmaps[w(p+28)],NULL,NULL);
g3_check_and_draw_tmap(3,point_list,uvl_list,lrgb_list,model_bitmaps[w(p+28)],NULL,NULL);
point_list[1] = point_list[2];
morph_uvls[1].u = morph_uvls[2].u;
@ -398,11 +467,12 @@ bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angve
case OP_RODBM: {
g3s_point rod_bot_p,rod_top_p;
g3s_lrgb rodbm_light = { f1_0, f1_0, f1_0 };
g3_rotate_point(&rod_bot_p,vp(p+20));
g3_rotate_point(&rod_top_p,vp(p+4));
g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),f1_0);
g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),rodbm_light);
p+=36;
break;

View file

@ -30,9 +30,11 @@ g3s_point rod_points[4];
g3s_point *rod_point_list[] = {&rod_points[0],&rod_points[1],&rod_points[2],&rod_points[3]};
g3s_uvl uvl_list[4] = { { 0x0200,0x0200,0 },
{ 0xfe00,0x0200,0 },
{ 0xfe00,0xfe00,0 },
{ 0x0200,0xfe00,0 }};
{ 0xfe00,0x0200,0 },
{ 0xfe00,0xfe00,0 },
{ 0x0200,0xfe00,0 } };
g3s_lrgb lrgb_list[4] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
//compute the corners of a rod. fills in vertbuf.
int calc_rod_corners(g3s_point *bot_point,fix bot_width,g3s_point *top_point,fix top_width)
@ -115,14 +117,17 @@ bool g3_draw_rod_flat(g3s_point *bot_point,fix bot_width,g3s_point *top_point,fi
//draw a bitmap object that is always facing you
//returns 1 if off screen, 0 if drew
bool g3_draw_rod_tmap(grs_bitmap *bitmap,g3s_point *bot_point,fix bot_width,g3s_point *top_point,fix top_width,fix light)
bool g3_draw_rod_tmap(grs_bitmap *bitmap,g3s_point *bot_point,fix bot_width,g3s_point *top_point,fix top_width,g3s_lrgb light)
{
if (calc_rod_corners(bot_point,bot_width,top_point,top_width))
return 0;
uvl_list[0].l = uvl_list[1].l = uvl_list[2].l = uvl_list[3].l = light;
uvl_list[0].l = uvl_list[1].l = uvl_list[2].l = uvl_list[3].l = (light.r+light.g+light.b)/3;
lrgb_list[0].r = lrgb_list[1].r = lrgb_list[2].r = lrgb_list[3].r = light.r;
lrgb_list[0].g = lrgb_list[1].g = lrgb_list[2].g = lrgb_list[3].g = light.g;
lrgb_list[0].b = lrgb_list[1].b = lrgb_list[2].b = lrgb_list[3].b = light.b;
return g3_draw_tmap(4,rod_point_list,uvl_list,bitmap);
return g3_draw_tmap(4,rod_point_list,uvl_list,lrgb_list,bitmap);
}
#ifndef __powerc

View file

@ -1,5 +1,9 @@
D1X-Rebirth Changelog
20110407
--------
3d/draw.c, 3d/interp.c, 3d/rod.c, arch/ogl/ogl.c, include/3d.h, include/ogl_init.h, main/endlevel.c, main/gamesave.c, main/lighting.c, main/lighting.h, main/menu.c, main/morph.c, main/multi.c, main/object.c, main/object.h, main/playsave.c, main/playsave.h, main/polyobj.c, main/polyobj.h, main/render.c, main/state.c, main/terrain.c: Made lighting code work with actual RGB values and added feature to let certain objects emit colored dynamic light as well as let mine flash red when control center destroyed (OpenGL-only at the moment)
20110405
--------
SConstruct, arch/win32/ipx.c, d1x.ini, include/args.h, main/inferno.c, main/menu.c, main/multi.h, main/net_ipx.h, main/net_udp.c, main/net_udp.h, misc/args.c: Client-side implementation for Tracker support by Matt "1360" Vandermeulen including improvements in udp_dns_filladdr and IPv4/IPv6 compability; Very little adjustments by me, too including IPv6 support for Windows (untested); Actual tracker code will follow later as seperate branch when it's done

View file

@ -869,7 +869,7 @@ extern void (*tmap_drawer_ptr)(grs_bitmap *bm,int nv,g3s_point **vertlist);
/*
* Everything texturemapped (walls, robots, ship)
*/
bool g3_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,grs_bitmap *bm)
bool g3_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,g3s_lrgb *light_rgb,grs_bitmap *bm)
{
int c, index2, index3, index4;
GLfloat vertex_array[nv*3];
@ -906,12 +906,16 @@ bool g3_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,grs_bitmap *bm)
vertex_array[index3+2] = -f2glf(pointlist[c]->p3_vec.z);
if (tmap_drawer_ptr == draw_tmap_flat) {
color_array[index4] = 0;
color_array[index4+1] = color_array[index4];
color_array[index4+2] = color_array[index4];
color_array[index4+3] = color_alpha;
} else {
color_array[index4] = bm->bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf(uvl_list[c].l);
color_array[index4] = bm->bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf(light_rgb[c].r);
color_array[index4+1] = bm->bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf(light_rgb[c].g);
color_array[index4+2] = bm->bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf(light_rgb[c].b);
color_array[index4+3] = color_alpha;
}
color_array[index4+1] = color_array[index4];
color_array[index4+2] = color_array[index4];
color_array[index4+3] = color_alpha;
texcoord_array[index2] = f2glf(uvl_list[c].u);
texcoord_array[index2+1] = f2glf(uvl_list[c].v);
}
@ -934,12 +938,12 @@ bool g3_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,grs_bitmap *bm)
/*
* Everything texturemapped with secondary texture (walls with secondary texture)
*/
bool g3_draw_tmap_2(int nv, g3s_point **pointlist, g3s_uvl *uvl_list, grs_bitmap *bmbot, grs_bitmap *bm, int orient)
bool g3_draw_tmap_2(int nv, g3s_point **pointlist, g3s_uvl *uvl_list, g3s_lrgb *light_rgb, grs_bitmap *bmbot, grs_bitmap *bm, int orient)
{
int c, index2, index3, index4;;
GLfloat vertex_array[nv*3], color_array[nv*4], texcoord_array[nv*2];
g3_draw_tmap(nv,pointlist,uvl_list,bmbot);//draw the bottom texture first.. could be optimized with multitexturing..
g3_draw_tmap(nv,pointlist,uvl_list,light_rgb,bmbot);//draw the bottom texture first.. could be optimized with multitexturing..
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
@ -974,9 +978,9 @@ bool g3_draw_tmap_2(int nv, g3s_point **pointlist, g3s_uvl *uvl_list, grs_bitmap
break;
}
color_array[index4] = bm->bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf(uvl_list[c].l);
color_array[index4+1] = color_array[c*4];
color_array[index4+2] = color_array[c*4];
color_array[index4] = bm->bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf(light_rgb[c].r);
color_array[index4+1] = bm->bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf(light_rgb[c].g);
color_array[index4+2] = bm->bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf(light_rgb[c].b);
color_array[index4+3] = (grd_curcanv->cv_fade_level >= GR_FADE_OFF)?1.0:(1.0 - (float)grd_curcanv->cv_fade_level / ((float)GR_FADE_LEVELS - 1.0));
vertex_array[index3] = f2glf(pointlist[c]->p3_vec.x);

View file

@ -54,6 +54,11 @@ typedef struct g3s_uvl {
fix u,v,l;
} g3s_uvl;
//Structure for storing light color. Also uses l of g3s-uvl to add/compute mono (white) light
typedef struct g3s_lrgb {
fix r,g,b;
} g3s_lrgb;
//Stucture to store clipping codes in a word
typedef struct g3s_codes {
ubyte or,and; //or is low byte, and is high byte
@ -192,7 +197,7 @@ bool g3_draw_poly(int nv,g3s_point **pointlist);
//draw a texture-mapped face.
//returns 1 if off screen, 0 if drew
bool g3_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,grs_bitmap *bm);
bool g3_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,g3s_lrgb *light_rgb,grs_bitmap *bm);
//draw a sortof sphere - i.e., the 2d radius is proportional to the 3d
//radius, but not to the distance from the eye
@ -209,7 +214,7 @@ int g3_draw_sphere(g3s_point *pnt,fix rad);
//g3_draw_poly().
//returns -1 if not facing, 1 if off screen, 0 if drew
bool g3_check_and_draw_poly(int nv,g3s_point **pointlist,vms_vector *norm,vms_vector *pnt);
bool g3_check_and_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,grs_bitmap *bm,vms_vector *norm,vms_vector *pnt);
bool g3_check_and_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,g3s_lrgb *light_rgb, grs_bitmap *bm,vms_vector *norm,vms_vector *pnt);
//draws a line. takes two points.
bool g3_draw_line(g3s_point *p0,g3s_point *p1);
@ -220,7 +225,7 @@ bool g3_draw_rod_flat(g3s_point *bot_point,fix bot_width,g3s_point *top_point,fi
//draw a bitmap object that is always facing you
//returns 1 if off screen, 0 if drew
bool g3_draw_rod_tmap(grs_bitmap *bitmap,g3s_point *bot_point,fix bot_width,g3s_point *top_point,fix top_width,fix light);
bool g3_draw_rod_tmap(grs_bitmap *bitmap,g3s_point *bot_point,fix bot_width,g3s_point *top_point,fix top_width,g3s_lrgb light);
//draws a bitmap with the specified 3d width & height
//returns 1 if off screen, 0 if drew
@ -237,13 +242,16 @@ void g3_set_interp_points(g3s_point *pointlist);
//calls the object interpreter to render an object. The object renderer
//is really a seperate pipeline. returns true if drew
bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix light,fix *glow_values);
bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,g3s_lrgb light,fix *glow_values);
//init code for bitmap models
void g3_init_polygon_model(void *model_ptr);
//alternate interpreter for morphing object
bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix light,vms_vector *new_points);
bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,g3s_lrgb light,vms_vector *new_points);
// check a polymodel for it's color and return it
int g3_poly_get_color(void *model_ptr);
// routine to convert little to big endian in polygon model data
void swap_polygon_model_data(ubyte *data);

View file

@ -101,7 +101,7 @@ void ogl_upixelc(int x, int y, int c);
void ogl_ulinec(int left, int top, int right, int bot, int c);
#include "3d.h"
bool g3_draw_tmap_2(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,grs_bitmap *bmbot,grs_bitmap *bm, int orient);
bool g3_draw_tmap_2(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,g3s_lrgb *light_rgb, grs_bitmap *bmbot,grs_bitmap *bm, int orient);
void ogl_draw_vertex_reticle(int cross,int primary,int secondary,int color,int alpha,int size_offs);
void ogl_toggle_depth_test(int enable);

View file

@ -821,11 +821,12 @@ void draw_exit_model()
{
vms_vector model_pos;
int f=15,u=0; //21;
g3s_lrgb lrgb = { f1_0, f1_0, f1_0 };
vm_vec_scale_add(&model_pos,&mine_exit_point,&mine_exit_orient.fvec,i2f(f));
vm_vec_scale_add2(&model_pos,&mine_exit_orient.uvec,i2f(u));
draw_polygon_model(&model_pos,&mine_exit_orient,NULL,(mine_destroyed)?destroyed_exit_modelnum:exit_modelnum,0,f1_0,NULL,NULL);
draw_polygon_model(&model_pos,&mine_exit_orient,NULL,(mine_destroyed)?destroyed_exit_modelnum:exit_modelnum,0,lrgb,NULL,NULL);
}
@ -841,6 +842,7 @@ void render_external_scene(fix eye_offset)
{
int orig_Render_depth = Render_depth;
Viewer_eye = Viewer->pos;
g3s_lrgb lrgb = { f1_0, f1_0, f1_0 };
if (eye_offset)
vm_vec_scale_add2(&Viewer_eye,&Viewer->orient.rvec,eye_offset);
@ -871,14 +873,14 @@ void render_external_scene(fix eye_offset)
if (! (p.p3_flags & PF_OVERFLOW)) {
Interpolation_method = 0;
//gr_bitmapm(f2i(p.p3_sx)-32,f2i(p.p3_sy)-32,satellite_bitmap);
g3_draw_rod_tmap(satellite_bitmap,&p,SATELLITE_WIDTH,&top_pnt,SATELLITE_WIDTH,f1_0);
g3_draw_rod_tmap(satellite_bitmap,&p,SATELLITE_WIDTH,&top_pnt,SATELLITE_WIDTH,lrgb);
Interpolation_method = save_im;
}
}
}
#ifdef STATION_ENABLED
draw_polygon_model(&station_pos,&vmd_identity_matrix,NULL,station_modelnum,0,f1_0,NULL,NULL);
draw_polygon_model(&station_pos,&vmd_identity_matrix,NULL,station_modelnum,0,lrgb,NULL,NULL);
#endif
#ifdef OGL

View file

@ -525,6 +525,7 @@ void read_object(object *obj,CFILE *f,int version)
#endif
obj->rtype.pobj_info.alt_textures = 0;
obj->rtype.pobj_info.lrgb.r = obj->rtype.pobj_info.lrgb.g = obj->rtype.pobj_info.lrgb.b = -1;
break;
}
@ -537,6 +538,7 @@ void read_object(object *obj,CFILE *f,int version)
obj->rtype.vclip_info.vclip_num = convert_vclip(cfile_read_int(f));
obj->rtype.vclip_info.frametime = cfile_read_fix(f);
obj->rtype.vclip_info.framenum = cfile_read_byte(f);
obj->rtype.vclip_info.lrgb.r = obj->rtype.vclip_info.lrgb.g = obj->rtype.vclip_info.lrgb.b = -1;
break;

View file

@ -34,16 +34,19 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#include "laser.h"
#include "timer.h"
#include "player.h"
#include "playsave.h"
#include "weapon.h"
#include "powerup.h"
#include "fvi.h"
#include "robot.h"
#include "multi.h"
#include "palette.h"
#include "bm.h"
#include "rle.h"
int Do_dynamic_light=1;
//int Use_fvi_lighting = 0;
fix Dynamic_light[MAX_VERTICES];
g3s_lrgb Dynamic_light[MAX_VERTICES];
#define LIGHTING_CACHE_SIZE 4096 // Must be power of 2!
#define LIGHTING_FRAME_DELTA 256 // Recompute cache value every 8 frames.
@ -121,12 +124,13 @@ Cache_hits++;
#define HEADLIGHT_SCALE (F1_0*10)
// ----------------------------------------------------------------------------------------------
void apply_light(fix obj_intensity, int obj_seg, vms_vector *obj_pos, int n_render_vertices, short *render_vertices, int objnum)
void apply_light(g3s_lrgb obj_light_emission, int obj_seg, vms_vector *obj_pos, int n_render_vertices, short *render_vertices, int objnum)
{
int vv;
if (obj_intensity) {
fix obji_64 = obj_intensity*64;
if (((obj_light_emission.r+obj_light_emission.g+obj_light_emission.b)/3) > 0)
{
fix obji_64 = ((obj_light_emission.r+obj_light_emission.g+obj_light_emission.b)/3)*64;
// for pretty dim sources, only process vertices in object's own segment.
// 12/04/95, MK, markers only cast light in own segment.
@ -147,7 +151,9 @@ void apply_light(fix obj_intensity, int obj_seg, vms_vector *obj_pos, int n_rend
if (dist < MIN_LIGHT_DIST)
dist = MIN_LIGHT_DIST;
Dynamic_light[vertnum] += fixdiv(obj_intensity, dist);
Dynamic_light[vertnum].r += fixdiv(obj_light_emission.r, dist);
Dynamic_light[vertnum].g += fixdiv(obj_light_emission.g, dist);
Dynamic_light[vertnum].b += fixdiv(obj_light_emission.b, dist);
}
}
}
@ -180,25 +186,48 @@ void apply_light(fix obj_intensity, int obj_seg, vms_vector *obj_pos, int n_rend
//} else
apply_light = 1;
if (apply_light) {
if (headlight_shift) {
fix dot;
vms_vector vec_to_point;
if (apply_light)
{
if (headlight_shift)
{
fix dot;
vms_vector vec_to_point;
vm_vec_sub(&vec_to_point, vertpos, obj_pos);
vm_vec_normalize_quick(&vec_to_point); // MK, Optimization note: You compute distance about 15 lines up, this is partially redundant
vm_vec_normalize_quick(&vec_to_point); // MK, Optimization note: You compute distance about 15 lines up, this is partially redundant
dot = vm_vec_dot(&vec_to_point, &Objects[objnum].orient.fvec);
if (dot < F1_0/2)
Dynamic_light[vertnum] += fixdiv(obj_intensity, fixmul(HEADLIGHT_SCALE, dist)); // Do the normal thing, but darken around headlight.
else {
if (Game_mode & GM_MULTI) {
if (dist < max_headlight_dist)
Dynamic_light[vertnum] += fixmul(fixmul(dot, dot), obj_intensity)/8;
} else
Dynamic_light[vertnum] += fixmul(fixmul(dot, dot), obj_intensity)/8;
{
// Do the normal thing, but darken around headlight.
Dynamic_light[vertnum].r += fixdiv(obj_light_emission.r, fixmul(HEADLIGHT_SCALE, dist));
Dynamic_light[vertnum].g += fixdiv(obj_light_emission.g, fixmul(HEADLIGHT_SCALE, dist));
Dynamic_light[vertnum].b += fixdiv(obj_light_emission.b, fixmul(HEADLIGHT_SCALE, dist));
}
} else
Dynamic_light[vertnum] += fixdiv(obj_intensity, dist);
else
{
if (Game_mode & GM_MULTI)
{
if (dist < max_headlight_dist)
{
Dynamic_light[vertnum].r += fixmul(fixmul(dot, dot), obj_light_emission.r)/8;
Dynamic_light[vertnum].g += fixmul(fixmul(dot, dot), obj_light_emission.g)/8;
Dynamic_light[vertnum].b += fixmul(fixmul(dot, dot), obj_light_emission.b)/8;
}
}
else
{
Dynamic_light[vertnum].r += fixmul(fixmul(dot, dot), obj_light_emission.r)/8;
Dynamic_light[vertnum].g += fixmul(fixmul(dot, dot), obj_light_emission.g)/8;
Dynamic_light[vertnum].b += fixmul(fixmul(dot, dot), obj_light_emission.b)/8;
}
}
}
else
{
Dynamic_light[vertnum].r += fixdiv(obj_light_emission.r, dist);
Dynamic_light[vertnum].g += fixdiv(obj_light_emission.g, dist);
Dynamic_light[vertnum].b += fixdiv(obj_light_emission.b, dist);
}
}
}
}
@ -207,93 +236,272 @@ void apply_light(fix obj_intensity, int obj_seg, vms_vector *obj_pos, int n_rend
}
}
#define FLASH_LEN_FIXED_SECONDS (F1_0/3)
#define FLASH_SCALE (3*F1_0/FLASH_LEN_FIXED_SECONDS)
#define FLASH_LEN_FIXED_SECONDS (F1_0/3)
#define FLASH_SCALE (3*F1_0/FLASH_LEN_FIXED_SECONDS)
// ----------------------------------------------------------------------------------------------
void cast_muzzle_flash_light(int n_render_vertices, short *render_vertices)
{
fix64 current_time;
int i;
short time_since_flash;
int i;
short time_since_flash;
current_time = timer_query();
for (i=0; i<MUZZLE_QUEUE_MAX; i++) {
if (Muzzle_data[i].create_time) {
for (i=0; i<MUZZLE_QUEUE_MAX; i++)
{
if (Muzzle_data[i].create_time)
{
time_since_flash = current_time - Muzzle_data[i].create_time;
if (time_since_flash < FLASH_LEN_FIXED_SECONDS)
apply_light((FLASH_LEN_FIXED_SECONDS - time_since_flash) * FLASH_SCALE, Muzzle_data[i].segnum, &Muzzle_data[i].pos, n_render_vertices, render_vertices, -1);
{
g3s_lrgb ml;
ml.r = ml.g = ml.b = ((FLASH_LEN_FIXED_SECONDS - time_since_flash) * FLASH_SCALE);
apply_light(ml, Muzzle_data[i].segnum, &Muzzle_data[i].pos, n_render_vertices, render_vertices, -1);
}
else
Muzzle_data[i].create_time = 0; // turn off this muzzle flash
{
Muzzle_data[i].create_time = 0; // turn off this muzzle flash
}
}
}
}
// Translation table to make flares flicker at different rates
fix Obj_light_xlate[16] =
{0x1234, 0x3321, 0x2468, 0x1735,
0x0123, 0x19af, 0x3f03, 0x232a,
0x2123, 0x39af, 0x0f03, 0x132a,
0x3123, 0x29af, 0x1f03, 0x032a};
// Flag array of objects lit last frame. Guaranteed to process this frame if lit last frame.
// Translation table to make flares flicker at different rates
fix Obj_light_xlate[16] = { 0x1234, 0x3321, 0x2468, 0x1735,
0x0123, 0x19af, 0x3f03, 0x232a,
0x2123, 0x39af, 0x0f03, 0x132a,
0x3123, 0x29af, 0x1f03, 0x032a };
// Flag array of objects lit last frame. Guaranteed to process this frame if lit last frame.
sbyte Lighting_objects[MAX_OBJECTS];
#define MAX_HEADLIGHTS 8
object *Headlights[MAX_HEADLIGHTS];
int Num_headlights;
#define MAX_HEADLIGHTS 8
object *Headlights[MAX_HEADLIGHTS];
int Num_headlights;
g3s_lrgb compute_lrgb_on(object *obj)
{
int i, x, y, color, count = 0, t_idx_s = -1, t_idx_e = -1;
g3s_lrgb t_color = {0,0,0}, obj_color = {255,255,255};
switch (obj->render_type)
{
case RT_POLYOBJ:
{
polymodel *po = &Polygon_models[obj->rtype.pobj_info.model_num];
if (po->n_textures <= 0)
{
int color = g3_poly_get_color(po->model_data);
if (color)
{
obj_color.r = gr_current_pal[color*3];
obj_color.g = gr_current_pal[color*3+1];
obj_color.b = gr_current_pal[color*3+2];
}
}
else
{
t_idx_s = ObjBitmaps[ObjBitmapPtrs[po->first_texture]].index;
t_idx_e = t_idx_s + po->n_textures - 1;
}
break;
}
case RT_WEAPON_VCLIP:
{
t_idx_s = Vclip[Weapon_info[obj->id].weapon_vclip].frames[0].index;
t_idx_e = Vclip[Weapon_info[obj->id].weapon_vclip].frames[Vclip[Weapon_info[obj->id].weapon_vclip].num_frames-1].index;
break;
}
default:
{
t_idx_s = Vclip[obj->id].frames[0].index;
t_idx_e = Vclip[obj->id].frames[Vclip[obj->id].num_frames-1].index;
break;
}
}
if (t_idx_s != -1 && t_idx_e != -1)
{
for (i = t_idx_s; i <= t_idx_e; i++)
{
grs_bitmap *bm = &GameBitmaps[i];
ubyte buf[bm->bm_w*bm->bm_h];
if (!bm->bm_data)
return obj_color;
memset(&buf,0,bm->bm_w*bm->bm_h);
if (bm->bm_flags & BM_FLAG_RLE){
unsigned char * dbits;
unsigned char * sbits;
int data_offset;
data_offset = 1;
if (bm->bm_flags & BM_FLAG_RLE_BIG)
data_offset = 2;
sbits = &bm->bm_data[4 + (bm->bm_h * data_offset)];
dbits = buf;
for (i=0; i < bm->bm_h; i++ ) {
gr_rle_decode(sbits,dbits);
if ( bm->bm_flags & BM_FLAG_RLE_BIG )
sbits += (int)INTEL_SHORT(*((short *)&(bm->bm_data[4+(i*data_offset)])));
else
sbits += (int)bm->bm_data[4+i];
dbits += bm->bm_w;
}
}
else
{
memcpy(&buf, bm->bm_data, sizeof(unsigned char)*(bm->bm_w*bm->bm_h));
}
i = 0;
for (x = 0; x < bm->bm_h; x++)
{
for (y = 0; y < bm->bm_w; y++)
{
color = buf[i++];
t_color.r = gr_palette[color*3];
t_color.g = gr_palette[color*3+1];
t_color.b = gr_palette[color*3+2];
if (!(color == TRANSPARENCY_COLOR || (t_color.r == t_color.g && t_color.r == t_color.b)))
{
obj_color.r += t_color.r;
obj_color.g += t_color.g;
obj_color.b += t_color.b;
count++;
}
}
}
}
if (count)
{
obj_color.r /= count;
obj_color.g /= count;
obj_color.b /= count;
}
}
if (obj->render_type == RT_POLYOBJ)
obj->rtype.pobj_info.lrgb = obj_color;
else
obj->rtype.vclip_info.lrgb = obj_color;
return obj_color;
}
// ---------------------------------------------------------
fix compute_light_intensity(int objnum)
g3s_lrgb compute_light_emission(int objnum)
{
object *obj = &Objects[objnum];
int objtype = obj->type;
object *obj = &Objects[objnum];
int compute_color = 0;
float cscale = 255.0;
fix light_intensity = 0;
g3s_lrgb lemission, obj_color = { 255, 255, 255 };
switch (objtype) {
switch (obj->type)
{
case OBJ_PLAYER:
{
vms_vector sthrust = obj->mtype.phys_info.thrust;
fix k = fixmuldiv(obj->mtype.phys_info.mass,obj->mtype.phys_info.drag,(f1_0-obj->mtype.phys_info.drag));
// smooth thrust value like set_thrust_from_velocity()
vm_vec_copy_scale(&sthrust,&obj->mtype.phys_info.velocity,k);
return max(vm_vec_mag_quick(&sthrust)/4, F1_0*2) + F1_0/2;
vms_vector sthrust = obj->mtype.phys_info.thrust;
fix k = fixmuldiv(obj->mtype.phys_info.mass,obj->mtype.phys_info.drag,(f1_0-obj->mtype.phys_info.drag));
// smooth thrust value like set_thrust_from_velocity()
vm_vec_copy_scale(&sthrust,&obj->mtype.phys_info.velocity,k);
light_intensity = max(vm_vec_mag_quick(&sthrust)/4, F1_0*2) + F1_0/2;
break;
}
case OBJ_FIREBALL:
if (obj->id != 0xff) {
if (obj->id != 0xff)
{
if (obj->lifeleft < F1_0*4)
return fixmul(fixdiv(obj->lifeleft, Vclip[obj->id].play_time), Vclip[obj->id].light_value);
light_intensity = fixmul(fixdiv(obj->lifeleft, Vclip[obj->id].play_time), Vclip[obj->id].light_value);
else
return Vclip[obj->id].light_value;
} else
return 0;
light_intensity = Vclip[obj->id].light_value;
}
else
light_intensity = 0;
break;
case OBJ_ROBOT:
return F1_0/2; // F1_0*Robot_info[obj->id].lightcast;
light_intensity = F1_0/2; // F1_0*Robot_info[obj->id].lightcast;
break;
case OBJ_WEAPON: {
case OBJ_WEAPON:
{
fix tval = Weapon_info[obj->id].light;
if (obj->id == FLARE_ID )
return 2* (min(tval, obj->lifeleft) + ((((fix)GameTime64) ^ Obj_light_xlate[objnum&0x0f]) & 0x3fff));
light_intensity = 2* (min(tval, obj->lifeleft) + ((((fix)GameTime64) ^ Obj_light_xlate[objnum&0x0f]) & 0x3fff));
else
return tval;
light_intensity = tval;
break;
}
case OBJ_POWERUP:
return Powerup_info[obj->id].light;
light_intensity = Powerup_info[obj->id].light;
break;
case OBJ_DEBRIS:
return F1_0/4;
light_intensity = F1_0/4;
break;
case OBJ_LIGHT:
return obj->ctype.light_info.intensity;
light_intensity = obj->ctype.light_info.intensity;
break;
default:
return 0;
light_intensity = 0;
break;
}
lemission.r = lemission.g = lemission.b = light_intensity;
if (!PlayerCfg.DynLightColor) // colored lights not desired so use intensity only OR no intensity (== no light == no color) at all
return lemission;
switch (obj->type) // find out if given object should cast colored light and compute if so
{
case OBJ_FIREBALL:
case OBJ_WEAPON:
case OBJ_FLARE:
compute_color = 1;
break;
case OBJ_POWERUP:
{
switch (obj->id)
{
case POW_EXTRA_LIFE:
case POW_ENERGY:
case POW_SHIELD_BOOST:
case POW_KEY_BLUE:
case POW_KEY_RED:
case POW_KEY_GOLD:
case POW_CLOAK:
case POW_INVULNERABILITY:
compute_color = 1;
break;
default:
break;
}
break;
}
}
if (compute_color)
{
if (light_intensity < F1_0) // for every effect we want color, increase light_intensity so the effect becomes barely visible
light_intensity = F1_0;
obj_color = (obj->render_type == RT_POLYOBJ)?obj->rtype.pobj_info.lrgb:obj->rtype.vclip_info.lrgb;
if (obj_color.r == -1 || obj_color.g == -1 || obj_color.b == -1) // object does not have any color value, yet. compute!
obj_color = compute_lrgb_on(obj);
// scale color to light intensity
cscale = ((float)(light_intensity*3)/(obj_color.r+obj_color.g+obj_color.b));
lemission.r = obj_color.r * cscale;
lemission.g = obj_color.g * cscale;
lemission.b = obj_color.b * cscale;
}
return lemission;
}
// ----------------------------------------------------------------------------------------------
@ -346,7 +554,7 @@ void set_dynamic_light(void)
vertnum = render_vertices[vv];
Assert(vertnum >= 0 && vertnum <= Highest_vertex_index);
if ((vertnum ^ FrameCount) & 1)
Dynamic_light[vertnum] = 0;
Dynamic_light[vertnum].r = Dynamic_light[vertnum].g = Dynamic_light[vertnum].b = 0;
}
cast_muzzle_flash_light(n_render_vertices, render_vertices);
@ -366,12 +574,12 @@ void set_dynamic_light(void)
while (objnum != -1) {
object *obj = &Objects[objnum];
vms_vector *objpos = &obj->pos;
fix obj_intensity;
g3s_lrgb obj_light_emission;
obj_intensity = compute_light_intensity(objnum);
obj_light_emission = compute_light_emission(objnum);
if (obj_intensity) {
apply_light(obj_intensity, obj->segnum, objpos, n_render_vertices, render_vertices, obj-Objects);
if (((obj_light_emission.r+obj_light_emission.g+obj_light_emission.b)/3) > 0) {
apply_light(obj_light_emission, obj->segnum, objpos, n_render_vertices, render_vertices, obj-Objects);
new_lighting_objects[objnum] = 1;
}
@ -387,12 +595,12 @@ void set_dynamic_light(void)
// Lighted last frame, but not this frame. Get intensity...
object *obj = &Objects[objnum];
vms_vector *objpos = &obj->pos;
fix obj_intensity;
g3s_lrgb obj_light_emission;
obj_intensity = compute_light_intensity(objnum);
obj_light_emission = compute_light_emission(objnum);
if (obj_intensity) {
apply_light(obj_intensity, obj->segnum, objpos, n_render_vertices, render_vertices, objnum);
if (((obj_light_emission.r+obj_light_emission.g+obj_light_emission.b)/3) > 0) {
apply_light(obj_light_emission, obj->segnum, objpos, n_render_vertices, render_vertices, objnum);
Lighting_objects[objnum] = 1;
} else
Lighting_objects[objnum] = 0;
@ -447,159 +655,134 @@ fix compute_headlight_light_on_object(object *objp)
return light;
}
// -- Unused -- //Compute the lighting from the headlight for a given vertex on a face.
// -- Unused -- //Takes:
// -- Unused -- // point - the 3d coords of the point
// -- Unused -- // face_light - a scale factor derived from the surface normal of the face
// -- Unused -- //If no surface normal effect is wanted, pass F1_0 for face_light
// -- Unused -- fix compute_headlight_light(vms_vector *point,fix face_light)
// -- Unused -- {
// -- Unused -- fix light;
// -- Unused -- int use_beam = 0; //flag for beam effect
// -- Unused --
// -- Unused -- light = Beam_brightness;
// -- Unused --
// -- Unused -- if ((Players[Player_num].flags & PLAYER_FLAGS_HEADLIGHT) && (Players[Player_num].flags & PLAYER_FLAGS_HEADLIGHT_ON) && Viewer==&Objects[Players[Player_num].objnum] && Players[Player_num].energy > 0) {
// -- Unused -- light *= HEADLIGHT_BOOST_SCALE;
// -- Unused -- use_beam = 1; //give us beam effect
// -- Unused -- }
// -- Unused --
// -- Unused -- if (light) { //if no beam, don't bother with the rest of this
// -- Unused -- fix point_dist;
// -- Unused --
// -- Unused -- point_dist = vm_vec_mag_quick(point);
// -- Unused --
// -- Unused -- if (point_dist >= MAX_DIST)
// -- Unused --
// -- Unused -- light = 0;
// -- Unused --
// -- Unused -- else {
// -- Unused -- fix dist_scale,face_scale;
// -- Unused --
// -- Unused -- dist_scale = (MAX_DIST - point_dist) >> MAX_DIST_LOG;
// -- Unused -- light = fixmul(light,dist_scale);
// -- Unused --
// -- Unused -- if (face_light < 0)
// -- Unused -- face_light = 0;
// -- Unused --
// -- Unused -- face_scale = f1_0/4 + face_light/2;
// -- Unused -- light = fixmul(light,face_scale);
// -- Unused --
// -- Unused -- if (use_beam) {
// -- Unused -- fix beam_scale;
// -- Unused --
// -- Unused -- if (face_light > f1_0*3/4 && point->z > i2f(12)) {
// -- Unused -- beam_scale = fixdiv(point->z,point_dist);
// -- Unused -- beam_scale = fixmul(beam_scale,beam_scale); //square it
// -- Unused -- light = fixmul(light,beam_scale);
// -- Unused -- }
// -- Unused -- }
// -- Unused -- }
// -- Unused -- }
// -- Unused --
// -- Unused -- return light;
// -- Unused -- }
//compute the average dynamic light in a segment. Takes the segment number
fix compute_seg_dynamic_light(int segnum)
g3s_lrgb compute_seg_dynamic_light(int segnum)
{
fix sum;
g3s_lrgb sum, seg_lrgb;
segment *seg;
short *verts;
seg = &Segments[segnum];
verts = seg->verts;
sum = 0;
sum.r = sum.g = sum.b = 0;
sum += Dynamic_light[*verts++];
sum += Dynamic_light[*verts++];
sum += Dynamic_light[*verts++];
sum += Dynamic_light[*verts++];
sum += Dynamic_light[*verts++];
sum += Dynamic_light[*verts++];
sum += Dynamic_light[*verts++];
sum += Dynamic_light[*verts];
return sum >> 3;
sum.r += Dynamic_light[*verts].r;
sum.g += Dynamic_light[*verts].g;
sum.b += Dynamic_light[*verts++].b;
sum.r += Dynamic_light[*verts].r;
sum.g += Dynamic_light[*verts].g;
sum.b += Dynamic_light[*verts++].b;
sum.r += Dynamic_light[*verts].r;
sum.g += Dynamic_light[*verts].g;
sum.b += Dynamic_light[*verts++].b;
sum.r += Dynamic_light[*verts].r;
sum.g += Dynamic_light[*verts].g;
sum.b += Dynamic_light[*verts++].b;
sum.r += Dynamic_light[*verts].r;
sum.g += Dynamic_light[*verts].g;
sum.b += Dynamic_light[*verts++].b;
sum.r += Dynamic_light[*verts].r;
sum.g += Dynamic_light[*verts].g;
sum.b += Dynamic_light[*verts++].b;
sum.r += Dynamic_light[*verts].r;
sum.g += Dynamic_light[*verts].g;
sum.b += Dynamic_light[*verts++].b;
sum.r += Dynamic_light[*verts].r;
sum.g += Dynamic_light[*verts].g;
sum.b += Dynamic_light[*verts].b;
seg_lrgb.r = sum.r >> 3;
seg_lrgb.g = sum.g >> 3;
seg_lrgb.b = sum.b >> 3;
return seg_lrgb;
}
fix object_light[MAX_OBJECTS];
g3s_lrgb object_light[MAX_OBJECTS];
int object_sig[MAX_OBJECTS];
object *old_viewer;
int reset_lighting_hack;
#define LIGHT_RATE i2f(4) //how fast the light ramps up
#define LIGHT_RATE i2f(4) //how fast the light ramps up
void start_lighting_frame(object *viewer)
{
reset_lighting_hack = (viewer != old_viewer);
old_viewer = viewer;
}
//compute the lighting for an object. Takes a pointer to the object,
//and possibly a rotated 3d point. If the point isn't specified, the
//object's center point is rotated.
fix compute_object_light(object *obj,vms_vector *rotated_pnt)
g3s_lrgb compute_object_light(object *obj,vms_vector *rotated_pnt)
{
fix light;
g3s_lrgb light, seg_dl;
fix mlight;
g3s_point objpnt;
int objnum = obj-Objects;
if (!rotated_pnt) {
if (!rotated_pnt)
{
g3_rotate_point(&objpnt,&obj->pos);
rotated_pnt = &objpnt.p3_vec;
}
//First, get static light for this segment
light = Segments[obj->segnum].static_light;
//return light;
//First, get static (mono) light for this segment
light.r = light.g = light.b = Segments[obj->segnum].static_light;
//Now, maybe return different value to smooth transitions
if (!reset_lighting_hack && object_sig[objnum] == obj->signature)
{
fix frame_delta;
g3s_lrgb delta_light;
if (!reset_lighting_hack && object_sig[objnum] == obj->signature) {
fix delta_light,frame_delta;
delta_light = light - object_light[objnum];
delta_light.r = light.r - object_light[objnum].r;
delta_light.g = light.g - object_light[objnum].g;
delta_light.b = light.b - object_light[objnum].b;
frame_delta = fixmul(LIGHT_RATE,FrameTime);
if (abs(delta_light) <= frame_delta)
if (abs(((delta_light.r+delta_light.g+delta_light.b)/3)) <= frame_delta)
{
object_light[objnum] = light; //we've hit the goal
}
else
if (delta_light < 0)
light = object_light[objnum] -= frame_delta;
{
if (((delta_light.r+delta_light.g+delta_light.b)/3) < 0)
{
light.r = object_light[objnum].r -= frame_delta;
light.g = object_light[objnum].g -= frame_delta;
light.b = object_light[objnum].b -= frame_delta;
}
else
light = object_light[objnum] += frame_delta;
{
light.r = object_light[objnum].r += frame_delta;
light.g = object_light[objnum].g += frame_delta;
light.b = object_light[objnum].b += frame_delta;
}
}
}
else { //new object, initialize
else //new object, initialize
{
object_sig[objnum] = obj->signature;
object_light[objnum] = light;
object_light[objnum].r = light.r;
object_light[objnum].g = light.g;
object_light[objnum].b = light.b;
}
//Next, add in headlight on this object
// -- Matt code: light += compute_headlight_light(rotated_pnt,f1_0);
light += compute_headlight_light_on_object(obj);
//Next, add in (NOTE: WHITE) headlight on this object
mlight = compute_headlight_light_on_object(obj);
light.r += mlight;
light.g += mlight;
light.b += mlight;
//Finally, add in dynamic light for this segment
light += compute_seg_dynamic_light(obj->segnum);
seg_dl = compute_seg_dynamic_light(obj->segnum);
light.r += seg_dl.r;
light.g += seg_dl.g;
light.b += seg_dl.b;
return light;
}

View file

@ -27,7 +27,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#define MIN_LIGHT_DIST (F1_0*4)
extern fix Beam_brightness;
extern fix Dynamic_light[MAX_VERTICES];
extern g3s_lrgb Dynamic_light[MAX_VERTICES];
extern void set_dynamic_light(void);
@ -39,12 +39,12 @@ extern void set_dynamic_light(void);
fix compute_headlight_light(vms_vector *point,fix face_light);
// compute the average dynamic light in a segment. Takes the segment number
fix compute_seg_dynamic_light(int segnum);
g3s_lrgb compute_seg_dynamic_light(int segnum);
// compute the lighting for an object. Takes a pointer to the object,
// and possibly a rotated 3d point. If the point isn't specified, the
// object's center point is rotated.
fix compute_object_light(object *obj,vms_vector *rotated_pnt);
g3s_lrgb compute_object_light(object *obj,vms_vector *rotated_pnt);
// turn headlight boost on & off
void toggle_headlight_active(void);

View file

@ -1211,7 +1211,7 @@ void reticle_config()
PlayerCfg.ReticleSize = m[opt_ret_size].value;
}
int opt_gr_texfilt, opt_gr_brightness, opt_gr_reticlemenu, opt_gr_alphafx, opt_gr_vsync, opt_gr_multisample, opt_gr_fpsindi;
int opt_gr_texfilt, opt_gr_brightness, opt_gr_reticlemenu, opt_gr_alphafx, opt_gr_dynlightcolor, opt_gr_vsync, opt_gr_multisample, opt_gr_fpsindi;
int graphics_config_menuset(newmenu *menu, d_event *event, void *userdata)
{
newmenu_item *items = newmenu_get_items(menu);
@ -1252,7 +1252,7 @@ int graphics_config_menuset(newmenu *menu, d_event *event, void *userdata)
void graphics_config()
{
#ifdef OGL
newmenu_item m[12];
newmenu_item m[13];
int i = 0;
#else
newmenu_item m[3];
@ -1275,6 +1275,8 @@ void graphics_config()
#ifdef OGL
opt_gr_alphafx = nitems;
m[nitems].type = NM_TYPE_CHECK; m[nitems].text = "Transparency Effects"; m[nitems].value = PlayerCfg.AlphaEffects; nitems++;
opt_gr_dynlightcolor = nitems;
m[nitems].type = NM_TYPE_CHECK; m[nitems].text = "Colored Dynamic Light"; m[nitems].value = PlayerCfg.DynLightColor; nitems++;
opt_gr_vsync = nitems;
m[nitems].type = NM_TYPE_CHECK; m[nitems].text="VSync"; m[nitems].value = GameCfg.VSync; nitems++;
opt_gr_multisample = nitems;
@ -1296,6 +1298,7 @@ void graphics_config()
if (m[i+opt_gr_texfilt].value)
GameCfg.TexFilt = i;
PlayerCfg.AlphaEffects = m[opt_gr_alphafx].value;
PlayerCfg.DynLightColor = m[opt_gr_dynlightcolor].value;
GameCfg.VSync = m[opt_gr_vsync].value;
GameCfg.Multisample = m[opt_gr_multisample].value;
#endif

View file

@ -321,7 +321,7 @@ void morph_start(object *obj)
}
void draw_model(polymodel *pm,int submodel_num,vms_angvec *anim_angles,fix light,morph_data *md)
void draw_model(polymodel *pm,int submodel_num,vms_angvec *anim_angles,g3s_lrgb light,morph_data *md)
{
int i,mn;
int facing;
@ -411,7 +411,7 @@ void draw_morph_object(object *obj)
{
// int save_light;
polymodel *po;
fix light;
g3s_lrgb light;
morph_data *md;
md = find_morph_data(obj);

View file

@ -3860,6 +3860,7 @@ void multi_object_rw_to_object(object_rw *obj_rw, object *obj)
obj->rtype.pobj_info.subobj_flags = obj_rw->rtype.pobj_info.subobj_flags;
obj->rtype.pobj_info.tmap_override = obj_rw->rtype.pobj_info.tmap_override;
obj->rtype.pobj_info.alt_textures = obj_rw->rtype.pobj_info.alt_textures;
obj->rtype.pobj_info.lrgb.r = obj->rtype.pobj_info.lrgb.g = obj->rtype.pobj_info.lrgb.b = -1;
break;
}
@ -3870,6 +3871,7 @@ void multi_object_rw_to_object(object_rw *obj_rw, object *obj)
obj->rtype.vclip_info.vclip_num = obj_rw->rtype.vclip_info.vclip_num;
obj->rtype.vclip_info.frametime = obj_rw->rtype.vclip_info.frametime;
obj->rtype.vclip_info.framenum = obj_rw->rtype.vclip_info.framenum;
obj->rtype.vclip_info.lrgb.r = obj->rtype.vclip_info.lrgb.g = obj->rtype.vclip_info.lrgb.b = -1;
break;
case RT_LASER:

View file

@ -196,7 +196,7 @@ void draw_object_blob(object *obj,bitmap_index bmi)
void draw_object_tmap_rod(object *obj,bitmap_index bitmapi,int lighted)
{
grs_bitmap * bitmap = &GameBitmaps[bitmapi.index];
fix light;
g3s_lrgb light;
vms_vector delta,top_v,bot_v;
g3s_point top_p,bot_p;
@ -212,9 +212,13 @@ void draw_object_tmap_rod(object *obj,bitmap_index bitmapi,int lighted)
g3_rotate_point(&bot_p,&bot_v);
if (lighted)
{
light = compute_object_light(obj,&top_p.p3_vec);
}
else
light = f1_0;
{
light.r = light.g = light.b = f1_0;
}
g3_draw_rod_tmap(bitmap,&bot_p,obj->size,&top_p,obj->size,light);
@ -244,7 +248,7 @@ fix Cloak_fadein_duration;
fix Cloak_fadeout_duration;
//do special cloaked render
void draw_cloaked_object(object *obj,fix light,fix *glow,fix64 cloak_start_time,fix64 cloak_end_time,bitmap_index * alt_textures)
void draw_cloaked_object(object *obj,g3s_lrgb light,fix *glow,fix64 cloak_start_time,fix64 cloak_end_time,bitmap_index * alt_textures)
{
fix cloak_delta_time,total_cloaked_time;
fix light_scale=F1_0;
@ -309,9 +313,12 @@ void draw_cloaked_object(object *obj,fix light,fix *glow,fix64 cloak_start_time,
if (fading) {
fix new_light,new_glow;
fix new_glow;
g3s_lrgb new_light;
new_light = fixmul(light,light_scale);
new_light.r = fixmul(light.r,light_scale);
new_light.g = fixmul(light.g,light_scale);
new_light.b = fixmul(light.b,light_scale);
new_glow = fixmul(*glow,light_scale);
draw_polygon_model(&obj->pos,&obj->orient,obj->rtype.pobj_info.anim_angles,obj->rtype.pobj_info.model_num,obj->rtype.pobj_info.subobj_flags,new_light,&new_glow, alt_textures );
}
@ -328,7 +335,7 @@ void draw_cloaked_object(object *obj,fix light,fix *glow,fix64 cloak_start_time,
//draw an object which renders as a polygon model
void draw_polygon_object(object *obj)
{
fix light;
g3s_lrgb light;
int imsave;
fix engine_glow_value;
@ -338,7 +345,7 @@ void draw_polygon_object(object *obj)
#ifdef NETWORK
if (Game_mode & GM_MULTI)
if (Netgame.BrightPlayers)
light = F1_0*2;
light.r = light.g = light.b = F1_0*2;
#endif
imsave = Interpolation_method;
@ -397,6 +404,15 @@ void draw_polygon_object(object *obj)
draw_polygon_model(&obj->pos,&obj->orient,obj->rtype.pobj_info.anim_angles,obj->rtype.pobj_info.model_num,obj->rtype.pobj_info.subobj_flags,light,&engine_glow_value,alt_textures);
#ifndef OGL // in software rendering must draw inner model last
if (obj->type == OBJ_WEAPON && (Weapon_info[obj->id].model_num_inner > -1 )) {
fix dist_to_eye = vm_vec_dist_quick(&Viewer->pos, &obj->pos);
gr_settransblend(GR_FADE_OFF, GR_BLEND_ADDITIVE_A);
if (dist_to_eye < Simple_model_threshhold_scale * F1_0*2)
draw_polygon_model(&obj->pos,&obj->orient,obj->rtype.pobj_info.anim_angles,Weapon_info[obj->id].model_num_inner,obj->rtype.pobj_info.subobj_flags,light,&engine_glow_value,alt_textures);
}
#endif
if (obj->type == OBJ_WEAPON && (Weapon_info[obj->id].model_num_inner > -1 ))
gr_settransblend(GR_FADE_OFF, GR_BLEND_NORMAL);
@ -605,7 +621,7 @@ void render_object(object *obj)
break;
case RT_WEAPON_VCLIP:
if ( PlayerCfg.AlphaEffects ) // set nice transparency/blending for certrain objects
if ( PlayerCfg.AlphaEffects && obj->id != PROXIMITY_ID ) // set nice transparency/blending for certrain objects
gr_settransblend( 7, GR_BLEND_ADDITIVE_A );
draw_weapon_vclip(obj);
@ -1176,6 +1192,12 @@ int obj_create(ubyte type,ubyte id,int segnum,vms_vector *pos,
if (obj->type == OBJ_DEBRIS)
Debris_object_count++;
// set light color values to -1 to lighting code will compute them is desired
if (obj->render_type == RT_POLYOBJ)
obj->rtype.pobj_info.lrgb.r = obj->rtype.pobj_info.lrgb.g = obj->rtype.pobj_info.lrgb.b = -1;
else
obj->rtype.vclip_info.lrgb.r = obj->rtype.vclip_info.lrgb.g = obj->rtype.vclip_info.lrgb.b = -1;
return objnum;
}

View file

@ -211,8 +211,15 @@ typedef struct vclip_info {
int vclip_num;
fix frametime;
sbyte framenum;
g3s_lrgb lrgb; // light color this vclip will emit
} __pack__ vclip_info;
typedef struct vclip_info_rw {
int vclip_num;
fix frametime;
sbyte framenum;
} __pack__ vclip_info_rw;
//structures for different kinds of rendering
typedef struct polyobj_info {
@ -221,8 +228,17 @@ typedef struct polyobj_info {
int subobj_flags; //specify which subobjs to draw
int tmap_override; //if this is not -1, map all face to this
int alt_textures; //if not -1, use these textures instead
g3s_lrgb lrgb; // light color this polyobj will emit
} __pack__ polyobj_info;
typedef struct polyobj_info_rw {
int model_num; //which polygon model
vms_angvec anim_angles[MAX_SUBMODELS]; //angles for each subobject
int subobj_flags; //specify which subobjs to draw
int tmap_override; //if this is not -1, map all face to this
int alt_textures; //if not -1, use these textures instead
} __pack__ polyobj_info_rw;
typedef struct object {
int signature; // Every object ever has a unique signature...
ubyte type; // what type of object this is... robot, weapon, hostage, powerup, fireball
@ -318,8 +334,8 @@ typedef struct object_rw {
//render info, determined by RENDER_TYPE
union {
polyobj_info pobj_info; //polygon model
vclip_info vclip_info; //vclip
polyobj_info_rw pobj_info; //polygon model
vclip_info_rw vclip_info; //vclip
} __pack__ rtype;
#ifdef WORDS_NEED_ALIGNMENT
short pad2;

View file

@ -94,6 +94,7 @@ int new_player_config()
PlayerCfg.MultiMessages = 0;
PlayerCfg.BombGauge = 1;
PlayerCfg.AlphaEffects = 0;
PlayerCfg.DynLightColor = 0;
// Default taunt macros
#ifdef NETWORK
@ -304,6 +305,8 @@ int read_player_d1x(char *filename)
{
if(!strcmp(word,"ALPHAEFFECTS"))
PlayerCfg.AlphaEffects = atoi(line);
if(!strcmp(word,"DYNLIGHTCOLOR"))
PlayerCfg.DynLightColor = atoi(line);
d_free(word);
cfgets(line,50,f);
word=splitword(line,'=');
@ -576,6 +579,7 @@ int write_player_d1x(char *filename)
PHYSFSX_printf(fout,"[end]\n");
PHYSFSX_printf(fout,"[graphics]\n");
PHYSFSX_printf(fout,"alphaeffects=%i\n",PlayerCfg.AlphaEffects);
PHYSFSX_printf(fout,"dynlightcolor=%i\n",PlayerCfg.DynLightColor);
PHYSFSX_printf(fout,"[end]\n");
PHYSFSX_printf(fout,"[plx version]\n");
PHYSFSX_printf(fout,"plx version=%s\n",VERSION);

View file

@ -80,6 +80,7 @@ typedef struct player_config
ubyte MultiMessages;
ubyte BombGauge;
int AlphaEffects;
int DynLightColor;
} __pack__ player_config;
extern struct player_config PlayerCfg;

View file

@ -504,7 +504,7 @@ bitmap_index texture_list_index[MAX_POLYOBJ_TEXTURES];
//draw a polygon model
void draw_polygon_model(vms_vector *pos,vms_matrix *orient,vms_angvec *anim_angles,int model_num,int flags,fix light,fix *glow_values,bitmap_index alt_textures[])
void draw_polygon_model(vms_vector *pos,vms_matrix *orient,vms_angvec *anim_angles,int model_num,int flags,g3s_lrgb light,fix *glow_values,bitmap_index alt_textures[])
{
polymodel *po;
int i;
@ -714,6 +714,7 @@ void draw_model_picture(int mn,vms_angvec *orient_angles)
{
vms_vector temp_pos=ZERO_VECTOR;
vms_matrix temp_orient = IDENTITY_MATRIX;
g3s_lrgb lrgb = { f1_0, f1_0, f1_0 };
Assert(mn>=0 && mn<N_polygon_models);
@ -727,7 +728,7 @@ void draw_model_picture(int mn,vms_angvec *orient_angles)
temp_pos.z = DEFAULT_VIEW_DIST;
vm_angles_2_matrix(&temp_orient, orient_angles);
draw_polygon_model(&temp_pos,&temp_orient,NULL,mn,0,f1_0,NULL,NULL);
draw_polygon_model(&temp_pos,&temp_orient,NULL,mn,0,lrgb,NULL,NULL);
g3_end_frame();
}

View file

@ -80,7 +80,7 @@ int load_polygon_model(char *filename,int n_textures,grs_bitmap ***textures);
#endif
//draw a polygon model
void draw_polygon_model(vms_vector *pos,vms_matrix *orient,vms_angvec *anim_angles,int model_num,int flags,fix light,fix *glow_values,bitmap_index alt_textures[]);
void draw_polygon_model(vms_vector *pos,vms_matrix *orient,vms_angvec *anim_angles,int model_num,int flags,g3s_lrgb light,fix *glow_values,bitmap_index alt_textures[]);
//fills in arrays gun_points & gun_dirs, returns the number of guns read
int read_model_guns(char *filename,vms_vector *gun_points, vms_vector *gun_dirs, int *gun_submodels);

View file

@ -192,6 +192,7 @@ void render_face(int segnum, int sidenum, int nv, short *vp, int tmap1, int tmap
#endif
fix reflect;
g3s_uvl uvl_copy[8];
g3s_lrgb dyn_light[8];
int i;
g3s_point *pointlist[8];
@ -200,7 +201,7 @@ void render_face(int segnum, int sidenum, int nv, short *vp, int tmap1, int tmap
for (i=0; i<nv; i++) {
uvl_copy[i].u = uvlp[i].u;
uvl_copy[i].v = uvlp[i].v;
uvl_copy[i].l = uvlp[i].l;
dyn_light[i].r = dyn_light[i].g = dyn_light[i].b = uvl_copy[i].l = uvlp[i].l;
pointlist[i] = &Segment_points[vp[i]];
}
@ -244,26 +245,50 @@ void render_face(int segnum, int sidenum, int nv, short *vp, int tmap1, int tmap
{
int i;
// face_light = fixmul(face_light,reflect);
for (i=0;i<nv;i++) {
for (i=0;i<nv;i++)
{
fix highval = 0;
//the uvl struct has static light already in it
//scale static light for destruction effect
if (Control_center_destroyed) //make lights flash
uvl_copy[i].l = fixmul(flash_scale,uvl_copy[i].l);
//add in dynamic light (from explosions, etc.)
uvl_copy[i].l += Dynamic_light[vp[i]];
//add in light from player's headlight
// uvl_copy[i].l += compute_headlight_light(&Segment_points[vp[i]].p3_vec,face_light);
uvl_copy[i].l += (Dynamic_light[vp[i]].r+Dynamic_light[vp[i]].g+Dynamic_light[vp[i]].b)/3;
//saturate at max value
if (uvl_copy[i].l > MAX_LIGHT)
uvl_copy[i].l = MAX_LIGHT;
// And now the same for the ACTUAL (rgb) light we want to use
//scale static light for destruction effect
if (Control_center_destroyed) //make lights flash
{
if (PlayerCfg.DynLightColor) // let the mine glow red a little
{
dyn_light[i].r = fixmul(flash_scale>=f0_5*1.5?flash_scale:f0_5*1.5,uvl_copy[i].l);
dyn_light[i].g = dyn_light[i].b = fixmul(flash_scale,uvl_copy[i].l);
}
else
dyn_light[i].r = dyn_light[i].g = dyn_light[i].b = fixmul(flash_scale,uvl_copy[i].l);
}
// add light color
dyn_light[i].r += Dynamic_light[vp[i]].r;
dyn_light[i].g += Dynamic_light[vp[i]].g;
dyn_light[i].b += Dynamic_light[vp[i]].b;
// saturate at max value
if (dyn_light[i].r > highval)
highval = dyn_light[i].r;
if (dyn_light[i].g > highval)
highval = dyn_light[i].g;
if (dyn_light[i].b > highval)
highval = dyn_light[i].b;
if (highval > MAX_LIGHT)
{
dyn_light[i].r -= highval - MAX_LIGHT;
dyn_light[i].g -= highval - MAX_LIGHT;
dyn_light[i].b -= highval - MAX_LIGHT;
}
}
}
@ -274,7 +299,7 @@ void render_face(int segnum, int sidenum, int nv, short *vp, int tmap1, int tmap
#ifdef EDITOR
if ((Render_only_bottom) && (sidenum == WBOTTOM))
{
g3_draw_tmap(nv,pointlist,uvl_copy,&GameBitmaps[Textures[Bottom_bitmap_num].index]);
g3_draw_tmap(nv,pointlist,uvl_copy,dyn_light,&GameBitmaps[Textures[Bottom_bitmap_num].index]);
}
else
#endif
@ -282,12 +307,12 @@ void render_face(int segnum, int sidenum, int nv, short *vp, int tmap1, int tmap
#ifdef OGL
if (bm2)
{
g3_draw_tmap_2(nv,pointlist,uvl_copy,bm,bm2,((tmap2&0xC000)>>14) & 3);
g3_draw_tmap_2(nv,pointlist,uvl_copy,dyn_light,bm,bm2,((tmap2&0xC000)>>14) & 3);
}
else
#endif
{
g3_draw_tmap(nv,pointlist,uvl_copy,bm);
g3_draw_tmap(nv,pointlist,uvl_copy,dyn_light,bm);
}
}
@ -310,6 +335,7 @@ void check_face(int segnum, int sidenum, int facenum, int nv, short *vp, int tma
int save_lighting;
grs_bitmap *bm;
g3s_uvl uvl_copy[8];
g3s_lrgb dyn_light[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
g3s_point *pointlist[4];
if (tmap2 > 0 )
@ -320,7 +346,7 @@ void check_face(int segnum, int sidenum, int facenum, int nv, short *vp, int tma
for (i=0; i<nv; i++) {
uvl_copy[i].u = uvlp[i].u;
uvl_copy[i].v = uvlp[i].v;
uvl_copy[i].l = uvlp[i].l;
dyn_light[i].r = dyn_light[i].g = dyn_light[i].b = uvl_copy[i].l = uvlp[i].l;
pointlist[i] = &Segment_points[vp[i]];
}
@ -330,7 +356,7 @@ void check_face(int segnum, int sidenum, int facenum, int nv, short *vp, int tma
save_lighting = Lighting_on;
Lighting_on = 2;
//g3_draw_poly(nv,vp);
g3_draw_tmap(nv,&pointlist[0], uvl_copy, bm);
g3_draw_tmap(nv,&pointlist[0], uvl_copy, dyn_light, bm);
Lighting_on = save_lighting;
if (gr_ugpixel(&grd_curcanv->cv_bitmap,_search_x,_search_y) == 1) {

View file

@ -381,6 +381,7 @@ void state_object_rw_to_object(object_rw *obj_rw, object *obj)
obj->rtype.pobj_info.subobj_flags = obj_rw->rtype.pobj_info.subobj_flags;
obj->rtype.pobj_info.tmap_override = obj_rw->rtype.pobj_info.tmap_override;
obj->rtype.pobj_info.alt_textures = obj_rw->rtype.pobj_info.alt_textures;
obj->rtype.pobj_info.lrgb.r = obj->rtype.pobj_info.lrgb.g = obj->rtype.pobj_info.lrgb.b = -1;
break;
}
@ -391,6 +392,7 @@ void state_object_rw_to_object(object_rw *obj_rw, object *obj)
obj->rtype.vclip_info.vclip_num = obj_rw->rtype.vclip_info.vclip_num;
obj->rtype.vclip_info.frametime = obj_rw->rtype.vclip_info.frametime;
obj->rtype.vclip_info.framenum = obj_rw->rtype.vclip_info.framenum;
obj->rtype.vclip_info.lrgb.r = obj->rtype.vclip_info.lrgb.g = obj->rtype.vclip_info.lrgb.b = -1;
break;
case RT_LASER:

View file

@ -41,6 +41,8 @@ int grid_w,grid_h;
g3s_uvl uvl_list1[] = { {0,0,0}, {f1_0,0,0}, {0,f1_0,0} };
g3s_uvl uvl_list2[] = { {f1_0,0,0}, {f1_0,f1_0,0}, {0,f1_0,0} };
g3s_lrgb lrgb_list1[] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
g3s_lrgb lrgb_list2[] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
ubyte *height_array;
ubyte *light_array;
@ -76,15 +78,15 @@ void draw_cell(int i,int j,g3s_point *p0,g3s_point *p1,g3s_point *p2,g3s_point *
pointlist[0] = p0;
pointlist[1] = p1;
pointlist[2] = p3;
uvl_list1[0].l = LIGHTVAL(i,j);
uvl_list1[1].l = LIGHTVAL(i,j+1);
uvl_list1[2].l = LIGHTVAL(i+1,j);
lrgb_list1[0].r = lrgb_list1[0].g = lrgb_list1[0].b = uvl_list1[0].l = LIGHTVAL(i,j);
lrgb_list1[1].r = lrgb_list1[1].g = lrgb_list1[1].b = uvl_list1[1].l = LIGHTVAL(i,j+1);
lrgb_list1[2].r = lrgb_list1[2].g = lrgb_list1[2].b = uvl_list1[2].l = LIGHTVAL(i+1,j);
uvl_list1[0].u = (i)*f1_0/4; uvl_list1[0].v = (j)*f1_0/4;
uvl_list1[1].u = (i)*f1_0/4; uvl_list1[1].v = (j+1)*f1_0/4;
uvl_list1[2].u = (i+1)*f1_0/4; uvl_list1[2].v = (j)*f1_0/4;
g3_check_and_draw_tmap(3,pointlist,uvl_list1,terrain_bm,NULL,NULL);
g3_check_and_draw_tmap(3,pointlist,uvl_list1,lrgb_list1,terrain_bm,NULL,NULL);
if (terrain_outline) {
int lsave=Lighting_on;
Lighting_on=0;
@ -96,15 +98,15 @@ void draw_cell(int i,int j,g3s_point *p0,g3s_point *p1,g3s_point *p2,g3s_point *
pointlist[0] = p1;
pointlist[1] = p2;
uvl_list2[0].l = LIGHTVAL(i,j+1);
uvl_list2[1].l = LIGHTVAL(i+1,j+1);
uvl_list2[2].l = LIGHTVAL(i+1,j);
lrgb_list2[0].r = lrgb_list2[0].g = lrgb_list2[0].b = uvl_list2[0].l = LIGHTVAL(i,j+1);
lrgb_list2[1].r = lrgb_list2[1].g = lrgb_list2[1].b = uvl_list2[1].l = LIGHTVAL(i+1,j+1);
lrgb_list2[2].r = lrgb_list2[2].g = lrgb_list2[2].b = uvl_list2[2].l = LIGHTVAL(i+1,j);
uvl_list2[0].u = (i)*f1_0/4; uvl_list2[0].v = (j+1)*f1_0/4;
uvl_list2[1].u = (i+1)*f1_0/4; uvl_list2[1].v = (j+1)*f1_0/4;
uvl_list2[2].u = (i+1)*f1_0/4; uvl_list2[2].v = (j)*f1_0/4;
g3_check_and_draw_tmap(3,pointlist,uvl_list2,terrain_bm,NULL,NULL);
g3_check_and_draw_tmap(3,pointlist,uvl_list2,lrgb_list2,terrain_bm,NULL,NULL);
if (terrain_outline) {
int lsave=Lighting_on;
Lighting_on=0;