Fix most shader errors, light rendering
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 18s

This commit is contained in:
smallmodel 2024-12-21 21:43:42 +01:00
parent 66664b7b46
commit e04cbd57ea
No known key found for this signature in database
GPG key ID: 9F2D623CEDF08512
12 changed files with 1105 additions and 78 deletions

View file

@ -36,6 +36,13 @@ static float s_flipMatrix[16] = {
0, 0, 0, 1
};
//
// OPENMOHAA-specific stuff
//=========================
const void* RB_SpriteSurfs(const void* data);
//=========================
/*
** GL_BindToTMU
@ -1839,6 +1846,13 @@ void RB_ExecuteRenderCommands( const void *data ) {
case RC_EXPORT_CUBEMAPS:
data = RB_ExportCubemaps(data);
break;
//
// OPENMOHAA-specific stuff
//=========================
case RC_SPRITE_SURFS:
data = RB_SpriteSurfs( data );
break;
//=========================
case RC_END_OF_LIST:
default:
// finish any 2D drawing if needed
@ -1853,3 +1867,102 @@ void RB_ExecuteRenderCommands( const void *data ) {
}
}
//
// OPENMOHAA-specific stuff
//
/*
==================
RB_RenderSpriteSurfList
==================
*/
void RB_RenderSpriteSurfList(drawSurf_t* drawSurfs, int numDrawSurfs) {
shader_t *shader;
shader_t *oldShader;
qboolean depthRange;
qboolean oldDepthRange;
int i;
drawSurf_t *drawSurf;
backEnd.currentEntity = &tr.worldEntity;
backEnd.currentStaticModel = NULL;
backEnd.pc.c_surfaces += numDrawSurfs;
backEnd.or = backEnd.viewParms.world;
oldShader = NULL;
depthRange = qfalse;
oldDepthRange = qfalse;
for (i = 0, drawSurf = drawSurfs; i < numDrawSurfs; i++, drawSurf++) {
shader = tr.sortedShaders[((refSprite_t*)drawSurf->surface)->shaderNum];
depthRange = (((refSprite_t*)drawSurf->surface)->renderfx & RF_DEPTHHACK) != 0;
if (shader != oldShader)
{
if (oldShader) {
RB_EndSurface();
}
RB_BeginSurface(shader, 0, 0);
oldShader = shader;
}
GL_SetModelviewMatrix( backEnd.or.modelMatrix );
if (oldDepthRange != depthRange)
{
if (depthRange) {
qglDepthRange(0.0, 0.3);
} else {
qglDepthRange(0.0, 1.0);
}
oldDepthRange = depthRange;
}
backEnd.shaderStartTime = ((refSprite_t*)drawSurf->surface)->shaderTime;
// add the triangles for this surface
rb_surfaceTable[*drawSurf->surface](drawSurf->surface);
}
if (oldShader) {
RB_EndSurface();
}
// go back to the world modelview matrix
GL_SetModelviewMatrix( backEnd.viewParms.world.modelMatrix );
// go back to the previous depth range
if (depthRange) {
qglDepthRange(0.0, 1.0);
}
}
/*
=============
RB_SpriteSurfs
=============
*/
const void* RB_SpriteSurfs(const void* data) {
const drawSurfsCommand_t* cmd;
// finish any 2D drawing if needed
if (tess.numIndexes) {
RB_EndSurface();
}
cmd = (const drawSurfsCommand_t*)data;
backEnd.refdef = cmd->refdef;
backEnd.viewParms = cmd->viewParms;
//RB_SetupFog();
RB_RenderSpriteSurfList(cmd->drawSurfs, cmd->numDrawSurfs);
return (const void*)(cmd + 1);
}

View file

@ -3163,8 +3163,8 @@ void R_LoadLightGrid2(lump_t* plPal, lump_t* plOffsets, lump_t* plData) {
}
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);
w->lightGridData = ri.Hunk_Alloc(plData->filelen, h_dontcare);
Com_Memcpy(w->lightGridData, fileBase + plData->fileofs, plData->filelen);
}
/*
@ -3480,6 +3480,9 @@ void RE_LoadWorldMap( const char *name ) {
g_nStaticModels = 0;
g_nStaticModelIndices = 0;
}
ri.UI_LoadResource("*111");
R_Sphere_InitLights();
//=========================
// determine vertex light directions
@ -3715,8 +3718,6 @@ void RE_LoadWorldMap( const char *name ) {
//
// OPENMOHAA-specific stuff
//=========================
ri.UI_LoadResource("*111");
R_Sphere_InitLights();
ri.UI_LoadResource("*112");
R_InitTerrain();
ri.UI_LoadResource("*113");

View file

@ -624,3 +624,29 @@ void RE_TakeVideoFrame( int width, int height,
cmd->encodeBuffer = encodeBuffer;
cmd->motionJpeg = motionJpeg;
}
//
// OPENMOHAA-specific stuff
//
/*
=============
R_AddSpriteSurfCmd
=============
*/
void R_AddSpriteSurfCmd(drawSurf_t* drawSurfs, int numDrawSurfs) {
drawSurfsCommand_t* cmd;
cmd = R_GetCommandBuffer(sizeof(*cmd));
if (!cmd) {
return;
}
cmd->commandId = RC_SPRITE_SURFS;
cmd->drawSurfs = drawSurfs;
cmd->numDrawSurfs = numDrawSurfs;
cmd->refdef = tr.refdef;
cmd->viewParms = tr.viewParms;
}

View file

@ -272,7 +272,20 @@ cvar_t* r_farplane_nocull;
cvar_t* r_farplane_nofog;
cvar_t* r_skybox_farplane;
cvar_t* r_farclip;
// Lighting
cvar_t* r_lightcoronasize;
cvar_t *r_entlight_scale;
cvar_t *r_entlight_errbound;
cvar_t *r_entlight_cubelevel;
cvar_t *r_entlight_cubefraction;
cvar_t *r_entlight_maxcalc;
cvar_t *r_light_lines;
cvar_t *r_light_sun_line;
cvar_t *r_light_int_scale;
cvar_t *r_light_nolight;
cvar_t *r_light_showgrid;
// LOD
@ -1570,7 +1583,20 @@ void R_Register( void )
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);
// Lighting
r_lightcoronasize = ri.Cvar_Get("r_lightcoronasize", ".1", CVAR_ARCHIVE);
r_light_lines = ri.Cvar_Get("r_light_lines", "0", CVAR_CHEAT);
r_light_sun_line = ri.Cvar_Get("r_light_sun_line", "0", CVAR_CHEAT);
r_light_int_scale = ri.Cvar_Get("r_light_int_scale", "0.05", CVAR_ARCHIVE);
r_light_nolight = ri.Cvar_Get("r_light_nolight", "0", CVAR_CHEAT | CVAR_ARCHIVE);
r_light_showgrid = ri.Cvar_Get("r_light_showgrid", "0", CVAR_CHEAT);
r_entlight_scale = ri.Cvar_Get("r_entlight_scale", "1.3", CVAR_CHEAT);
r_entlight_errbound = ri.Cvar_Get("r_entlight_errbound", "6", CVAR_ARCHIVE);
r_entlight_cubelevel = ri.Cvar_Get("r_entlight_cubelevel", "0", CVAR_ARCHIVE);
r_entlight_cubefraction = ri.Cvar_Get("r_entlight_cubefraction", "0.5", CVAR_ARCHIVE);
r_entlight_maxcalc = ri.Cvar_Get("r_entlight_maxcalc", "2", CVAR_ARCHIVE);
// LOD

View file

@ -127,6 +127,7 @@ R_SetupEntityLightingGrid
=================
*/
#if 0
static void R_SetupEntityLightingGrid( trRefEntity_t *ent, world_t *world ) {
vec3_t lightOrigin;
int pos[3];
@ -277,6 +278,9 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent, world_t *world ) {
VectorNormalize2( direction, ent->lightDir );
}
#endif
static void R_SetupEntityLightingGrid(trRefEntity_t* ent, world_t* world);
/*
@ -461,7 +465,7 @@ int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, ve
return qtrue;
}
#if 0
int R_LightDirForPoint( vec3_t point, vec3_t lightDir, vec3_t normal, world_t *world )
{
trRefEntity_t ent;
@ -480,7 +484,7 @@ int R_LightDirForPoint( vec3_t point, vec3_t lightDir, vec3_t normal, world_t *w
return qtrue;
}
#endif
int R_CubemapForPoint( vec3_t point )
{
@ -514,6 +518,246 @@ int R_CubemapForPoint( vec3_t point )
// OPENMOHAA-specific stuff
//
/*
===============
RB_SetupEntityGridLighting
===============
*/
void RB_SetupEntityGridLighting()
{
// FIXME: unimplemented
}
/*
===============
RB_SetupStaticModelGridLighting
===============
*/
void RB_SetupStaticModelGridLighting(trRefdef_t *refdef, cStaticModelUnpacked_t *ent, const vec3_t lightOrigin)
{
// FIXME: unimplemented
}
/*
===============
R_PointInLeaf
===============
*/
mnode_t *R_FindPoint( world_t *world, const vec3_t p ) {
mnode_t *node;
float d;
cplane_t *plane;
node = world->nodes;
while( 1 ) {
if (node->contents != -1) {
break;
}
plane = node->plane;
d = DotProduct (p,plane->normal) - plane->dist;
if (d > 0) {
node = node->children[0];
} else {
node = node->children[1];
}
}
return node;
}
/*
===============
R_GetLightGridPalettedColor
===============
*/
static byte *R_GetLightGridPalettedColor(world_t *world, int iColor)
{
return &world->lightGridPalette[iColor * 3];
}
/*
===============
R_GetLightingGridValue
===============
*/
void R_GetLightingGridValue(world_t *world, const vec3_t vPos, vec3_t vAmbientLight, vec3_t vDirectedLight)
{
byte *pColor;
int iBaseOffset;
int i;
int iOffset;
int iRowPos;
int iData;
int iLen;
int iGridPos[3];
int iArrayXStep;
float fV;
float fFrac[3];
float fOMFrac[3];
float fWeight, fWeight2;
float fTotalFactor;
int iCurData;
vec3_t vLightOrigin;
byte *pCurData;
if (!world || !world->lightGridData || !world->lightGridOffsets) {
vDirectedLight[0] = vDirectedLight[1] = vDirectedLight[2] = tr.identityLightByte;
vAmbientLight[0] = vAmbientLight[1] = vAmbientLight[2] = tr.identityLightByte;
return;
}
VectorSubtract(vPos, world->lightGridOrigin, vLightOrigin);
for (i = 0; i < 3; i++) {
fV = vLightOrigin[i] * world->lightGridInverseSize[i];
iGridPos[i] = floor(fV);
fFrac[i] = fV - iGridPos[i];
fOMFrac[i] = 1.0 - fFrac[i];
if (iGridPos[i] < 0) {
iGridPos[i] = 0;
} else if (iGridPos[i] > world->lightGridBounds[i] - 2) {
iGridPos[i] = world->lightGridBounds[i] - 2;
}
}
fTotalFactor = 0;
iArrayXStep = world->lightGridBounds[1];
iBaseOffset = world->lightGridBounds[0] + iGridPos[1] + iArrayXStep * iGridPos[0];
VectorClear(vDirectedLight);
VectorClear(vAmbientLight);
for (i = 0; i < 4; i++) {
qboolean bContinue = qfalse;
switch (i) {
case 0:
fWeight = fOMFrac[0] * fOMFrac[1] * fOMFrac[2];
fWeight2 = fOMFrac[0] * fOMFrac[1] * fFrac[2];
iOffset = world->lightGridOffsets[iBaseOffset] + (world->lightGridOffsets[iGridPos[0]] << 8);
break;
case 1:
fWeight = fOMFrac[0] * fFrac[1] * fOMFrac[2];
fWeight2 = fOMFrac[0] * fFrac[1] * fFrac[2];
iOffset = world->lightGridOffsets[iBaseOffset + 1] + (world->lightGridOffsets[iGridPos[0]] << 8);
break;
case 2:
fWeight = fFrac[0] * fOMFrac[1] * fOMFrac[2];
fWeight2 = fFrac[0] * fOMFrac[1] * fFrac[2];
iOffset = world->lightGridOffsets[iBaseOffset + iArrayXStep]
+ (world->lightGridOffsets[iGridPos[0] + 1] << 8);
break;
case 3:
fWeight = fFrac[0] * fFrac[1] * fOMFrac[2];
fWeight2 = fFrac[0] * fFrac[1] * fFrac[2];
iOffset = world->lightGridOffsets[iBaseOffset + iArrayXStep + 1]
+ (world->lightGridOffsets[iGridPos[0] + 1] << 8);
break;
}
iRowPos = iGridPos[2];
pCurData = &world->lightGridData[iOffset];
iData = 0;
while (1) {
while (1) {
iCurData = (char)pCurData[iData];
iData++;
if (iCurData >= 0) {
break;
}
iLen = -iCurData;
if (iLen > iRowPos) {
iData += iRowPos;
if (pCurData[iData]) {
pColor = R_GetLightGridPalettedColor(world, pCurData[iData]);
VectorMA(vAmbientLight, fWeight, pColor, vAmbientLight);
fTotalFactor += fWeight;
}
iData++;
if (iLen - 1 == iRowPos) {
iData++;
}
if (pCurData[iData]) {
pColor = R_GetLightGridPalettedColor(world, pCurData[iData]);
VectorMA(vDirectedLight, fWeight2, pColor, vDirectedLight);
fTotalFactor += fWeight2;
}
bContinue = qtrue;
break;
}
iRowPos -= iLen;
iData += iLen;
}
if (bContinue) {
break;
}
iLen = iCurData + 2;
if (iLen - 1 >= iRowPos) {
break;
}
iRowPos -= iLen;
iData++;
}
if (bContinue) {
continue;
}
if (iLen - 1 > iRowPos) {
if (!pCurData[iData]) {
continue;
}
pColor = R_GetLightGridPalettedColor(world, pCurData[iData]);
VectorMA(vAmbientLight, fWeight + fWeight2, pColor, vAmbientLight);
VectorMA(vDirectedLight, fWeight + fWeight2, pColor, vDirectedLight);
fTotalFactor += fWeight + fWeight2;
} else {
if (pCurData[iData]) {
pColor = R_GetLightGridPalettedColor(world, pCurData[iData]);
VectorMA(vAmbientLight, fWeight, pColor, vAmbientLight);
fTotalFactor += fWeight;
}
iData += 2;
if (pCurData[iData]) {
pColor = R_GetLightGridPalettedColor(world, pCurData[iData]);
VectorMA(vDirectedLight, fWeight2, pColor, vDirectedLight);
fTotalFactor += fWeight2;
}
}
}
if (fTotalFactor > 0.0 && fTotalFactor < 0.99) {
VectorScale(vAmbientLight, 1.0 / fTotalFactor, vAmbientLight);
VectorScale(vDirectedLight, 1.0 / fTotalFactor, vDirectedLight);
}
if (fTotalFactor) {
/*
if (vLight[0] > 255.0 || vLight[1] > 255.0 || vLight[2] > 255.0) {
float t;
// normalize color values
t = 255.0 / Q_max(vLight[0], Q_max(vLight[1], vLight[2]));
VectorScale(vLight, t, vLight);
}
*/
} else {
vDirectedLight[0] = vDirectedLight[1] = vDirectedLight[2] = tr.identityLightByte;
vAmbientLight[0] = vAmbientLight[1] = vAmbientLight[2] = tr.identityLightByte;
}
}
/*
===============
R_GetLightingForDecal
@ -533,3 +777,128 @@ void R_GetLightingForSmoke(vec3_t vLight, const vec3_t vOrigin)
{
// FIXME: unimplemented (GL2)
}
qboolean R_FindGridPointForSphere(world_t *world, const vec3_t sphereOrigin, const vec3_t point, vec3_t out) {
int i, j, k;
int gridStep[3][3];
trace_t trace;
for (i = 0; i < 3; i++) {
gridStep[i][0] = 0;
gridStep[i][1] = -world->lightGridSize[i];
gridStep[i][2] = world->lightGridSize[i];
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
for (k = 0; k < 3; k++) {
vec3_t vOffset;
vOffset[0] = point[0] + gridStep[0][i];
vOffset[1] = point[1] + gridStep[1][j];
vOffset[2] = point[2] + gridStep[2][k];
ri.CM_BoxTrace(&trace, point, sphereOrigin, vec3_origin, vec3_origin, 0, CONTENTS_SOLID, 0);
if (trace.fraction == 1 || trace.surfaceFlags & SURF_SKY) {
return qtrue;
}
}
}
}
return qfalse;
}
int R_LightDirForPoint( vec3_t point, vec3_t lightDir, vec3_t normal, world_t *world )
{
vec3_t vLight;
vec3_t vEnd;
mnode_t* leaf;
trace_t trace;
vec3_t summedDir;
float addSize;
int iNumLights;
int i;
int j, k, l;
int gridStep[3][3];
if ( world->lightGridData == NULL )
return qfalse;
VectorClear(summedDir);
leaf = NULL;
iNumLights = 0;
if (world->vis) {
leaf = R_FindPoint(world, point);
if (leaf->area == -1 || !leaf->numlights) {
leaf = NULL;
}
}
if (leaf && leaf->numlights) {
spherel_t* sphere;
for (i = (leaf->lights[0] == &tr.sSunLight ? 1 : 0); i < leaf->numlights; i++) {
sphere = leaf->lights[i];
if (sphere->leaf != (mnode_t*)-1) {
byte mask = backEnd.refdef.areamask[sphere->leaf->area >> 3];
if (!(mask & (1 << (sphere->leaf->area & 7)))) {
ri.CM_BoxTrace(&trace, point, sphere->origin, vec3_origin, vec3_origin, 0, CONTENTS_SOLID, 0);
if (trace.fraction == 1) {
vec3_t dir;
VectorSubtract(sphere->origin, point, dir);
addSize = VectorLength(sphere->color);
VectorMA(summedDir, addSize, dir, summedDir);
iNumLights++;
}
}
}
}
}
if (s_sun.exists) {
if (leaf && leaf->lights[0] == &tr.sSunLight) {
vec3_t newPoint;
VectorMA(point, 16384.0, s_sun.direction, vEnd);
ri.CM_BoxTrace(&trace, point, vEnd, vec3_origin, vec3_origin, 0, CONTENTS_SOLID, 0);
if (trace.surfaceFlags & SURF_SKY) {
addSize = VectorLength(s_sun.color);
VectorMA(summedDir, addSize, s_sun.direction, summedDir);
iNumLights++;
}
}
}
VectorNormalize(summedDir);
if (DotProduct(summedDir, normal) > 0.2f)
VectorCopy(summedDir, lightDir);
else
VectorCopy(normal, lightDir);
return qtrue;
}
static void R_SetupEntityLightingGrid(trRefEntity_t* ent, world_t* world)
{
vec3_t normal;
R_GetLightingGridValue(world, ent->e.origin, ent->ambientLight, ent->directedLight);
VectorSet(normal, 1, 0, 0);
R_LightDirForPoint(ent->e.origin, ent->lightDir, normal, world);
}

View file

@ -88,6 +88,13 @@ typedef unsigned int vaoCacheGlIndex_t;
#define MAX_SPRITE_DIST 16384.0f
#define MAX_SPRITE_DIST_SQUARED (MAX_SPRITE_DIST * MAX_SPRITE_DIST)
typedef enum {
USE_S_COORDS,
USE_T_COORDS
} texDirection_t;
#define BUNDLE_ANIMATE_ONCE 1
//=========================
typedef struct cubemap_s {
@ -133,6 +140,7 @@ typedef struct {
// OPENMOHAA-specific stuff
//
int iGridLighting;
float lodpercentage[2];
} trRefEntity_t;
@ -243,7 +251,14 @@ typedef enum {
DEFORM_TEXT4,
DEFORM_TEXT5,
DEFORM_TEXT6,
DEFORM_TEXT7
DEFORM_TEXT7,
//
// OPENMOHAA-specific stuff
//=========================
DEFORM_LIGHTGLOW,
DEFORM_FLAP_S,
DEFORM_FLAP_T,
//=========================
} deform_t;
// deformVertexes types that can be handled by the GPU
@ -409,7 +424,12 @@ typedef struct {
} texModInfo_t;
#define MAX_IMAGE_ANIMATIONS 8
//#define MAX_IMAGE_ANIMATIONS 8
//
// OPENMOHAA-specific stuff
//=========================
#define MAX_IMAGE_ANIMATIONS 64
//=========================
typedef struct {
image_t *image[MAX_IMAGE_ANIMATIONS];
@ -425,6 +445,13 @@ typedef struct {
int videoMapHandle;
qboolean isLightmap;
qboolean isVideoMap;
//
// OPENMOHAA-specific stuff
//=========================
float imageAnimationPhase;
int flags;
//=========================
} textureBundle_t;
enum
@ -2156,6 +2183,7 @@ typedef struct {
// OPENMOHAA-specific stuff
//
int currentSpriteNum;
int shiftedIsStatic;
int overbrightShift;
@ -2381,7 +2409,20 @@ extern cvar_t* r_farplane_nocull;
extern cvar_t* r_farplane_nofog;
extern cvar_t* r_skybox_farplane;
extern cvar_t* r_farclip;
// Lighting
extern cvar_t* r_lightcoronasize;
extern cvar_t *r_entlight_scale;
extern cvar_t *r_entlight_errbound;
extern cvar_t *r_entlight_cubelevel;
extern cvar_t *r_entlight_cubefraction;
extern cvar_t *r_entlight_maxcalc;
extern cvar_t *r_light_lines;
extern cvar_t *r_light_sun_line;
extern cvar_t *r_light_int_scale;
extern cvar_t *r_light_nolight;
extern cvar_t *r_light_showgrid;
// LOD
@ -2641,6 +2682,7 @@ void R_SavePerformanceCounters(void);
// tr_main.c
//
void R_AddSpriteSurfaces();
qboolean SurfIsOffscreen2(const srfBspSurface_t* surface, shader_t* shader, int entityNum);
//
@ -2784,8 +2826,6 @@ 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();
/*
============================================================
@ -3022,6 +3062,17 @@ LIGHTS
void R_GetLightingForDecal(vec3_t vLight, const vec3_t vFacing, const vec3_t vOrigin);
void R_GetLightingForSmoke(vec3_t vLight, const vec3_t vOrigin);
void R_GetLightingGridValue(world_t* world, const vec3_t vPos, vec3_t vAmbientLight, vec3_t vDirectedLight);
void RB_SetupEntityGridLighting();
void RB_SetupStaticModelGridLighting(trRefdef_t* refdef, cStaticModelUnpacked_t* ent, const vec3_t lightOrigin);
void RB_Light_Real(unsigned char* colors);
void RB_Sphere_BuildDLights();
void RB_Sphere_SetupEntity();
void RB_Grid_SetupEntity();
void RB_Grid_SetupStaticModel();
void RB_Light_Fullbright(unsigned char* colors);
void R_Sphere_InitLights();
int R_GatherLightSources(const vec3_t vPos, vec3_t* pvLightPos, vec3_t* pvLightIntensity, int iMaxLights);
extern suninfo_t s_sun;
@ -3052,6 +3103,17 @@ void RE_AddTerrainMarkToScene(int iTerrainIndex, qhandle_t hShader, int numVerts
refEntity_t* RE_GetRenderEntity(int entityNumber);
qboolean RE_AddPolyToScene2(qhandle_t hShader, int numVerts, const polyVert_t* verts, int renderfx);
/*
============================================================
SHADE CALC
============================================================
*/
void RB_CalcLightGridColor(unsigned char* colors);
/*
=============================================================
@ -3202,9 +3264,12 @@ WORLD MAP
============================================================
*/
void R_GetInlineModelBounds(int iIndex, vec3_t vMins, vec3_t vMaxs);
int R_SphereInLeafs(const vec3_t p, float r, mnode_t** nodes, int nMaxNodes);
mnode_t* R_PointInLeaf(const vec3_t p);
int R_CheckDlightTerrain(cTerraPatchUnpacked_t* surf, int dlightBits);
void R_AddSpriteSurfCmd(drawSurf_t* drawSurfs, int numDrawSurfs);
//=========================
/*
@ -3359,7 +3424,13 @@ typedef enum {
RC_CLEARDEPTH,
RC_CAPSHADOWMAP,
RC_POSTPROCESS,
RC_EXPORT_CUBEMAPS
RC_EXPORT_CUBEMAPS,
//
// OPENMOHAA-specific stuff
//
RC_SPRITE_SURFS,
} renderCommand_t;

View file

@ -1586,7 +1586,9 @@ void R_DecomposeSort( unsigned sort, int *entityNum, shader_t **shader,
R_SortDrawSurfs
=================
*/
void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs ) {
void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs,
drawSurf_t *spriteSurfs, int numSpriteSurfs
) {
shader_t *shader;
int fogNum;
int entityNum;
@ -1601,11 +1603,13 @@ void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs ) {
if ( numDrawSurfs < 1 ) {
// we still need to add it for hyperspace cases
R_AddDrawSurfCmd( drawSurfs, numDrawSurfs );
R_AddSpriteSurfCmd( spriteSurfs, numSpriteSurfs );
return;
}
// sort the drawsurfs by sort type, then orientation, then shader
R_RadixSort( drawSurfs, numDrawSurfs );
R_RadixSort( spriteSurfs, numSpriteSurfs );
// skip pass through drawing if rendering a shadow map
if (tr.viewParms.flags & (VPF_SHADOWMAP | VPF_DEPTHSHADOW))
@ -1639,6 +1643,7 @@ void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs ) {
}
R_AddDrawSurfCmd( drawSurfs, numDrawSurfs );
R_AddSpriteSurfCmd( spriteSurfs, numSpriteSurfs );
}
static void R_AddEntitySurface (int entityNum)
@ -1780,6 +1785,12 @@ void R_GenerateDrawSurfs( void ) {
R_SetupProjectionZ (&tr.viewParms);
R_AddEntitySurfaces ();
//
// OPENMOHAA-specific stuff
//=========================
R_AddSpriteSurfaces();
//=========================
}
/*
@ -2066,7 +2077,8 @@ or a mirror / remote location
*/
void R_RenderView (viewParms_t *parms) {
int firstDrawSurf;
int numDrawSurfs;
int numDrawSurfs;
int firstSpriteSurf;
if ( parms->viewportWidth <= 0 || parms->viewportHeight <= 0 ) {
return;
@ -2078,7 +2090,8 @@ void R_RenderView (viewParms_t *parms) {
tr.viewParms.frameSceneNum = tr.frameSceneNum;
tr.viewParms.frameCount = tr.frameCount;
firstDrawSurf = tr.refdef.numDrawSurfs;
firstDrawSurf = tr.refdef.numDrawSurfs;
firstSpriteSurf = tr.refdef.numSpriteSurfs;
tr.viewCount++;
@ -2097,7 +2110,9 @@ void R_RenderView (viewParms_t *parms) {
numDrawSurfs = MAX_DRAWSURFS;
}
R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, numDrawSurfs - firstDrawSurf );
R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, numDrawSurfs - firstDrawSurf,
tr.refdef.spriteSurfs + firstSpriteSurf, tr.refdef.numSpriteSurfs - firstSpriteSurf
);
// draw main system development information (surface outlines, etc)
R_DebugGraphics();
@ -2248,6 +2263,24 @@ void R_RenderPshadowMaps(const refdef_t *fd)
radius = 0.5f * VectorLength( diag );
}
break;
// OPENMOHAA-specific stuff
//=========================
case MOD_TIKI:
radius = ri.TIKI_GlobalRadius(model->d.tiki);
break;
case MOD_SPRITE:
{
float w;
radius = model->d.sprite->width * model->d.sprite->scale * 0.5;
w = model->d.sprite->height * model->d.sprite->scale * 0.5;
if (radius <= w) {
radius = w;
}
}
break;
//=========================
default:
break;
@ -2401,6 +2434,7 @@ void R_RenderPshadowMaps(const refdef_t *fd)
for ( i = 0; i < tr.refdef.num_pshadows; i++)
{
int firstDrawSurf;
int firstSpriteSurf;
pshadow_t *shadow = &tr.refdef.pshadows[i];
int j;
@ -2443,7 +2477,8 @@ void R_RenderPshadowMaps(const refdef_t *fd)
tr.viewParms.frameSceneNum = tr.frameSceneNum;
tr.viewParms.frameCount = tr.frameCount;
firstDrawSurf = tr.refdef.numDrawSurfs;
firstDrawSurf = tr.refdef.numDrawSurfs;
firstSpriteSurf = tr.refdef.numSpriteSurfs;
tr.viewCount++;
@ -2514,7 +2549,9 @@ void R_RenderPshadowMaps(const refdef_t *fd)
R_AddEntitySurface(shadow->entityNums[j]);
}
R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, tr.refdef.numDrawSurfs - firstDrawSurf );
R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, tr.refdef.numDrawSurfs - firstDrawSurf,
tr.refdef.spriteSurfs + firstSpriteSurf, tr.refdef.numSpriteSurfs - firstSpriteSurf
);
if (!glRefConfig.framebufferObject)
R_AddCapShadowmapCmd( i, -1 );
@ -2810,6 +2847,7 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
{
int firstDrawSurf;
int firstSpriteSurf;
Com_Memset( &shadowParms, 0, sizeof( shadowParms ) );
@ -2853,6 +2891,7 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
tr.viewParms.frameCount = tr.frameCount;
firstDrawSurf = tr.refdef.numDrawSurfs;
firstSpriteSurf = tr.refdef.numSpriteSurfs;
tr.viewCount++;
@ -2867,7 +2906,8 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
R_AddEntitySurfaces ();
R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, tr.refdef.numDrawSurfs - firstDrawSurf );
R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, tr.refdef.numDrawSurfs - firstDrawSurf,
tr.refdef.spriteSurfs + firstSpriteSurf, tr.refdef.numSpriteSurfs - firstSpriteSurf );
}
Mat4Multiply(tr.viewParms.projectionMatrix, tr.viewParms.world.modelMatrix, tr.refdef.sunShadowMvp[level]);
@ -3003,6 +3043,29 @@ void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene )
// OPENMOHAA-specific stuff
//
void R_AdjustVisBoundsForSprite(refSprite_t* ent, viewParms_t* viewParms, orientationr_t* or )
{
if (tr.viewParms.visBounds[0][0] > ent->origin[0] - ent->scale) {
tr.viewParms.visBounds[0][0] = ent->origin[0] - ent->scale;
}
if (tr.viewParms.visBounds[0][1] > ent->origin[1] - ent->scale) {
tr.viewParms.visBounds[0][1] = ent->origin[1] - ent->scale;
}
if (tr.viewParms.visBounds[0][2] > ent->origin[2] - ent->scale) {
tr.viewParms.visBounds[0][2] = ent->origin[2] - ent->scale;
}
if (tr.viewParms.visBounds[1][0] < ent->origin[0] + ent->scale) {
tr.viewParms.visBounds[1][0] = ent->origin[0] + ent->scale;
}
if (tr.viewParms.visBounds[1][1] < ent->origin[1] + ent->scale) {
tr.viewParms.visBounds[1][1] = ent->origin[1] + ent->scale;
}
if (tr.viewParms.visBounds[1][2] < ent->origin[2] + ent->scale) {
tr.viewParms.visBounds[1][2] = ent->origin[2] + ent->scale;
}
}
/*
=================
R_AddSpriteSurf
@ -3022,6 +3085,58 @@ void R_AddSpriteSurf(surfaceType_t* surface, shader_t* shader, float zDistance)
tr.refdef.numSpriteSurfs++;
}
void R_AddSpriteSurfaces()
{
refSprite_t* sprite;
vec3_t delta;
if (!r_drawsprites->integer) {
return;
}
// FIXME: fix buggy sprites causing annoying crashes
return;
for (tr.currentSpriteNum = 0; tr.currentSpriteNum < tr.refdef.num_sprites; ++tr.currentSpriteNum)
{
sprite = &tr.refdef.sprites[tr.currentSpriteNum];
if (tr.viewParms.isPortalSky) {
if (!(sprite->renderfx & RF_SKYENTITY)) {
continue;
}
} else {
if (sprite->renderfx & RF_SKYENTITY) {
continue;
}
}
if (tr.viewParms.isPortal) {
if (!(sprite->renderfx & (RF_SHADOW_PLANE | RF_WRAP_FRAMES))) {
continue;
}
} else {
if (sprite->renderfx & RF_SHADOW_PLANE) {
continue;
}
}
tr.currentEntityNum = ENTITYNUM_WORLD;
tr.shiftedEntityNum = tr.currentEntityNum << QSORT_REFENTITYNUM_SHIFT;
if (sprite->hModel && sprite->hModel < tr.numModels) {
tr.currentModel = tr.models[sprite->hModel];
} else {
tr.currentModel = tr.models[0];
}
R_AdjustVisBoundsForSprite(&tr.refdef.sprites[tr.currentSpriteNum], &tr.viewParms, &tr.or );
sprite->shaderNum = tr.currentModel->d.sprite->shader->sortedIndex;
VectorSubtract(sprite->origin, tr.refdef.vieworg, delta);
R_AddSpriteSurf(&sprite->surftype, tr.currentModel->d.sprite->shader, VectorLengthSquared(delta));
}
}
/*
=================
R_RotateForStaticModel

View file

@ -400,9 +400,19 @@ static void AutospriteDeform( void ) {
}
// compensate for scale in the axes if necessary
if ( backEnd.currentEntity->e.nonNormalizedAxes ) {
if ( backEnd.currentStaticModel || backEnd.currentEntity->e.nonNormalizedAxes ) {
float axisLength;
axisLength = VectorLength( backEnd.currentEntity->e.axis[0] );
// OPENMOHAA-specific stuff
//=========================
if (backEnd.currentStaticModel) {
axisLength = VectorLength(backEnd.currentStaticModel->axis[0]);
}
else
//=========================
{
axisLength = VectorLength(backEnd.currentEntity->e.axis[0]);
}
if ( !axisLength ) {
axisLength = 0;
} else {
@ -816,3 +826,41 @@ void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix )
matrix[0] = cosValue; matrix[2] = -sinValue; matrix[4] = 0.5 - 0.5 * cosValue + 0.5 * sinValue;
matrix[1] = sinValue; matrix[3] = cosValue; matrix[5] = 0.5 - 0.5 * sinValue - 0.5 * cosValue;
}
//
// OPENMOHAA-specific stuff
//
void RB_CalcLightGridColor(unsigned char* colors)
{
int i;
if (!backEnd.currentEntity) {
for (i = 0; i < tess.numVertexes; i++) {
colors[i * 4] = ((byte*)&backEnd.currentStaticModel->iGridLighting)[0];
colors[i * 4 + 1] = ((byte*)&backEnd.currentStaticModel->iGridLighting)[1];
colors[i * 4 + 2] = ((byte*)&backEnd.currentStaticModel->iGridLighting)[2];
colors[i * 4 + 3] = ((byte*)&backEnd.currentStaticModel->iGridLighting)[3];
}
}
else if (backEnd.currentEntity != &tr.worldEntity) {
for (i = 0; i < tess.numVertexes; i++) {
colors[i * 4] = ((byte*)&backEnd.currentEntity->iGridLighting)[0];
colors[i * 4 + 1] = ((byte*)&backEnd.currentEntity->iGridLighting)[1];
colors[i * 4 + 2] = ((byte*)&backEnd.currentEntity->iGridLighting)[2];
colors[i * 4 + 3] = ((byte*)&backEnd.currentEntity->iGridLighting)[3];
}
}
else {
ri.Printf(PRINT_ALL,
"##### shader '%s' incorrectly uses rgbGen lightingGrid or lightingSpherical; was rgbGen vertex intended?\n",
tess.shader->name);
for (i = 0; i < tess.numVertexes; i++) {
colors[i * 4] = 0xFF;
colors[i * 4 + 1] = 0xFF;
colors[i * 4 + 2] = 0xFF;
colors[i * 4 + 3] = 0xFF;
}
}
}

View file

@ -38,6 +38,12 @@ static shader_t* hashTable[FILE_HASH_SIZE];
#define MAX_SHADERTEXT_HASH 2048
static char **shaderTextHashTable[MAX_SHADERTEXT_HASH];
//
// OPENMOHAA-specific stuff
//=========================
static void CreateMultistageFromBundle();
//=========================
/*
================
return a hash value for the filename
@ -663,16 +669,16 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
if ( !Q_stricmp( token, "$whiteimage" ) )
{
stage->bundle[0].image[0] = tr.whiteImage;
stage->bundle[cntBundle].image[0] = tr.whiteImage;
continue;
}
else if ( !Q_stricmp( token, "$lightmap" ) )
{
stage->bundle[0].isLightmap = qtrue;
stage->bundle[cntBundle].isLightmap = qtrue;
if ( shader.lightmapIndex < 0 || !tr.lightmaps ) {
stage->bundle[0].image[0] = tr.whiteImage;
stage->bundle[cntBundle].image[0] = tr.whiteImage;
} else {
stage->bundle[0].image[0] = tr.lightmaps[shader.lightmapIndex];
stage->bundle[cntBundle].image[0] = tr.lightmaps[shader.lightmapIndex];
}
continue;
}
@ -684,11 +690,11 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
return qfalse;
}
stage->bundle[0].isLightmap = qtrue;
stage->bundle[cntBundle].isLightmap = qtrue;
if ( shader.lightmapIndex < 0 ) {
stage->bundle[0].image[0] = tr.whiteImage;
stage->bundle[cntBundle].image[0] = tr.whiteImage;
} else {
stage->bundle[0].image[0] = tr.deluxemaps[shader.lightmapIndex];
stage->bundle[cntBundle].image[0] = tr.deluxemaps[shader.lightmapIndex];
}
continue;
}
@ -717,9 +723,9 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
flags |= IMGFLAG_GENNORMALMAP;
}
stage->bundle[0].image[0] = R_FindImageFile( token, type, flags );
stage->bundle[cntBundle].image[0] = R_FindImageFile( token, type, flags );
if ( !stage->bundle[0].image[0] )
if ( !stage->bundle[cntBundle].image[0] )
{
ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name );
return qfalse;
@ -762,8 +768,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
}
stage->bundle[0].image[0] = R_FindImageFile( token, type, flags );
if ( !stage->bundle[0].image[0] )
stage->bundle[cntBundle].image[0] = R_FindImageFile( token, type, flags );
if ( !stage->bundle[cntBundle].image[0] )
{
ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name );
return qfalse;
@ -782,7 +788,7 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'animMap' keyword in shader '%s'\n", shader.name );
return qfalse;
}
stage->bundle[0].imageAnimationSpeed = atof( token );
stage->bundle[cntBundle].imageAnimationSpeed = atof( token );
// parse up to MAX_IMAGE_ANIMATIONS animations
while ( 1 ) {
@ -792,7 +798,7 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
if ( !token[0] ) {
break;
}
num = stage->bundle[0].numImageAnimations;
num = stage->bundle[cntBundle].numImageAnimations;
if ( num < MAX_IMAGE_ANIMATIONS ) {
imgFlags_t flags = IMGFLAG_NONE;
@ -802,13 +808,13 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
if (!shader.noPicMip)
flags |= IMGFLAG_PICMIP;
stage->bundle[0].image[num] = R_FindImageFile( token, IMGTYPE_COLORALPHA, flags );
if ( !stage->bundle[0].image[num] )
stage->bundle[cntBundle].image[num] = R_FindImageFile( token, IMGTYPE_COLORALPHA, flags );
if ( !stage->bundle[cntBundle].image[num] )
{
ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name );
return qfalse;
}
stage->bundle[0].numImageAnimations++;
stage->bundle[cntBundle].numImageAnimations++;
}
totalImages++;
}
@ -826,10 +832,10 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'videoMap' keyword in shader '%s'\n", shader.name );
return qfalse;
}
stage->bundle[0].videoMapHandle = ri.CIN_PlayCinematic( token, 0, 0, 256, 256, (CIN_loop | CIN_silent | CIN_shader));
if (stage->bundle[0].videoMapHandle != -1) {
stage->bundle[0].isVideoMap = qtrue;
stage->bundle[0].image[0] = tr.scratchImage[stage->bundle[0].videoMapHandle];
stage->bundle[cntBundle].videoMapHandle = ri.CIN_PlayCinematic( token, 0, 0, 256, 256, (CIN_loop | CIN_silent | CIN_shader));
if (stage->bundle[cntBundle].videoMapHandle != -1) {
stage->bundle[cntBundle].isVideoMap = qtrue;
stage->bundle[cntBundle].image[0] = tr.scratchImage[stage->bundle[cntBundle].videoMapHandle];
} else {
ri.Printf( PRINT_WARNING, "WARNING: could not load '%s' for 'videoMap' keyword in shader '%s'\n", token, shader.name );
}
@ -1677,22 +1683,22 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
if ( !Q_stricmp( token, "environment" ) )
{
stage->bundle[0].tcGen = TCGEN_ENVIRONMENT_MAPPED;
stage->bundle[cntBundle].tcGen = TCGEN_ENVIRONMENT_MAPPED;
}
else if ( !Q_stricmp( token, "lightmap" ) )
{
stage->bundle[0].tcGen = TCGEN_LIGHTMAP;
stage->bundle[cntBundle].tcGen = TCGEN_LIGHTMAP;
}
else if ( !Q_stricmp( token, "texture" ) || !Q_stricmp( token, "base" ) )
{
stage->bundle[0].tcGen = TCGEN_TEXTURE;
stage->bundle[cntBundle].tcGen = TCGEN_TEXTURE;
}
else if ( !Q_stricmp( token, "vector" ) )
{
ParseVector( text, 3, stage->bundle[0].tcGenVectors[0] );
ParseVector( text, 3, stage->bundle[0].tcGenVectors[1] );
ParseVector( text, 3, stage->bundle[cntBundle].tcGenVectors[0] );
ParseVector( text, 3, stage->bundle[cntBundle].tcGenVectors[1] );
stage->bundle[0].tcGen = TCGEN_VECTOR;
stage->bundle[cntBundle].tcGen = TCGEN_VECTOR;
}
else
{
@ -1731,7 +1737,70 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
}
//
// OPENMOHAA-specific stuff
//
//=========================
else if ( !Q_stricmp(token, "animMapOnce") || !Q_stricmp(token, "animMapPhase"))
{
qboolean phased;
if (!Q_stricmp(token, "animMapOnce")) {
stage->bundle[cntBundle].flags |= BUNDLE_ANIMATE_ONCE;
}
phased = !Q_stricmp(token, "animMapPhase");
token = COM_ParseExt( text, qfalse );
if ( !token[0] )
{
ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'animMmap' keyword in shader '%s'\n", shader.name );
return qfalse;
}
stage->bundle[cntBundle].imageAnimationSpeed = atof( token );
stage->bundle[cntBundle].imageAnimationPhase = 0;
if (phased)
{
token = COM_ParseExt(text, qfalse);
if (!token[0])
{
ri.Printf(PRINT_WARNING, "WARNING: missing phase for 'animMapPhase' keyword in shader '%s'\n", shader.name);
return qfalse;
}
stage->bundle[cntBundle].imageAnimationPhase = atof(token);
}
// parse up to MAX_IMAGE_ANIMATIONS animations
while ( 1 ) {
int num;
token = COM_ParseExt( text, qfalse );
if ( !token[0] ) {
break;
}
num = stage->bundle[cntBundle].numImageAnimations;
if ( num < MAX_IMAGE_ANIMATIONS ) {
imgFlags_t flags = IMGFLAG_NONE;
if (!shader.noMipMaps)
flags |= IMGFLAG_MIPMAP;
if (!shader.noPicMip)
flags |= IMGFLAG_PICMIP;
stage->bundle[cntBundle].image[num] = R_FindImageFile( token, IMGTYPE_COLORALPHA, flags );
if ( !stage->bundle[cntBundle].image[num] )
{
ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name );
return qfalse;
}
stage->bundle[cntBundle].numImageAnimations++;
}
}
}
else if (!Q_stricmp(token, "nofog"))
{
// FIXME: unimplemented
continue;
}
else if (!Q_stricmp(token, "depthmask"))
{
depthMaskBits = GLS_DEPTHMASK_TRUE;
@ -1759,10 +1828,10 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
}
else if (!Q_stricmp(token, "nextBundle"))
{
if (!qglActiveTextureARB) {
ri.Printf(PRINT_ALL, "WARNING: " PRODUCT_NAME " requires a video card with multitexturing capability\n");
return qfalse;
}
//if (!qglActiveTextureARB) {
// ri.Printf(PRINT_ALL, "WARNING: " PRODUCT_NAME " requires a video card with multitexturing capability\n");
// return qfalse;
//}
token = COM_ParseExt(text, qfalse);
if (token[0] && !Q_stricmp(token, "add")) {
@ -1814,7 +1883,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
}
shouldProcess &= evaluatedValue ^ isNot;
}
}
//=========================
else
{
ri.Printf( PRINT_WARNING, "WARNING: unknown parameter '%s' in shader '%s'\n", token, shader.name );
@ -2016,6 +2086,72 @@ static void ParseDeform( char **text ) {
return;
}
//
// OPENMOHAA-specific stuff
//=========================
if (!Q_stricmp(token, "lightglow")) {
ds->deformation = DEFORM_LIGHTGLOW;
return;
}
if (!Q_stricmp(token, "flap")) {
texDirection_t coordDirection;
token = COM_ParseExt(text, qfalse);
if (token[0] == 's') {
coordDirection = USE_S_COORDS;
}
else if (token[0] == 't') {
coordDirection = USE_T_COORDS;
}
else {
ri.Printf(PRINT_WARNING, "WARNING: deformVertexes flap requires 's' or 't' in shader '%s'\n", shader.name);
return;
}
token = COM_ParseExt(text, qfalse);
if (token[0] == 0) {
ri.Printf(PRINT_WARNING, "WARNING: missing deformVertexes flap parm in shader '%s'\n", shader.name);
return;
}
if (!atof(token)) {
ds->deformationSpread = 100.0;
ri.Printf(PRINT_WARNING, "WARNING: illegal div value of 0 in deformVertexes command for shader '%s'\n", shader.name);
}
else {
ds->deformationSpread = 1.0 / atof(token);
}
ParseWaveForm(text, &ds->deformationWave);
if (coordDirection == USE_T_COORDS) {
ds->deformation = DEFORM_FLAP_T;
}
else {
ds->deformation = DEFORM_FLAP_S;
}
token = COM_ParseExt(text, qfalse);
if (token[0] == 0)
{
ds->bulgeWidth = 0.0;
ds->bulgeHeight = 1.0;
return;
}
ds->bulgeWidth = atof(token);
token = COM_ParseExt(text, qfalse);
if (token[0] == 0)
{
ri.Printf(PRINT_WARNING, "WARNING: missing deformVertexes parm 'max' in shader '%s'\n\n", shader.name);
return;
}
ds->bulgeHeight = atof(token);
return;
}
//=========================
ri.Printf( PRINT_WARNING, "WARNING: unknown deformVertexes subtype '%s' found in shader '%s'\n", token, shader.name );
}
@ -2473,7 +2609,44 @@ static qboolean ParseShader( char **text )
}
//
// OPENMOHAA-specific stuff
//=========================
//=========================
else if (!Q_stricmp(token, "noMerge"))
{
// FIXME: unimplemented
continue;
}
else if (!Q_stricmp(token, "spritegen"))
{
token = COM_ParseExt(text, qfalse);
if (token[0] == 0) {
ri.Printf(PRINT_WARNING, "WARNING: missing spritegen parm in shader '%s'\n", shader.name);
continue;
}
if (!Q_stricmp(token, "parallel")) {
shader.sprite.type = SPRITE_PARALLEL;
} else if (!Q_stricmp(token, "parallel_oriented")) {
shader.sprite.type = SPRITE_PARALLEL_ORIENTED;
} else if (!Q_stricmp(token, "parallel_upright")) {
shader.sprite.type = SPRITE_PARALLEL_UPRIGHT;
} else if (!Q_stricmp(token, "oriented")) {
shader.sprite.type = SPRITE_ORIENTED;
}
shader.sprite.scale = 1.0;
continue;
}
else if (!Q_stricmp(token, "spritescale"))
{
token = COM_ParseExt(text, qfalse);
if (token[0] == 0) {
ri.Printf(PRINT_WARNING, "WARNING: missing spritescale parm in shader '%s'\n", shader.name);
continue;
}
shader.sprite.scale = atof(token);
continue;
}
// force 32 bit images
if (!Q_stricmp(token, "force32bit"))
{
@ -3535,6 +3708,12 @@ static shader_t *FinishShader( void ) {
hasLightmapStage = qfalse;
vertexLightmap = qfalse;
//
// OPENMOHAA-specific stuff
//=========================
CreateMultistageFromBundle();
//=========================
//
// set sky stuff appropriate
//
@ -4500,6 +4679,46 @@ void R_InitShaders( void ) {
CreateExternalShaders();
}
//
// OPENMOHAA-specific stuff
//=========================
static void CreateMultistageFromBundle() {
int stage, bundle;
int i;
for (stage = 0; stage < MAX_SHADER_STAGES; stage++ ) {
shaderStage_t* pStage = &stages[stage];
if (!pStage->active) {
break;
}
if (pStage->bundle[TB_LIGHTMAP].isLightmap) {
shaderStage_t* newStage = NULL;
for (i = stage; i < MAX_SHADER_STAGES; i++) {
if (!stages[i].active) {
newStage = &stages[i];
break;
}
}
if (newStage) {
*newStage = *pStage;
newStage->stateBits = GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_DEPTHFUNC_EQUAL;
newStage->bundle[TB_COLORMAP] = pStage->bundle[TB_LIGHTMAP];
memset(&newStage->bundle[TB_LIGHTMAP], 0, sizeof(textureBundle_t));
memset(&pStage->bundle[TB_LIGHTMAP], 0, sizeof(textureBundle_t));
stage = i;
}
}
}
}
//=========================
qhandle_t RE_RefreshShaderNoMip(const char* name) {
shader_t* sh;
char strippedName[64];

View file

@ -72,8 +72,6 @@ static vec3_t offsets[26] = {
{-one_third_root, -one_third_root, -one_third_root}
};
#if 0
int compare_light_intensities(const void *p1, const void *p2)
{
return *(int *)&((const reallightinfo_t *)p2)->fIntensity - *(int *)&((const reallightinfo_t *)p1)->fIntensity;
@ -624,9 +622,11 @@ static void RB_Sphere_Light_Sun()
GL_State(GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE);
// FIXME: unimplemented
#if 0
qglPushMatrix();
qglLoadMatrixf(backEnd.ori.modelMatrix);
qglLoadMatrixf(backEnd.or.modelMatrix);
// Clear the depth range
qglDepthRange(0.0, 0.0);
@ -645,6 +645,7 @@ static void RB_Sphere_Light_Sun()
qglDepthRange(0.0, 1.0);
qglPopMatrix();
#endif
}
return;
@ -666,9 +667,11 @@ static void RB_Sphere_Light_Sun()
GL_State(GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE);
// FIXME: unimplemented
#if 0
qglPushMatrix();
qglLoadMatrixf(backEnd.ori.modelMatrix);
qglLoadMatrixf(backEnd.or.modelMatrix);
// Clear the depth range
qglDepthRange(0.0, 0.0);
@ -693,6 +696,7 @@ static void RB_Sphere_Light_Sun()
qglDepthRange(0.0, 1.0);
qglPopMatrix();
#endif
}
if (hitSun) {
@ -771,7 +775,7 @@ static bool RB_Sphere_SetupGlobals()
} else if (!RB_Sphere_CalculateSphereOrigin()) {
backEnd.currentSphere->TessFunction = &RB_CalcLightGridColor;
if (!backEnd.currentEntity->bLightGridCalculated) {
if (!backEnd.currentEntity->lightingCalculated) {
RB_SetupEntityGridLighting();
}
@ -793,9 +797,9 @@ static bool RB_Sphere_SetupGlobals()
static bool RB_Sphere_ResetPointColors()
{
vec3_t light_offset, amb;
vec3_t light_offset, amb_light_offset, amb;
R_GetLightingGridValue(backEnd.currentSphere->worldOrigin, light_offset);
R_GetLightingGridValue(tr.world, backEnd.currentSphere->worldOrigin, light_offset, amb_light_offset);
light_offset[0] = ambientlight[0] + light_offset[0] * 0.18;
light_offset[1] = ambientlight[1] + light_offset[1] * 0.18;
light_offset[2] = ambientlight[2] + light_offset[2] * 0.18;
@ -809,7 +813,7 @@ static bool RB_Sphere_ResetPointColors()
}
}
VectorScale(light_offset, tr.overbrightMult * r_entlight_scale->value, amb);
VectorScale(amb_light_offset, tr.overbrightMult * r_entlight_scale->value, amb);
backEnd.currentSphere->ambient.level[0] = Q_min(amb[0], 0xff);
backEnd.currentSphere->ambient.level[1] = Q_min(amb[1], 0xff);
backEnd.currentSphere->ambient.level[2] = Q_min(amb[2], 0xff);
@ -828,9 +832,11 @@ static void RB_Sphere_DrawDebugLine(const spherel_t *thislight, float falloff, c
return;
}
// FIXME: unimplemented
#if 0
qglPushMatrix();
qglLoadMatrixf(backEnd.ori.modelMatrix);
qglLoadMatrixf(backEnd.or.modelMatrix);
// Clear the depth range
qglDepthRange(0.0, 0.0);
@ -883,6 +889,7 @@ static void RB_Sphere_DrawDebugLine(const spherel_t *thislight, float falloff, c
// Restore depth
qglDepthRange(0.0, 1.0);
qglPopMatrix();
#endif
}
static void RB_Sphere_AddSpotLight(const spherel_t *thislight)
@ -1344,23 +1351,10 @@ 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
int R_GatherLightSources(const vec3_t vPos, vec3_t *pvLightPos, vec3_t *pvLightIntensity, int iMaxLights)
{
// FIXME: unimplemented (GL2)
return 0;
#if 0
int i, j;
int iLightCount;
vec3_t vEnd;
@ -1468,5 +1462,4 @@ int R_GatherLightSources(const vec3_t vPos, vec3_t *pvLightPos, vec3_t *pvLightI
}
return iLightCount;
#endif
}

View file

@ -96,7 +96,7 @@ void RB_DrawSprite( const refSprite_t *spr ) {
model = tr.models;
if (spr->hModel > 0 && spr->hModel < tr.numModels) {
model = &tr.models[spr->hModel];
model = tr.models[spr->hModel];
}
scale = spr->scale * model->d.sprite->scale;

View file

@ -869,6 +869,52 @@ void R_AddWorldSurfaces (void) {
// OPENMOHAA-specific stuff
//
int R_SphereInLeafs(const vec3_t p, float r, mnode_t** nodes, int nMaxNodes) {
mnode_t* nodestack[1024];
int iNodeStackPos;
mnode_t* pCurNode;
int nFoundNodes;
iNodeStackPos = 0;
pCurNode = tr.world->nodes;
nFoundNodes = 0;
while (1)
{
cplane_t* plane;
float d;
while (pCurNode->contents == -1)
{
plane = pCurNode->plane;
if (plane->type >= PLANE_NON_AXIAL) {
d = DotProduct(p, plane->normal) - plane->dist;
} else {
d = p[plane->type] - plane->dist;
}
if (d < r) {
if (d > -r) {
nodestack[iNodeStackPos++] = pCurNode->children[0];
}
pCurNode = pCurNode->children[1];
} else {
pCurNode = pCurNode->children[0];
}
}
nodes[nFoundNodes++] = pCurNode;
if (!iNodeStackPos || nFoundNodes == nMaxNodes) {
break;
}
iNodeStackPos--;
pCurNode = nodestack[iNodeStackPos];
}
return nFoundNodes;
}
void R_GetInlineModelBounds(int iIndex, vec3_t vMins, vec3_t vMaxs)
{
bmodel_t* bmodel;