mirror of https://github.com/PCSX2/pcsx2.git
parent
38edd77034
commit
ee5861efc8
|
@ -106,7 +106,6 @@ namespace GSPng {
|
||||||
|
|
||||||
bool Save(GSPng::Format fmt, const string& file, uint8* image, int w, int h, int pitch, bool rb_swapped)
|
bool Save(GSPng::Format fmt, const string& file, uint8* image, int w, int h, int pitch, bool rb_swapped)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_OGL_PNG
|
|
||||||
std::string root = file;
|
std::string root = file;
|
||||||
root.replace(file.length() - 4, 4, "");
|
root.replace(file.length() - 4, 4, "");
|
||||||
|
|
||||||
|
@ -124,9 +123,6 @@ namespace GSPng {
|
||||||
|
|
||||||
filename = root + pixel[fmt].extension[1];
|
filename = root + pixel[fmt].extension[1];
|
||||||
return SaveFile(filename, fmt, image, row.get(), w, h, pitch);
|
return SaveFile(filename, fmt, image, row.get(), w, h, pitch);
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Transaction::Transaction(GSPng::Format fmt, const string& file, const uint8* image, int w, int h, int pitch)
|
Transaction::Transaction(GSPng::Format fmt, const string& file, const uint8* image, int w, int h, int pitch)
|
||||||
|
|
|
@ -421,117 +421,12 @@ void GSTextureOGL::Unmap()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
struct BITMAPFILEHEADER
|
|
||||||
{
|
|
||||||
uint16 bfType;
|
|
||||||
uint32 bfSize;
|
|
||||||
uint16 bfReserved1;
|
|
||||||
uint16 bfReserved2;
|
|
||||||
uint32 bfOffBits;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BITMAPINFOHEADER
|
|
||||||
{
|
|
||||||
uint32 biSize;
|
|
||||||
int32 biWidth;
|
|
||||||
int32 biHeight;
|
|
||||||
uint16 biPlanes;
|
|
||||||
uint16 biBitCount;
|
|
||||||
uint32 biCompression;
|
|
||||||
uint32 biSizeImage;
|
|
||||||
int32 biXPelsPerMeter;
|
|
||||||
int32 biYPelsPerMeter;
|
|
||||||
uint32 biClrUsed;
|
|
||||||
uint32 biClrImportant;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BI_RGB 0
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
void GSTextureOGL::Save(const string& fn, const void* image, uint32 pitch)
|
|
||||||
{
|
|
||||||
// Build a BMP file
|
|
||||||
FILE* fp = fopen(fn.c_str(), "wb");
|
|
||||||
if (fp == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
BITMAPINFOHEADER bih;
|
|
||||||
|
|
||||||
memset(&bih, 0, sizeof(bih));
|
|
||||||
|
|
||||||
bih.biSize = sizeof(bih);
|
|
||||||
bih.biWidth = m_size.x;
|
|
||||||
bih.biHeight = m_size.y;
|
|
||||||
bih.biPlanes = 1;
|
|
||||||
bih.biBitCount = 32;
|
|
||||||
bih.biCompression = BI_RGB;
|
|
||||||
bih.biSizeImage = m_size.x * m_size.y << 2;
|
|
||||||
|
|
||||||
BITMAPFILEHEADER bfh;
|
|
||||||
|
|
||||||
memset(&bfh, 0, sizeof(bfh));
|
|
||||||
|
|
||||||
uint8* bfType = (uint8*)&bfh.bfType;
|
|
||||||
|
|
||||||
// bfh.bfType = 'MB';
|
|
||||||
bfType[0] = 0x42;
|
|
||||||
bfType[1] = 0x4d;
|
|
||||||
bfh.bfOffBits = sizeof(bfh) + sizeof(bih);
|
|
||||||
bfh.bfSize = bfh.bfOffBits + bih.biSizeImage;
|
|
||||||
bfh.bfReserved1 = bfh.bfReserved2 = 0;
|
|
||||||
|
|
||||||
fwrite(&bfh, 1, sizeof(bfh), fp);
|
|
||||||
fwrite(&bih, 1, sizeof(bih), fp);
|
|
||||||
|
|
||||||
uint8* data = (uint8*)image + (m_size.y - 1) * pitch;
|
|
||||||
|
|
||||||
for(int h = m_size.y; h > 0; h--, data -= pitch)
|
|
||||||
{
|
|
||||||
if (false && IsDss()) {
|
|
||||||
// Only get the depth and convert it to an integer
|
|
||||||
uint8* better_data = data;
|
|
||||||
for (int w = m_size.x; w > 0; w--, better_data += 8) {
|
|
||||||
float* input = (float*)better_data;
|
|
||||||
// FIXME how to dump 32 bits value into 8bits component color
|
|
||||||
GLuint depth_integer = (GLuint)(*input * (float)UINT_MAX);
|
|
||||||
uint8 r = (depth_integer >> 0) & 0xFF;
|
|
||||||
uint8 g = (depth_integer >> 8) & 0xFF;
|
|
||||||
uint8 b = (depth_integer >> 16) & 0xFF;
|
|
||||||
uint8 a = (depth_integer >> 24) & 0xFF;
|
|
||||||
|
|
||||||
fwrite(&r, 1, 1, fp);
|
|
||||||
fwrite(&g, 1, 1, fp);
|
|
||||||
fwrite(&b, 1, 1, fp);
|
|
||||||
fwrite(&a, 1, 1, fp);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// swap red and blue
|
|
||||||
uint8* better_data = data;
|
|
||||||
for (int w = m_size.x; w > 0; w--, better_data += 4) {
|
|
||||||
uint8 red = better_data[2];
|
|
||||||
better_data[2] = better_data[0];
|
|
||||||
better_data[0] = red;
|
|
||||||
fwrite(better_data, 1, 4, fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GSTextureOGL::Save(const string& fn, bool dds)
|
bool GSTextureOGL::Save(const string& fn, bool dds)
|
||||||
{
|
{
|
||||||
// Collect the texture data
|
// Collect the texture data
|
||||||
uint32 pitch = 4 * m_size.x;
|
uint32 pitch = 4 * m_size.x;
|
||||||
uint32 buf_size = pitch * m_size.y * 2;// Note *2 for security (depth/stencil)
|
uint32 buf_size = pitch * m_size.y * 2;// Note *2 for security (depth/stencil)
|
||||||
std::unique_ptr<uint8[]> image(new uint8[buf_size]);
|
std::unique_ptr<uint8[]> image(new uint8[buf_size]);
|
||||||
bool status = true;
|
|
||||||
#ifdef ENABLE_OGL_DEBUG
|
#ifdef ENABLE_OGL_DEBUG
|
||||||
GSPng::Format fmt = GSPng::RGB_A_PNG;
|
GSPng::Format fmt = GSPng::RGB_A_PNG;
|
||||||
#else
|
#else
|
||||||
|
@ -553,10 +448,6 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
|
||||||
glGetTextureImage(m_texture_id, 0, GL_RED_INTEGER, GL_INT, buf_size, image.get());
|
glGetTextureImage(m_texture_id, 0, GL_RED_INTEGER, GL_INT, buf_size, image.get());
|
||||||
|
|
||||||
fmt = GSPng::R32I_PNG;
|
fmt = GSPng::R32I_PNG;
|
||||||
|
|
||||||
// Not supported in Save function
|
|
||||||
status = false;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
||||||
|
|
||||||
|
@ -569,27 +460,17 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
|
||||||
{
|
{
|
||||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED_INTEGER, GL_UNSIGNED_SHORT, image.get());
|
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED_INTEGER, GL_UNSIGNED_SHORT, image.get());
|
||||||
fmt = GSPng::R16I_PNG;
|
fmt = GSPng::R16I_PNG;
|
||||||
// Not supported in Save function
|
|
||||||
status = false;
|
|
||||||
}
|
}
|
||||||
else if (m_format == GL_R8)
|
else if (m_format == GL_R8)
|
||||||
{
|
{
|
||||||
fmt = GSPng::R8I_PNG;
|
fmt = GSPng::R8I_PNG;
|
||||||
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED, GL_UNSIGNED_BYTE, image.get());
|
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED, GL_UNSIGNED_BYTE, image.get());
|
||||||
// Not supported in Save function
|
|
||||||
status = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_OGL_PNG
|
return GSPng::Save(fmt, fn, image.get(), m_size.x, m_size.y, pitch);
|
||||||
status = GSPng::Save(fmt, fn, image.get(), m_size.x, m_size.y, pitch);
|
|
||||||
#else
|
|
||||||
if (status) Save(fn, image.get(), pitch);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GSTextureOGL::GetMemUsage()
|
uint32 GSTextureOGL::GetMemUsage()
|
||||||
|
|
|
@ -64,7 +64,6 @@ class GSTextureOGL : public GSTexture
|
||||||
bool Map(GSMap& m, const GSVector4i* r = NULL);
|
bool Map(GSMap& m, const GSVector4i* r = NULL);
|
||||||
void Unmap();
|
void Unmap();
|
||||||
bool Save(const string& fn, bool dds = false);
|
bool Save(const string& fn, bool dds = false);
|
||||||
void Save(const string& fn, const void* image, uint32 pitch);
|
|
||||||
|
|
||||||
bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); }
|
bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); }
|
||||||
bool IsDss() { return (m_type == GSTexture::DepthStencil); }
|
bool IsDss() { return (m_type == GSTexture::DepthStencil); }
|
||||||
|
|
|
@ -85,105 +85,14 @@ void GSTextureSW::Unmap()
|
||||||
m_mapped.clear();
|
m_mapped.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
struct BITMAPFILEHEADER
|
|
||||||
{
|
|
||||||
uint16 bfType;
|
|
||||||
uint32 bfSize;
|
|
||||||
uint16 bfReserved1;
|
|
||||||
uint16 bfReserved2;
|
|
||||||
uint32 bfOffBits;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BITMAPINFOHEADER
|
|
||||||
{
|
|
||||||
uint32 biSize;
|
|
||||||
int32 biWidth;
|
|
||||||
int32 biHeight;
|
|
||||||
uint16 biPlanes;
|
|
||||||
uint16 biBitCount;
|
|
||||||
uint32 biCompression;
|
|
||||||
uint32 biSizeImage;
|
|
||||||
int32 biXPelsPerMeter;
|
|
||||||
int32 biYPelsPerMeter;
|
|
||||||
uint32 biClrUsed;
|
|
||||||
uint32 biClrImportant;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BI_RGB 0
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool GSTextureSW::Save(const string& fn, bool dds)
|
bool GSTextureSW::Save(const string& fn, bool dds)
|
||||||
{
|
{
|
||||||
if(dds) return false; // not implemented
|
if(dds) return false; // not implemented
|
||||||
|
|
||||||
#ifdef ENABLE_OGL_PNG
|
|
||||||
|
|
||||||
#ifdef ENABLE_OGL_DEBUG
|
#ifdef ENABLE_OGL_DEBUG
|
||||||
GSPng::Format fmt = GSPng::RGB_A_PNG;
|
GSPng::Format fmt = GSPng::RGB_A_PNG;
|
||||||
#else
|
#else
|
||||||
GSPng::Format fmt = GSPng::RGB_PNG;
|
GSPng::Format fmt = GSPng::RGB_PNG;
|
||||||
#endif
|
#endif
|
||||||
return GSPng::Save(fmt, fn, static_cast<uint8*>(m_data), m_size.x, m_size.y, m_pitch);
|
return GSPng::Save(fmt, fn, static_cast<uint8*>(m_data), m_size.x, m_size.y, m_pitch);
|
||||||
|
|
||||||
#else
|
|
||||||
if(FILE* fp = fopen(fn.c_str(), "wb"))
|
|
||||||
{
|
|
||||||
BITMAPINFOHEADER bih;
|
|
||||||
|
|
||||||
memset(&bih, 0, sizeof(bih));
|
|
||||||
|
|
||||||
bih.biSize = sizeof(bih);
|
|
||||||
bih.biWidth = m_size.x;
|
|
||||||
bih.biHeight = m_size.y;
|
|
||||||
bih.biPlanes = 1;
|
|
||||||
bih.biBitCount = 32;
|
|
||||||
bih.biCompression = BI_RGB;
|
|
||||||
bih.biSizeImage = m_size.x * m_size.y << 2;
|
|
||||||
|
|
||||||
BITMAPFILEHEADER bfh;
|
|
||||||
|
|
||||||
memset(&bfh, 0, sizeof(bfh));
|
|
||||||
|
|
||||||
uint8* bfType = (uint8*)&bfh.bfType;
|
|
||||||
|
|
||||||
// bfh.bfType = 'MB';
|
|
||||||
bfType[0] = 0x42;
|
|
||||||
bfType[1] = 0x4d;
|
|
||||||
bfh.bfOffBits = sizeof(bfh) + sizeof(bih);
|
|
||||||
bfh.bfSize = bfh.bfOffBits + bih.biSizeImage;
|
|
||||||
bfh.bfReserved1 = bfh.bfReserved2 = 0;
|
|
||||||
|
|
||||||
fwrite(&bfh, 1, sizeof(bfh), fp);
|
|
||||||
fwrite(&bih, 1, sizeof(bih), fp);
|
|
||||||
|
|
||||||
uint8* data = (uint8*)m_data + (m_size.y - 1) * m_pitch;
|
|
||||||
|
|
||||||
for(int h = m_size.y; h > 0; h--, data -= m_pitch)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < m_size.x; i++)
|
|
||||||
{
|
|
||||||
uint32 c = ((uint32*)data)[i];
|
|
||||||
|
|
||||||
c = (c & 0xff00ff00) | ((c & 0x00ff0000) >> 16) | ((c & 0x000000ff) << 16);
|
|
||||||
|
|
||||||
fwrite(&c, 1, sizeof(c), fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fwrite(data, 1, m_size.x << 2, fp); // TODO: swap red-blue?
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,9 +52,3 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
//#define ENABLE_OPENCL
|
//#define ENABLE_OPENCL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(__linux__) && PNGPP_SUPPORTED) || defined(_WIN32)
|
|
||||||
// Allow to dump texture as PNG (require libpng++). It reduces the size of the dump
|
|
||||||
// and alpha is well supported (on linux)
|
|
||||||
#define ENABLE_OGL_PNG
|
|
||||||
#endif
|
|
||||||
|
|
Loading…
Reference in New Issue