openmohaa/code/renderer/tr_sphere_shade.cpp

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;
}