From e158a9e71cdfa4466d4b3e91f661914856f3813a Mon Sep 17 00:00:00 2001 From: plagman Date: Tue, 10 Mar 2009 17:49:34 +0000 Subject: [PATCH] Basic model bounding sphere light culling and corrected the bounding sphere calculation algorithm. Note that light still leaks to models/sprites on overlapping sectors, but not on the sectors themselves. git-svn-id: https://svn.eduke32.com/eduke32@1240 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/build/src/mdsprite.c | 10 +++-- polymer/eduke32/build/src/polymer.c | 64 +++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/polymer/eduke32/build/src/mdsprite.c b/polymer/eduke32/build/src/mdsprite.c index 15adfc8f3..ccf39180c 100644 --- a/polymer/eduke32/build/src/mdsprite.c +++ b/polymer/eduke32/build/src/mdsprite.c @@ -1538,7 +1538,7 @@ static void md3postload(md3model_t* m) { int framei, surfi, verti; md3xyzn_t *frameverts; - float dist, lat, lng; + float dist, lat, lng, vec[3]; // apparently we can't trust loaded models bounding box/sphere information, // so let's compute it ourselves @@ -1608,9 +1608,11 @@ static void md3postload(md3model_t* m) verti = 0; while (verti < m->head.surfs[surfi].numverts) { - dist = m->head.frames[framei].cen.x * frameverts[verti].x + - m->head.frames[framei].cen.y * frameverts[verti].y + - m->head.frames[framei].cen.z * frameverts[verti].z; + vec[0] = frameverts[verti].x - m->head.frames[framei].cen.x; + vec[1] = frameverts[verti].y - m->head.frames[framei].cen.y; + vec[2] = frameverts[verti].z - m->head.frames[framei].cen.z; + + dist = vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]; if (dist > m->head.frames[framei].r) m->head.frames[framei].r = dist; diff --git a/polymer/eduke32/build/src/polymer.c b/polymer/eduke32/build/src/polymer.c index ad1d4ddd8..b8d7aa67c 100644 --- a/polymer/eduke32/build/src/polymer.c +++ b/polymer/eduke32/build/src/polymer.c @@ -278,7 +278,7 @@ _prprogrambit prprogrambits[PR_BIT_COUNT] = { " result += diffuseTexel * vec4(lightAttenuation * dotNormalLightDir * lightDiffuse, 0.0);\n" " float specular = pow( max(dot(reflect(-normalize(lightVector), fragmentNormal), normalize(-vertexPos)), 0.0), 60.0);\n" " result += diffuseTexel * vec4(lightAttenuation * specular * lightDiffuse * 10, 0.0);\n" - " }\n" + " } //else { result = vec4(0.0, 1.0, 0.0, 1.0); }\n" "\n" " l++;\n" " }\n" @@ -2434,12 +2434,16 @@ static void polymer_drawmdsprite(spritetype *tspr) float *v0, *v1; md3surf_t *s; char lpal; - float spos[3]; + float spos[3], tspos[3], lpos[3], tlpos[3], vec[3]; float ang; float scale; - int32_t surfi; + int32_t surfi, i; GLfloat* color; int32_t materialbits; + float sradius, lradius; + char modellights[PR_MAXLIGHTS]; + char modellightcount; + m = (md3model_t*)models[tile2model[Ptile2tile(tspr->picnum,sprite[tspr->owner].pal)].modelid]; updateanimation((md2model_t *)m,tspr); @@ -2488,6 +2492,8 @@ static void polymer_drawmdsprite(spritetype *tspr) bglScalef(scale * tspr->xrepeat, scale * tspr->xrepeat, scale * tspr->yrepeat); bglTranslatef(0.0f, 0.0, m->zadd * 64); + bglGetFloatv(GL_MODELVIEW_MATRIX, spritemodelview); + // debug code for drawing the model bounding sphere // bglDisable(GL_TEXTURE_2D); // bglBegin(GL_LINES); @@ -2551,6 +2557,54 @@ static void polymer_drawmdsprite(spritetype *tspr) if (pr_gpusmoothing) mdspritematerial.frameprogress = m->interpol; + // light culling + if (lightcount) + { + sradius = (m->head.frames[m->cframe].r * (1 - m->interpol)) + + (m->head.frames[m->nframe].r * m->interpol); + + sradius *= max(scale * tspr->xrepeat, scale * tspr->yrepeat); + sradius /= 1000.0f; + + spos[0] = (m->head.frames[m->cframe].cen.x * (1 - m->interpol)) + + (m->head.frames[m->nframe].cen.x * m->interpol); + spos[1] = (m->head.frames[m->cframe].cen.y * (1 - m->interpol)) + + (m->head.frames[m->nframe].cen.y * m->interpol); + spos[2] = (m->head.frames[m->cframe].cen.z * (1 - m->interpol)) + + (m->head.frames[m->nframe].cen.z * m->interpol); + + polymer_transformpoint(spos, tspos, spritemodelview); + + modellightcount = 0; + i = 0; + while (i < lightcount) + { + lradius = prlights[i].range / 1000.0f; + + lpos[0] = prlights[i].y; + lpos[1] = -prlights[i].z / 16.0f; + lpos[2] = -prlights[i].x; + + polymer_transformpoint(lpos, tlpos, rootmodelviewmatrix); + + vec[0] = tlpos[0] - tspos[0]; + vec[0] *= vec[0]; + vec[1] = tlpos[1] - tspos[1]; + vec[1] *= vec[1]; + vec[2] = tlpos[2] - tspos[2]; + vec[2] *= vec[2]; + + if ((vec[0] + vec[1] + vec[2]) <= + ((sradius+lradius) * (sradius+lradius))) + { + modellights[modellightcount] = i; + modellightcount++; + } + i++; + } + + } + for (surfi=0;surfihead.numsurfs;surfi++) { s = &m->head.surfs[surfi]; @@ -2617,7 +2671,7 @@ static void polymer_drawmdsprite(spritetype *tspr) mdspritematerial.nextframedatastride = sizeof(float) * 6; } - materialbits = polymer_bindmaterial(mdspritematerial, NULL, 0); + materialbits = polymer_bindmaterial(mdspritematerial, modellights, modellightcount); bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m->indices[surfi]); bglDrawElements(GL_TRIANGLES, s->numtris * 3, GL_UNSIGNED_INT, 0); @@ -2639,7 +2693,7 @@ static void polymer_drawmdsprite(spritetype *tspr) mdspritematerial.nextframedatastride = sizeof(float) * 6; } - materialbits = polymer_bindmaterial(mdspritematerial, NULL, 0); + materialbits = polymer_bindmaterial(mdspritematerial, modellights, modellightcount); bglDrawElements(GL_TRIANGLES, s->numtris * 3, GL_UNSIGNED_INT, s->tris);