[OGL] Textures now save to PNG not TGA
This commit is contained in:
parent
15bb974224
commit
3a13dfdd9b
|
@ -1627,7 +1627,7 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangle& r
|
||||||
|
|
||||||
// For testing zbuffer targets.
|
// For testing zbuffer targets.
|
||||||
// Renderer::SetZBufferRender();
|
// Renderer::SetZBufferRender();
|
||||||
// SaveTexture("tex.tga", GL_TEXTURE_2D, s_FakeZTarget,
|
// SaveTexture("tex.png", GL_TEXTURE_2D, s_FakeZTarget,
|
||||||
// GetTargetWidth(), GetTargetHeight());
|
// GetTargetWidth(), GetTargetHeight());
|
||||||
Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB));
|
Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB));
|
||||||
XFBWrited = false;
|
XFBWrited = false;
|
||||||
|
|
|
@ -64,10 +64,10 @@ bool SaveTexture(const char* filename, u32 textarget, u32 tex, int virtual_width
|
||||||
#ifndef USE_GLES3
|
#ifndef USE_GLES3
|
||||||
int width = std::max(virtual_width >> level, 1);
|
int width = std::max(virtual_width >> level, 1);
|
||||||
int height = std::max(virtual_height >> level, 1);
|
int height = std::max(virtual_height >> level, 1);
|
||||||
std::vector<u32> data(width * height);
|
u8* data = new u8[width * height * 4];
|
||||||
glActiveTexture(GL_TEXTURE0+9);
|
glActiveTexture(GL_TEXTURE0+9);
|
||||||
glBindTexture(textarget, tex);
|
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);
|
glBindTexture(textarget, 0);
|
||||||
TextureCache::SetStage();
|
TextureCache::SetStage();
|
||||||
|
|
||||||
|
@ -75,10 +75,11 @@ bool SaveTexture(const char* filename, u32 textarget, u32 tex, int virtual_width
|
||||||
if (GL_NO_ERROR != err)
|
if (GL_NO_ERROR != err)
|
||||||
{
|
{
|
||||||
PanicAlert("Can't save texture, GL Error: %s", gluErrorString(err));
|
PanicAlert("Can't save texture, GL Error: %s", gluErrorString(err));
|
||||||
|
delete[] data;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SaveTGA(filename, width, height, &data[0]);
|
return TextureToPng(data, width*4, filename, width, height, true);
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
@ -127,11 +128,7 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
||||||
|
|
||||||
bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level)
|
bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level)
|
||||||
{
|
{
|
||||||
// TODO: make ogl dump PNGs
|
return SaveTexture(filename, GL_TEXTURE_2D, texture, virtual_width, virtual_height, level);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
||||||
|
@ -395,7 +392,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
if (g_ActiveConfig.bDumpEFBTarget)
|
if (g_ActiveConfig.bDumpEFBTarget)
|
||||||
{
|
{
|
||||||
static int count = 0;
|
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);
|
count++).c_str(), GL_TEXTURE_2D, texture, virtual_width, virtual_height, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -335,7 +335,7 @@ void VertexManager::vFlush()
|
||||||
if (g_ActiveConfig.iLog & CONF_SAVETARGETS)
|
if (g_ActiveConfig.iLog & CONF_SAVETARGETS)
|
||||||
{
|
{
|
||||||
char str[128];
|
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;
|
TargetRectangle tr;
|
||||||
tr.left = 0;
|
tr.left = 0;
|
||||||
tr.right = Renderer::GetTargetWidth();
|
tr.right = Renderer::GetTargetWidth();
|
||||||
|
|
|
@ -54,28 +54,20 @@ void SaveTexture(const char* filename, u32 texmap, s32 mip)
|
||||||
|
|
||||||
u8 *data = new u8[width * height * 4];
|
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 y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
for (u32 x = 0; x < width; x++)
|
for (u32 x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
TextureSampler::SampleMip(x << 7, y << 7, mip, false, texmap, sample);
|
TextureSampler::SampleMip(x << 7, y << 7, mip, false, texmap, dst);
|
||||||
|
dst += 4;
|
||||||
// RGBA to BGRA
|
|
||||||
*(dst++) = sample[2];
|
|
||||||
*(dst++) = sample[1];
|
|
||||||
*(dst++) = sample[0];
|
|
||||||
*(dst++) = sample[3];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +96,7 @@ void DumpActiveTextures()
|
||||||
s32 maxLod = GetMaxTextureLod(texmap);
|
s32 maxLod = GetMaxTextureLod(texmap);
|
||||||
for (s32 mip = 0; mip <= maxLod; ++mip)
|
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(),
|
File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
|
||||||
swstats.thisFrame.numDrawnObjects, stageNum, texmap, mip).c_str(), texmap, mip);
|
swstats.thisFrame.numDrawnObjects, stageNum, texmap, mip).c_str(), texmap, mip);
|
||||||
}
|
}
|
||||||
|
@ -121,7 +113,7 @@ void DumpActiveTextures()
|
||||||
s32 maxLod = GetMaxTextureLod(texmap);
|
s32 maxLod = GetMaxTextureLod(texmap);
|
||||||
for (s32 mip = 0; mip <= maxLod; ++mip)
|
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(),
|
File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
|
||||||
swstats.thisFrame.numDrawnObjects, stageNum, texmap, mip).c_str(), texmap, mip);
|
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++)
|
for (int x = 0; x < EFB_WIDTH; x++)
|
||||||
{
|
{
|
||||||
EfbInterface::GetColor(x, y, sample);
|
EfbInterface::GetColor(x, y, sample);
|
||||||
// ABGR to BGRA
|
// ABGR to RGBA
|
||||||
*(writePtr++) = sample[1];
|
|
||||||
*(writePtr++) = sample[2];
|
|
||||||
*(writePtr++) = sample[3];
|
*(writePtr++) = sample[3];
|
||||||
|
*(writePtr++) = sample[2];
|
||||||
|
*(writePtr++) = sample[1];
|
||||||
*(writePtr++) = sample[0];
|
*(writePtr++) = sample[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)SaveTGA(filename, EFB_WIDTH, EFB_HEIGHT, data);
|
(void)TextureToPng(data, EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true);
|
||||||
|
|
||||||
delete []data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DumpDepth(const char* filename)
|
void DumpDepth(const char* filename)
|
||||||
|
@ -162,17 +152,15 @@ void DumpDepth(const char* filename)
|
||||||
for (int x = 0; x < EFB_WIDTH; x++)
|
for (int x = 0; x < EFB_WIDTH; x++)
|
||||||
{
|
{
|
||||||
u32 depth = EfbInterface::GetDepth(x, y);
|
u32 depth = EfbInterface::GetDepth(x, y);
|
||||||
// depth to bgra
|
// depth to rgba
|
||||||
*(writePtr++) = (depth >> 16) & 0xff;
|
*(writePtr++) = depth & 0xff;
|
||||||
*(writePtr++) = (depth >> 8) & 0xff;
|
*(writePtr++) = (depth >> 8) & 0xff;
|
||||||
*(writePtr++) = depth & 0xff;
|
*(writePtr++) = (depth >> 16) & 0xff;
|
||||||
*(writePtr++) = 255;
|
*(writePtr++) = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)SaveTGA(filename, EFB_WIDTH, EFB_HEIGHT, data);
|
(void)TextureToPng(data, EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true);
|
||||||
|
|
||||||
delete []data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name)
|
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_bSkipCurrentFrame)
|
||||||
{
|
{
|
||||||
if (g_SWVideoConfig.bDumpObjects && swstats.thisFrame.numDrawnObjects >= g_SWVideoConfig.drawStart && swstats.thisFrame.numDrawnObjects < g_SWVideoConfig.drawEnd)
|
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(),
|
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
|
||||||
swstats.thisFrame.numDrawnObjects).c_str());
|
swstats.thisFrame.numDrawnObjects).c_str());
|
||||||
|
|
||||||
|
@ -247,10 +235,11 @@ void OnObjectEnd()
|
||||||
if (DrawnToBuffer[i])
|
if (DrawnToBuffer[i])
|
||||||
{
|
{
|
||||||
DrawnToBuffer[i] = false;
|
DrawnToBuffer[i] = false;
|
||||||
(void)SaveTGA(StringFromFormat("%sobject%i_%s(%i).tga",
|
std::string filename = StringFromFormat("%sobject%i_%s(%i).png",
|
||||||
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
|
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
|
||||||
swstats.thisFrame.numDrawnObjects, ObjectBufferName[i], i - BufferBase[i]).c_str(),
|
swstats.thisFrame.numDrawnObjects, ObjectBufferName[i], i - BufferBase[i]);
|
||||||
EFB_WIDTH, EFB_HEIGHT, ObjectBuffer[i]);
|
|
||||||
|
(void)TextureToPng((u8*)ObjectBuffer[i], EFB_WIDTH * 4, filename.c_str(), EFB_WIDTH, EFB_HEIGHT, true);
|
||||||
memset(ObjectBuffer[i], 0, sizeof(ObjectBuffer[i]));
|
memset(ObjectBuffer[i], 0, sizeof(ObjectBuffer[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,9 +254,9 @@ void OnFrameEnd()
|
||||||
{
|
{
|
||||||
if (g_SWVideoConfig.bDumpFrames)
|
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());
|
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());
|
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace DebugUtil
|
||||||
{
|
{
|
||||||
void Init();
|
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();
|
void DumpActiveTextures();
|
||||||
|
|
||||||
|
|
|
@ -329,15 +329,12 @@ namespace HwRasterizer
|
||||||
int image_width = texImage0.width;
|
int image_width = texImage0.width;
|
||||||
int image_height = texImage0.height;
|
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);
|
glGenTextures(1, (GLuint *)&texture);
|
||||||
glBindTexture(TEX2D, 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);
|
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();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,52 +9,6 @@
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
#include "FileUtil.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)
|
bool SaveData(const char* filename, const char* data)
|
||||||
{
|
{
|
||||||
std::ofstream f;
|
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)
|
// Open file for writing (binary mode)
|
||||||
fp = fopen(filename, "wb");
|
fp = fopen(filename, "wb");
|
||||||
if (fp == NULL) {
|
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;
|
goto finalise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
bool SaveTGA(const char* filename, int width, int height, void* pdata);
|
|
||||||
bool SaveData(const char* filename, const char* 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);
|
bool TextureToPng(u8* data, int row_stride, const char* filename, int width, int height, bool saveAlpha = true);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue