summaryrefslogtreecommitdiff
path: root/src/renderergl2/tr_bsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderergl2/tr_bsp.c')
-rw-r--r--src/renderergl2/tr_bsp.c166
1 files changed, 145 insertions, 21 deletions
diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c
index beb07fe3..8429d8cb 100644
--- a/src/renderergl2/tr_bsp.c
+++ b/src/renderergl2/tr_bsp.c
@@ -24,6 +24,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "tr_local.h"
+#define JSON_IMPLEMENTATION
+#include "../qcommon/json.h"
+#undef JSON_IMPLEMENTATION
+
/*
Loads and prepares a map file for scene rendering.
@@ -102,7 +106,11 @@ static void R_ColorShiftLightingBytes( byte in[4], byte out[4] ) {
int shift, r, g, b;
// shift the color data based on overbright range
+#if defined(USE_OVERBRIGHT)
shift = r_mapOverBrightBits->integer - tr.overbrightBits;
+#else
+ shift = 0;
+#endif
// shift the data based on overbright range
r = in[0] << shift;
@@ -137,7 +145,9 @@ static void R_ColorShiftLightingFloats(float in[4], float out[4], float scale )
{
float r, g, b;
- scale *= pow(2.0f, r_mapOverBrightBits->integer - tr.overbrightBits);
+#if defined(USE_OVERBRIGHT)
+ scale *= 1 << (r_mapOverBrightBits->integer - tr.overbrightBits);
+#endif
r = in[0] * scale;
g = in[1] * scale;
@@ -2756,7 +2766,11 @@ void R_LoadLightGrid( lump_t *l ) {
if (hdrLightGrid)
{
- float lightScale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits);
+#if defined(USE_OVERBRIGHT)
+ float lightScale = 1 << (r_mapOverBrightBits->integer - tr.overbrightBits);
+#else
+ float lightScale = 1.0f;
+#endif
//ri.Printf(PRINT_ALL, "found!\n");
@@ -2963,6 +2977,78 @@ qboolean R_ParseSpawnVars( char *spawnVarChars, int maxSpawnVarChars, int *numSp
return qtrue;
}
+void R_LoadEnvironmentJson(const char *baseName)
+{
+ char filename[MAX_QPATH];
+
+ union {
+ char *c;
+ void *v;
+ } buffer;
+ char *bufferEnd;
+
+ const char *cubemapArrayJson;
+ int filelen, i;
+
+ Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/env.json", baseName);
+
+ filelen = ri.FS_ReadFile(filename, &buffer.v);
+ if (!buffer.c)
+ return;
+ bufferEnd = buffer.c + filelen;
+
+ if (JSON_ValueGetType(buffer.c, bufferEnd) != JSONTYPE_OBJECT)
+ {
+ ri.Printf(PRINT_ALL, "Bad %s: does not start with a object\n", filename);
+ ri.FS_FreeFile(buffer.v);
+ return;
+ }
+
+ cubemapArrayJson = JSON_ObjectGetNamedValue(buffer.c, bufferEnd, "Cubemaps");
+ if (!cubemapArrayJson)
+ {
+ ri.Printf(PRINT_ALL, "Bad %s: no Cubemaps\n", filename);
+ ri.FS_FreeFile(buffer.v);
+ return;
+ }
+
+ if (JSON_ValueGetType(cubemapArrayJson, bufferEnd) != JSONTYPE_ARRAY)
+ {
+ ri.Printf(PRINT_ALL, "Bad %s: Cubemaps not an array\n", filename);
+ ri.FS_FreeFile(buffer.v);
+ return;
+ }
+
+ tr.numCubemaps = JSON_ArrayGetIndex(cubemapArrayJson, bufferEnd, NULL, 0);
+ tr.cubemaps = ri.Hunk_Alloc(tr.numCubemaps * sizeof(*tr.cubemaps), h_low);
+ memset(tr.cubemaps, 0, tr.numCubemaps * sizeof(*tr.cubemaps));
+
+ for (i = 0; i < tr.numCubemaps; i++)
+ {
+ cubemap_t *cubemap = &tr.cubemaps[i];
+ const char *cubemapJson, *keyValueJson, *indexes[3];
+ int j;
+
+ cubemapJson = JSON_ArrayGetValue(cubemapArrayJson, bufferEnd, i);
+
+ keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Name");
+ if (!JSON_ValueGetString(keyValueJson, bufferEnd, cubemap->name, MAX_QPATH))
+ cubemap->name[0] = '\0';
+
+ keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Position");
+ JSON_ArrayGetIndex(keyValueJson, bufferEnd, indexes, 3);
+ for (j = 0; j < 3; j++)
+ cubemap->origin[j] = JSON_ValueGetFloat(indexes[j], bufferEnd);
+
+ cubemap->parallaxRadius = 1000.0f;
+ keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Radius");
+ if (keyValueJson)
+ cubemap->parallaxRadius = JSON_ValueGetFloat(keyValueJson, bufferEnd);
+ }
+
+ ri.FS_FreeFile(buffer.v);
+}
+
void R_LoadCubemapEntities(char *cubemapEntityName)
{
char spawnVarChars[2048];
@@ -2987,33 +3073,45 @@ void R_LoadCubemapEntities(char *cubemapEntityName)
return;
tr.numCubemaps = numCubemaps;
- tr.cubemapOrigins = ri.Hunk_Alloc( tr.numCubemaps * sizeof(*tr.cubemapOrigins), h_low);
- tr.cubemaps = ri.Hunk_Alloc( tr.numCubemaps * sizeof(*tr.cubemaps), h_low);
+ tr.cubemaps = ri.Hunk_Alloc(tr.numCubemaps * sizeof(*tr.cubemaps), h_low);
+ memset(tr.cubemaps, 0, tr.numCubemaps * sizeof(*tr.cubemaps));
numCubemaps = 0;
while(R_ParseSpawnVars(spawnVarChars, sizeof(spawnVarChars), &numSpawnVars, spawnVars))
{
int i;
+ char name[MAX_QPATH];
qboolean isCubemap = qfalse;
- qboolean positionSet = qfalse;
+ qboolean originSet = qfalse;
vec3_t origin;
+ float parallaxRadius = 1000.0f;
+ name[0] = '\0';
for (i = 0; i < numSpawnVars; i++)
{
if (!Q_stricmp(spawnVars[i][0], "classname") && !Q_stricmp(spawnVars[i][1], cubemapEntityName))
isCubemap = qtrue;
+ if (!Q_stricmp(spawnVars[i][0], "name"))
+ Q_strncpyz(name, spawnVars[i][1], MAX_QPATH);
+
if (!Q_stricmp(spawnVars[i][0], "origin"))
{
sscanf(spawnVars[i][1], "%f %f %f", &origin[0], &origin[1], &origin[2]);
- positionSet = qtrue;
+ originSet = qtrue;
+ }
+ else if (!Q_stricmp(spawnVars[i][0], "radius"))
+ {
+ sscanf(spawnVars[i][1], "%f", &parallaxRadius);
}
}
- if (isCubemap && positionSet)
+ if (isCubemap && originSet)
{
- //ri.Printf(PRINT_ALL, "cubemap at %f %f %f\n", origin[0], origin[1], origin[2]);
- VectorCopy(origin, tr.cubemapOrigins[numCubemaps]);
+ cubemap_t *cubemap = &tr.cubemaps[numCubemaps];
+ Q_strncpyz(cubemap->name, name, MAX_QPATH);
+ VectorCopy(origin, cubemap->origin);
+ cubemap->parallaxRadius = parallaxRadius;
numCubemaps++;
}
}
@@ -3053,23 +3151,41 @@ void R_AssignCubemapsToWorldSurfaces(void)
}
-void R_RenderAllCubemaps(void)
+void R_LoadCubemaps(void)
{
- int i, j;
+ int i;
+ imgFlags_t flags = IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_NOLIGHTSCALE | IMGFLAG_CUBEMAP;
for (i = 0; i < tr.numCubemaps; i++)
{
- tr.cubemaps[i] = R_CreateImage(va("*cubeMap%d", i), NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8);
+ char filename[MAX_QPATH];
+ cubemap_t *cubemap = &tr.cubemaps[i];
+
+ Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i);
+
+ cubemap->image = R_FindImageFile(filename, IMGTYPE_COLORALPHA, flags);
}
-
+}
+
+
+void R_RenderMissingCubemaps(void)
+{
+ int i, j;
+ imgFlags_t flags = IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_NOLIGHTSCALE | IMGFLAG_CUBEMAP;
+
for (i = 0; i < tr.numCubemaps; i++)
{
- for (j = 0; j < 6; j++)
+ if (!tr.cubemaps[i].image)
{
- RE_ClearScene();
- R_RenderCubemapSide(i, j, qfalse);
- R_IssuePendingRenderCommands();
- R_InitNextFrame();
+ tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, flags, GL_RGBA8);
+
+ for (j = 0; j < 6; j++)
+ {
+ RE_ClearScene();
+ R_RenderCubemapSide(i, j, qfalse);
+ R_IssuePendingRenderCommands();
+ R_InitNextFrame();
+ }
}
}
}
@@ -3386,7 +3502,14 @@ void RE_LoadWorldMap( const char *name ) {
// load cubemaps
if (r_cubeMapping->integer)
{
- R_LoadCubemapEntities("misc_cubemap");
+ // Try loading an env.json file first
+ R_LoadEnvironmentJson(s_worldData.baseName);
+
+ if (!tr.numCubemaps)
+ {
+ R_LoadCubemapEntities("misc_cubemap");
+ }
+
if (!tr.numCubemaps)
{
// use deathmatch spawn points as cubemaps
@@ -3410,10 +3533,11 @@ void RE_LoadWorldMap( const char *name ) {
// make sure the VAO glState entry is safe
R_BindNullVao();
- // Render all cubemaps
+ // Render or load all cubemaps
if (r_cubeMapping->integer && tr.numCubemaps)
{
- R_RenderAllCubemaps();
+ R_LoadCubemaps();
+ R_RenderMissingCubemaps();
}
ri.FS_FreeFile( buffer.v );