static bool SL_CreatePNGFile (const char* filename, unsigned char* buffer, int width, int height) { ScopedFile f; /* create the .bmp file... */ if (FS_OpenFile(filename, &f, FILE_WRITE) == -1) return false; R_WritePNG(&f, buffer, width, height); return true; }
static qboolean SL_CreatePNGFile (const char *filename, unsigned char *buffer, int width, int height) { qFILE f; /* create the .bmp file... */ if (FS_OpenFile(filename, &f, FILE_WRITE) == -1) return qfalse; R_WritePNG(&f, buffer, width, height); FS_CloseFile(&f); return qtrue; }
/** * Take a screenshot of the frame buffer * @param[in] x * @param[in] y * @param[in] width * @param[in] height * @param[in] filename Force to use a filename. Else NULL to autogen a filename * @param[in] ext Force to use an image format (tga/png/jpg). Else NULL to use value of r_screenshot_format */ void R_ScreenShot (int x, int y, int width, int height, const char *filename, const char *ext) { char checkName[MAX_OSPATH]; int type, shotNum, quality = 100; qFILE f; int rowPack; glGetIntegerv(GL_PACK_ALIGNMENT, &rowPack); glPixelStorei(GL_PACK_ALIGNMENT, 1); /* Find out what format to save in */ if (ext == NULL) ext = r_screenshot_format->string; if (!Q_strcasecmp(ext, "png")) type = SSHOTTYPE_PNG; else if (!Q_strcasecmp(ext, "jpg")) type = SSHOTTYPE_JPG; else type = SSHOTTYPE_TGA_COMP; /* Set necessary values */ switch (type) { case SSHOTTYPE_TGA_COMP: Com_Printf("Taking TGA screenshot...\n"); ext = "tga"; break; case SSHOTTYPE_PNG: Com_Printf("Taking PNG screenshot...\n"); ext = "png"; break; case SSHOTTYPE_JPG: if (Cmd_Argc() == 3) quality = atoi(Cmd_Argv(2)); else quality = r_screenshot_jpeg_quality->integer; if (quality > 100 || quality <= 0) quality = 100; Com_Printf("Taking JPG screenshot (at %i%% quality)...\n", quality); ext = "jpg"; break; } /* Find a file name to save it to */ if (filename) { Com_sprintf(checkName, sizeof(checkName), "scrnshot/%s.%s", filename, ext); } else { for (shotNum = 0; shotNum < 1000; shotNum++) { Com_sprintf(checkName, sizeof(checkName), "scrnshot/ufo%i%i.%s", shotNum / 10, shotNum % 10, ext); if (FS_CheckFile("%s", checkName) == -1) break; } if (shotNum == 1000) { Com_Printf("R_ScreenShot_f: screenshot limit (of 1000) exceeded!\n"); return; } } /* Open it */ FS_OpenFile(checkName, &f, FILE_WRITE); if (!f.f) { Com_Printf("R_ScreenShot_f: Couldn't create file: %s\n", checkName); return; } /* Allocate room for a copy of the framebuffer */ byte* const buffer = Mem_PoolAllocTypeN(byte, width * height * 3, vid_imagePool); if (!buffer) { Com_Printf("R_ScreenShot_f: Could not allocate %i bytes for screenshot!\n", width * height * 3); FS_CloseFile(&f); return; } /* Read the framebuffer into our storage */ glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer); R_CheckError(); /* Write */ switch (type) { case SSHOTTYPE_TGA_COMP: R_WriteCompressedTGA(&f, buffer, width, height); break; case SSHOTTYPE_PNG: R_WritePNG(&f, buffer, width, height); break; case SSHOTTYPE_JPG: R_WriteJPG(&f, buffer, width, height, quality); break; } /* Finish */ FS_CloseFile(&f); Mem_Free(buffer); Com_Printf("Wrote %s to %s\n", checkName, FS_Gamedir()); glPixelStorei(GL_PACK_ALIGNMENT, rowPack); }