123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698 |
- #include "quakedef.h"
- int skytexturenum;
- #ifndef GL_RGBA4
- #define GL_RGBA4 0
- #endif
- int lightmap_bytes;
- int lightmap_textures;
- unsigned blocklights[18*18];
- #define BLOCK_WIDTH 128
- #define BLOCK_HEIGHT 128
- #define MAX_LIGHTMAPS 64
- int active_lightmaps;
- typedef struct glRect_s {
- unsigned char l,t,w,h;
- } glRect_t;
- glpoly_t *lightmap_polys[MAX_LIGHTMAPS];
- qboolean lightmap_modified[MAX_LIGHTMAPS];
- glRect_t lightmap_rectchange[MAX_LIGHTMAPS];
- int allocated[MAX_LIGHTMAPS][BLOCK_WIDTH];
- byte lightmaps[4*MAX_LIGHTMAPS*BLOCK_WIDTH*BLOCK_HEIGHT];
- msurface_t *skychain = NULL;
- msurface_t *waterchain = NULL;
- void R_RenderDynamicLightmaps (msurface_t *fa);
- void R_AddDynamicLights (msurface_t *surf)
- {
- int lnum;
- int sd, td;
- float dist, rad, minlight;
- vec3_t impact, local;
- int s, t;
- int i;
- int smax, tmax;
- mtexinfo_t *tex;
- smax = (surf->extents[0]>>4)+1;
- tmax = (surf->extents[1]>>4)+1;
- tex = surf->texinfo;
- for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
- {
- if ( !(surf->dlightbits & (1<<lnum) ) )
- continue;
- rad = cl_dlights[lnum].radius;
- dist = DotProduct (cl_dlights[lnum].origin, surf->plane->normal) -
- surf->plane->dist;
- rad -= fabs(dist);
- minlight = cl_dlights[lnum].minlight;
- if (rad < minlight)
- continue;
- minlight = rad - minlight;
- for (i=0 ; i<3 ; i++)
- {
- impact[i] = cl_dlights[lnum].origin[i] -
- surf->plane->normal[i]*dist;
- }
- local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
- local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
- local[0] -= surf->texturemins[0];
- local[1] -= surf->texturemins[1];
-
- for (t = 0 ; t<tmax ; t++)
- {
- td = local[1] - t*16;
- if (td < 0)
- td = -td;
- for (s=0 ; s<smax ; s++)
- {
- sd = local[0] - s*16;
- if (sd < 0)
- sd = -sd;
- if (sd > td)
- dist = sd + (td>>1);
- else
- dist = td + (sd>>1);
- if (dist < minlight)
- blocklights[t*smax + s] += (rad - dist)*256;
- }
- }
- }
- }
- void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
- {
- int smax, tmax;
- int t;
- int i, j, size;
- byte *lightmap;
- unsigned scale;
- int maps;
- unsigned *bl;
- surf->cached_dlight = (surf->dlightframe == r_framecount);
- smax = (surf->extents[0]>>4)+1;
- tmax = (surf->extents[1]>>4)+1;
- size = smax*tmax;
- lightmap = surf->samples;
- if ( !cl.worldmodel->lightdata)
- {
- for (i=0 ; i<size ; i++)
- blocklights[i] = 255*256;
- goto store;
- }
- for (i=0 ; i<size ; i++)
- blocklights[i] = 0;
- if (lightmap)
- for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
- maps++)
- {
- scale = d_lightstylevalue[surf->styles[maps]];
- surf->cached_light[maps] = scale;
- for (i=0 ; i<size ; i++)
- blocklights[i] += lightmap[i] * scale;
- lightmap += size;
- }
- if (surf->dlightframe == r_framecount)
- R_AddDynamicLights (surf);
- store:
- switch (gl_lightmap_format)
- {
- case GL_RGBA:
- stride -= (smax<<2);
- bl = blocklights;
- for (i=0 ; i<tmax ; i++, dest += stride)
- {
- for (j=0 ; j<smax ; j++)
- {
- t = *bl++;
- t >>= 7;
- if (t > 255)
- t = 255;
- dest[3] = 255-t;
- dest += 4;
- }
- }
- break;
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_INTENSITY:
- bl = blocklights;
- for (i=0 ; i<tmax ; i++, dest += stride)
- {
- for (j=0 ; j<smax ; j++)
- {
- t = *bl++;
- t >>= 7;
- if (t > 255)
- t = 255;
- dest[j] = 255-t;
- }
- }
- break;
- default:
- Sys_Error ("Bad lightmap format");
- }
- }
- texture_t *R_TextureAnimation (texture_t *base)
- {
- int reletive;
- int count;
- if (currententity->frame)
- {
- if (base->alternate_anims)
- base = base->alternate_anims;
- }
-
- if (!base->anim_total)
- return base;
- reletive = (int)(cl.time*10) % base->anim_total;
- count = 0;
- while (base->anim_min > reletive || base->anim_max <= reletive)
- {
- base = base->anim_next;
- if (!base)
- Sys_Error ("R_TextureAnimation: broken cycle");
- if (++count > 100)
- Sys_Error ("R_TextureAnimation: infinite cycle");
- }
- return base;
- }
- extern int solidskytexture;
- extern int alphaskytexture;
- extern float speedscale;
- void DrawGLWaterPoly (glpoly_t *p);
- void DrawGLWaterPolyLightmap (glpoly_t *p);
- #ifdef _WIN32
- lpMTexFUNC qglMTexCoord2fSGIS = NULL;
- lpSelTexFUNC qglSelectTextureSGIS = NULL;
- #endif
- qboolean mtexenabled = false;
- void GL_SelectTexture (GLenum target);
- void GL_DisableMultitexture(void)
- {
- if (mtexenabled) {
- glDisable(GL_TEXTURE_2D);
- GL_SelectTexture(TEXTURE0_SGIS);
- mtexenabled = false;
- }
- }
- void GL_EnableMultitexture(void)
- {
- if (gl_mtexable) {
- GL_SelectTexture(TEXTURE1_SGIS);
- glEnable(GL_TEXTURE_2D);
- mtexenabled = true;
- }
- }
- #ifndef _WIN32
- void R_DrawSequentialPoly (msurface_t *s)
- {
- glpoly_t *p;
- float *v;
- int i;
- texture_t *t;
-
-
-
- if (0)
- {
- p = s->polys;
- t = R_TextureAnimation (s->texinfo->texture);
- GL_Bind (t->gl_texturenum);
- glBegin (GL_POLYGON);
- v = p->verts[0];
- for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
- {
- glTexCoord2f (v[3], v[4]);
- glVertex3fv (v);
- }
- glEnd ();
- GL_Bind (lightmap_textures + s->lightmaptexturenum);
- glEnable (GL_BLEND);
- glBegin (GL_POLYGON);
- v = p->verts[0];
- for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
- {
- glTexCoord2f (v[5], v[6]);
- glVertex3fv (v);
- }
- glEnd ();
- glDisable (GL_BLEND);
- return;
- }
-
-
-
- if (s->flags & SURF_DRAWTURB)
- {
- GL_Bind (s->texinfo->texture->gl_texturenum);
- EmitWaterPolys (s);
- return;
- }
-
-
-
- if (s->flags & SURF_DRAWSKY)
- {
- GL_Bind (solidskytexture);
- speedscale = realtime*8;
- speedscale -= (int)speedscale;
- EmitSkyPolys (s);
- glEnable (GL_BLEND);
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- GL_Bind (alphaskytexture);
- speedscale = realtime*16;
- speedscale -= (int)speedscale;
- EmitSkyPolys (s);
- if (gl_lightmap_format == GL_LUMINANCE)
- glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
- glDisable (GL_BLEND);
- }
-
-
-
- p = s->polys;
- t = R_TextureAnimation (s->texinfo->texture);
- GL_Bind (t->gl_texturenum);
- DrawGLWaterPoly (p);
- GL_Bind (lightmap_textures + s->lightmaptexturenum);
- glEnable (GL_BLEND);
- DrawGLWaterPolyLightmap (p);
- glDisable (GL_BLEND);
- }
- #else
- void R_DrawSequentialPoly (msurface_t *s)
- {
- glpoly_t *p;
- float *v;
- int i;
- texture_t *t;
- vec3_t nv, dir;
- float ss, ss2, length;
- float s1, t1;
- glRect_t *theRect;
-
-
-
- if (! (s->flags & (SURF_DRAWSKY|SURF_DRAWTURB|SURF_UNDERWATER) ) )
- {
- R_RenderDynamicLightmaps (s);
- if (gl_mtexable) {
- p = s->polys;
- t = R_TextureAnimation (s->texinfo->texture);
-
- GL_SelectTexture(TEXTURE0_SGIS);
- GL_Bind (t->gl_texturenum);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
- GL_EnableMultitexture();
- GL_Bind (lightmap_textures + s->lightmaptexturenum);
- i = s->lightmaptexturenum;
- if (lightmap_modified[i])
- {
- lightmap_modified[i] = false;
- theRect = &lightmap_rectchange[i];
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
- BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE,
- lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes);
- theRect->l = BLOCK_WIDTH;
- theRect->t = BLOCK_HEIGHT;
- theRect->h = 0;
- theRect->w = 0;
- }
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
- glBegin(GL_POLYGON);
- v = p->verts[0];
- for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
- {
- qglMTexCoord2fSGIS (TEXTURE0_SGIS, v[3], v[4]);
- qglMTexCoord2fSGIS (TEXTURE1_SGIS, v[5], v[6]);
- glVertex3fv (v);
- }
- glEnd ();
- return;
- } else {
- p = s->polys;
- t = R_TextureAnimation (s->texinfo->texture);
- GL_Bind (t->gl_texturenum);
- glBegin (GL_POLYGON);
- v = p->verts[0];
- for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
- {
- glTexCoord2f (v[3], v[4]);
- glVertex3fv (v);
- }
- glEnd ();
- GL_Bind (lightmap_textures + s->lightmaptexturenum);
- glEnable (GL_BLEND);
- glBegin (GL_POLYGON);
- v = p->verts[0];
- for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
- {
- glTexCoord2f (v[5], v[6]);
- glVertex3fv (v);
- }
- glEnd ();
- glDisable (GL_BLEND);
- }
- return;
- }
-
-
-
- if (s->flags & SURF_DRAWTURB)
- {
- GL_DisableMultitexture();
- GL_Bind (s->texinfo->texture->gl_texturenum);
- EmitWaterPolys (s);
- return;
- }
-
-
-
- if (s->flags & SURF_DRAWSKY)
- {
- GL_DisableMultitexture();
- GL_Bind (solidskytexture);
- speedscale = realtime*8;
- speedscale -= (int)speedscale & ~127;
- EmitSkyPolys (s);
- glEnable (GL_BLEND);
- GL_Bind (alphaskytexture);
- speedscale = realtime*16;
- speedscale -= (int)speedscale & ~127;
- EmitSkyPolys (s);
- glDisable (GL_BLEND);
- return;
- }
-
-
-
- R_RenderDynamicLightmaps (s);
- if (gl_mtexable) {
- p = s->polys;
- t = R_TextureAnimation (s->texinfo->texture);
- GL_SelectTexture(TEXTURE0_SGIS);
- GL_Bind (t->gl_texturenum);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- GL_EnableMultitexture();
- GL_Bind (lightmap_textures + s->lightmaptexturenum);
- i = s->lightmaptexturenum;
- if (lightmap_modified[i])
- {
- lightmap_modified[i] = false;
- theRect = &lightmap_rectchange[i];
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
- BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE,
- lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes);
- theRect->l = BLOCK_WIDTH;
- theRect->t = BLOCK_HEIGHT;
- theRect->h = 0;
- theRect->w = 0;
- }
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
- glBegin (GL_TRIANGLE_FAN);
- v = p->verts[0];
- for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
- {
- qglMTexCoord2fSGIS (TEXTURE0_SGIS, v[3], v[4]);
- qglMTexCoord2fSGIS (TEXTURE1_SGIS, v[5], v[6]);
- nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime);
- nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime);
- nv[2] = v[2];
- glVertex3fv (nv);
- }
- glEnd ();
- } else {
- p = s->polys;
- t = R_TextureAnimation (s->texinfo->texture);
- GL_Bind (t->gl_texturenum);
- DrawGLWaterPoly (p);
- GL_Bind (lightmap_textures + s->lightmaptexturenum);
- glEnable (GL_BLEND);
- DrawGLWaterPolyLightmap (p);
- glDisable (GL_BLEND);
- }
- }
- #endif
- void DrawGLWaterPoly (glpoly_t *p)
- {
- int i;
- float *v;
- vec3_t nv;
- GL_DisableMultitexture();
- glBegin (GL_TRIANGLE_FAN);
- v = p->verts[0];
- for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
- {
- glTexCoord2f (v[3], v[4]);
- nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime);
- nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime);
- nv[2] = v[2];
- glVertex3fv (nv);
- }
- glEnd ();
- }
- void DrawGLWaterPolyLightmap (glpoly_t *p)
- {
- int i;
- float *v;
- vec3_t nv;
- GL_DisableMultitexture();
- glBegin (GL_TRIANGLE_FAN);
- v = p->verts[0];
- for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
- {
- glTexCoord2f (v[5], v[6]);
- nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime);
- nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime);
- nv[2] = v[2];
- glVertex3fv (nv);
- }
- glEnd ();
- }
- void DrawGLPoly (glpoly_t *p)
- {
- int i;
- float *v;
- glBegin (GL_POLYGON);
- v = p->verts[0];
- for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
- {
- glTexCoord2f (v[3], v[4]);
- glVertex3fv (v);
- }
- glEnd ();
- }
- void R_BlendLightmaps (void)
- {
- int i, j;
- glpoly_t *p;
- float *v;
- glRect_t *theRect;
- #if 0
- if (r_fullbright.value)
- return;
- #endif
- if (!gl_texsort.value)
- return;
- glDepthMask (0);
- if (gl_lightmap_format == GL_LUMINANCE)
- glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
- else if (gl_lightmap_format == GL_INTENSITY)
- {
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glColor4f (0,0,0,1);
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
- if (!r_lightmap.value)
- {
- glEnable (GL_BLEND);
- }
- for (i=0 ; i<MAX_LIGHTMAPS ; i++)
- {
- p = lightmap_polys[i];
- if (!p)
- continue;
- GL_Bind(lightmap_textures+i);
- if (lightmap_modified[i])
- {
- lightmap_modified[i] = false;
- theRect = &lightmap_rectchange[i];
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
- BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE,
- lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes);
- theRect->l = BLOCK_WIDTH;
- theRect->t = BLOCK_HEIGHT;
- theRect->h = 0;
- theRect->w = 0;
- }
- for ( ; p ; p=p->chain)
- {
- if (((r_viewleaf->contents==CONTENTS_EMPTY && (p->flags & SURF_UNDERWATER)) ||
- (r_viewleaf->contents!=CONTENTS_EMPTY && !(p->flags & SURF_UNDERWATER)))
- && !(p->flags & SURF_DONTWARP))
- DrawGLWaterPolyLightmap (p);
- else
- {
- glBegin (GL_POLYGON);
- v = p->verts[0];
- for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)
- {
- glTexCoord2f (v[5], v[6]);
- glVertex3fv (v);
- }
- glEnd ();
- }
- }
- }
- glDisable (GL_BLEND);
- if (gl_lightmap_format == GL_LUMINANCE)
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- else if (gl_lightmap_format == GL_INTENSITY)
- {
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glColor4f (1,1,1,1);
- }
- glDepthMask (1);
- }
- void R_RenderBrushPoly (msurface_t *fa)
- {
- texture_t *t;
- byte *base;
- int maps;
- glRect_t *theRect;
- int smax, tmax;
- c_brush_polys++;
- if (fa->flags & SURF_DRAWSKY)
- {
- EmitBothSkyLayers (fa);
- return;
- }
-
- t = R_TextureAnimation (fa->texinfo->texture);
- GL_Bind (t->gl_texturenum);
- if (fa->flags & SURF_DRAWTURB)
- {
- EmitWaterPolys (fa);
- return;
- }
- if (((r_viewleaf->contents==CONTENTS_EMPTY && (fa->flags & SURF_UNDERWATER)) ||
- (r_viewleaf->contents!=CONTENTS_EMPTY && !(fa->flags & SURF_UNDERWATER)))
- && !(fa->flags & SURF_DONTWARP))
- DrawGLWaterPoly (fa->polys);
- else
- DrawGLPoly (fa->polys);
-
- fa->polys->chain = lightmap_polys[fa->lightmaptexturenum];
- lightmap_polys[fa->lightmaptexturenum] = fa->polys;
-
- for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ;
- maps++)
- if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps])
- goto dynamic;
- if (fa->dlightframe == r_framecount
- || fa->cached_dlight)
- {
- dynamic:
- if (r_dynamic.value)
- {
- lightmap_modified[fa->lightmaptexturenum] = true;
- theRect = &lightmap_rectchange[fa->lightmaptexturenum];
- if (fa->light_t < theRect->t) {
- if (theRect->h)
- theRect->h += theRect->t - fa->light_t;
- theRect->t = fa->light_t;
- }
- if (fa->light_s < theRect->l) {
- if (theRect->w)
- theRect->w += theRect->l - fa->light_s;
- theRect->l = fa->light_s;
- }
- smax = (fa->extents[0]>>4)+1;
- tmax = (fa->extents[1]>>4)+1;
- if ((theRect->w + theRect->l) < (fa->light_s + smax))
- theRect->w = (fa->light_s-theRect->l)+smax;
- if ((theRect->h + theRect->t) < (fa->light_t + tmax))
- theRect->h = (fa->light_t-theRect->t)+tmax;
- base = lightmaps + fa->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT;
- base += fa->light_t * BLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes;
- R_BuildLightMap (fa, base, BLOCK_WIDTH*lightmap_bytes);
- }
- }
- }
- void R_RenderDynamicLightmaps (msurface_t *fa)
- {
- byte *base;
- int maps;
- glRect_t *theRect;
- int smax, tmax;
- c_brush_polys++;
- if (fa->flags & ( SURF_DRAWSKY | SURF_DRAWTURB) )
- return;
-
- fa->polys->chain = lightmap_polys[fa->lightmaptexturenum];
- lightmap_polys[fa->lightmaptexturenum] = fa->polys;
-
- for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ;
- maps++)
- if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps])
- goto dynamic;
- if (fa->dlightframe == r_framecount
- || fa->cached_dlight)
- {
- dynamic:
- if (r_dynamic.value)
- {
- lightmap_modified[fa->lightmaptexturenum] = true;
- theRect = &lightmap_rectchange[fa->lightmaptexturenum];
- if (fa->light_t < theRect->t) {
- if (theRect->h)
- theRect->h += theRect->t - fa->light_t;
- theRect->t = fa->light_t;
- }
- if (fa->light_s < theRect->l) {
- if (theRect->w)
- theRect->w += theRect->l - fa->light_s;
- theRect->l = fa->light_s;
- }
- smax = (fa->extents[0]>>4)+1;
- tmax = (fa->extents[1]>>4)+1;
- if ((theRect->w + theRect->l) < (fa->light_s + smax))
- theRect->w = (fa->light_s-theRect->l)+smax;
- if ((theRect->h + theRect->t) < (fa->light_t + tmax))
- theRect->h = (fa->light_t-theRect->t)+tmax;
- base = lightmaps + fa->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT;
- base += fa->light_t * BLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes;
- R_BuildLightMap (fa, base, BLOCK_WIDTH*lightmap_bytes);
- }
- }
- }
- void R_MirrorChain (msurface_t *s)
- {
- if (mirror)
- return;
- mirror = true;
- mirror_plane = s->plane;
- }
- #if 0
- void R_DrawWaterSurfaces (void)
- {
- int i;
- msurface_t *s;
- texture_t *t;
- if (r_wateralpha.value == 1.0)
- return;
-
-
-
- glLoadMatrixf (r_world_matrix);
- glEnable (GL_BLEND);
- glColor4f (1,1,1,r_wateralpha.value);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- for (i=0 ; i<cl.worldmodel->numtextures ; i++)
- {
- t = cl.worldmodel->textures[i];
- if (!t)
- continue;
- s = t->texturechain;
- if (!s)
- continue;
- if ( !(s->flags & SURF_DRAWTURB) )
- continue;
-
- GL_Bind (t->gl_texturenum);
- for ( ; s ; s=s->texturechain)
- R_RenderBrushPoly (s);
- t->texturechain = NULL;
- }
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glColor4f (1,1,1,1);
- glDisable (GL_BLEND);
- }
- #else
- void R_DrawWaterSurfaces (void)
- {
- int i;
- msurface_t *s;
- texture_t *t;
- if (r_wateralpha.value == 1.0 && gl_texsort.value)
- return;
-
-
-
- glLoadMatrixf (r_world_matrix);
- if (r_wateralpha.value < 1.0) {
- glEnable (GL_BLEND);
- glColor4f (1,1,1,r_wateralpha.value);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- }
- if (!gl_texsort.value) {
- if (!waterchain)
- return;
- for ( s = waterchain ; s ; s=s->texturechain) {
- GL_Bind (s->texinfo->texture->gl_texturenum);
- EmitWaterPolys (s);
- }
-
- waterchain = NULL;
- } else {
- for (i=0 ; i<cl.worldmodel->numtextures ; i++)
- {
- t = cl.worldmodel->textures[i];
- if (!t)
- continue;
- s = t->texturechain;
- if (!s)
- continue;
- if ( !(s->flags & SURF_DRAWTURB ) )
- continue;
-
-
- GL_Bind (t->gl_texturenum);
- for ( ; s ; s=s->texturechain)
- EmitWaterPolys (s);
-
- t->texturechain = NULL;
- }
- }
- if (r_wateralpha.value < 1.0) {
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glColor4f (1,1,1,1);
- glDisable (GL_BLEND);
- }
- }
- #endif
- void DrawTextureChains (void)
- {
- int i;
- msurface_t *s;
- texture_t *t;
- if (!gl_texsort.value) {
- GL_DisableMultitexture();
- if (skychain) {
- R_DrawSkyChain(skychain);
- skychain = NULL;
- }
- return;
- }
- for (i=0 ; i<cl.worldmodel->numtextures ; i++)
- {
- t = cl.worldmodel->textures[i];
- if (!t)
- continue;
- s = t->texturechain;
- if (!s)
- continue;
- if (i == skytexturenum)
- R_DrawSkyChain (s);
- else if (i == mirrortexturenum && r_mirroralpha.value != 1.0)
- {
- R_MirrorChain (s);
- continue;
- }
- else
- {
- if ((s->flags & SURF_DRAWTURB) && r_wateralpha.value != 1.0)
- continue;
- for ( ; s ; s=s->texturechain)
- R_RenderBrushPoly (s);
- }
- t->texturechain = NULL;
- }
- }
- void R_DrawBrushModel (entity_t *e)
- {
- int i;
- int k;
- vec3_t mins, maxs;
- msurface_t *psurf;
- float dot;
- mplane_t *pplane;
- model_t *clmodel;
- qboolean rotated;
- currententity = e;
- currenttexture = -1;
- clmodel = e->model;
- if (e->angles[0] || e->angles[1] || e->angles[2])
- {
- rotated = true;
- for (i=0 ; i<3 ; i++)
- {
- mins[i] = e->origin[i] - clmodel->radius;
- maxs[i] = e->origin[i] + clmodel->radius;
- }
- }
- else
- {
- rotated = false;
- VectorAdd (e->origin, clmodel->mins, mins);
- VectorAdd (e->origin, clmodel->maxs, maxs);
- }
- if (R_CullBox (mins, maxs))
- return;
- glColor3f (1,1,1);
- memset (lightmap_polys, 0, sizeof(lightmap_polys));
- VectorSubtract (r_refdef.vieworg, e->origin, modelorg);
- if (rotated)
- {
- vec3_t temp;
- vec3_t forward, right, up;
- VectorCopy (modelorg, temp);
- AngleVectors (e->angles, forward, right, up);
- modelorg[0] = DotProduct (temp, forward);
- modelorg[1] = -DotProduct (temp, right);
- modelorg[2] = DotProduct (temp, up);
- }
- psurf = &clmodel->surfaces[clmodel->firstmodelsurface];
- if (clmodel->firstmodelsurface != 0 && !gl_flashblend.value)
- {
- for (k=0 ; k<MAX_DLIGHTS ; k++)
- {
- if ((cl_dlights[k].die < cl.time) ||
- (!cl_dlights[k].radius))
- continue;
- R_MarkLights (&cl_dlights[k], 1<<k,
- clmodel->nodes + clmodel->hulls[0].firstclipnode);
- }
- }
- glPushMatrix ();
- e->angles[0] = -e->angles[0];
- R_RotateForEntity (e);
- e->angles[0] = -e->angles[0];
-
-
-
- for (i=0 ; i<clmodel->nummodelsurfaces ; i++, psurf++)
- {
-
- pplane = psurf->plane;
- dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
-
- if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
- (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
- {
- if (gl_texsort.value)
- R_RenderBrushPoly (psurf);
- else
- R_DrawSequentialPoly (psurf);
- }
- }
- R_BlendLightmaps ();
- glPopMatrix ();
- }
- void R_RecursiveWorldNode (mnode_t *node)
- {
- int c, side;
- mplane_t *plane;
- msurface_t *surf, **mark;
- mleaf_t *pleaf;
- double dot;
- if (node->contents == CONTENTS_SOLID)
- return;
- if (node->visframe != r_visframecount)
- return;
- if (R_CullBox (node->minmaxs, node->minmaxs+3))
- return;
-
- if (node->contents < 0)
- {
- pleaf = (mleaf_t *)node;
- mark = pleaf->firstmarksurface;
- c = pleaf->nummarksurfaces;
- if (c)
- {
- do
- {
- (*mark)->visframe = r_framecount;
- mark++;
- } while (--c);
- }
-
- if (pleaf->efrags)
- R_StoreEfrags (&pleaf->efrags);
- return;
- }
- plane = node->plane;
- switch (plane->type)
- {
- case PLANE_X:
- dot = modelorg[0] - plane->dist;
- break;
- case PLANE_Y:
- dot = modelorg[1] - plane->dist;
- break;
- case PLANE_Z:
- dot = modelorg[2] - plane->dist;
- break;
- default:
- dot = DotProduct (modelorg, plane->normal) - plane->dist;
- break;
- }
- if (dot >= 0)
- side = 0;
- else
- side = 1;
- R_RecursiveWorldNode (node->children[side]);
- c = node->numsurfaces;
- if (c)
- {
- surf = cl.worldmodel->surfaces + node->firstsurface;
- if (dot < 0 -BACKFACE_EPSILON)
- side = SURF_PLANEBACK;
- else if (dot > BACKFACE_EPSILON)
- side = 0;
- {
- for ( ; c ; c--, surf++)
- {
- if (surf->visframe != r_framecount)
- continue;
-
- if ( !(((r_viewleaf->contents==CONTENTS_EMPTY && (surf->flags & SURF_UNDERWATER)) ||
- (r_viewleaf->contents!=CONTENTS_EMPTY && !(surf->flags & SURF_UNDERWATER)))
- && !(surf->flags & SURF_DONTWARP)) && ( (dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) )
- continue;
-
- if (gl_texsort.value)
- {
- if (!mirror
- || surf->texinfo->texture != cl.worldmodel->textures[mirrortexturenum])
- {
- surf->texturechain = surf->texinfo->texture->texturechain;
- surf->texinfo->texture->texturechain = surf;
- }
- } else if (surf->flags & SURF_DRAWSKY) {
- surf->texturechain = skychain;
- skychain = surf;
- } else if (surf->flags & SURF_DRAWTURB) {
- surf->texturechain = waterchain;
- waterchain = surf;
- } else
- R_DrawSequentialPoly (surf);
- }
- }
- }
- R_RecursiveWorldNode (node->children[!side]);
- }
- void R_DrawWorld (void)
- {
- entity_t ent;
- memset (&ent, 0, sizeof(ent));
- ent.model = cl.worldmodel;
- VectorCopy (r_refdef.vieworg, modelorg);
- currententity = &ent;
- currenttexture = -1;
- glColor3f (1,1,1);
- memset (lightmap_polys, 0, sizeof(lightmap_polys));
- #ifdef QUAKE2
- R_ClearSkyBox ();
- #endif
- R_RecursiveWorldNode (cl.worldmodel->nodes);
- DrawTextureChains ();
- R_BlendLightmaps ();
- #ifdef QUAKE2
- R_DrawSkyBox ();
- #endif
- }
- void R_MarkLeaves (void)
- {
- byte *vis;
- mnode_t *node;
- int i;
- byte solid[4096];
- if (r_oldviewleaf == r_viewleaf && !r_novis.value)
- return;
-
- if (mirror)
- return;
- r_visframecount++;
- r_oldviewleaf = r_viewleaf;
- if (r_novis.value)
- {
- vis = solid;
- memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3);
- }
- else
- vis = Mod_LeafPVS (r_viewleaf, cl.worldmodel);
-
- for (i=0 ; i<cl.worldmodel->numleafs ; i++)
- {
- if (vis[i>>3] & (1<<(i&7)))
- {
- node = (mnode_t *)&cl.worldmodel->leafs[i+1];
- do
- {
- if (node->visframe == r_visframecount)
- break;
- node->visframe = r_visframecount;
- node = node->parent;
- } while (node);
- }
- }
- }
- int AllocBlock (int w, int h, int *x, int *y)
- {
- int i, j;
- int best, best2;
- int texnum;
- for (texnum=0 ; texnum<MAX_LIGHTMAPS ; texnum++)
- {
- best = BLOCK_HEIGHT;
- for (i=0 ; i<BLOCK_WIDTH-w ; i++)
- {
- best2 = 0;
- for (j=0 ; j<w ; j++)
- {
- if (allocated[texnum][i+j] >= best)
- break;
- if (allocated[texnum][i+j] > best2)
- best2 = allocated[texnum][i+j];
- }
- if (j == w)
- {
- *x = i;
- *y = best = best2;
- }
- }
- if (best + h > BLOCK_HEIGHT)
- continue;
- for (i=0 ; i<w ; i++)
- allocated[texnum][*x + i] = best + h;
- return texnum;
- }
- Sys_Error ("AllocBlock: full");
- return 0;
- }
- mvertex_t *r_pcurrentvertbase;
- model_t *currentmodel;
- int nColinElim;
- void BuildSurfaceDisplayList (msurface_t *fa)
- {
- int i, lindex, lnumverts;
- medge_t *pedges, *r_pedge;
- int vertpage;
- float *vec;
- float s, t;
- glpoly_t *poly;
- pedges = currentmodel->edges;
- lnumverts = fa->numedges;
- vertpage = 0;
-
-
-
- poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float));
- poly->next = fa->polys;
- poly->flags = fa->flags;
- fa->polys = poly;
- poly->numverts = lnumverts;
- for (i=0 ; i<lnumverts ; i++)
- {
- lindex = currentmodel->surfedges[fa->firstedge + i];
- if (lindex > 0)
- {
- r_pedge = &pedges[lindex];
- vec = r_pcurrentvertbase[r_pedge->v[0]].position;
- }
- else
- {
- r_pedge = &pedges[-lindex];
- vec = r_pcurrentvertbase[r_pedge->v[1]].position;
- }
- s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
- s /= fa->texinfo->texture->width;
- t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
- t /= fa->texinfo->texture->height;
- VectorCopy (vec, poly->verts[i]);
- poly->verts[i][3] = s;
- poly->verts[i][4] = t;
-
-
-
- s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
- s -= fa->texturemins[0];
- s += fa->light_s*16;
- s += 8;
- s /= BLOCK_WIDTH*16;
- t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
- t -= fa->texturemins[1];
- t += fa->light_t*16;
- t += 8;
- t /= BLOCK_HEIGHT*16;
- poly->verts[i][5] = s;
- poly->verts[i][6] = t;
- }
-
-
-
- if (!gl_keeptjunctions.value && !(fa->flags & SURF_UNDERWATER) )
- {
- for (i = 0 ; i < lnumverts ; ++i)
- {
- vec3_t v1, v2;
- float *prev, *this, *next;
- prev = poly->verts[(i + lnumverts - 1) % lnumverts];
- this = poly->verts[i];
- next = poly->verts[(i + 1) % lnumverts];
- VectorSubtract( this, prev, v1 );
- VectorNormalize( v1 );
- VectorSubtract( next, prev, v2 );
- VectorNormalize( v2 );
-
- #define COLINEAR_EPSILON 0.001
- if ((fabs( v1[0] - v2[0] ) <= COLINEAR_EPSILON) &&
- (fabs( v1[1] - v2[1] ) <= COLINEAR_EPSILON) &&
- (fabs( v1[2] - v2[2] ) <= COLINEAR_EPSILON))
- {
- int j;
- for (j = i + 1; j < lnumverts; ++j)
- {
- int k;
- for (k = 0; k < VERTEXSIZE; ++k)
- poly->verts[j - 1][k] = poly->verts[j][k];
- }
- --lnumverts;
- ++nColinElim;
-
- --i;
- }
- }
- }
- poly->numverts = lnumverts;
- }
- void GL_CreateSurfaceLightmap (msurface_t *surf)
- {
- int smax, tmax;
- byte *base;
- if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB))
- return;
- smax = (surf->extents[0]>>4)+1;
- tmax = (surf->extents[1]>>4)+1;
- surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t);
- base = lightmaps + surf->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT;
- base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes;
- R_BuildLightMap (surf, base, BLOCK_WIDTH*lightmap_bytes);
- }
- void GL_BuildLightmaps (void)
- {
- int i, j;
- model_t *m;
- memset (allocated, 0, sizeof(allocated));
- r_framecount = 1;
- if (!lightmap_textures)
- {
- lightmap_textures = texture_extension_number;
- texture_extension_number += MAX_LIGHTMAPS;
- }
- gl_lightmap_format = GL_LUMINANCE;
- if (COM_CheckParm ("-lm_1"))
- gl_lightmap_format = GL_LUMINANCE;
- if (COM_CheckParm ("-lm_a"))
- gl_lightmap_format = GL_ALPHA;
- if (COM_CheckParm ("-lm_i"))
- gl_lightmap_format = GL_INTENSITY;
- if (COM_CheckParm ("-lm_2"))
- gl_lightmap_format = GL_RGBA4;
- if (COM_CheckParm ("-lm_4"))
- gl_lightmap_format = GL_RGBA;
- switch (gl_lightmap_format)
- {
- case GL_RGBA:
- lightmap_bytes = 4;
- break;
- case GL_RGBA4:
- lightmap_bytes = 2;
- break;
- case GL_LUMINANCE:
- case GL_INTENSITY:
- case GL_ALPHA:
- lightmap_bytes = 1;
- break;
- }
- for (j=1 ; j<MAX_MODELS ; j++)
- {
- m = cl.model_precache[j];
- if (!m)
- break;
- if (m->name[0] == '*')
- continue;
- r_pcurrentvertbase = m->vertexes;
- currentmodel = m;
- for (i=0 ; i<m->numsurfaces ; i++)
- {
- GL_CreateSurfaceLightmap (m->surfaces + i);
- if ( m->surfaces[i].flags & SURF_DRAWTURB )
- continue;
- #ifndef QUAKE2
- if ( m->surfaces[i].flags & SURF_DRAWSKY )
- continue;
- #endif
- BuildSurfaceDisplayList (m->surfaces + i);
- }
- }
- if (!gl_texsort.value)
- GL_SelectTexture(TEXTURE1_SGIS);
-
-
-
- for (i=0 ; i<MAX_LIGHTMAPS ; i++)
- {
- if (!allocated[i][0])
- break;
- lightmap_modified[i] = false;
- lightmap_rectchange[i].l = BLOCK_WIDTH;
- lightmap_rectchange[i].t = BLOCK_HEIGHT;
- lightmap_rectchange[i].w = 0;
- lightmap_rectchange[i].h = 0;
- GL_Bind(lightmap_textures + i);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes
- , BLOCK_WIDTH, BLOCK_HEIGHT, 0,
- gl_lightmap_format, GL_UNSIGNED_BYTE, lightmaps+i*BLOCK_WIDTH*BLOCK_HEIGHT*lightmap_bytes);
- }
- if (!gl_texsort.value)
- GL_SelectTexture(TEXTURE0_SGIS);
- }
|