mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
fixed shutdown and screenshot functionallity
This commit is contained in:
parent
c1942ca6cb
commit
d7fe3ddaab
|
@ -203,6 +203,43 @@ class CCommandProcessorFragment_OpenGL
|
|||
};
|
||||
}
|
||||
|
||||
void Cmd_Screenshot(const CCommandBuffer::SCommand_Screenshot *pCommand)
|
||||
{
|
||||
// fetch image data
|
||||
GLint aViewport[4] = {0,0,0,0};
|
||||
glGetIntegerv(GL_VIEWPORT, aViewport);
|
||||
|
||||
int w = aViewport[2];
|
||||
int h = aViewport[3];
|
||||
|
||||
dbg_msg("graphics", "grabbing %d x %d", w, h);
|
||||
|
||||
// we allocate one more row to use when we are flipping the texture
|
||||
unsigned char *pPixelData = (unsigned char *)mem_alloc(w*(h+1)*3, 1);
|
||||
unsigned char *pTempRow = pPixelData+w*h*3;
|
||||
|
||||
// fetch the pixels
|
||||
GLint Alignment;
|
||||
glGetIntegerv(GL_PACK_ALIGNMENT, &Alignment);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(0,0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pPixelData);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, Alignment);
|
||||
|
||||
// flip the pixel because opengl works from bottom left corner
|
||||
for(int y = 0; y < h/2; y++)
|
||||
{
|
||||
mem_copy(pTempRow, pPixelData+y*w*3, w*3);
|
||||
mem_copy(pPixelData+y*w*3, pPixelData+(h-y-1)*w*3, w*3);
|
||||
mem_copy(pPixelData+(h-y-1)*w*3, pTempRow,w*3);
|
||||
}
|
||||
|
||||
// fill in the information
|
||||
pCommand->m_pImage->m_Width = w;
|
||||
pCommand->m_pImage->m_Height = h;
|
||||
pCommand->m_pImage->m_Format = CImageInfo::FORMAT_RGB;
|
||||
pCommand->m_pImage->m_pData = pPixelData;
|
||||
}
|
||||
|
||||
public:
|
||||
CCommandProcessorFragment_OpenGL()
|
||||
{
|
||||
|
@ -218,6 +255,7 @@ public:
|
|||
case CCommandBuffer::CMD_TEXTURE_UPDATE: Cmd_Texture_Update(static_cast<const CCommandBuffer::SCommand_Texture_Update *>(pBaseCommand)); break;
|
||||
case CCommandBuffer::CMD_CLEAR: Cmd_Clear(static_cast<const CCommandBuffer::SCommand_Clear *>(pBaseCommand)); break;
|
||||
case CCommandBuffer::CMD_RENDER: Cmd_Render(static_cast<const CCommandBuffer::SCommand_Render *>(pBaseCommand)); break;
|
||||
case CCommandBuffer::CMD_SCREENSHOT: Cmd_Screenshot(static_cast<const CCommandBuffer::SCommand_Screenshot *>(pBaseCommand)); break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
|
@ -415,6 +453,14 @@ void CCommandProcessorHandler::Start(ICommandProcessor *pProcessor)
|
|||
m_BufferDone.signal();
|
||||
}
|
||||
|
||||
void CCommandProcessorHandler::Stop()
|
||||
{
|
||||
m_Shutdown = true;
|
||||
m_Activity.signal();
|
||||
thread_wait(m_pThread);
|
||||
thread_destroy(m_pThread);
|
||||
}
|
||||
|
||||
void CCommandProcessorHandler::RunBuffer(CCommandBuffer *pBuffer)
|
||||
{
|
||||
WaitForIdle();
|
||||
|
@ -428,7 +474,7 @@ void CCommandProcessorHandler::WaitForIdle()
|
|||
m_BufferDone.wait();
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::Flush()
|
||||
void CGraphics_Threaded::FlushVertices()
|
||||
{
|
||||
if(m_NumVertices == 0)
|
||||
return;
|
||||
|
@ -464,7 +510,7 @@ void CGraphics_Threaded::AddVertices(int Count)
|
|||
{
|
||||
m_NumVertices += Count;
|
||||
if((m_NumVertices + Count) >= MAX_VERTICES)
|
||||
Flush();
|
||||
FlushVertices();
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::Rotate4(const CCommandBuffer::SPoint &rCenter, CCommandBuffer::SVertex *pPoints)
|
||||
|
@ -622,7 +668,7 @@ void CGraphics_Threaded::LinesBegin()
|
|||
void CGraphics_Threaded::LinesEnd()
|
||||
{
|
||||
dbg_assert(m_Drawing == DRAWING_LINES, "called Graphics()->LinesEnd without begin");
|
||||
Flush();
|
||||
FlushVertices();
|
||||
m_Drawing = 0;
|
||||
}
|
||||
|
||||
|
@ -828,34 +874,33 @@ int CGraphics_Threaded::LoadPNG(CImageInfo *pImg, const char *pFilename, int Sto
|
|||
return 1;
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::KickCommandBuffer()
|
||||
{
|
||||
m_Handler.RunBuffer(m_pCommandBuffer);
|
||||
|
||||
// swap buffer
|
||||
m_CurrentCommandBuffer ^= 1;
|
||||
m_pCommandBuffer = m_apCommandBuffers[m_CurrentCommandBuffer];
|
||||
m_pCommandBuffer->Reset();
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::ScreenshotDirect(const char *pFilename)
|
||||
{
|
||||
// TODO: screenshot support
|
||||
return;
|
||||
// add swap command
|
||||
CImageInfo Image;
|
||||
mem_zero(&Image, sizeof(Image));
|
||||
|
||||
/*
|
||||
// fetch image data
|
||||
int y;
|
||||
int w = m_ScreenWidth;
|
||||
int h = m_ScreenHeight;
|
||||
unsigned char *pPixelData = (unsigned char *)mem_alloc(w*(h+1)*3, 1);
|
||||
unsigned char *pTempRow = pPixelData+w*h*3;
|
||||
GLint Alignment;
|
||||
glGetIntegerv(GL_PACK_ALIGNMENT, &Alignment);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(0,0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pPixelData);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, Alignment);
|
||||
CCommandBuffer::SCommand_Screenshot Cmd;
|
||||
Cmd.m_pImage = &Image;
|
||||
m_pCommandBuffer->AddCommand(Cmd);
|
||||
|
||||
// flip the pixel because opengl works from bottom left corner
|
||||
for(y = 0; y < h/2; y++)
|
||||
{
|
||||
mem_copy(pTempRow, pPixelData+y*w*3, w*3);
|
||||
mem_copy(pPixelData+y*w*3, pPixelData+(h-y-1)*w*3, w*3);
|
||||
mem_copy(pPixelData+(h-y-1)*w*3, pTempRow,w*3);
|
||||
}
|
||||
|
||||
// find filename
|
||||
// kick the buffer and wait for the result
|
||||
KickCommandBuffer();
|
||||
WaitForIdle();
|
||||
|
||||
if(Image.m_pData)
|
||||
{
|
||||
// find filename
|
||||
char aWholePath[1024];
|
||||
png_t Png; // ignore_convention
|
||||
|
||||
|
@ -868,13 +913,11 @@ void CGraphics_Threaded::ScreenshotDirect(const char *pFilename)
|
|||
str_format(aBuf, sizeof(aBuf), "saved screenshot to '%s'", aWholePath);
|
||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
|
||||
png_open_file_write(&Png, aWholePath); // ignore_convention
|
||||
png_set_data(&Png, w, h, 8, PNG_TRUECOLOR, (unsigned char *)pPixelData); // ignore_convention
|
||||
png_set_data(&Png, Image.m_Width, Image.m_Height, 8, PNG_TRUECOLOR, (unsigned char *)Image.m_pData); // ignore_convention
|
||||
png_close_file(&Png); // ignore_convention
|
||||
}
|
||||
|
||||
// clean up
|
||||
mem_free(pPixelData);
|
||||
*/
|
||||
mem_free(Image.m_pData);
|
||||
}
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::TextureSet(int TextureID)
|
||||
|
@ -906,7 +949,7 @@ void CGraphics_Threaded::QuadsBegin()
|
|||
void CGraphics_Threaded::QuadsEnd()
|
||||
{
|
||||
dbg_assert(m_Drawing == DRAWING_QUADS, "called Graphics()->QuadsEnd without begin");
|
||||
Flush();
|
||||
FlushVertices();
|
||||
m_Drawing = 0;
|
||||
}
|
||||
|
||||
|
@ -1154,8 +1197,8 @@ bool CGraphics_Threaded::Init()
|
|||
m_aTextures[MAX_TEXTURES-1].m_Next = -1;
|
||||
|
||||
// start the command processor
|
||||
ICommandProcessor *pProcessor = new CCommandProcessor_SDL_OpenGL;
|
||||
m_Handler.Start(pProcessor);
|
||||
m_pProcessor = new CCommandProcessor_SDL_OpenGL;
|
||||
m_Handler.Start(m_pProcessor);
|
||||
|
||||
// create command buffers
|
||||
m_apCommandBuffers[0] = new CCommandBuffer(1024*512, 1024*1024);
|
||||
|
@ -1184,9 +1227,16 @@ bool CGraphics_Threaded::Init()
|
|||
|
||||
void CGraphics_Threaded::Shutdown()
|
||||
{
|
||||
// TODO: SDL, is this correct?
|
||||
|
||||
//
|
||||
// add swap command
|
||||
CCommandBuffer::SCommand_Shutdown Cmd;
|
||||
m_pCommandBuffer->AddCommand(Cmd);
|
||||
m_Handler.RunBuffer(m_pCommandBuffer);
|
||||
|
||||
// wait for everything to process and then stop the command processor
|
||||
m_Handler.WaitForIdle();
|
||||
m_Handler.Stop();
|
||||
delete m_pProcessor;
|
||||
m_pProcessor = 0;
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::Minimize()
|
||||
|
@ -1213,34 +1263,27 @@ int CGraphics_Threaded::WindowOpen()
|
|||
void CGraphics_Threaded::TakeScreenshot(const char *pFilename)
|
||||
{
|
||||
// TODO: screenshot support
|
||||
return;
|
||||
/*
|
||||
char aDate[20];
|
||||
str_timestamp(aDate, sizeof(aDate));
|
||||
str_format(m_aScreenshotName, sizeof(m_aScreenshotName), "screenshots/%s_%s.png", pFilename?pFilename:"screenshot", aDate);
|
||||
m_DoScreenshot = true;
|
||||
*/
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::Swap()
|
||||
{
|
||||
// TODO: screenshot support
|
||||
/*
|
||||
if(m_DoScreenshot)
|
||||
{
|
||||
ScreenshotDirect(m_aScreenshotName);
|
||||
m_DoScreenshot = false;
|
||||
}*/
|
||||
}
|
||||
|
||||
// add swap command
|
||||
CCommandBuffer::SCommand_Swap Cmd;
|
||||
m_pCommandBuffer->AddCommand(Cmd);
|
||||
m_Handler.RunBuffer(m_pCommandBuffer);
|
||||
|
||||
// swap buffer
|
||||
m_CurrentCommandBuffer ^= 1;
|
||||
m_pCommandBuffer = m_apCommandBuffers[m_CurrentCommandBuffer];
|
||||
m_pCommandBuffer->Reset();
|
||||
// kick the command buffer
|
||||
KickCommandBuffer();
|
||||
}
|
||||
|
||||
// syncronization
|
||||
|
|
|
@ -124,7 +124,7 @@ public:
|
|||
SPoint m_Pos;
|
||||
STexCoord m_Tex;
|
||||
SColor m_Color;
|
||||
} ;
|
||||
};
|
||||
|
||||
struct SCommand
|
||||
{
|
||||
|
@ -198,8 +198,7 @@ public:
|
|||
struct SCommand_Screenshot : public SCommand
|
||||
{
|
||||
SCommand_Screenshot() : SCommand(CMD_SCREENSHOT) {}
|
||||
|
||||
CImageInfo *m_pImage; // processor will fill this out
|
||||
CImageInfo *m_pImage; // processor will fill this out, the one who adds this command must free the data as well
|
||||
};
|
||||
|
||||
struct SCommand_Swap : public SCommand
|
||||
|
@ -307,6 +306,8 @@ class CCommandProcessorHandler
|
|||
public:
|
||||
CCommandProcessorHandler();
|
||||
void Start(ICommandProcessor *pProcessor);
|
||||
void Stop();
|
||||
|
||||
void RunBuffer(CCommandBuffer *pBuffer);
|
||||
bool IsIdle() const { return m_pBuffer == 0; }
|
||||
void WaitForIdle();
|
||||
|
@ -316,6 +317,7 @@ class CGraphics_Threaded : public IEngineGraphics
|
|||
{
|
||||
CCommandBuffer::SState m_State;
|
||||
CCommandProcessorHandler m_Handler;
|
||||
ICommandProcessor *m_pProcessor;
|
||||
|
||||
CCommandBuffer *m_apCommandBuffers[2];
|
||||
CCommandBuffer *m_pCommandBuffer;
|
||||
|
@ -361,13 +363,15 @@ class CGraphics_Threaded : public IEngineGraphics
|
|||
int m_FirstFreeTexture;
|
||||
int m_TextureMemoryUsage;
|
||||
|
||||
void Flush();
|
||||
void FlushVertices();
|
||||
void AddVertices(int Count);
|
||||
void Rotate4(const CCommandBuffer::SPoint &rCenter, CCommandBuffer::SVertex *pPoints);
|
||||
|
||||
static unsigned char Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp);
|
||||
static unsigned char *Rescale(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData);
|
||||
|
||||
void KickCommandBuffer();
|
||||
|
||||
int IssueInit();
|
||||
int InitWindow();
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue