diff options
Diffstat (limited to 'src/renderergl2/tr_bsp.c')
-rw-r--r-- | src/renderergl2/tr_bsp.c | 166 |
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", ¶llaxRadius); } } - 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 ); |