mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 21:57:57 +03:00
310 lines
7.7 KiB
C++
310 lines
7.7 KiB
C++
/*
|
|
===========================================================================
|
|
Copyright (C) 2023 the OpenMoHAA team
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
or (at your option) any later version.
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
|
|
// tr_sphere_shade.cpp -- sphere shade
|
|
|
|
#include "tr_local.h"
|
|
|
|
vec3_t spheredef[6];
|
|
suninfo_t s_sun;
|
|
static vec3_t ambientlight;
|
|
static qboolean bEntityOverbright;
|
|
static int iEntityLightingMax;
|
|
static int light_reference_count = 0;
|
|
|
|
int compare_light_intensities(const void* p1, const void* p2)
|
|
{
|
|
return ((const reallightinfo_t*)p2)->fIntensity - ((const reallightinfo_t*)p1)->fIntensity;
|
|
}
|
|
|
|
static void RB_OptimizeLights()
|
|
{
|
|
// FIXME: unimplemented
|
|
}
|
|
|
|
static void RB_Light_CubeMap(const color4ub_t colors)
|
|
{
|
|
// FIXME: unimplemented
|
|
}
|
|
|
|
void RB_Light_Real(unsigned char* colors)
|
|
{
|
|
int i, j;
|
|
float* normal;
|
|
float* xyz;
|
|
unsigned char* color;
|
|
vec3_t v;
|
|
vec3_t colorout;
|
|
float fDot;
|
|
reallightinfo_t* pLight;
|
|
|
|
|
|
// FIXME: unimplemented
|
|
}
|
|
|
|
static void RB_Sphere_Light_Sun()
|
|
{
|
|
// FIXME: unimplemented
|
|
}
|
|
|
|
static qboolean RB_Sphere_CalculateSphereOrigin()
|
|
{
|
|
// FIXME: unimplemented
|
|
return qfalse;
|
|
}
|
|
|
|
static bool RB_Sphere_SetupGlobals()
|
|
{
|
|
int i;
|
|
|
|
if (backEnd.refdef.rdflags & RDF_NOWORLDMODEL) {
|
|
if (!(backEnd.refdef.rdflags & RDF_FULLBRIGHT)) {
|
|
backEnd.currentSphere->TessFunction = &RB_Light_Fullbright;
|
|
return false;
|
|
}
|
|
}
|
|
else if (!(backEnd.refdef.rdflags & RDF_FULLBRIGHT)) {
|
|
if (!RB_Sphere_CalculateSphereOrigin()) {
|
|
backEnd.currentSphere->TessFunction = &RB_CalcLightGridColor;
|
|
|
|
if (!backEnd.currentEntity->bLightGridCalculated) {
|
|
RB_SetupEntityGridLighting();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (backEnd.refdef.vieworg[0] == 0 && backEnd.refdef.vieworg[1] == 0 && backEnd.refdef.vieworg[2] == 0) {
|
|
backEnd.currentSphere->TessFunction = &RB_Light_Fullbright;
|
|
return false;
|
|
}
|
|
|
|
VectorCopy(backEnd.refdef.vieworg, backEnd.currentSphere->worldOrigin);
|
|
VectorClear(backEnd.currentSphere->origin);
|
|
backEnd.currentSphere->radius = 2.0;
|
|
}
|
|
|
|
light_reference_count++;
|
|
for (i = 0; i < 8; i++) {
|
|
backEnd.currentSphere->leaves[i] = 0;
|
|
}
|
|
|
|
R_SphereInLeafs(backEnd.currentSphere->worldOrigin, backEnd.currentSphere->radius, backEnd.currentSphere->leaves, 8);
|
|
|
|
backEnd.currentSphere->TessFunction = &RB_Light_Real;
|
|
return true;
|
|
}
|
|
|
|
static bool RB_Sphere_ResetPointColors()
|
|
{
|
|
vec3_t light_offset, amb;
|
|
|
|
R_GetLightingGridValue(backEnd.currentSphere->worldOrigin, 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;
|
|
if (tr.refdef.rdflags & RDF_FULLBRIGHT)
|
|
{
|
|
float fMin = tr.identityLight * 20.0;
|
|
|
|
if (fMin <= light_offset[0] || fMin <= light_offset[1] || fMin <= light_offset[2]) {
|
|
light_offset[0] += fMin;
|
|
light_offset[1] += fMin;
|
|
light_offset[2] += fMin;
|
|
}
|
|
}
|
|
|
|
backEnd.currentSphere->ambient.level[0] = r_entlight_scale->value * tr.overbrightMult * light_offset[0];
|
|
if (backEnd.currentSphere->ambient.level[0] >= 255.0) {
|
|
backEnd.currentSphere->ambient.level[0] = -1;
|
|
}
|
|
|
|
backEnd.currentSphere->ambient.level[1] = r_entlight_scale->value * tr.overbrightMult * light_offset[0];
|
|
if (backEnd.currentSphere->ambient.level[1] >= 255.0) {
|
|
backEnd.currentSphere->ambient.level[1] = -1;
|
|
}
|
|
|
|
backEnd.currentSphere->ambient.level[2] = r_entlight_scale->value * tr.overbrightMult * light_offset[0];
|
|
if (backEnd.currentSphere->ambient.level[2] >= 255.0) {
|
|
backEnd.currentSphere->ambient.level[2] = -1;
|
|
}
|
|
|
|
backEnd.currentSphere->ambient.level[3] = -1;
|
|
|
|
return true;
|
|
}
|
|
|
|
static void RB_Sphere_DrawDebugLine(const spherel_t* thislight, float falloff, const vec3_t origin)
|
|
{
|
|
// FIXME: unimplemented
|
|
}
|
|
|
|
static void RB_Sphere_AddSpotLight(const spherel_t* thislight)
|
|
{
|
|
// FIXME: unimplemented
|
|
}
|
|
|
|
static void RB_Sphere_AddLight(const spherel_t* thislight)
|
|
{
|
|
// FIXME: unimplemented
|
|
}
|
|
|
|
static void RB_Sphere_BuildStaticLights()
|
|
{
|
|
// FIXME: unimplemented
|
|
}
|
|
|
|
void RB_Sphere_BuildDLights()
|
|
{
|
|
// FIXME: unimplemented
|
|
}
|
|
|
|
void RB_Sphere_SetupEntity()
|
|
{
|
|
if (r_light_nolight->integer)
|
|
{
|
|
backEnd.currentSphere->TessFunction = &RB_Light_Fullbright;
|
|
}
|
|
else if (RB_Sphere_SetupGlobals() && RB_Sphere_ResetPointColors())
|
|
{
|
|
backEnd.currentSphere->numRealLights = 0;
|
|
RB_Sphere_Light_Sun();
|
|
RB_Sphere_BuildStaticLights();
|
|
RB_Sphere_BuildDLights();
|
|
backEnd.pc.c_characterlights += backEnd.currentSphere->numRealLights;
|
|
RB_OptimizeLights();
|
|
}
|
|
}
|
|
|
|
void RB_Grid_SetupEntity()
|
|
{
|
|
// FIXME: unimplemented
|
|
}
|
|
|
|
void RB_Grid_SetupStaticModel()
|
|
{
|
|
RB_SetupStaticModelGridLighting(&tr.refdef, backEnd.currentStaticModel, backEnd.currentStaticModel->origin);
|
|
}
|
|
|
|
void RB_Light_Fullbright(unsigned char* colors)
|
|
{
|
|
memset((void*)colors, 0xFF, tess.numVertexes);
|
|
}
|
|
|
|
void R_Sphere_InitLights()
|
|
{
|
|
const char* ents;
|
|
const char* ret;
|
|
qboolean bFlareDirSet;
|
|
|
|
ents = ri.CM_EntityString();
|
|
bFlareDirSet = qfalse;
|
|
s_sun.szFlareName[0] = 0;
|
|
s_sun.exists = qfalse;
|
|
|
|
for (int i = 0; i < 128; i++) {
|
|
backEnd.spheres[i].TessFunction = &RB_Light_Real;
|
|
}
|
|
|
|
VectorClear(ambientlight);
|
|
backEnd.spareSphere.TessFunction = &RB_Light_Real;
|
|
backEnd.currentSphere = &backEnd.spareSphere;
|
|
bEntityOverbright = qfalse;
|
|
iEntityLightingMax = tr.identityLightByte;
|
|
s_sun.color[0] = s_sun.color[1] = s_sun.color[2] = tr.overbrightMult * 70;
|
|
|
|
while (ents)
|
|
{
|
|
ret = COM_Parse((char**)&ents);
|
|
if (*ret == '{' || *ret == '}') {
|
|
continue;
|
|
}
|
|
|
|
if (!strcmp(ret, "suncolor") || !strcmp(ret, "sunlight"))
|
|
{
|
|
sscanf(COM_Parse((char**)&ents), "%f %f %f", &s_sun.color[0], &s_sun.color[1], &s_sun.color[2]);
|
|
s_sun.color[0] *= tr.overbrightMult;
|
|
s_sun.color[1] *= tr.overbrightMult;
|
|
s_sun.color[2] *= tr.overbrightMult;
|
|
s_sun.exists = qtrue;
|
|
}
|
|
else if (!strcmp(ret, "sundirection"))
|
|
{
|
|
vec3_t dir;
|
|
|
|
sscanf(COM_Parse((char**)&ents), "%f %f %f", &dir[0], &dir[1], &dir[2]);
|
|
AngleVectorsLeft(dir, s_sun.direction, 0, 0);
|
|
|
|
s_sun.exists = qtrue;
|
|
if (!bFlareDirSet)
|
|
{
|
|
s_sun.flaredirection[0] = s_sun.direction[0];
|
|
s_sun.flaredirection[1] = s_sun.direction[1];
|
|
s_sun.flaredirection[2] = s_sun.direction[2];
|
|
}
|
|
}
|
|
else if (!strcmp(ret, "sunflaredirection"))
|
|
{
|
|
vec3_t dir;
|
|
|
|
sscanf(COM_Parse((char**)&ents), "%f %f %f", &dir[0], &dir[1], &dir[2]);
|
|
AngleVectorsLeft(dir, s_sun.flaredirection, 0, 0);
|
|
bFlareDirSet = qtrue;
|
|
}
|
|
else if (!strcmp(ret, "sunflarename"))
|
|
{
|
|
strcpy(s_sun.szFlareName, COM_Parse((char**)&ents));
|
|
}
|
|
else if (!strcmp(ret, "ambientlight"))
|
|
{
|
|
sscanf(COM_Parse((char**)&ents), "%f %f %f", &ambientlight[0], &ambientlight[1], &ambientlight[2]);
|
|
}
|
|
else if (!strcmp(ret, "overbright"))
|
|
{
|
|
ret = COM_Parse((char**)&ents);
|
|
if (strcmp(ret, "world") || strcmp(ret, "none"))
|
|
{
|
|
bEntityOverbright = qtrue;
|
|
iEntityLightingMax = 0xFF;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
COM_Parse((char**)&ents);
|
|
}
|
|
}
|
|
|
|
if (s_sun.exists)
|
|
{
|
|
if (!s_sun.szFlareName[0]) {
|
|
strcpy(s_sun.szFlareName, "sun");
|
|
}
|
|
}
|
|
}
|
|
|
|
int R_GatherLightSources(const vec3_t vPos, vec3_t* pvLightPos, vec3_t* pvLightIntensity, int iMaxLights)
|
|
{
|
|
// FIXME: unimplemented
|
|
return 0;
|
|
}
|