Fixed bugs:

- Game crash when taking a "Big Screenshot" on the main menu.
- GUI used to be visible on each of the tiles when taking a Big
Screenshot while playing the game. Removed the GUI all together from the
Big Screenshot.

This was SVN commit r6827.
This commit is contained in:
Zyi 2009-04-18 15:27:38 +00:00
parent 60f48f558d
commit ab4b930042
3 changed files with 102 additions and 89 deletions

View File

@ -82,6 +82,7 @@ ERROR_TYPE(System, RequiredExtensionsMissing);
#define LOG_CATEGORY "gamesetup"
bool DoRenderGui = true;
static int SetVideoMode(int w, int h, int bpp, bool fullscreen)
{
@ -378,7 +379,7 @@ void Render()
// Temp GUI message GeeTODO
MICROLOG(L"render GUI");
PROFILE_START( "render gui" );
g_GUI.Draw();
if(DoRenderGui) g_GUI.Draw();
PROFILE_END( "render gui" );
#endif
@ -1057,3 +1058,8 @@ void Init(const CmdLineArgs& args, int flags)
}
}
void RenderGui(bool RenderingState)
{
DoRenderGui = RenderingState;
}

View File

@ -1,4 +1,3 @@
//
// GUI integration
//
@ -12,12 +11,9 @@ extern void GUI_ShowMainMenu();
// display progress / description in loading screen
extern void GUI_DisplayLoadProgress(int percent, const wchar_t* pending_task);
extern void Render();
extern void RenderActor();
/**
* initialize global modules that are be needed before Init.
* must be called from the very beginning of main.
@ -40,6 +36,8 @@ enum InitFlags
INIT_NO_SIM = 4
};
void RenderGui(bool RenderingState);
class CmdLineArgs;
extern void Init(const CmdLineArgs& args, int flags);
extern void Shutdown(int flags);

View File

@ -239,99 +239,108 @@ void WriteScreenshot(const char* extension)
// Similar to WriteScreenshot, but generates an image of size 640*tiles x 480*tiles.
void WriteBigScreenshot(const char* extension, int tiles)
{
// get next available numbered filename
// note: %04d -> always 4 digits, so sorting by filename works correctly.
const VfsPath basenameFormat("screenshots/screenshot%04d");
const VfsPath filenameFormat = fs::change_extension(basenameFormat, extension);
VfsPath filename;
fs_NextNumberedFilename(g_VFS, filenameFormat, s_nextScreenshotNumber, filename);
// Slightly ugly and inflexible: Always draw 640*480 tiles onto the screen, and
// hope the screen is actually large enough for that.
const int tile_w = 640, tile_h = 480;
debug_assert(g_xres >= tile_w && g_yres >= tile_h);
const int img_w = tile_w*tiles, img_h = tile_h*tiles;
const int bpp = 24;
GLenum fmt = GL_RGB;
int flags = TEX_BOTTOM_UP;
// we want writing BMP to be as fast as possible,
// so read data from OpenGL in BMP format to obviate conversion.
if(!strcasecmp(extension, "bmp"))
// If the game hasn't started yet then use WriteScreenshot to generate the image.
if(g_Game == NULL)
WriteScreenshot(".bmp");
else
{
fmt = GL_BGR;
flags |= TEX_BGR;
}
const size_t img_size = img_w * img_h * bpp/8;
const size_t tile_size = tile_w * tile_h * bpp/8;
const size_t hdr_size = tex_hdr_size(filename);
void* tile_data = malloc(tile_size);
if(!tile_data)
WARN_ERR_RETURN(ERR::NO_MEM);
shared_ptr<u8> img_buf = io_Allocate(hdr_size+img_size);
// get next available numbered filename
// note: %04d -> always 4 digits, so sorting by filename works correctly.
const VfsPath basenameFormat("screenshots/screenshot%04d");
const VfsPath filenameFormat = fs::change_extension(basenameFormat, extension);
VfsPath filename;
fs_NextNumberedFilename(g_VFS, filenameFormat, s_nextScreenshotNumber, filename);
Tex t;
GLvoid* img = img_buf.get() + hdr_size;
if(tex_wrap(img_w, img_h, bpp, flags, img_buf, hdr_size, &t) < 0)
return;
// Slightly ugly and inflexible: Always draw 640*480 tiles onto the screen, and
// hope the screen is actually large enough for that.
const int tile_w = 640, tile_h = 480;
debug_assert(g_xres >= tile_w && g_yres >= tile_h);
ogl_WarnIfError();
// Resize various things so that the sizes and aspect ratios are correct
{
g_Renderer.Resize(tile_w, tile_h);
SViewPort vp = { 0, 0, tile_w, tile_h };
g_Game->GetView()->GetCamera()->SetViewPort(&vp);
g_Game->GetView()->GetCamera()->SetProjection(CGameView::defaultNear, CGameView::defaultFar, CGameView::defaultFOV);
}
// Temporarily move everything onto the front buffer, so the user can
// see the exciting progress as it renders (and can tell when it's finished).
// (It doesn't just use SwapBuffers, because it doesn't know whether to
// call the SDL version or the Atlas version.)
GLint oldReadBuffer, oldDrawBuffer;
glGetIntegerv(GL_READ_BUFFER, &oldReadBuffer);
glGetIntegerv(GL_DRAW_BUFFER, &oldDrawBuffer);
glDrawBuffer(GL_FRONT);
glReadBuffer(GL_FRONT);
// Render each tile
for (int tile_y = 0; tile_y < tiles; ++tile_y)
{
for (int tile_x = 0; tile_x < tiles; ++tile_x)
const int img_w = tile_w*tiles, img_h = tile_h*tiles;
const int bpp = 24;
GLenum fmt = GL_RGB;
int flags = TEX_BOTTOM_UP;
// we want writing BMP to be as fast as possible,
// so read data from OpenGL in BMP format to obviate conversion.
if(!strcasecmp(extension, "bmp"))
{
// Adjust the camera to render the appropriate region
g_Game->GetView()->GetCamera()->SetProjectionTile(tiles, tile_x, tile_y);
fmt = GL_BGR;
flags |= TEX_BGR;
}
Render();
const size_t img_size = img_w * img_h * bpp/8;
const size_t tile_size = tile_w * tile_h * bpp/8;
const size_t hdr_size = tex_hdr_size(filename);
void* tile_data = malloc(tile_size);
if(!tile_data)
WARN_ERR_RETURN(ERR::NO_MEM);
shared_ptr<u8> img_buf = io_Allocate(hdr_size+img_size);
// Copy the tile pixels into the main image
glReadPixels(0, 0, tile_w, tile_h, fmt, GL_UNSIGNED_BYTE, tile_data);
for (int y = 0; y < tile_h; ++y)
Tex t;
GLvoid* img = img_buf.get() + hdr_size;
if(tex_wrap(img_w, img_h, bpp, flags, img_buf, hdr_size, &t) < 0)
return;
ogl_WarnIfError();
// Resize various things so that the sizes and aspect ratios are correct
{
g_Renderer.Resize(tile_w, tile_h);
SViewPort vp = { 0, 0, tile_w, tile_h };
g_Game->GetView()->GetCamera()->SetViewPort(&vp);
g_Game->GetView()->GetCamera()->SetProjection(CGameView::defaultNear, CGameView::defaultFar, CGameView::defaultFOV);
}
// Temporarily move everything onto the front buffer, so the user can
// see the exciting progress as it renders (and can tell when it's finished).
// (It doesn't just use SwapBuffers, because it doesn't know whether to
// call the SDL version or the Atlas version.)
GLint oldReadBuffer, oldDrawBuffer;
glGetIntegerv(GL_READ_BUFFER, &oldReadBuffer);
glGetIntegerv(GL_DRAW_BUFFER, &oldDrawBuffer);
glDrawBuffer(GL_FRONT);
glReadBuffer(GL_FRONT);
// Render each tile
for (int tile_y = 0; tile_y < tiles; ++tile_y)
{
for (int tile_x = 0; tile_x < tiles; ++tile_x)
{
void* dest = (char*)img + ((tile_y*tile_h + y) * img_w + (tile_x*tile_w)) * bpp/8;
void* src = (char*)tile_data + y * tile_w * bpp/8;
cpu_memcpy(dest, src, tile_w * bpp/8);
// Adjust the camera to render the appropriate region
g_Game->GetView()->GetCamera()->SetProjectionTile(tiles, tile_x, tile_y);
RenderGui(false);
Render();
RenderGui(true);
// Copy the tile pixels into the main image
glReadPixels(0, 0, tile_w, tile_h, fmt, GL_UNSIGNED_BYTE, tile_data);
for (int y = 0; y < tile_h; ++y)
{
void* dest = (char*)img + ((tile_y*tile_h + y) * img_w + (tile_x*tile_w)) * bpp/8;
void* src = (char*)tile_data + y * tile_w * bpp/8;
cpu_memcpy(dest, src, tile_w * bpp/8);
}
}
}
// Restore the buffer settings
glDrawBuffer(oldDrawBuffer);
glReadBuffer(oldReadBuffer);
// Restore the viewport settings
{
g_Renderer.Resize(g_xres, g_yres);
SViewPort vp = { 0, 0, g_xres, g_yres };
g_Game->GetView()->GetCamera()->SetViewPort(&vp);
g_Game->GetView()->GetCamera()->SetProjection(CGameView::defaultNear, CGameView::defaultFar, CGameView::defaultFOV);
g_Game->GetView()->GetCamera()->SetProjectionTile(1, 0, 0);
}
(void)tex_write(&t, filename);
tex_free(&t);
free(tile_data);
}
// Restore the buffer settings
glDrawBuffer(oldDrawBuffer);
glReadBuffer(oldReadBuffer);
// Restore the viewport settings
{
g_Renderer.Resize(g_xres, g_yres);
SViewPort vp = { 0, 0, g_xres, g_yres };
g_Game->GetView()->GetCamera()->SetViewPort(&vp);
g_Game->GetView()->GetCamera()->SetProjection(CGameView::defaultNear, CGameView::defaultFar, CGameView::defaultFOV);
g_Game->GetView()->GetCamera()->SetProjectionTile(1, 0, 0);
}
(void)tex_write(&t, filename);
tex_free(&t);
free(tile_data);
}