Add basic 3D GL2 rendering with static models and terrain

This commit is contained in:
smallmodel 2024-12-21 17:04:23 +01:00
parent 14e83a52a4
commit 546b90d75f
No known key found for this signature in database
GPG key ID: 9F2D623CEDF08512
14 changed files with 1303 additions and 47 deletions

View file

@ -433,6 +433,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
int oldSort;
double originalTime;
FBO_t* fbo = NULL;
qboolean bStaticModel, oldbStaticModel;
// save original time for entity shader offsets
originalTime = backEnd.refdef.floatTime;
@ -450,6 +451,10 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
oldPshadowed = qfalse;
oldCubemapIndex = -1;
oldSort = -1;
// OPENMOHAA-specific stuff
//=========================
oldbStaticModel = -1;
//=========================
backEnd.pc.c_surfaces += numDrawSurfs;
@ -463,7 +468,19 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
continue;
}
oldSort = drawSurf->sort;
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted, &pshadowed );
//
// OPENMOHAA-specific stuff
//=========================
if (*drawSurf->surface != SF_SPRITE) {
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted, &pshadowed,
&bStaticModel );
} else {
shader = tr.sortedShaders[((refSprite_t*)drawSurf->surface)->shaderNum];
entityNum = ENTITYNUM_WORLD;
dlighted = 0;
bStaticModel = qfalse;
}
//=========================
cubemapIndex = drawSurf->cubemapIndex;
//
@ -471,7 +488,9 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
// a "entityMergable" shader is a shader that can have surfaces from separate
// entities merged into a single batch, like smoke and blood puff sprites
if ( shader != NULL && ( shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted || pshadowed != oldPshadowed || cubemapIndex != oldCubemapIndex
|| ( entityNum != oldEntityNum && !shader->entityMergable ) ) ) {
|| ( entityNum != oldEntityNum && !shader->entityMergable )
|| ( bStaticModel != oldbStaticModel && !shader->entityMergable )
) ) {
if (oldShader != NULL) {
RB_EndSurface();
}
@ -490,43 +509,60 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
//
// change the modelview matrix if needed
//
if ( entityNum != oldEntityNum ) {
if ( entityNum != oldEntityNum
|| bStaticModel != oldbStaticModel ) {
depthRange = isCrosshair = qfalse;
//
// OPENMOHAA-specific stuff
//=========================
if (bStaticModel) {
backEnd.shaderStartTime = 0.0;
backEnd.currentEntity = 0;
backEnd.spareSphere.TessFunction = 0;
backEnd.currentStaticModel = &backEnd.refdef.staticModels[entityNum];
R_RotateForStaticModel(backEnd.currentStaticModel, &backEnd.viewParms, &backEnd.or);
}
else {
backEnd.currentStaticModel = NULL;
oldbStaticModel = bStaticModel;
//=========================
if ( entityNum != REFENTITYNUM_WORLD ) {
backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
if ( entityNum != REFENTITYNUM_WORLD ) {
backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
// FIXME: e.shaderTime must be passed as int to avoid fp-precision loss issues
backEnd.refdef.floatTime = originalTime - (double)backEnd.currentEntity->e.shaderTime;
// FIXME: e.shaderTime must be passed as int to avoid fp-precision loss issues
backEnd.refdef.floatTime = originalTime - (double)backEnd.currentEntity->e.shaderTime;
// we have to reset the shaderTime as well otherwise image animations start
// from the wrong frame
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
// we have to reset the shaderTime as well otherwise image animations start
// from the wrong frame
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
// set up the transformation matrix
R_RotateForEntity( backEnd.currentEntity, &backEnd.viewParms, &backEnd.or );
// set up the transformation matrix
R_RotateForEntity( backEnd.currentEntity, &backEnd.viewParms, &backEnd.or );
// set up the dynamic lighting if needed
if ( backEnd.currentEntity->needDlights ) {
// set up the dynamic lighting if needed
if ( backEnd.currentEntity->needDlights ) {
R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
}
if(backEnd.currentEntity->e.renderfx & RF_DEPTHHACK)
{
// hack the depth range to prevent view model from poking into walls
depthRange = qtrue;
if(backEnd.currentEntity->e.renderfx & RF_CROSSHAIR)
isCrosshair = qtrue;
}
} else {
backEnd.currentEntity = &tr.worldEntity;
backEnd.refdef.floatTime = originalTime;
backEnd.or = backEnd.viewParms.world;
// we have to reset the shaderTime as well otherwise image animations on
// the world (like water) continue with the wrong frame
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
}
if(backEnd.currentEntity->e.renderfx & RF_DEPTHHACK)
{
// hack the depth range to prevent view model from poking into walls
depthRange = qtrue;
if(backEnd.currentEntity->e.renderfx & RF_CROSSHAIR)
isCrosshair = qtrue;
}
} else {
backEnd.currentEntity = &tr.worldEntity;
backEnd.refdef.floatTime = originalTime;
backEnd.or = backEnd.viewParms.world;
// we have to reset the shaderTime as well otherwise image animations on
// the world (like water) continue with the wrong frame
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
}
GL_SetModelviewMatrix( backEnd.or.modelMatrix );
@ -579,6 +615,10 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
oldEntityNum = entityNum;
}
if (*drawSurf->surface == SF_SPRITE) {
backEnd.shaderStartTime = ((refSprite_t*)drawSurf->surface)->shaderTime;
}
// add the triangles for this surface
rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
}

View file

@ -37,6 +37,8 @@ void RE_LoadWorldMap( const char *name );
*/
#define _R( id ) ri.UI_LoadResource( "*" #id )
static world_t s_worldData;
static byte *fileBase;
@ -1982,6 +1984,16 @@ static void R_LoadNodesAndLeafs (lump_t *nodeLump, lump_t *leafLump) {
out->firstmarksurface = LittleLong(inLeaf->firstLeafSurface);
out->nummarksurfaces = LittleLong(inLeaf->numLeafSurfaces);
//
// OPENMOHAA-specific stuff
//=========================
out->firstTerraPatch = LittleLong(inLeaf->firstTerraPatch);
out->numTerraPatches = LittleLong(inLeaf->numTerraPatches);
out->firstStaticModel = LittleLong(inLeaf->firstStaticModel);
out->numStaticModels = LittleLong(inLeaf->numStaticModels);
//=========================
}
// chain descendants
@ -2320,6 +2332,29 @@ void R_LoadEntities( lump_t *l ) {
w->lightGridSize[1] = 64;
w->lightGridSize[2] = 128;
//
// OPENMOHAA-specific stuff
//=========================
switch (map_version)
{
case 21:
w->lightGridSize[0] = 80.0;
w->lightGridSize[1] = 80.0;
w->lightGridSize[2] = 80.0;
break;
case 20:
w->lightGridSize[0] = 48.0;
w->lightGridSize[1] = 48.0;
w->lightGridSize[2] = 64.0;
break;
default:
w->lightGridSize[0] = 32.0;
w->lightGridSize[1] = 32.0;
w->lightGridSize[2] = 32.0;
break;
}
//=========================
p = (char *)(fileBase + l->fileofs);
// store for reference by the cgame
@ -2730,6 +2765,530 @@ void R_CalcVertexLightDirs( void )
}
}
//
// OPENMOHAA-specific stuff
//=========================
/*
================
R_LoadSphereLights
================
*/
void R_LoadSphereLights(lump_t* l) {
int i, j;
mapspherel_t* at;
spherel_t* light;
if (l->filelen % sizeof(mapspherel_t)) {
Com_Error(ERR_DROP, "LoadMap: funny lump size in spherelight data for %s\n", s_worldData.name);
}
tr.numSLights = l->filelen / sizeof(mapspherel_t);
if (tr.numSLights >= MAX_MAP_SPHERE_L_SIZE) {
Com_Error(ERR_DROP, "LoadMap: Too many spherelights on map %s, limit is %d\n", s_worldData.name, MAX_MAP_SPHERE_L_SIZE);
}
at = (mapspherel_t*)(fileBase + l->fileofs);
light = tr.sLights;
for (i = 0; i < tr.numSLights; at++, light++, i++) {
VectorCopy(at->origin, light->origin);
VectorCopy(at->color, light->color);
VectorCopy(at->spot_dir, light->spot_dir);
for (j = 0; j < 3; j++) {
light->origin[j] = LittleFloat(light->origin[j]);
light->color[j] = LittleFloat(light->color[j]);
light->spot_dir[j] = LittleFloat(light->spot_dir[j]);
}
light->spot_radiusbydistance = LittleFloat(at->spot_radiusbydistance);
light->intensity = LittleFloat(at->intensity);
light->spot_light = LittleLong(at->spot_light);
light->needs_trace = LittleLong(at->needs_trace);
light->leaf = &s_worldData.nodes[s_worldData.numDecisionNodes + LittleLong(at->leaf)];
}
}
/*
================
R_LoadSphereLightVis
================
*/
void R_LoadSphereLightVis(lump_t* l) {
int i;
int j;
int h;
mnode_t* node;
int numentries;
int* entries;
memset(&tr.sSunLight, 0, sizeof(spherel_t));
if (l->filelen % 4) {
ri.Error(ERR_DROP, "LoadMap: funny lump size in spherelight vis data for %s\n",
s_worldData.name);
}
else {
entries = (int*)(fileBase + l->fileofs);
numentries = l->filelen / sizeof(int);
if (numentries) {
if (numentries != s_worldData.numnodes - s_worldData.numDecisionNodes) {
for (i = 0; i < numentries; ++i)
entries[i] = LittleLong(entries[i]);
for (node = &s_worldData.nodes[s_worldData.numDecisionNodes]; numentries; node++) {
j = 0;
if (entries[0] != -1) {
do
++j;
while (entries[j] != -1);
}
if (j) {
node->lights = ri.Hunk_Alloc(j * sizeof(spherel_t*), h_dontcare);
node->numlights = j;
h = 0;
if (entries[0] == -2) {
node->lights[0] = &tr.sSunLight;
tr.sSunLight.leaf = (mnode_t*)-1;
h = 1;
}
while (entries[h] != -1) {
node->lights[h] = &tr.sLights[entries[h]];
h++;
}
entries += h + 1;
numentries = numentries - 1 - h;
}
else {
numentries--;
entries++;
}
}
}
}
}
}
/*
=================
R_LoadNodesAndLeafsOld
=================
*/
static void R_LoadNodesAndLeafsOld(lump_t* nodeLump, lump_t* leafLump) {
int i, j, p;
dnode_t* in;
dleaf_t_ver17* inLeaf;
mnode_t* out;
int numNodes, numLeafs;
in = (dnode_t*)(fileBase + nodeLump->fileofs);
if (nodeLump->filelen % sizeof(dnode_t) ||
leafLump->filelen % sizeof(dleaf_t)) {
ri.Error(ERR_DROP, "LoadMap: funny lump size in %s", s_worldData.name);
}
numNodes = nodeLump->filelen / sizeof(dnode_t);
numLeafs = leafLump->filelen / sizeof(dleaf_t);
out = ri.Hunk_Alloc((numNodes + numLeafs) * sizeof(*out), h_dontcare);
s_worldData.nodes = out;
s_worldData.numnodes = numNodes + numLeafs;
s_worldData.numDecisionNodes = numNodes;
// load nodes
for (i = 0; i < numNodes; i++, in++, out++)
{
for (j = 0; j < 3; j++)
{
out->mins[j] = LittleLong(in->mins[j]);
out->maxs[j] = LittleLong(in->maxs[j]);
}
p = LittleLong(in->planeNum);
out->plane = s_worldData.planes + p;
out->contents = CONTENTS_NODE; // differentiate from leafs
for (j = 0; j < 2; j++)
{
p = LittleLong(in->children[j]);
if (p >= 0)
out->children[j] = s_worldData.nodes + p;
else
out->children[j] = s_worldData.nodes + numNodes + (-1 - p);
}
}
// load leafs
inLeaf = (dleaf_t_ver17*)(fileBase + leafLump->fileofs);
for (i = 0; i < numLeafs; i++, inLeaf++, out++)
{
for (j = 0; j < 3; j++)
{
out->mins[j] = LittleLong(inLeaf->mins[j]);
out->maxs[j] = LittleLong(inLeaf->maxs[j]);
}
out->cluster = LittleLong(inLeaf->cluster);
out->area = LittleLong(inLeaf->area);
if (out->cluster >= s_worldData.numClusters) {
s_worldData.numClusters = out->cluster + 1;
}
out->firstmarksurface = s_worldData.marksurfaces +
LittleLong(inLeaf->firstLeafSurface);
out->nummarksurfaces = LittleLong(inLeaf->numLeafSurfaces);
out->firstTerraPatch = LittleLong(inLeaf->firstTerraPatch);
out->numTerraPatches = LittleLong(inLeaf->numTerraPatches);
}
// chain decendants
R_SetParent(s_worldData.nodes, NULL);
}
/*
================
R_UnpackTerraPatch
================
*/
void R_UnpackTerraPatch(cTerraPatch_t* pPacked, cTerraPatchUnpacked_t* pUnpacked) {
int i, j;
pUnpacked->byDirty = qfalse;
pUnpacked->visCountCheck = 0;
pUnpacked->visCountDraw = 0;
pUnpacked->uiDistRecalc = 0;
if (pPacked->lmapScale <= 0) {
Com_Error(ERR_DROP, "invalid map: terrain has lmapScale <= 0");
}
pUnpacked->drawinfo.lmapStep = (float)(64 / pPacked->lmapScale);
pUnpacked->drawinfo.lmapSize = pPacked->lmapScale * 8 + 1;
pUnpacked->s = ((float)pPacked->s + 0.5) / LIGHTMAP_SIZE;
pUnpacked->t = ((float)pPacked->t + 0.5) / LIGHTMAP_SIZE;
pUnpacked->drawinfo.lmData = NULL;
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
pUnpacked->texCoord[i][j][0] = pPacked->texCoord[i][j][0];
pUnpacked->texCoord[i][j][1] = pPacked->texCoord[i][j][1];
}
}
pUnpacked->x0 = ((int)pPacked->x << 6);
pUnpacked->y0 = ((int)pPacked->y << 6);
pUnpacked->z0 = pPacked->iBaseHeight;
pUnpacked->shader = ShaderForShaderNum(pPacked->iShader, pPacked->iLightMap);
pUnpacked->iNorth = pPacked->iNorth;
pUnpacked->iEast = pPacked->iEast;
pUnpacked->iSouth = pPacked->iSouth;
pUnpacked->iWest = pPacked->iWest;
for (i = 0; i < MAX_TERRAIN_VARNODES; i++)
{
varnode_t *packedVarTree;
packedVarTree = &pPacked->varTree[0][i];
pUnpacked->varTree[0][i].fVariance = packedVarTree->flags & 0x7FF;
pUnpacked->varTree[0][i].flags &= ~0xFF;
pUnpacked->varTree[0][i].flags |= (packedVarTree->flags >> 12) & 0xFF;
packedVarTree = &pPacked->varTree[1][i];
pUnpacked->varTree[1][i].fVariance = packedVarTree->flags & 0x7FF;
pUnpacked->varTree[1][i].flags &= ~0xFF;
pUnpacked->varTree[1][i].flags |= (packedVarTree->flags >> 12) & 0xFF;
}
for (i = 0; i < ARRAY_LEN(pUnpacked->heightmap); i++) {
pUnpacked->heightmap[i] = pPacked->heightmap[i];
}
pUnpacked->zmax = 0;
pUnpacked->flags = pPacked->flags;
for (i = 0; i < ARRAY_LEN(pUnpacked->heightmap); i++)
{
if (pUnpacked->zmax < pUnpacked->heightmap[i]) {
pUnpacked->zmax = pUnpacked->heightmap[i];
}
}
pUnpacked->frameCount = 0;
pUnpacked->zmax += pUnpacked->zmax;
}
/*
================
R_LoadTerrain
================
IneQuation was here
*/
void R_LoadTerrain(lump_t* lump) {
int i;
cTerraPatch_t* in;
cTerraPatchUnpacked_t* out;
if (!lump->filelen) {
s_worldData.numTerraPatches = 0;
s_worldData.terraPatches = NULL;
return;
}
if (lump->filelen % sizeof(cTerraPatch_t)) {
Com_Error(ERR_DROP, "R_LoadTerrain: funny lump size");
}
s_worldData.numTerraPatches = lump->filelen / sizeof(cTerraPatch_t);
s_worldData.terraPatches = ri.Hunk_Alloc(s_worldData.numTerraPatches * sizeof(cTerraPatchUnpacked_t), h_dontcare);
in = (cTerraPatch_t*)(fileBase + lump->fileofs);
out = s_worldData.terraPatches;
for (i = 0; i < s_worldData.numTerraPatches; in++, out++, i++) {
R_SwapTerraPatch(in);
R_UnpackTerraPatch(in, out);
}
}
/*
================
R_LoadTerrainIndexes
================
*/
void R_LoadTerrainIndexes(lump_t* lump) {
int i;
short* in;
cTerraPatchUnpacked_t** out;
if (!lump->filelen) {
s_worldData.numVisTerraPatches = 0;
s_worldData.visTerraPatches = NULL;
return;
}
if (lump->filelen % sizeof(short)) {
Com_Error(ERR_DROP, "R_LoadTerrainIndexes: funny lump size");
}
s_worldData.numVisTerraPatches = lump->filelen / sizeof(short);
s_worldData.visTerraPatches = ri.Hunk_Alloc(s_worldData.numVisTerraPatches * sizeof(cTerraPatchUnpacked_t*), h_dontcare);
in = (short*)(fileBase + lump->fileofs);
out = s_worldData.visTerraPatches;
for (i = 0; i < s_worldData.numVisTerraPatches; in++, out++, i++) {
*out = &s_worldData.terraPatches[LittleShort(*in)];
}
}
/*
================
R_LoadLightGrid2
================
*/
void R_LoadLightGrid2(lump_t* plPal, lump_t* plOffsets, lump_t* plData) {
int i;
vec3_t maxs;
int numGridPoints;
world_t *w;
float *wMins, *wMaxs;
w = &s_worldData;
if (!plPal->filelen || !plOffsets->filelen || !plData->filelen) {
ri.Printf(PRINT_WARNING, "WARNING: No light grid data present\n");
w->lightGridOffsets = 0;
w->lightGridData = 0;
return;
}
switch (map_version)
{
case 21:
w->lightGridSize[0] = 80.0;
w->lightGridSize[1] = 80.0;
w->lightGridSize[2] = 80.0;
break;
case 20:
w->lightGridSize[0] = 48.0;
w->lightGridSize[1] = 48.0;
w->lightGridSize[2] = 64.0;
break;
default:
w->lightGridSize[0] = 32.0;
w->lightGridSize[1] = 32.0;
w->lightGridSize[2] = 32.0;
break;
}
w->lightGridInverseSize[0] = 1.0f / w->lightGridSize[0];
w->lightGridInverseSize[1] = 1.0f / w->lightGridSize[1];
w->lightGridInverseSize[2] = 1.0f / w->lightGridSize[2];
wMins = w->bmodels[0].bounds[0];
wMaxs = w->bmodels[0].bounds[1];
for ( i = 0 ; i < 3 ; i++ ) {
w->lightGridOrigin[i] = w->lightGridSize[i] * ceil( wMins[i] / w->lightGridSize[i] );
maxs[i] = w->lightGridSize[i] * floor( wMaxs[i] / w->lightGridSize[i] );
w->lightGridBounds[i] = (maxs[i] - w->lightGridOrigin[i])/w->lightGridSize[i] + 1;
}
numGridPoints = w->lightGridBounds[0] * w->lightGridBounds[1] + w->lightGridBounds[0];
if (plOffsets->filelen != numGridPoints * 2) {
ri.Printf(PRINT_WARNING, "WARNING: light grid offset size mismatch\n");
w->lightGridOffsets = NULL;
w->lightGridData = NULL;
return;
}
if (plPal->filelen != 768) {
ri.Printf(PRINT_WARNING, "WARNING: light grid palette size mismatch\n");
w->lightGridOffsets = NULL;
w->lightGridData = NULL;
return;
}
w->lightGridOffsets = ri.Hunk_Alloc(plOffsets->filelen, h_dontcare);
for (i = 0; i < plOffsets->filelen / 2; i++) {
w->lightGridOffsets[i] = LittleUnsignedShort(((short*)(fileBase + plOffsets->fileofs))[i]);
}
Com_Memcpy(w->lightGridPalette, fileBase + plPal->fileofs, sizeof(s_worldData.lightGridPalette));
//w->lightGridData = ri.Hunk_Alloc(plData->filelen, h_dontcare);
//Com_Memcpy(w->lightGridData, fileBase + plData->fileofs, plData->filelen);
}
/*
================
R_LoadStaticModelData
================
*/
void R_LoadStaticModelData(lump_t* lump) {
int i;
byte* pDstColors;
byte* pSrcColors;
if (!lump->filelen) {
s_worldData.numStaticModelData = 0;
s_worldData.staticModelData = 0;
return;
}
if (lump->filelen % (sizeof(byte) * 3)) {
Com_Error(1, "R_LoadStaticModelData: funny lump size");
}
s_worldData.numStaticModelData = lump->filelen / (sizeof(byte) * 3);
s_worldData.staticModelData = (byte*)ri.Hunk_Alloc(s_worldData.numStaticModelData * sizeof(color4ub_t), h_dontcare);
pSrcColors = (byte*)(fileBase + lump->fileofs);
pDstColors = s_worldData.staticModelData;
for (i = 0; i < lump->filelen; i += sizeof(byte) * 3)
{
// Colors are stored as integers
pDstColors[0] = pSrcColors[0];
pDstColors[1] = pSrcColors[1];
pDstColors[2] = pSrcColors[2];
pDstColors[3] = 0xFF;
pSrcColors += sizeof(byte) * 3;
pDstColors += sizeof(byte) * 4;
}
}
/*
================
R_CopyStaticModel
================
*/
void R_CopyStaticModel(cStaticModel_t* pSM, cStaticModelUnpacked_t* pUnpackedSM) {
pUnpackedSM->visCount = 0;
pUnpackedSM->angles[0] = LittleFloat(pSM->angles[0]);
pUnpackedSM->angles[1] = LittleFloat(pSM->angles[1]);
pUnpackedSM->angles[2] = LittleFloat(pSM->angles[2]);
pUnpackedSM->origin[0] = LittleFloat(pSM->origin[0]);
pUnpackedSM->origin[1] = LittleFloat(pSM->origin[1]);
pUnpackedSM->origin[2] = LittleFloat(pSM->origin[2]);
pUnpackedSM->scale = LittleFloat(pSM->scale);
pUnpackedSM->firstVertexData = LittleLong(pSM->firstVertexData) * sizeof(color4ub_t) / (sizeof(byte) * 3);
pUnpackedSM->numVertexData = LittleLong(pSM->numVertexData);
memcpy(pUnpackedSM->model, pSM->model, sizeof(pUnpackedSM->model));
}
/*
================
R_LoadStaticModelDefs
================
*/
void R_LoadStaticModelDefs(lump_t* lump) {
int i;
cStaticModel_t* in;
cStaticModelUnpacked_t* out;
if (!lump->filelen) {
s_worldData.numStaticModels = 0;
s_worldData.staticModels = NULL;
return;
}
if (lump->filelen % sizeof(cStaticModel_t)) {
Com_Error(ERR_DROP, "R_LoadStaticModelDefs: funny lump size");
}
s_worldData.numStaticModels = lump->filelen / sizeof(cStaticModel_t);
s_worldData.staticModels = ri.Hunk_Alloc(s_worldData.numStaticModels * sizeof(cStaticModelUnpacked_t), h_dontcare);
in = (cStaticModel_t*)(fileBase + lump->fileofs);
out = s_worldData.staticModels;
for (i = 0; i < s_worldData.numStaticModels; in++, out++, i++) {
R_CopyStaticModel(in, out);
}
}
/*
================
R_LoadStaticModelIndexes
================
*/
void R_LoadStaticModelIndexes(lump_t* lump) {
int i;
unsigned short* in;
cStaticModelUnpacked_t** out;
if (lump->filelen % sizeof(short)) {
Com_Error(ERR_DROP, "R_LoadStaticModelDefs: funny lump size");
}
s_worldData.numVisStaticModels = lump->filelen / sizeof(short);
s_worldData.visStaticModels = ri.Hunk_Alloc(s_worldData.numVisStaticModels * sizeof(cStaticModelUnpacked_t*), h_dontcare);
in = (unsigned short*)(fileBase + lump->fileofs);
out = s_worldData.visStaticModels;
for (i = 0; i < s_worldData.numVisStaticModels; in++, out++, i++) {
unsigned short index = LittleUnsignedShort(*in);
if (index >= s_worldData.numStaticModels) {
// Added in OPM
Com_Error(ERR_DROP, "R_LoadStaticModelIndexes: bad static model index %d", index);
}
*out = &s_worldData.staticModels[index];
}
}
//=========================
/*
=================
@ -2809,18 +3368,119 @@ void RE_LoadWorldMap( const char *name ) {
((int *)header)[i] = LittleLong ( ((int *)header)[i]);
}
//
// OPENMOHAA-specific stuff
//=========================
map_version = header->version;
//=========================
// load into heap
#if 0
R_LoadEntities( &header->lumps[LUMP_ENTITIES] );
R_LoadShaders( &header->lumps[LUMP_SHADERS] );
R_LoadLightmaps( &header->lumps[LUMP_LIGHTMAPS], &header->lumps[LUMP_SURFACES] );
R_LoadPlanes (&header->lumps[LUMP_PLANES]);
R_LoadFogs( &header->lumps[LUMP_FOGS], &header->lumps[LUMP_BRUSHES], &header->lumps[LUMP_BRUSHSIDES] );
//R_LoadFogs( &header->lumps[LUMP_FOGS], &header->lumps[LUMP_BRUSHES], &header->lumps[LUMP_BRUSHSIDES] );
R_LoadSurfaces( &header->lumps[LUMP_SURFACES], &header->lumps[LUMP_DRAWVERTS], &header->lumps[LUMP_DRAWINDEXES] );
R_LoadMarksurfaces (&header->lumps[LUMP_LEAFSURFACES]);
R_LoadNodesAndLeafs (&header->lumps[LUMP_NODES], &header->lumps[LUMP_LEAFS]);
R_LoadSubmodels (&header->lumps[LUMP_MODELS]);
R_LoadVisibility( &header->lumps[LUMP_VISIBILITY] );
R_LoadLightGrid( &header->lumps[LUMP_LIGHTGRID] );
#endif
//
// OPENMOHAA-specific stuff
//=========================
_R(53);
_R(54);
R_LoadShaders(Q_GetLumpByVersion(header, LUMP_SHADERS));
_R(55);
_R(56);
R_LoadPlanes(Q_GetLumpByVersion(header, LUMP_PLANES));
_R(57);
_R(58);
_R(59);
R_LoadLightmaps(Q_GetLumpByVersion(header, LUMP_LIGHTMAPS), Q_GetLumpByVersion(header, LUMP_SURFACES));
_R(60);
_R(61);
_R(62);
_R(63);
_R(64);
R_LoadSurfaces(Q_GetLumpByVersion(header, LUMP_SURFACES), Q_GetLumpByVersion(header, LUMP_DRAWVERTS), Q_GetLumpByVersion(header, LUMP_DRAWINDEXES));
_R(65);
_R(66);
_R(67);
_R(68);
_R(69);
R_LoadMarksurfaces(Q_GetLumpByVersion(header, LUMP_LEAFSURFACES));
_R(70);
_R(71);
_R(72);
_R(73);
if (header->version > BSP_BETA_VERSION) {
R_LoadNodesAndLeafs(Q_GetLumpByVersion(header, LUMP_NODES), Q_GetLumpByVersion(header, LUMP_LEAFS));
} else {
R_LoadNodesAndLeafsOld(Q_GetLumpByVersion(header, LUMP_NODES), Q_GetLumpByVersion(header, LUMP_LEAFS));
}
_R(74);
_R(75);
_R(76);
numFogs = 0;
_R(77);
R_LoadSubmodels(Q_GetLumpByVersion(header, LUMP_MODELS));
_R(78);
_R(79);
_R(80);
R_LoadVisibility(Q_GetLumpByVersion(header, LUMP_VISIBILITY));
_R(81);
_R(82);
_R(83);
_R(84);
_R(85);
R_LoadLightGrid2(Q_GetLumpByVersion(header, LUMP_LIGHTGRIDPALETTE), Q_GetLumpByVersion(header, LUMP_LIGHTGRIDOFFSETS), Q_GetLumpByVersion(header, LUMP_LIGHTGRIDDATA));
_R(86);
_R(87);
_R(88);
_R(89);
_R(90);
R_LoadSphereLights(Q_GetLumpByVersion(header, LUMP_SPHERELIGHTS));
_R(91);
_R(92);
_R(93);
R_LoadSphereLightVis(Q_GetLumpByVersion(header, LUMP_SPHERELIGHTVIS));
_R(94);
_R(95);
_R(96);
R_LoadTerrain(Q_GetLumpByVersion(header, LUMP_TERRAIN));
_R(97);
_R(98);
_R(99);
R_LoadTerrainIndexes(Q_GetLumpByVersion(header, LUMP_TERRAININDEXES));
_R(100);
_R(101);
if (header->version > BSP_BETA_VERSION)
{
_R(102);
R_LoadStaticModelData(Q_GetLumpByVersion(header, LUMP_STATICMODELDATA));
_R(103);
_R(104);
_R(105);
R_LoadStaticModelDefs(Q_GetLumpByVersion(header, LUMP_STATICMODELDEF));
_R(106);
_R(107);
_R(108);
R_LoadStaticModelIndexes(Q_GetLumpByVersion(header, LUMP_STATICMODELINDEXES));
_R(109);
_R(110);
}
else
{
g_nStaticModelData = 0;
g_nStaticModels = 0;
g_nStaticModelIndices = 0;
}
//=========================
// determine vertex light directions
R_CalcVertexLightDirs();
@ -3051,6 +3711,22 @@ void RE_LoadWorldMap( const char *name ) {
}
ri.FS_FreeFile( buffer.v );
//
// OPENMOHAA-specific stuff
//=========================
ri.UI_LoadResource("*111");
R_Sphere_InitLights();
ri.UI_LoadResource("*112");
R_InitTerrain();
ri.UI_LoadResource("*113");
R_InitStaticModels();
ri.UI_LoadResource("*114");
R_LevelMarksLoad(name);
ri.UI_LoadResource("*115");
R_VisDebugLoad(name);
ri.UI_LoadResource("*116");
//=========================
}
//

View file

@ -554,7 +554,13 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) {
}
}
tr.refdef.stereoFrame = stereoFrame;
tr.refdef.stereoFrame = stereoFrame;
//
// OPENMOHAA-specific stuff
//
g_nStaticSurfaces = 0;
}

View file

@ -3098,6 +3098,13 @@ void R_SetColorMappings( void ) {
{
GLimp_SetGamma( s_gammatable, s_gammatable, s_gammatable );
}
//
// OPENMOHAA-specific stuff
//=========================
tr.overbrightShift = r_mapOverBrightBits->integer - tr.overbrightBits;
tr.overbrightMult = (float)(1 << tr.overbrightShift);
//=========================
}
/*

View file

@ -265,6 +265,13 @@ int max_termarks;
cvar_t* r_skyportal;
cvar_t* r_skyportal_origin;
cvar_t* r_farplane;
cvar_t* r_farplane_bias;
cvar_t* r_farplane_color;
cvar_t* r_farplane_nocull;
cvar_t* r_farplane_nofog;
cvar_t* r_skybox_farplane;
cvar_t* r_farclip;
cvar_t* r_lightcoronasize;
// LOD
@ -313,6 +320,7 @@ cvar_t* r_showstaticbboxes;
cvar_t* r_showcull;
cvar_t* r_showlod;
cvar_t* r_showstaticlod;
cvar_t* r_showportal;
//=========================
@ -1555,6 +1563,13 @@ void R_Register( void )
r_skyportal = ri.Cvar_Get("r_skyportal", "0", 0);
r_skyportal_origin = ri.Cvar_Get("r_skyportal_origin", "0 0 0", 0);
r_farplane = ri.Cvar_Get("r_farplane", "0", CVAR_CHEAT);
r_farplane_bias = ri.Cvar_Get("r_farplane_bias", "0", CVAR_CHEAT);
r_farplane_color = ri.Cvar_Get("r_farplane_color", ".5 .5 .5", CVAR_CHEAT);
r_farplane_nocull = ri.Cvar_Get("r_farplane_nocull", "0", CVAR_CHEAT);
r_farplane_nofog = ri.Cvar_Get("r_farplane_nofog", "0", CVAR_CHEAT);
r_skybox_farplane = ri.Cvar_Get("r_skybox_farplane", "0", CVAR_CHEAT);
r_farclip = ri.Cvar_Get("r_farclip", "0", CVAR_CHEAT);
r_lightcoronasize = ri.Cvar_Get("r_lightcoronasize", ".1", CVAR_ARCHIVE);
// LOD
@ -1603,6 +1618,7 @@ void R_Register( void )
r_showcull = ri.Cvar_Get("r_showcull", "0", CVAR_CHEAT);
r_showlod = ri.Cvar_Get("r_showlod", "0", CVAR_TEMP);
r_showstaticlod = ri.Cvar_Get("r_showstaticlod", "0", CVAR_TEMP);
r_showportal = ri.Cvar_Get("r_showportal", "0", 0);
}
void R_InitQueries(void)
@ -1718,6 +1734,22 @@ void R_Init( void ) {
R_InitQueries();
//
// OPENMOHAA-specific stuff
//=========================
R_Sky_Init();
max_termarks = r_maxtermarks->integer;
if (max_termarks < MAX_TERMARKS)
max_termarks = MAX_TERMARKS;
R_LevelMarksInit();
tr.pFontDebugStrings = R_LoadFont("verdana-14");
g_bInfoworldtris = qfalse;
//=========================
err = qglGetError();
if ( err != GL_NO_ERROR )

View file

@ -78,6 +78,18 @@ typedef unsigned int vaoCacheGlIndex_t;
#define MAX_DRAWN_PSHADOWS 16 // do not increase past 32, because bit flags are used on surfaces
#define PSHADOW_MAP_SIZE 512
//
// OPENMOHAA-specific stuff
//=========================
#define MAX_SPHERE_LIGHTS 512
#define MAX_SPRITESURFS 0x8000
#define MAX_SPRITE_DIST 16384.0f
#define MAX_SPRITE_DIST_SQUARED (MAX_SPRITE_DIST * MAX_SPRITE_DIST)
//=========================
typedef struct cubemap_s {
char name[MAX_QPATH];
vec3_t origin;
@ -874,6 +886,9 @@ typedef struct {
// OPENMOHAA-specific stuff
//
int num_sprites;
struct refSprite_s *sprites;
int numTerMarks;
struct srfMarkFragment_s *terMarks;
@ -1020,7 +1035,6 @@ typedef enum {
//
SF_MARK_FRAG,
SF_DISPLAY_LIST,
SF_TIKI_SKEL,
SF_TIKI_STATIC,
SF_SWIPE,
@ -1215,7 +1229,7 @@ extern void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])(void *);
//
// OPENMOHAA-specific stuff
//
//=========================
typedef struct {
struct mnode_s* cntNode;
@ -1417,6 +1431,8 @@ typedef struct refSprite_s {
float shaderTime;
} refSprite_t;
//=========================
/*
==============================================================================
@ -1586,6 +1602,9 @@ typedef struct {
// OPENMOHAA-specific stuff
//
unsigned short* lightGridOffsets;
byte lightGridPalette[768];
int numTerraPatches;
cTerraPatchUnpacked_t* terraPatches;
cTerraPatchUnpacked_t* activeTerraPatches;
@ -1605,7 +1624,7 @@ typedef struct {
//
// OPENMOHAA-specific stuff
//
//=========================
typedef struct {
float width;
float height;
@ -1614,6 +1633,7 @@ typedef struct {
float scale;
shader_t* shader;
} sprite_t;
//=========================
/*
==============================================================================
@ -1696,7 +1716,10 @@ typedef enum {
MOD_MESH,
MOD_MDR,
MOD_IQM,
//
// OPENMOHAA-specific stuff
//
MOD_TIKI,
MOD_SPRITE
} modtype_t;
@ -1767,6 +1790,11 @@ the bits are allocated as follows:
1 : pshadow flag
0 : dlight flag
*/
/*
#define QSORT_FOGNUM_SHIFT 2
#define QSORT_REFENTITYNUM_SHIFT 7
#define QSORT_SHADERNUM_SHIFT (QSORT_REFENTITYNUM_SHIFT+REFENTITYNUM_BITS)
*/
#define QSORT_FOGNUM_SHIFT 2
#define QSORT_REFENTITYNUM_SHIFT 4
#define QSORT_STATICMODEL_SHIFT (QSORT_REFENTITYNUM_SHIFT+REFENTITYNUM_BITS)
@ -1932,7 +1960,13 @@ typedef struct {
//
// OPENMOHAA-specific stuff
//
sphereor_t spheres[MAX_SPHERE_LIGHTS];
unsigned short numSpheresUsed;
sphereor_t* currentSphere;
sphereor_t spareSphere;
sphereor_t hudSphere;
cStaticModelUnpacked_t* currentStaticModel;
float shaderStartTime;
int dsStreamVert;
} backEndState_t;
@ -2139,6 +2173,7 @@ typedef struct {
int frame_skel_index;
int skel_index[1024];
fontheader_t* pFontDebugStrings;
int farclip;
} trGlobals_t;
extern backEndState_t backEnd;
@ -2339,6 +2374,13 @@ extern int max_termarks;
extern cvar_t* r_skyportal;
extern cvar_t* r_skyportal_origin;
extern cvar_t* r_farplane;
extern cvar_t* r_farplane_bias;
extern cvar_t* r_farplane_color;
extern cvar_t* r_farplane_nocull;
extern cvar_t* r_farplane_nofog;
extern cvar_t* r_skybox_farplane;
extern cvar_t* r_farclip;
extern cvar_t* r_lightcoronasize;
// LOD
@ -2387,6 +2429,7 @@ extern cvar_t* r_showstaticbboxes;
extern cvar_t* r_showcull;
extern cvar_t* r_showlod;
extern cvar_t* r_showstaticlod;
extern cvar_t* r_showportal;
//=========================
@ -2435,7 +2478,7 @@ void R_AddLightningBoltSurfaces( trRefEntity_t *e );
void R_AddPolygonSurfaces( void );
void R_DecomposeSort( unsigned sort, int *entityNum, shader_t **shader,
int *fogNum, int *dlightMap, int *pshadowMap );
int *fogNum, int *dlightMap, int *pshadowMap, qboolean *bStaticModel );
void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader,
int fogIndex, int dlightMap, int pshadowMap, int cubemap );
@ -2741,6 +2784,8 @@ int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, ve
int R_LightDirForPoint( vec3_t point, vec3_t lightDir, vec3_t normal, world_t *world );
int R_CubemapForPoint( vec3_t point );
void R_Sphere_InitLights();
/*
============================================================
@ -2920,7 +2965,6 @@ int R_IQMLerpTag( orientation_t *tag, iqmData_t *data,
// OPENMOHAA-specific stuff
//=========================
/*
=============================================================
@ -3060,6 +3104,10 @@ TERRAIN
=============================================================
*/
extern terraTri_t* g_pTris;
extern terrainVert_t* g_pVert;
void R_MarkTerrainPatch(cTerraPatchUnpacked_t* pPatch);
void R_AddTerrainSurfaces();
void R_AddTerrainMarkSurfaces();
@ -3335,7 +3383,8 @@ typedef struct {
//
// OPENMOHAA-specific stuff
//
//
drawSurf_t spriteSurfs[MAX_SPRITESURFS];
srfMarkFragment_t* terMarks;
refSprite_t sprites[2048];
cStaticModelUnpacked_t* staticModels;

View file

@ -743,6 +743,86 @@ void R_SetupFrustum (viewParms_t *dest, float xmin, float xmax, float ymax, floa
SetPlaneSignbits( &dest->frustum[4] );
dest->flags |= VPF_FARPLANEFRUSTUM;
}
//
// OPENMOHAA-specific stuff
//=========================
if (dest->isPortalSky) {
// since 2.0: skybox farplane
if (r_skybox_farplane->integer) {
dest->farplane_distance = r_skybox_farplane->value;
sscanf(
r_farplane_color->string,
"%f %f %f",
&dest->farplane_color[0],
&dest->farplane_color[1],
&dest->farplane_color[2]
);
if (r_farplane_nocull->integer > 0) {
dest->farplane_cull = 0;
} else if (r_farplane_nocull->integer == 0) {
dest->farplane_cull = 1;
} else {
dest->farplane_cull = 2;
}
}
}
else if (r_farplane->integer)
{
dest->farplane_distance = r_farplane->value;
dest->farplane_bias = r_farplane_bias->value;
sscanf(
r_farplane_color->string,
"%f %f %f",
&dest->farplane_color[0],
&dest->farplane_color[1],
&dest->farplane_color[2]);
if (r_farplane_nocull->integer > 0) {
dest->farplane_cull = 0;
} else if (r_farplane_nocull->integer == 0) {
dest->farplane_cull = 1;
} else {
dest->farplane_cull = 2;
}
}
if (dest->farplane_distance)
{
vec3_t farPoint;
float realPlaneLen;
float tmp;
vec4_t fogColor;
dest->fog.len = dest->farplane_distance;
dest->fog.oolen = 1.0 / dest->farplane_distance;
VectorMA(dest->or.origin, dest->farplane_distance, dest->or.axis[0], farPoint);
VectorNegate(dest->or.axis[0], dest->frustum[4].normal);
dest->frustum[4].type = PLANE_NON_AXIAL;
dest->frustum[4].dist = DotProduct(farPoint, dest->frustum[4].normal);
SetPlaneSignbits(&dest->frustum[4]);
dest->fog.enabled = r_farplane_nofog->integer == 0;
if (dest->farplane_cull) {
// extra fustum for culling
dest->flags |= VPF_FARPLANEFRUSTUM;
dest->fog.extrafrustums = 1;
} else {
dest->fog.extrafrustums = 0;
}
}
else
{
dest->fog.enabled = 0;
dest->fog.extrafrustums = 0;
}
//=========================
}
/*
@ -1208,10 +1288,12 @@ static qboolean SurfIsOffscreen( const drawSurf_t *drawSurf, vec4_t clipDest[128
int i;
unsigned int pointOr = 0;
unsigned int pointAnd = (unsigned int)~0;
qboolean bStaticModel;
R_RotateForViewer();
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted, &pshadowed );
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted, &pshadowed,
&bStaticModel );
RB_BeginSurface( shader, fogNum, drawSurf->cubemapIndex);
rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
@ -1469,7 +1551,8 @@ void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader,
// compared quickly during the qsorting process
tr.refdef.drawSurfs[index].sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT)
| tr.shiftedEntityNum | ( fogIndex << QSORT_FOGNUM_SHIFT )
| ((int)pshadowMap << QSORT_PSHADOW_SHIFT) | (int)dlightMap;
| ((int)pshadowMap << QSORT_PSHADOW_SHIFT) | (int)dlightMap
| tr.shiftedIsStatic;
tr.refdef.drawSurfs[index].cubemapIndex = cubemap;
tr.refdef.drawSurfs[index].surface = surface;
tr.refdef.numDrawSurfs++;
@ -1481,12 +1564,21 @@ R_DecomposeSort
=================
*/
void R_DecomposeSort( unsigned sort, int *entityNum, shader_t **shader,
int *fogNum, int *dlightMap, int *pshadowMap ) {
int *fogNum, int *dlightMap, int *pshadowMap,
qboolean *bStaticModel
) {
*fogNum = ( sort >> QSORT_FOGNUM_SHIFT ) & 31;
*shader = tr.sortedShaders[ ( sort >> QSORT_SHADERNUM_SHIFT ) & (MAX_SHADERS-1) ];
*entityNum = ( sort >> QSORT_REFENTITYNUM_SHIFT ) & REFENTITYNUM_MASK;
*pshadowMap = (sort >> QSORT_PSHADOW_SHIFT ) & 1;
*dlightMap = sort & 1;
*dlightMap = sort & 1;
//
// OPENMOHAA-specific stuff
//=========================
*fogNum = 0;
*bStaticModel = sort & (1 << QSORT_STATICMODEL_SHIFT);
//=========================
}
/*
@ -1500,7 +1592,8 @@ void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs ) {
int entityNum;
int dlighted;
int pshadowed;
int i;
int i;
qboolean bStaticModel;
//ri.Printf(PRINT_ALL, "firstDrawSurf %d numDrawSurfs %d\n", (int)(drawSurfs - tr.refdef.drawSurfs), numDrawSurfs);
@ -1524,7 +1617,7 @@ void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs ) {
// check for any pass through drawing, which
// may cause another view to be rendered first
for ( i = 0 ; i < numDrawSurfs ; i++ ) {
R_DecomposeSort( (drawSurfs+i)->sort, &entityNum, &shader, &fogNum, &dlighted, &pshadowed );
R_DecomposeSort( (drawSurfs+i)->sort, &entityNum, &shader, &fogNum, &dlighted, &pshadowed, &bStaticModel );
if ( shader->sort > SS_PORTAL ) {
break;
@ -1611,6 +1704,16 @@ static void R_AddEntitySurface (int entityNum)
case MOD_BRUSH:
R_AddBrushModelSurfaces( ent );
break;
//
// OPENMOHAA-specific stuff
//=========================
case MOD_SPRITE:
ri.Printf(PRINT_ALL, "sprite model '%s' being added to renderer!\n", tr.currentModel->name);
break;
case MOD_TIKI:
R_AddSkelSurfaces(ent);
break;
//=========================
case MOD_BAD: // null model axis
if ( (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal) {
break;
@ -1640,6 +1743,12 @@ void R_AddEntitySurfaces (void) {
return;
}
//
// OPENMOHAA-specific stuff
//=========================
tr.shiftedIsStatic = 0;
//=========================
for ( i = 0; i < tr.refdef.num_entities; i++)
R_AddEntitySurface(i);
}
@ -1826,6 +1935,8 @@ R_DrawDebugLines
================
*/
void R_DrawDebugLines(void) {
// FIXME: unimplemented
#if 0
debugline_t* line;
int i;
float width;
@ -1902,6 +2013,7 @@ void R_DrawDebugLines(void) {
}
qglDepthRange(0.0, 1.0);
#endif
}
/*
@ -2891,6 +3003,25 @@ void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene )
// OPENMOHAA-specific stuff
//
/*
=================
R_AddSpriteSurf
=================
*/
void R_AddSpriteSurf(surfaceType_t* surface, shader_t* shader, float zDistance)
{
int index;
if (zDistance > MAX_SPRITE_DIST_SQUARED) {
zDistance = MAX_SPRITE_DIST_SQUARED;
}
index = tr.refdef.numSpriteSurfs % MAX_SPRITES;
tr.refdef.spriteSurfs[index].sort = (int)(MAX_SPRITE_DIST_SQUARED - zDistance) | (shader->sortedIndex << QSORT_SHADERNUM_SHIFT);
tr.refdef.spriteSurfs[index].surface = surface;
tr.refdef.numSpriteSurfs++;
}
/*
=================
R_RotateForStaticModel

View file

@ -243,6 +243,7 @@ void R_AddMarkFragments(int numClipPoints, vec3_t clipPoints[2][MAX_VERTS_ON_POL
mf = fragmentBuffer + (*returnedFragments);
mf->firstPoint = (*returnedPoints);
mf->numPoints = numClipPoints;
mf->iIndex = 0; // OPENMOHAA-specific stuff
Com_Memcpy( pointBuffer + (*returnedPoints) * 3, clipPoints[pingPong], numClipPoints * sizeof(vec3_t) );
(*returnedPoints) += numClipPoints;

View file

@ -39,6 +39,8 @@ int r_numpolyverts;
// OPENMOHAA-specific stuff
//=========================
int r_firstSceneSpriteSurf;
int r_numsprites;
int r_firstSceneSprite;
@ -453,6 +455,35 @@ void RE_BeginScene(const refdef_t *fd)
// each scene / view.
tr.frameSceneNum++;
tr.sceneCount++;
//
// OPENMOHAA-specific stuff
//=========================
TIKI_Reset_Caches();
// copy the sky data
tr.refdef.sky_alpha = fd->sky_alpha;
tr.refdef.sky_portal = fd->sky_portal;
VectorCopy(fd->sky_origin, tr.refdef.sky_origin);
VectorCopy(fd->sky_axis[0], tr.refdef.sky_axis[0]);
VectorCopy(fd->sky_axis[1], tr.refdef.sky_axis[1]);
VectorCopy(fd->sky_axis[2], tr.refdef.sky_axis[2]);
tr.refdef.numSpriteSurfs = r_firstSceneSpriteSurf;
tr.refdef.spriteSurfs = backEndData->spriteSurfs;
tr.refdef.num_sprites = r_numsprites - r_firstSceneSprite;
tr.refdef.sprites = &backEndData->sprites[r_firstSceneSprite];
tr.refdef.numTerMarks = r_numtermarks - r_firstSceneTerMark;
tr.refdef.terMarks = &backEndData->terMarks[r_firstSceneTerMark];
backEndData->staticModelData = tr.refdef.staticModelData;
tr.skyRendered = qfalse;
tr.portalRendered = qfalse;
//=========================
}
@ -463,6 +494,14 @@ void RE_EndScene(void)
r_firstSceneEntity = r_numentities;
r_firstSceneDlight = r_numdlights;
r_firstScenePoly = r_numpolys;
//
// OPENMOHAA-specific stuff
//
r_firstSceneSpriteSurf = tr.refdef.numSpriteSurfs;
r_firstSceneSprite = r_numsprites;
r_firstSceneTerMark = r_numtermarks;
}
/*
@ -583,6 +622,68 @@ void RE_RenderScene( const refdef_t *fd ) {
parms.flags = VPF_USESUNLIGHT;
}
//
// OPENMOHAA-specific stuff
//=========================
// copy the farplane data
parms.farplane_distance = fd->farplane_distance;
parms.farplane_bias = fd->farplane_bias;
parms.farplane_color[0] = fd->farplane_color[0];
parms.farplane_color[1] = fd->farplane_color[1];
parms.farplane_color[2] = fd->farplane_color[2];
parms.farplane_cull = fd->farplane_cull;
parms.renderTerrain = fd->renderTerrain;
tr.refdef.skybox_farplane = fd->skybox_farplane;
tr.refdef.render_terrain = parms.renderTerrain;
if (fd->farclipOverride >= 15900 || fd->farclipOverride <= -0.99) {
tr.farclip = 0;
} else {
tr.farclip = r_farclip->integer;
if (!tr.farclip && (r_picmip->integer > 1 || r_colorbits->integer == 16)) {
tr.farclip = 2800;
}
}
if (tr.farclip) {
if (fd->farclipOverride != 0) {
parms.farplane_distance = fd->farclipOverride;
} else {
parms.farplane_distance = tr.farclip;
}
if (fd->farplane_color[0] >= 0 && fd->farplane_color[1] >= 0 && fd->farplane_color[2] >= 0) {
parms.farplane_color[0] = fd->farplane_color[0];
parms.farplane_color[1] = fd->farplane_color[1];
parms.farplane_color[2] = fd->farplane_color[2];
}
if (fd->farplaneColorOverride[0] >= 0 && fd->farplaneColorOverride[1] >= 0 && fd->farplaneColorOverride[2] >= 0) {
parms.farplane_color[0] = fd->farplaneColorOverride[0];
parms.farplane_color[1] = fd->farplaneColorOverride[1];
parms.farplane_color[2] = fd->farplaneColorOverride[2];
}
parms.farplane_cull = qtrue;
if (fd->farplane_distance > 0 && fd->farplane_distance < parms.farplane_distance) {
parms.farplane_distance = fd->farplane_distance;
} else {
if (fd->farplane_bias == 0) {
parms.farplane_bias = parms.farplane_distance * 0.18f;
} else if (fd->farplane_distance <= 500.f) {
parms.farplane_bias = parms.farplane_distance * 0.18f;
} else {
parms.farplane_bias = parms.farplane_distance / fd->farplane_distance;
}
}
} else if (parms.farplane_bias == 0) {
parms.farplane_bias = parms.farplane_distance * 0.18f;
}
//=========================
R_RenderView( &parms );
if(!( fd->rdflags & RDF_NOWORLDMODEL ))

View file

@ -541,6 +541,21 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
case CGEN_IDENTITY_LIGHTING:
case CGEN_BAD:
break;
//
// OPENMOHAA-specific stuff
//=========================
case CGEN_STATIC:
baseColor[0] =
baseColor[1] =
baseColor[2] =
baseColor[3] = 0.0f;
vertColor[0] =
vertColor[1] =
vertColor[2] =
vertColor[3] = 1.0f;
break;
//=========================
}
//

View file

@ -3165,9 +3165,11 @@ static void FixRenderCommandList( int newShader ) {
int pshadowMap;
int sortedIndex;
const drawSurfsCommand_t *ds_cmd = (const drawSurfsCommand_t *)curCmd;
qboolean bStaticModel;
for( i = 0, drawSurf = ds_cmd->drawSurfs; i < ds_cmd->numDrawSurfs; i++, drawSurf++ ) {
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlightMap, &pshadowMap );
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlightMap, &pshadowMap,
&bStaticModel );
sortedIndex = (( drawSurf->sort >> QSORT_SHADERNUM_SHIFT ) & (MAX_SHADERS-1));
if( sortedIndex >= newShader ) {
sortedIndex++;

View file

@ -1344,6 +1344,13 @@ static void R_InsertLightIntoList(spherel_t *pLight, float fIntensity, gatheredL
pCurrLight->pLight = pLight;
}
#else
void R_Sphere_InitLights()
{
// UNIMPLEMENTED
}
#endif
#define MAX_GATHERED_LIGHTS 8

View file

@ -1299,6 +1299,128 @@ void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface)
static void RB_SurfaceSkip( void *surf ) {
}
//
// OPENMOHAA-specific stuff
//=========================
/*
=============
RB_SurfaceMarkFragment
=============
*/
void RB_SurfaceMarkFragment(srfMarkFragment_t* p) {
int i;
int numv;
RB_CHECKOVERFLOW( p->numVerts, 3*(p->numVerts - 2) );
if (p->iIndex <= 0 || R_TerrainHeightForPoly(&tr.world->terraPatches[p->iIndex - 1], p->verts, p->numVerts))
{
// FIXME: from here on out, it's mostly the same code as in RB_SurfacePolychain,
// common part could be extracted into an inline func
// fan triangles into the tess array
numv = tess.numVertexes;
for ( i = 0; i < p->numVerts; i++ )
{
VectorCopy( p->verts[i].xyz, tess.xyz[numv] );
tess.texCoords[numv][0] = p->verts[i].st[0];
tess.texCoords[numv][1] = p->verts[i].st[1];
tess.color[numv][0] = p->verts[i].modulate[0] * 65535 / 255;
tess.color[numv][1] = p->verts[i].modulate[1] * 65535 / 255;
tess.color[numv][2] = p->verts[i].modulate[2] * 65535 / 255;
tess.color[numv][3] = p->verts[i].modulate[3] * 65535 / 255;
numv++;
}
// generate fan indexes into the tess array
for ( i = 0; i < p->numVerts - 2; i++ ) {
tess.indexes[tess.numIndexes + 0] = tess.numVertexes;
tess.indexes[tess.numIndexes + 1] = tess.numVertexes + i + 1;
tess.indexes[tess.numIndexes + 2] = tess.numVertexes + i + 2;
tess.numIndexes += 3;
}
tess.numVertexes = numv;
}
}
void RB_DrawTerrainTris(srfTerrain_t* p) {
int i;
terraInt numv;
int dlightBits;
RB_CHECKOVERFLOW(p->nVerts, p->nTris * 3);
dlightBits = p->dlightBits[0];
tess.dlightBits |= dlightBits;
if (p->dlightMap[0])
{
float lmScale = (1.0 / LIGHTMAP_SIZE) / p->lmapStep;
for (i = p->iVertHead; i; i = g_pVert[i].iNext) {
assert(tess.numVertexes < SHADER_MAX_VERTEXES);
VectorCopy(g_pVert[i].xyz, tess.xyz[tess.numVertexes]);
tess.texCoords[tess.numVertexes][0] = g_pVert[i].texCoords[0][0];
tess.texCoords[tess.numVertexes][1] = g_pVert[i].texCoords[0][1];
tess.lightCoords[tess.numVertexes][0] = g_pVert[i].xyz[0] * lmScale + p->lmapX;
tess.lightCoords[tess.numVertexes][1] = g_pVert[i].xyz[1] * lmScale + p->lmapY;
tess.normal[tess.numVertexes][0] = 0;
tess.normal[tess.numVertexes][1] = 0;
tess.normal[tess.numVertexes][2] = 1.0;
tess.color[tess.numVertexes][0] = 0xffff;
tess.color[tess.numVertexes][1] = 0xffff;
tess.color[tess.numVertexes][2] = 0xffff;
tess.color[tess.numVertexes][3] = 0xffff;
g_pVert[i].iVertArray = tess.numVertexes;
tess.numVertexes++;
}
}
else
{
for (i = p->iVertHead; i; i = g_pVert[i].iNext) {
assert(tess.numVertexes < SHADER_MAX_VERTEXES);
VectorCopy(g_pVert[i].xyz, tess.xyz[tess.numVertexes]);
tess.texCoords[tess.numVertexes][0] = g_pVert[i].texCoords[0][0];
tess.texCoords[tess.numVertexes][1] = g_pVert[i].texCoords[0][1];
tess.lightCoords[tess.numVertexes][0] = g_pVert[i].texCoords[1][0];
tess.lightCoords[tess.numVertexes][1] = g_pVert[i].texCoords[1][1];
//tess.vertexDlightBits[tess.numVertexes] = dlightBits;
tess.normal[tess.numVertexes][0] = 0;
tess.normal[tess.numVertexes][1] = 0;
tess.normal[tess.numVertexes][2] = 1.0;
tess.color[tess.numVertexes][0] = 0xffff;
tess.color[tess.numVertexes][1] = 0xffff;
tess.color[tess.numVertexes][2] = 0xffff;
tess.color[tess.numVertexes][3] = 0xffff;
g_pVert[i].iVertArray = tess.numVertexes;
tess.numVertexes++;
}
}
for (i = p->iTriHead; i; i = g_pTris[i].iNext)
{
assert(tess.numVertexes < SHADER_MAX_INDEXES);
//
// Make sure these can be drawn
//
if (g_pTris[i].byConstChecks & 4)
{
tess.indexes[tess.numIndexes] = g_pVert[g_pTris[i].iPt[0]].iVertArray;
tess.indexes[tess.numIndexes + 1] = g_pVert[g_pTris[i].iPt[1]].iVertArray;
tess.indexes[tess.numIndexes + 2] = g_pVert[g_pTris[i].iPt[2]].iVertArray;
tess.numIndexes += 3;
}
}
}
//=========================
void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( void *) = {
(void(*)(void*))RB_SurfaceBad, // SF_BAD,
@ -1313,5 +1435,15 @@ void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( void *) = {
(void(*)(void*))RB_SurfaceFlare, // SF_FLARE,
(void(*)(void*))RB_SurfaceEntity, // SF_ENTITY
(void(*)(void*))RB_SurfaceVaoMdvMesh, // SF_VAO_MDVMESH
(void(*)(void*))RB_IQMSurfaceAnimVao, // SF_VAO_IQM
(void(*)(void*))RB_IQMSurfaceAnimVao, // SF_VAO_IQM
//
// OPENMOHAA-specific stuff
//=========================
(void(*)(void*))RB_SurfaceMarkFragment, // SF_MARK_FRAG
(void(*)(void*))RB_SkelMesh, // SF_TIKI_SKEL
(void(*)(void*))RB_StaticMesh, // SF_TIKI_STATIC
(void(*)(void*))RB_DrawSwipeSurface, // SF_SWIPE
(void(*)(void*))RB_DrawSprite, // SF_SPRITE
(void(*)(void*))RB_DrawTerrainTris, // SF_TERRAIN_PATCH
//=========================
};

View file

@ -581,6 +581,35 @@ static void R_RecursiveWorldNode( mnode_t *node, uint32_t planeBits, uint32_t dl
}
}
//
// OPENMOHAA-specific stuff
//=========================
if (r_drawterrain->integer && tr.refdef.render_terrain && !tr.viewParms.isPortalSky)
{
int i;
for (i = 0; i < node->numTerraPatches; i++) {
R_MarkTerrainPatch(tr.world->visTerraPatches[node->firstTerraPatch + i]);
}
}
if (r_drawstaticdecals->integer) {
if (node->pFirstMarkFragment) {
R_AddPermanentMarkFragmentSurfaces(node->pFirstMarkFragment, node->iNumMarkFragment);
}
}
if (r_drawstaticmodels->integer) {
int i;
for (i = 0; i < node->numStaticModels; i++) {
tr.world->visStaticModels[node->firstStaticModel + i]->visCount = tr.visCounts[tr.visIndex];
}
}
//=========================
}
@ -752,6 +781,14 @@ void R_AddWorldSurfaces (void) {
tr.currentEntityNum = REFENTITYNUM_WORLD;
tr.shiftedEntityNum = tr.currentEntityNum << QSORT_REFENTITYNUM_SHIFT;
//
// OPENMOHAA-specific stuff
//=========================
if (r_drawterrain->integer && tr.refdef.render_terrain && !tr.viewParms.isPortalSky) {
R_TerrainPrepareFrame();
}
//=========================
// determine which leaves are in the PVS / areamask
if (!(tr.viewParms.flags & VPF_DEPTHSHADOW))
R_MarkLeaves ();
@ -806,6 +843,26 @@ void R_AddWorldSurfaces (void) {
tr.refdef.dlightMask = ~tr.refdef.dlightMask;
}
//
// OPENMOHAA-specific stuff
//=========================
if (r_drawterrain->integer && tr.refdef.render_terrain && !tr.viewParms.isPortalSky) {
R_AddTerrainSurfaces();
}
if (r_drawstaticmodels->integer) {
R_AddStaticModelSurfaces();
}
if (g_bInfostaticmodels) {
g_bInfostaticmodels = 0;
R_PrintInfoStaticModels();
}
R_UpdateLevelMarksSystem();
//=========================
}
//