doom3quest/Projects/Android/jni/d3es-multithread-master/neo/renderer/tr_turboshadow.cpp
Simon b2b8f43c9d Initial Commit
Builds, runs, no stereo or much else is working, menus work ok though
2020-09-08 23:10:45 +01:00

183 lines
No EOL
5.6 KiB
C++

/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "sys/platform.h"
#include "renderer/tr_local.h"
int c_turboUsedVerts;
int c_turboUnusedVerts;
/*
=====================
R_CreateVertexProgramTurboShadowVolume
are dangling edges that are outside the light frustum still making planes?
=====================
*/
srfTriangles_t *R_CreateVertexProgramTurboShadowVolume(const idRenderEntityLocal *ent,
const srfTriangles_t *tri, const idRenderLightLocal *light,
srfCullInfo_t &cullInfo) {
int i, j;
srfTriangles_t *newTri;
silEdge_t *sil;
const glIndex_t *indexes;
const byte *facing;
R_CalcInteractionFacing(ent, tri, light, cullInfo);
if (r_useShadowProjectedCull.GetBool()) {
R_CalcInteractionCullBits(ent, tri, light, cullInfo);
}
int numFaces = tri->numIndexes / 3;
int numShadowingFaces = 0;
facing = cullInfo.facing;
// if all the triangles are inside the light frustum
if (cullInfo.cullBits == LIGHT_CULL_ALL_FRONT || !r_useShadowProjectedCull.GetBool()) {
// count the number of shadowing faces
for (i = 0; i < numFaces; i++) {
numShadowingFaces += facing[i];
}
numShadowingFaces = numFaces - numShadowingFaces;
} else {
// make all triangles that are outside the light frustum "facing", so they won't cast shadows
indexes = tri->indexes;
byte *modifyFacing = cullInfo.facing;
const byte *cullBits = cullInfo.cullBits;
for (j = i = 0; i < tri->numIndexes; i += 3, j++) {
if (!modifyFacing[j]) {
int i1 = indexes[i+0];
int i2 = indexes[i+1];
int i3 = indexes[i+2];
if (cullBits[i1] & cullBits[i2] & cullBits[i3]) {
modifyFacing[j] = 1;
} else {
numShadowingFaces++;
}
}
}
}
if (!numShadowingFaces) {
// no faces are inside the light frustum and still facing the right way
return NULL;
}
// shadowVerts will be NULL on these surfaces, so the shadowVerts will be taken from the ambient surface
newTri = R_AllocStaticTriSurf();
newTri->numVerts = tri->numVerts * 2;
// alloc the max possible size
#ifdef USE_TRI_DATA_ALLOCATOR
R_AllocStaticTriSurfIndexes(newTri, (numShadowingFaces + tri->numSilEdges) * 6);
glIndex_t *tempIndexes = newTri->indexes;
glIndex_t *shadowIndexes = newTri->indexes;
#else
glIndex_t *tempIndexes = (glIndex_t *)_alloca16(tri->numSilEdges * 6 * sizeof(tempIndexes[0]));
glIndex_t *shadowIndexes = tempIndexes;
#endif
// create new triangles along sil planes
for (sil = tri->silEdges, i = tri->numSilEdges; i > 0; i--, sil++) {
int f1 = facing[sil->p1];
int f2 = facing[sil->p2];
if (!(f1 ^ f2)) {
continue;
}
int v1 = sil->v1 << 1;
int v2 = sil->v2 << 1;
// set the two triangle winding orders based on facing
// without using a poorly-predictable branch
shadowIndexes[0] = v1;
shadowIndexes[1] = v2 ^ f1;
shadowIndexes[2] = v2 ^ f2;
shadowIndexes[3] = v1 ^ f2;
shadowIndexes[4] = v1 ^ f1;
shadowIndexes[5] = v2 ^ 1;
shadowIndexes += 6;
}
int numShadowIndexes = shadowIndexes - tempIndexes;
// we aren't bothering to separate front and back caps on these
newTri->numIndexes = newTri->numShadowIndexesNoFrontCaps = numShadowIndexes + numShadowingFaces * 6;
newTri->numShadowIndexesNoCaps = numShadowIndexes;
newTri->shadowCapPlaneBits = SHADOW_CAP_INFINITE;
#ifdef USE_TRI_DATA_ALLOCATOR
// decrease the size of the memory block to only store the used indexes
R_ResizeStaticTriSurfIndexes(newTri, newTri->numIndexes);
#else
// allocate memory for the indexes
R_AllocStaticTriSurfIndexes(newTri, newTri->numIndexes);
// copy the indexes we created for the sil planes
SIMDProcessor->Memcpy(newTri->indexes, tempIndexes, numShadowIndexes * sizeof(tempIndexes[0]));
#endif
// these have no effect, because they extend to infinity
newTri->bounds.Clear();
// put some faces on the model and some on the distant projection
indexes = tri->indexes;
shadowIndexes = newTri->indexes + numShadowIndexes;
for (i = 0, j = 0; i < tri->numIndexes; i += 3, j++) {
if (facing[j]) {
continue;
}
int i0 = indexes[i+0] << 1;
shadowIndexes[2] = i0;
shadowIndexes[3] = i0 ^ 1;
int i1 = indexes[i+1] << 1;
shadowIndexes[1] = i1;
shadowIndexes[4] = i1 ^ 1;
int i2 = indexes[i+2] << 1;
shadowIndexes[0] = i2;
shadowIndexes[5] = i2 ^ 1;
shadowIndexes += 6;
}
return newTri;
}