summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSmileTheory <SmileTheory@gmail.com>2015-12-22 05:04:07 -0800
committerTim Angus <tim@ngus.net>2016-04-07 11:46:05 +0100
commit19c44d9c50d6a3057e79007c779552d0eb7fe4ef (patch)
treee3bb41cd085c1b1c4851bd4daf593f3322a523ef /src
parente78dc015d1c94fbe4fa5014d412a2cdf23f2dc7d (diff)
OpenGL2: Add r_exportCubemaps for saving cubemaps on map load.
Diffstat (limited to 'src')
-rw-r--r--src/renderergl2/tr_bsp.c37
-rw-r--r--src/renderergl2/tr_image_dds.c45
-rw-r--r--src/renderergl2/tr_init.c3
-rw-r--r--src/renderergl2/tr_local.h1
4 files changed, 85 insertions, 1 deletions
diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c
index d2a5f5f2..81463c66 100644
--- a/src/renderergl2/tr_bsp.c
+++ b/src/renderergl2/tr_bsp.c
@@ -3068,16 +3068,23 @@ void R_AssignCubemapsToWorldSurfaces(void)
}
}
+// FIXME: put this function declaration elsewhere
+void R_SaveDDS(const char *filename, byte *pic, int width, int height, int depth);
void R_RenderAllCubemaps(void)
{
+ byte *data = NULL;
+ int sideSize = CUBE_MAP_SIZE * CUBE_MAP_SIZE * 4;
int i, j;
for (i = 0; i < tr.numCubemaps; i++)
{
tr.cubemaps[i].image = 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);
}
-
+
+ if (r_exportCubemaps->integer)
+ data = ri.Malloc(sideSize * 6);
+
for (i = 0; i < tr.numCubemaps; i++)
{
for (j = 0; j < 6; j++)
@@ -3087,6 +3094,34 @@ void R_RenderAllCubemaps(void)
R_IssuePendingRenderCommands();
R_InitNextFrame();
}
+
+ if (r_exportCubemaps->integer)
+ {
+ char filename[MAX_QPATH];
+ byte *p;
+ cubemap_t *cubemap = &tr.cubemaps[i];
+
+ // FIXME: do this in backEnd
+ FBO_Bind(tr.renderCubeFbo);
+
+ p = data;
+ for (j = 0; j < 6; j++)
+ {
+ qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, cubemap->image->texnum, 0);
+ qglReadPixels(0, 0, CUBE_MAP_SIZE, CUBE_MAP_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, p);
+ p += sideSize;
+ }
+ FBO_Bind(NULL);
+
+ Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, backEnd.viewParms.targetFboCubemapIndex);
+ R_SaveDDS(filename, data, CUBE_MAP_SIZE, CUBE_MAP_SIZE, 6);
+ }
+ }
+
+ if (r_exportCubemaps->integer)
+ {
+ ri.Cvar_Set("r_exportCubemaps", "0");
+ ri.Free(data);
}
}
diff --git a/src/renderergl2/tr_image_dds.c b/src/renderergl2/tr_image_dds.c
index 8ad406fd..b509014d 100644
--- a/src/renderergl2/tr_image_dds.c
+++ b/src/renderergl2/tr_image_dds.c
@@ -451,3 +451,48 @@ void R_LoadDDS ( const char *filename, byte **pic, int *width, int *height, GLen
ri.FS_FreeFile(buffer.v);
}
+
+void R_SaveDDS(const char *filename, byte *pic, int width, int height, int depth)
+{
+ byte *data;
+ ddsHeader_t *ddsHeader;
+ int picSize, size;
+
+ if (!depth)
+ depth = 1;
+
+ picSize = width * height * depth * 4;
+ size = 4 + sizeof(*ddsHeader) + picSize;
+ data = ri.Malloc(size);
+
+ data[0] = 'D';
+ data[1] = 'D';
+ data[2] = 'S';
+ data[3] = ' ';
+
+ ddsHeader = (ddsHeader_t *)(data + 4);
+ memset(ddsHeader, 0, sizeof(ddsHeader_t));
+
+ ddsHeader->headerSize = 0x7c;
+ ddsHeader->flags = _DDSFLAGS_REQUIRED;
+ ddsHeader->height = height;
+ ddsHeader->width = width;
+ ddsHeader->always_0x00000020 = 0x00000020;
+ ddsHeader->caps = DDSCAPS_COMPLEX | DDSCAPS_REQUIRED;
+
+ if (depth == 6)
+ ddsHeader->caps2 = DDSCAPS2_CUBEMAP;
+
+ ddsHeader->pixelFormatFlags = DDSPF_RGB | DDSPF_ALPHAPIXELS;
+ ddsHeader->rgbBitCount = 32;
+ ddsHeader->rBitMask = 0x000000ff;
+ ddsHeader->gBitMask = 0x0000ff00;
+ ddsHeader->bBitMask = 0x00ff0000;
+ ddsHeader->aBitMask = 0xff000000;
+
+ Com_Memcpy(data + 4 + sizeof(*ddsHeader), pic, picSize);
+
+ ri.FS_WriteFile(filename, data, size);
+
+ ri.Free(data);
+}
diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c
index 2828270e..44808639 100644
--- a/src/renderergl2/tr_init.c
+++ b/src/renderergl2/tr_init.c
@@ -141,6 +141,7 @@ cvar_t *r_specularMapping;
cvar_t *r_deluxeMapping;
cvar_t *r_parallaxMapping;
cvar_t *r_cubeMapping;
+cvar_t *r_exportCubemaps;
cvar_t *r_specularIsMetallic;
cvar_t *r_glossIsRoughness;
cvar_t *r_baseNormalX;
@@ -383,6 +384,7 @@ byte *RB_ReadPixels(int x, int y, int width, int height, size_t *offset, int *pa
buffer = ri.Hunk_AllocateTempMemory(padwidth * height + *offset + packAlign - 1);
bufstart = PADP((intptr_t) buffer + *offset, packAlign);
+
qglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, bufstart);
*offset = bufstart - buffer;
@@ -1141,6 +1143,7 @@ void R_Register( void )
r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
+ r_exportCubemaps = ri.Cvar_Get("r_exportCubemaps", "0", 0);
r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_glossIsRoughness = ri.Cvar_Get("r_glossIsRoughness", "0", CVAR_ARCHIVE | CVAR_LATCH);
r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH );
diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h
index 0a1dc5fe..f716065e 100644
--- a/src/renderergl2/tr_local.h
+++ b/src/renderergl2/tr_local.h
@@ -1794,6 +1794,7 @@ extern cvar_t *r_specularMapping;
extern cvar_t *r_deluxeMapping;
extern cvar_t *r_parallaxMapping;
extern cvar_t *r_cubeMapping;
+extern cvar_t *r_exportCubemaps;
extern cvar_t *r_specularIsMetallic;
extern cvar_t *r_glossIsRoughness;
extern cvar_t *r_baseNormalX;