diff options
Diffstat (limited to 'src/renderergl2/tr_backend.c')
-rw-r--r-- | src/renderergl2/tr_backend.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index ad43e5b2..4a29c966 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -1738,6 +1738,65 @@ const void *RB_PostProcess(const void *data) return (const void *)(cmd + 1); } +// FIXME: put this function declaration elsewhere +void R_SaveDDS(const char *filename, byte *pic, int width, int height, int depth); + +/* +============= +RB_ExportCubemaps + +============= +*/ +const void *RB_ExportCubemaps(const void *data) +{ + const exportCubemapsCommand_t *cmd = data; + + // finish any 2D drawing if needed + if (tess.numIndexes) + RB_EndSurface(); + + if (!glRefConfig.framebufferObject || !tr.world || tr.numCubemaps == 0) + { + // do nothing + ri.Printf(PRINT_ALL, "Nothing to export!\n"); + return (const void *)(cmd + 1); + } + + if (cmd) + { + FBO_t *oldFbo = glState.currentFBO; + int sideSize = CUBE_MAP_SIZE * CUBE_MAP_SIZE * 4; + byte *cubemapPixels = ri.Malloc(sideSize * 6); + int i, j; + + FBO_Bind(tr.renderCubeFbo); + + for (i = 0; i < tr.numCubemaps; i++) + { + char filename[MAX_QPATH]; + cubemap_t *cubemap = &tr.cubemaps[i]; + char *p = cubemapPixels; + + 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; + } + + Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i); + R_SaveDDS(filename, cubemapPixels, CUBE_MAP_SIZE, CUBE_MAP_SIZE, 6); + ri.Printf(PRINT_ALL, "Saved cubemap %d as %s\n", i, filename); + } + + FBO_Bind(oldFbo); + + ri.Free(cubemapPixels); + } + + return (const void *)(cmd + 1); +} + /* ==================== @@ -1786,6 +1845,9 @@ void RB_ExecuteRenderCommands( const void *data ) { case RC_POSTPROCESS: data = RB_PostProcess(data); break; + case RC_EXPORT_CUBEMAPS: + data = RB_ExportCubemaps(data); + break; case RC_END_OF_LIST: default: // finish any 2D drawing if needed |