X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=gl_poly.c;h=3947bbd80fabb9dfc3e6c48b6fed04b987beddd5;hp=9dad35b38306d7e40d7517a7a2331d2a6092ff69;hb=3879b7753eaa209f8e279430e69af9c8228bb474;hpb=cc63b89849022ef37ef113a7dc9489c2e846bd1b diff --git a/gl_poly.c b/gl_poly.c index 9dad35b3..3947bbd8 100644 --- a/gl_poly.c +++ b/gl_poly.c @@ -18,8 +18,25 @@ unsigned short currentskyvert; cvar_t gl_multitexture = {"gl_multitexture", "1"}; cvar_t gl_vertexarrays = {"gl_vertexarrays", "1"}; +typedef struct translistitem_s +{ + transpoly_t *poly; + struct translistitem_s *next; +} +translistitem; + +translistitem translist[MAX_TRANSPOLYS]; +translistitem *currenttranslist; + +translistitem *translisthash[4096]; + +float transviewdist; // distance of view origin along the view normal + +float transreciptable[256]; + void glpoly_init() { + int i; Cvar_RegisterVariable (&gl_multitexture); Cvar_RegisterVariable (&gl_vertexarrays); transvert = malloc(MAX_TRANSVERTS * sizeof(transvert_t)); @@ -29,13 +46,21 @@ void glpoly_init() wallpoly = malloc(MAX_WALLPOLYS * sizeof(wallpoly_t)); skyvert = malloc(MAX_SKYVERTS * sizeof(skyvert_t)); skypoly = malloc(MAX_SKYPOLYS * sizeof(skypoly_t)); + transreciptable[0] = 0.0f; + for (i = 1;i < 256;i++) + transreciptable[i] = 1.0f / i; } void transpolyclear() { currenttranspoly = currenttransvert = 0; + currenttranslist = translist; + memset(translisthash, 0, sizeof(translisthash)); + transviewdist = DotProduct(r_refdef.vieworg, vpn); } +// turned into a #define +/* void transpolybegin(int texnum, int glowtexnum, int fogtexnum, int transpolytype) { if (currenttranspoly >= MAX_TRANSPOLYS || currenttransvert >= MAX_TRANSVERTS) @@ -48,6 +73,7 @@ void transpolybegin(int texnum, int glowtexnum, int fogtexnum, int transpolytype transpoly[currenttranspoly].verts = 0; // transpoly[currenttranspoly].ndist = 0; // clear the normal } +*/ // turned into a #define /* @@ -72,19 +98,45 @@ void transpolyvert(float x, float y, float z, float s, float t, int r, int g, in void transpolyend() { - if (currenttranspoly >= MAX_TRANSPOLYS) + float center, d, maxdist; + int i; + transvert_t *v; + if (currenttranspoly >= MAX_TRANSPOLYS || currenttransvert >= MAX_TRANSVERTS) return; if (transpoly[currenttranspoly].verts < 3) // skip invalid polygons { currenttransvert = transpoly[currenttranspoly].firstvert; // reset vert pointer return; } - if (currenttransvert >= MAX_TRANSVERTS) + center = 0; + maxdist = -1000000000000000.0f; // eh, it's definitely behind it, so... + for (i = 0,v = &transvert[transpoly[currenttranspoly].firstvert];i < transpoly[currenttranspoly].verts;i++, v++) + { + d = DotProduct(v->v, vpn); + center += d; + if (d > maxdist) + maxdist = d; + } + maxdist -= transviewdist; + if (maxdist < 4.0f) // behind view + { + currenttransvert = transpoly[currenttranspoly].firstvert; // reset vert pointer return; + } + center *= transreciptable[transpoly[currenttranspoly].verts]; + center -= transviewdist; + i = bound(0, (int) center, 4095); + currenttranslist->next = translisthash[i]; + currenttranslist->poly = transpoly + currenttranspoly; + translisthash[i] = currenttranslist; + currenttranslist++; currenttranspoly++; } int transpolyindices; +extern qboolean isG200; + +/* void transpolyrenderminmax() { int i, j, k, lastvert; @@ -111,6 +163,7 @@ void transpolyrenderminmax() if (max < 4) // free to check here, so skip polys behind the view continue; transpoly[i].distance = average; +*/ /* transpoly[i].mindistance = min; transpoly[i].maxdistance = max; @@ -164,6 +217,7 @@ skip: ; } */ +/* // sorted insert for (j = 0;j < transpolyindices;j++) if (transpoly[transpolyindex[j]].distance < average) @@ -174,9 +228,9 @@ skip: transpolyindex[j] = i; } } - -// LordHavoc: qsort compare function +*/ /* +// LordHavoc: qsort compare function int transpolyqsort(const void *ia, const void *ib) { transpoly_t *a, *b; @@ -206,16 +260,50 @@ int transpolyqsort(const void *ia, const void *ib) return -1; // (-1) a is behind b return j == b->verts; // (1) a is infront of b (0) a and b intersect // return (transpoly[*((unsigned short *)ib)].mindistance + transpoly[*((unsigned short *)ib)].maxdistance) - (transpoly[*((unsigned short *)ia)].mindistance + transpoly[*((unsigned short *)ia)].maxdistance); + */ +/* + return ((transpoly_t*)ia)->distance - ((transpoly_t*)ib)->distance; } */ -extern qboolean isG200; +/* +int transpolyqsort(const void *ia, const void *ib) +{ + return (transpoly[*((unsigned short *)ib)].distance - transpoly[*((unsigned short *)ia)].distance); +} +*/ /* -void transpolysort() +void transpolyrenderminmax() { + int i, j, lastvert; + vec_t d, max, viewdist, average; + transpolyindices = 0; + viewdist = DotProduct(r_refdef.vieworg, vpn); + for (i = 0;i < currenttranspoly;i++) + { + if (transpoly[i].verts < 3) // only process valid polygons + continue; + max = -1000000; + lastvert = transpoly[i].firstvert + transpoly[i].verts; + average = 0; + for (j = transpoly[i].firstvert;j < lastvert;j++) + { + d = DotProduct(transvert[j].v, vpn)-viewdist; + average += d; + if (d > max) + max = d; + } + if (max < 4) // free to check here, so skip polys behind the view + continue; + transpoly[i].distance = average / transpoly[i].verts; + transpolyindex[transpolyindices++] = i; + } + qsort(&transpolyindex[0], transpolyindices, sizeof(unsigned short), transpolyqsort); +} +*/ +/* int i, j, a; -// qsort(&transpolyindex[0], transpolyindices, sizeof(unsigned short), transpolyqsort); a = true; while(a) { @@ -267,9 +355,9 @@ void transpolyrender() transpoly_t *p; if (currenttranspoly < 1) return; - transpolyrenderminmax(); - if (transpolyindices < 1) - return; +// transpolyrenderminmax(); +// if (transpolyindices < 1) +// return; // testing // Con_DPrintf("transpolyrender: %i polys %i infront %i vertices\n", currenttranspoly, transpolyindices, currenttransvert); // if (transpolyindices >= 2) @@ -282,10 +370,6 @@ void transpolyrender() glEnable(GL_ALPHA_TEST); else glDisable(GL_ALPHA_TEST); - // later note: wasn't working on my TNT drivers... strangely... used a cheaper hack in transpolyvert - //// offset by 16 depth units so decal sprites appear infront of walls - //glPolygonOffset(1, -16); - //glEnable(GL_POLYGON_OFFSET_FILL); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); tpolytype = TPOLYTYPE_ALPHA; texnum = -1; @@ -331,128 +415,135 @@ void transpolyrender() */ { int points = -1; + translistitem *item; transvert_t *vert; - for (i = 0;i < transpolyindices;i++) + for (i = 4095;i >= 0;i--) { - p = &transpoly[transpolyindex[i]]; - if (p->texnum != texnum || p->verts != points || p->transpolytype != tpolytype) - { - glEnd(); - if (isG200) - { - if (p->fogtexnum) // alpha - glEnable(GL_ALPHA_TEST); - else - glDisable(GL_ALPHA_TEST); - } - if (p->texnum != texnum) - { - texnum = p->texnum; - glBindTexture(GL_TEXTURE_2D, texnum); - } - if (p->transpolytype != tpolytype) - { - tpolytype = p->transpolytype; - if (tpolytype == TPOLYTYPE_ADD) // additive - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - else // alpha - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - points = p->verts; - switch (points) - { - case 3: - glBegin(GL_TRIANGLES); - break; - case 4: - glBegin(GL_QUADS); - break; - default: - glBegin(GL_TRIANGLE_FAN); - points = -1; // to force a reinit on the next poly - break; - } - } - for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++) + item = translisthash[i]; + while (item) { - // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...) - glTexCoord2f(vert->s, vert->t); - // again, vector version isn't supported I think - glColor4ub(vert->r, vert->g, vert->b, vert->a); - glVertex3fv(vert->v); - } - if (p->glowtexnum) - { - glEnd(); - texnum = p->glowtexnum; // highly unlikely to match next poly, but... - glBindTexture(GL_TEXTURE_2D, texnum); - if (tpolytype != TPOLYTYPE_ADD) + p = item->poly; + item = item->next; + if (p->texnum != texnum || p->verts != points || p->transpolytype != tpolytype) { - tpolytype = TPOLYTYPE_ADD; // might match next poly - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glEnd(); + if (isG200) + { + if (p->fogtexnum) // alpha + glEnable(GL_ALPHA_TEST); + else + glDisable(GL_ALPHA_TEST); + } + if (p->texnum != texnum) + { + texnum = p->texnum; + glBindTexture(GL_TEXTURE_2D, texnum); + } + if (p->transpolytype != tpolytype) + { + tpolytype = p->transpolytype; + if (tpolytype == TPOLYTYPE_ADD) // additive + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + else // alpha + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + points = p->verts; + switch (points) + { + case 3: + glBegin(GL_TRIANGLES); + break; + case 4: + glBegin(GL_QUADS); + break; + default: + glBegin(GL_TRIANGLE_FAN); + points = -1; // to force a reinit on the next poly + break; + } } - points = -1; - glBegin(GL_TRIANGLE_FAN); for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++) { - glColor4ub(255,255,255,vert->a); // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...) glTexCoord2f(vert->s, vert->t); + // again, vector version isn't supported I think + glColor4ub(vert->r, vert->g, vert->b, vert->a); glVertex3fv(vert->v); } - glEnd(); - } - if (fogenabled && p->transpolytype == TPOLYTYPE_ALPHA) - { - vec3_t diff; - glEnd(); - points = -1; // to force a reinit on the next poly - if (tpolytype != TPOLYTYPE_ALPHA) - { - tpolytype = TPOLYTYPE_ALPHA; // probably matchs next poly - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - if (p->fogtexnum) + if (p->glowtexnum) { - if (texnum != p->fogtexnum) // highly unlikely to match next poly, but... + glEnd(); + texnum = p->glowtexnum; // highly unlikely to match next poly, but... + glBindTexture(GL_TEXTURE_2D, texnum); + if (tpolytype != TPOLYTYPE_ADD) { - texnum = p->fogtexnum; - glBindTexture(GL_TEXTURE_2D, texnum); + tpolytype = TPOLYTYPE_ADD; // might match next poly + glBlendFunc(GL_SRC_ALPHA, GL_ONE); } + points = -1; glBegin(GL_TRIANGLE_FAN); for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++) { - VectorSubtract(vert->v, r_refdef.vieworg,diff); + glColor4ub(255,255,255,vert->a); + // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...) glTexCoord2f(vert->s, vert->t); - glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff))); glVertex3fv(vert->v); } - glEnd (); + glEnd(); } - else + if (fogenabled && p->transpolytype == TPOLYTYPE_ALPHA) { - glDisable(GL_TEXTURE_2D); - glBegin(GL_TRIANGLE_FAN); - for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++) + vec3_t diff; + glEnd(); + points = -1; // to force a reinit on the next poly + if (tpolytype != TPOLYTYPE_ALPHA) { - VectorSubtract(vert->v, r_refdef.vieworg,diff); - glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff))); - glVertex3fv(vert->v); + tpolytype = TPOLYTYPE_ALPHA; // probably matchs next poly + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + if (p->fogtexnum) + { + if (texnum != p->fogtexnum) // highly unlikely to match next poly, but... + { + texnum = p->fogtexnum; + glBindTexture(GL_TEXTURE_2D, texnum); + } + glBegin(GL_TRIANGLE_FAN); + for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++) + { + VectorSubtract(vert->v, r_refdef.vieworg,diff); + glTexCoord2f(vert->s, vert->t); + glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff))); + glVertex3fv(vert->v); + } + glEnd (); + } + else + { + glDisable(GL_TEXTURE_2D); + glBegin(GL_TRIANGLE_FAN); + for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++) + { + VectorSubtract(vert->v, r_refdef.vieworg,diff); + glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff))); + glVertex3fv(vert->v); + } + glEnd (); + glEnable(GL_TEXTURE_2D); } - glEnd (); - glEnable(GL_TEXTURE_2D); } } } glEnd(); } - //glDisable(GL_POLYGON_OFFSET_FILL); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(1); // enable zbuffer updates glDisable(GL_ALPHA_TEST); } +extern qboolean isG200; + void wallpolyclear() { currentwallpoly = currentwallvert = 0; @@ -466,6 +557,7 @@ void wallpolyrender() wallvert_t *vert; if (currentwallpoly < 1) return; + c_brush_polys += currentwallpoly; // testing //Con_DPrintf("wallpolyrender: %i polys %i vertices\n", currentwallpoly, currentwallvert); if (!gl_mtexable) @@ -482,7 +574,7 @@ void wallpolyrender() { glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); texnum = -1; - for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++) + for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++) { if (p->texnum != texnum) { @@ -491,7 +583,7 @@ void wallpolyrender() } vert = &wallvert[p->firstvert]; glBegin(GL_POLYGON); - for (j=0 ; jverts ; j++, vert++) + for (j=0 ; jnumverts ; j++, vert++) { glTexCoord2f (vert->s, vert->t); glVertex3fv (vert->vert); @@ -509,20 +601,20 @@ void wallpolyrender() glEnable(GL_TEXTURE_2D); texnum = -1; lighttexnum = -1; - for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++) + for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++) { -// if (p->texnum != texnum || p->lighttexnum != lighttexnum) -// { + if (p->texnum != texnum || p->lighttexnum != lighttexnum) + { texnum = p->texnum; lighttexnum = p->lighttexnum; qglSelectTexture(gl_mtex_enum+0); glBindTexture(GL_TEXTURE_2D, texnum); qglSelectTexture(gl_mtex_enum+1); glBindTexture(GL_TEXTURE_2D, lighttexnum); -// } + } vert = &wallvert[p->firstvert]; glBegin(GL_POLYGON); - for (j=0 ; jverts ; j++, vert++) + for (j=0 ; jnumverts ; j++, vert++) { qglMTexCoord2f(gl_mtex_enum, vert->s, vert->t); // texture qglMTexCoord2f((gl_mtex_enum+1), vert->u, vert->v); // lightmap @@ -542,7 +634,7 @@ void wallpolyrender() // first do the textures glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); texnum = -1; - for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++) + for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++) { if (p->texnum != texnum) { @@ -551,7 +643,7 @@ void wallpolyrender() } vert = &wallvert[p->firstvert]; glBegin(GL_POLYGON); - for (j=0 ; jverts ; j++, vert++) + for (j=0 ; jnumverts ; j++, vert++) { glTexCoord2f (vert->s, vert->t); glVertex3fv (vert->vert); @@ -563,7 +655,7 @@ void wallpolyrender() glBlendFunc(GL_ZERO, GL_SRC_COLOR); glEnable(GL_BLEND); texnum = -1; - for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++) + for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++) { if (p->lighttexnum != texnum) { @@ -572,7 +664,7 @@ void wallpolyrender() } vert = &wallvert[p->firstvert]; glBegin(GL_POLYGON); - for (j=0 ; jverts ; j++, vert++) + for (j=0 ; jnumverts ; j++, vert++) { glTexCoord2f (vert->u, vert->v); glVertex3fv (vert->vert); @@ -580,17 +672,50 @@ void wallpolyrender() glEnd (); } } - // render glow textures + // switch to additive mode settings glDepthMask(0); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glBlendFunc(GL_ONE, GL_ONE); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glShadeModel(GL_SMOOTH); + // render vertex lit overlays ontop + texnum = -1; + for (i = 0, p = wallpoly;i < currentwallpoly;i++, p++) + { + if (!p->lit) + continue; + for (j = 0,vert = &wallvert[p->firstvert];j < p->numverts;j++, vert++) + if (vert->r || vert->g || vert->b) + goto lit; + continue; +lit: + c_light_polys++; + if (p->texnum != texnum) + { + texnum = p->texnum; + glBindTexture(GL_TEXTURE_2D, texnum); + } + glBegin(GL_POLYGON); + for (j = 0,vert = &wallvert[p->firstvert];j < p->numverts;j++, vert++) + { + // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...) + glTexCoord2f(vert->s, vert->t); + // again, vector version isn't supported I think + glColor3ub(vert->r, vert->g, vert->b); + glVertex3fv(vert->vert); + } + glEnd(); + } + // render glow textures + glShadeModel(GL_FLAT); + glBlendFunc(GL_ONE, GL_ONE); if (lighthalf) glColor3f(0.5,0.5,0.5); else glColor3f(1,1,1); texnum = -1; - for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++) + for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++) { if (!p->glowtexnum) continue; @@ -601,12 +726,12 @@ void wallpolyrender() } vert = &wallvert[p->firstvert]; glBegin(GL_POLYGON); - for (j=0 ; jverts ; j++, vert++) + for (j=0 ; jnumverts ; j++, vert++) { glTexCoord2f (vert->s, vert->t); glVertex3fv (vert->vert); } - glEnd (); + glEnd(); } glColor3f(1,1,1); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -619,7 +744,7 @@ void wallpolyrender() { vert = &wallvert[p->firstvert]; glBegin(GL_POLYGON); - for (j=0 ; jverts ; j++, vert++) + for (j=0 ; jnumverts ; j++, vert++) { VectorSubtract(vert->vert, r_refdef.vieworg,diff); glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff))); @@ -629,6 +754,10 @@ void wallpolyrender() } glEnable(GL_TEXTURE_2D); } + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_ALPHA_TEST); + glShadeModel(GL_SMOOTH); glDisable(GL_BLEND); glDepthMask(1); } @@ -639,31 +768,94 @@ void skypolyclear() } extern qboolean isATI; + +extern char skyname[]; +extern int solidskytexture, alphaskytexture; void skypolyrender() { int i, j; skypoly_t *p; skyvert_t *vert; + float length, speedscale; + vec3_t dir; if (currentskypoly < 1) return; // testing // Con_DPrintf("skypolyrender: %i polys %i vertices\n", currentskypoly, currentskyvert); - glDisable(GL_TEXTURE_2D); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_ALPHA_TEST); glDisable(GL_BLEND); // make sure zbuffer is enabled glEnable(GL_DEPTH_TEST); glDepthMask(1); - glColor3fv(fogcolor); // note: gets rendered over by sky if fog is not enabled - for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++) + if (!fogenabled && !skyname[0]) // normal quake sky { - vert = &skyvert[p->firstvert]; - glBegin(GL_POLYGON); - for (j=0 ; jverts ; j++, vert++) - glVertex3fv (vert->v); - glEnd (); + glColor3f(0.5f, 0.5f, 0.5f); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, solidskytexture); // upper clouds + speedscale = realtime*8; + speedscale -= (int)speedscale & ~127 ; + for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++) + { + vert = &skyvert[p->firstvert]; + glBegin(GL_POLYGON); + for (j=0 ; jverts ; j++, vert++) + { + VectorSubtract (vert->v, r_origin, dir); + dir[2] *= 3; // flatten the sphere + + length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]; + length = sqrt (length); + length = 6*63/length; + + glTexCoord2f ((speedscale + dir[0] * length) * (1.0/128), (speedscale + dir[1] * length) * (1.0/128)); + glVertex3fv (vert->v); + } + glEnd (); + } + glEnable(GL_BLEND); + glDepthMask(0); + glBindTexture(GL_TEXTURE_2D, alphaskytexture); // lower clouds + speedscale = realtime*16; + speedscale -= (int)speedscale & ~127 ; + for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++) + { + vert = &skyvert[p->firstvert]; + glBegin(GL_POLYGON); + for (j=0 ; jverts ; j++, vert++) + { + VectorSubtract (vert->v, r_origin, dir); + dir[2] *= 3; // flatten the sphere + + length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]; + length = sqrt (length); + length = 6*63/length; + + glTexCoord2f ((speedscale + dir[0] * length) * (1.0/128), (speedscale + dir[1] * length) * (1.0/128)); + glVertex3fv (vert->v); + } + glEnd (); + } + glDisable(GL_BLEND); + glColor3f(1,1,1); + glDepthMask(1); + } + else + { + glDisable(GL_TEXTURE_2D); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor3fv(fogcolor); // note: gets rendered over by skybox if fog is not enabled + for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++) + { + vert = &skyvert[p->firstvert]; + glBegin(GL_POLYGON); + for (j=0 ; jverts ; j++, vert++) + glVertex3fv (vert->v); + glEnd (); + } + glColor3f(1,1,1); + glEnable(GL_TEXTURE_2D); } - glColor3f(1,1,1); - glEnable(GL_TEXTURE_2D); }