diff --git a/Source/Core/VideoBackends/OGL/Src/Render.cpp b/Source/Core/VideoBackends/OGL/Src/Render.cpp index b32fc74f34..784e2612bf 100644 --- a/Source/Core/VideoBackends/OGL/Src/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Src/Render.cpp @@ -1627,7 +1627,7 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangle& r // For testing zbuffer targets. // Renderer::SetZBufferRender(); - // SaveTexture("tex.tga", GL_TEXTURE_2D, s_FakeZTarget, + // SaveTexture("tex.png", GL_TEXTURE_2D, s_FakeZTarget, // GetTargetWidth(), GetTargetHeight()); Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB)); XFBWrited = false; diff --git a/Source/Core/VideoBackends/OGL/Src/TextureCache.cpp b/Source/Core/VideoBackends/OGL/Src/TextureCache.cpp index 41c52ec724..0c4fe8a187 100644 --- a/Source/Core/VideoBackends/OGL/Src/TextureCache.cpp +++ b/Source/Core/VideoBackends/OGL/Src/TextureCache.cpp @@ -64,10 +64,10 @@ bool SaveTexture(const char* filename, u32 textarget, u32 tex, int virtual_width #ifndef USE_GLES3 int width = std::max(virtual_width >> level, 1); int height = std::max(virtual_height >> level, 1); - std::vector data(width * height); + u8* data = new u8[width * height * 4]; glActiveTexture(GL_TEXTURE0+9); glBindTexture(textarget, tex); - glGetTexImage(textarget, level, GL_BGRA, GL_UNSIGNED_BYTE, &data[0]); + glGetTexImage(textarget, level, GL_RGBA, GL_UNSIGNED_BYTE, data); glBindTexture(textarget, 0); TextureCache::SetStage(); @@ -75,10 +75,11 @@ bool SaveTexture(const char* filename, u32 textarget, u32 tex, int virtual_width if (GL_NO_ERROR != err) { PanicAlert("Can't save texture, GL Error: %s", gluErrorString(err)); + delete[] data; return false; } - return SaveTGA(filename, width, height, &data[0]); + return TextureToPng(data, width*4, filename, width, height, true); #else return false; #endif @@ -127,11 +128,7 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage) bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level) { - // TODO: make ogl dump PNGs - std::string tga_filename(filename); - tga_filename.replace(tga_filename.size() - 3, 3, "tga"); - - return SaveTexture(tga_filename.c_str(), GL_TEXTURE_2D, texture, virtual_width, virtual_height, level); + return SaveTexture(filename, GL_TEXTURE_2D, texture, virtual_width, virtual_height, level); } TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, @@ -395,7 +392,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo if (g_ActiveConfig.bDumpEFBTarget) { static int count = 0; - SaveTexture(StringFromFormat("%sefb_frame_%i.tga", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(), + SaveTexture(StringFromFormat("%sefb_frame_%i.png", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(), count++).c_str(), GL_TEXTURE_2D, texture, virtual_width, virtual_height, 0); } diff --git a/Source/Core/VideoBackends/OGL/Src/VertexManager.cpp b/Source/Core/VideoBackends/OGL/Src/VertexManager.cpp index 438eff890d..1ff9b53e28 100644 --- a/Source/Core/VideoBackends/OGL/Src/VertexManager.cpp +++ b/Source/Core/VideoBackends/OGL/Src/VertexManager.cpp @@ -335,7 +335,7 @@ void VertexManager::vFlush() if (g_ActiveConfig.iLog & CONF_SAVETARGETS) { char str[128]; - sprintf(str, "%starg%.3d.tga", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), g_ActiveConfig.iSaveTargetId); + sprintf(str, "%starg%.3d.png", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), g_ActiveConfig.iSaveTargetId); TargetRectangle tr; tr.left = 0; tr.right = Renderer::GetTargetWidth(); diff --git a/Source/Core/VideoBackends/Software/Src/DebugUtil.cpp b/Source/Core/VideoBackends/Software/Src/DebugUtil.cpp index 4472639a20..3f21e6a758 100644 --- a/Source/Core/VideoBackends/Software/Src/DebugUtil.cpp +++ b/Source/Core/VideoBackends/Software/Src/DebugUtil.cpp @@ -54,28 +54,20 @@ void SaveTexture(const char* filename, u32 texmap, s32 mip) u8 *data = new u8[width * height * 4]; - GetTextureBGRA(data, texmap, mip, width, height); + GetTextureRGBA(data, texmap, mip, width, height); - (void)SaveTGA(filename, width, height, data); + (void)TextureToPng(data, width*4, filename, width, height, true); - delete []data; } -void GetTextureBGRA(u8 *dst, u32 texmap, s32 mip, u32 width, u32 height) +void GetTextureRGBA(u8 *dst, u32 texmap, s32 mip, u32 width, u32 height) { - u8 sample[4]; - for (u32 y = 0; y < height; y++) { for (u32 x = 0; x < width; x++) { - TextureSampler::SampleMip(x << 7, y << 7, mip, false, texmap, sample); - - // RGBA to BGRA - *(dst++) = sample[2]; - *(dst++) = sample[1]; - *(dst++) = sample[0]; - *(dst++) = sample[3]; + TextureSampler::SampleMip(x << 7, y << 7, mip, false, texmap, dst); + dst += 4; } } } @@ -104,7 +96,7 @@ void DumpActiveTextures() s32 maxLod = GetMaxTextureLod(texmap); for (s32 mip = 0; mip <= maxLod; ++mip) { - SaveTexture(StringFromFormat("%star%i_ind%i_map%i_mip%i.tga", + SaveTexture(StringFromFormat("%star%i_ind%i_map%i_mip%i.png", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(), swstats.thisFrame.numDrawnObjects, stageNum, texmap, mip).c_str(), texmap, mip); } @@ -121,7 +113,7 @@ void DumpActiveTextures() s32 maxLod = GetMaxTextureLod(texmap); for (s32 mip = 0; mip <= maxLod; ++mip) { - SaveTexture(StringFromFormat("%star%i_stage%i_map%i_mip%i.tga", + SaveTexture(StringFromFormat("%star%i_stage%i_map%i_mip%i.png", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(), swstats.thisFrame.numDrawnObjects, stageNum, texmap, mip).c_str(), texmap, mip); } @@ -139,17 +131,15 @@ void DumpEfb(const char* filename) for (int x = 0; x < EFB_WIDTH; x++) { EfbInterface::GetColor(x, y, sample); - // ABGR to BGRA - *(writePtr++) = sample[1]; - *(writePtr++) = sample[2]; + // ABGR to RGBA *(writePtr++) = sample[3]; + *(writePtr++) = sample[2]; + *(writePtr++) = sample[1]; *(writePtr++) = sample[0]; } } - (void)SaveTGA(filename, EFB_WIDTH, EFB_HEIGHT, data); - - delete []data; + (void)TextureToPng(data, EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true); } void DumpDepth(const char* filename) @@ -162,17 +152,15 @@ void DumpDepth(const char* filename) for (int x = 0; x < EFB_WIDTH; x++) { u32 depth = EfbInterface::GetDepth(x, y); - // depth to bgra - *(writePtr++) = (depth >> 16) & 0xff; + // depth to rgba + *(writePtr++) = depth & 0xff; *(writePtr++) = (depth >> 8) & 0xff; - *(writePtr++) = depth & 0xff; + *(writePtr++) = (depth >> 16) & 0xff; *(writePtr++) = 255; } } - (void)SaveTGA(filename, EFB_WIDTH, EFB_HEIGHT, data); - - delete []data; + (void)TextureToPng(data, EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true); } void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name) @@ -232,7 +220,7 @@ void OnObjectEnd() if (!g_bSkipCurrentFrame) { if (g_SWVideoConfig.bDumpObjects && swstats.thisFrame.numDrawnObjects >= g_SWVideoConfig.drawStart && swstats.thisFrame.numDrawnObjects < g_SWVideoConfig.drawEnd) - DumpEfb(StringFromFormat("%sobject%i.tga", + DumpEfb(StringFromFormat("%sobject%i.png", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.thisFrame.numDrawnObjects).c_str()); @@ -247,10 +235,11 @@ void OnObjectEnd() if (DrawnToBuffer[i]) { DrawnToBuffer[i] = false; - (void)SaveTGA(StringFromFormat("%sobject%i_%s(%i).tga", - File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), - swstats.thisFrame.numDrawnObjects, ObjectBufferName[i], i - BufferBase[i]).c_str(), - EFB_WIDTH, EFB_HEIGHT, ObjectBuffer[i]); + std::string filename = StringFromFormat("%sobject%i_%s(%i).png", + File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), + swstats.thisFrame.numDrawnObjects, ObjectBufferName[i], i - BufferBase[i]); + + (void)TextureToPng((u8*)ObjectBuffer[i], EFB_WIDTH * 4, filename.c_str(), EFB_WIDTH, EFB_HEIGHT, true); memset(ObjectBuffer[i], 0, sizeof(ObjectBuffer[i])); } } @@ -265,9 +254,9 @@ void OnFrameEnd() { if (g_SWVideoConfig.bDumpFrames) { - DumpEfb(StringFromFormat("%sframe%i_color.tga", + DumpEfb(StringFromFormat("%sframe%i_color.png", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount).c_str()); - DumpDepth(StringFromFormat("%sframe%i_depth.tga", + DumpDepth(StringFromFormat("%sframe%i_depth.png", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount).c_str()); } } diff --git a/Source/Core/VideoBackends/Software/Src/DebugUtil.h b/Source/Core/VideoBackends/Software/Src/DebugUtil.h index 3cbb318ffb..7d5ac4beea 100644 --- a/Source/Core/VideoBackends/Software/Src/DebugUtil.h +++ b/Source/Core/VideoBackends/Software/Src/DebugUtil.h @@ -9,7 +9,7 @@ namespace DebugUtil { void Init(); - void GetTextureBGRA(u8 *dst, u32 texmap, s32 mip, u32 width, u32 height); + void GetTextureRGBA(u8 *dst, u32 texmap, s32 mip, u32 width, u32 height); void DumpActiveTextures(); diff --git a/Source/Core/VideoBackends/Software/Src/HwRasterizer.cpp b/Source/Core/VideoBackends/Software/Src/HwRasterizer.cpp index 996b440dc4..88b3e15ebd 100644 --- a/Source/Core/VideoBackends/Software/Src/HwRasterizer.cpp +++ b/Source/Core/VideoBackends/Software/Src/HwRasterizer.cpp @@ -329,15 +329,12 @@ namespace HwRasterizer int image_width = texImage0.width; int image_height = texImage0.height; - DebugUtil::GetTextureBGRA(temp, 0, 0, image_width, image_height); + DebugUtil::GetTextureRGBA(temp, 0, 0, image_width, image_height); glGenTextures(1, (GLuint *)&texture); glBindTexture(TEX2D, texture); -#ifdef USE_GLES glTexImage2D(TEX2D, 0, GL_RGBA, (GLsizei)image_width, (GLsizei)image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp); -#else - glTexImage2D(TEX2D, 0, GL_RGBA8, (GLsizei)image_width, (GLsizei)image_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, temp); -#endif + GL_REPORT_ERRORD(); } diff --git a/Source/Core/VideoCommon/Src/ImageWrite.cpp b/Source/Core/VideoCommon/Src/ImageWrite.cpp index b00975e615..5bf3f28e45 100644 --- a/Source/Core/VideoCommon/Src/ImageWrite.cpp +++ b/Source/Core/VideoCommon/Src/ImageWrite.cpp @@ -9,52 +9,6 @@ #include "ImageWrite.h" #include "FileUtil.h" -#pragma pack(push, 1) - -struct TGA_HEADER -{ - u8 identsize; // size of ID field that follows 18 u8 header (0 usually) - u8 colourmaptype; // type of colour map 0=none, 1=has palette - u8 imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed - - s16 colourmapstart; // first colour map entry in palette - s16 colourmaplength; // number of colours in palette - u8 colourmapbits; // number of bits per palette entry 15,16,24,32 - - s16 xstart; // image x origin - s16 ystart; // image y origin - s16 width; // image width in pixels - s16 height; // image height in pixels - u8 bits; // image bits per pixel 8,16,24,32 - u8 descriptor; // image descriptor bits (vh flip bits) - - // pixel data follows header -}; - -#pragma pack(pop) - -bool SaveTGA(const char* filename, int width, int height, void* pdata) -{ - TGA_HEADER hdr; - File::IOFile f(filename, "wb"); - if (!f) - return false; - - _assert_(sizeof(TGA_HEADER) == 18 && sizeof(hdr) == 18); - - memset(&hdr, 0, sizeof(hdr)); - hdr.imagetype = 2; - hdr.bits = 32; - hdr.width = width; - hdr.height = height; - hdr.descriptor |= 8|(1<<5); // 8bit alpha, flip vertical - - f.WriteArray(&hdr, 1); - f.WriteBytes(pdata, width * height * 4); - - return true; -} - bool SaveData(const char* filename, const char* data) { std::ofstream f; @@ -90,7 +44,7 @@ bool TextureToPng(u8* data, int row_stride, const char* filename, int width, int // Open file for writing (binary mode) fp = fopen(filename, "wb"); if (fp == NULL) { - PanicAlert("Screenshot failed: Could not open file %s\n", filename); + PanicAlert("Screenshot failed: Could not open file %s %d\n", filename, errno); goto finalise; } diff --git a/Source/Core/VideoCommon/Src/ImageWrite.h b/Source/Core/VideoCommon/Src/ImageWrite.h index af7f11ad27..82a942c767 100644 --- a/Source/Core/VideoCommon/Src/ImageWrite.h +++ b/Source/Core/VideoCommon/Src/ImageWrite.h @@ -7,7 +7,6 @@ #include "Common.h" -bool SaveTGA(const char* filename, int width, int height, void* pdata); bool SaveData(const char* filename, const char* pdata); bool TextureToPng(u8* data, int row_stride, const char* filename, int width, int height, bool saveAlpha = true);