Skip to content

Commit 1bbfb51

Browse files
committed
xrRenderGL: implement TGA screenshot for normal mode
1 parent 9ed96c5 commit 1bbfb51

File tree

1 file changed

+63
-2
lines changed

1 file changed

+63
-2
lines changed

src/Layers/xrRender/r__screenshot.cpp

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,71 @@ IC void MouseRayFromPoint(Fvector& direction, int x, int y, Fmatrix& m_CamMat)
4242
#define SM_FOR_SEND_HEIGHT 480
4343

4444
#if defined(USE_OGL)
45+
// XXX: remove
46+
// Temporary solution based on:
47+
// http://masandilov.ru/opengl/ScreenShots
48+
void WriteTGA(IWriter* file)
49+
{
50+
const u32 width = psCurrentVidMode[0];
51+
const u32 height = psCurrentVidMode[1];
52+
53+
constexpr u32 colorMode = 3;
54+
const u32 size = width * height * colorMode;
55+
56+
auto output = new u8[size];
57+
58+
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, output);
59+
60+
const u8 tgaHeader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
61+
62+
constexpr u8 bits = 24;
63+
constexpr u8 flipped = 32;
64+
65+
u8 header[6];
66+
header[0] = width % 256;
67+
header[1] = width / 256;
68+
header[2] = height % 256;
69+
header[3] = height / 256;
70+
header[4] = bits;
71+
header[5] = flipped;
72+
73+
file->w(tgaHeader, sizeof(tgaHeader));
74+
file->w(header, sizeof(header));
75+
76+
// TGA format used BGR instead of RGB
77+
for (u32 i = 0; i < size; i += colorMode)
78+
std::swap(output[i], output[i + 2]);
79+
80+
file->w(output, size);
81+
xr_delete(output);
82+
}
83+
84+
// XXX: Provide full implementation
4585
void CRender::ScreenshotImpl(ScreenshotMode mode, LPCSTR name, CMemoryWriter* memory_writer)
4686
{
47-
// TODO: OGL: Implement screenshot feature.
48-
VERIFY(!"CRender::ScreenshotImpl not implemented.");
87+
switch (mode)
88+
{
89+
case SM_NORMAL:
90+
{
91+
string64 time;
92+
string_path buf;
93+
xr_sprintf(buf, sizeof(buf), "ss_%s_%s_(%s).tga", Core.UserName, timestamp(time),
94+
g_pGameLevel ? g_pGameLevel->name().c_str() : "mainmenu");
95+
96+
IWriter* fs = FS.w_open("$screenshots$", buf);
97+
R_ASSERT(fs);
98+
WriteTGA(fs);
99+
FS.w_close(fs);
100+
101+
return;
102+
}
103+
104+
case SM_FOR_CUBEMAP:
105+
case SM_FOR_GAMESAVE:
106+
case SM_FOR_LEVELMAP:
107+
case SM_FOR_MPSENDING:
108+
VERIFY(!"CRender::Screenshot. This screenshot type is not supported for OGL.");
109+
}
49110
}
50111
#elif defined(USE_DX10) || defined(USE_DX11)
51112
void CRender::ScreenshotImpl(ScreenshotMode mode, LPCSTR name, CMemoryWriter* memory_writer)

0 commit comments

Comments
 (0)