From 1933978cb800c2348e8891c69b28e85c9417b32d Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Fri, 2 Mar 2012 17:17:02 +0300 Subject: Use FBO for screenshots. Disabled for windows. --- src/defaults.cpp | 1 + src/game.cpp | 1 + src/graphics.h | 3 ++ src/graphicsvertexes.h | 3 +- src/gui/setup_other.cpp | 5 ++++ src/gui/setup_visual.cpp | 6 ++++ src/opengl1graphics.h | 4 ++- src/openglgraphics.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++-- src/openglgraphics.h | 9 +++++- src/resources/image.h | 3 +- 10 files changed, 101 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/defaults.cpp b/src/defaults.cpp index 87771c427..1ca64d4e6 100644 --- a/src/defaults.cpp +++ b/src/defaults.cpp @@ -227,6 +227,7 @@ DefaultsData* getConfigDefaults() AddDEF(configData, "noframe", false); AddDEF(configData, "groupFriends", true); AddDEF(configData, "grabinput", false); + AddDEF(configData, "usefbo", false); AddDEF(configData, "gamma", 1); AddDEF(configData, "vsync", 0); AddDEF(configData, "enableBuggyServers", true); diff --git a/src/game.cpp b/src/game.cpp index 70d794ce8..39d38ac5c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -461,6 +461,7 @@ static bool saveScreenshot() if (!config.getBoolValue("showip")) { mainGraphics->setSecure(true); + mainGraphics->prepareScreenshot(); gui->draw(); screenshot = mainGraphics->getScreenshot(); mainGraphics->setSecure(false); diff --git a/src/graphics.h b/src/graphics.h index 5d496d654..03eecefff 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -251,6 +251,9 @@ class Graphics : public gcn::SDLGraphics */ virtual SDL_Surface *getScreenshot(); + virtual void prepareScreenshot() + { } + virtual bool drawNet(int x1, int y1, int x2, int y2, int width, int height); diff --git a/src/graphicsvertexes.h b/src/graphicsvertexes.h index 4245e8bf5..452cebc29 100644 --- a/src/graphicsvertexes.h +++ b/src/graphicsvertexes.h @@ -28,7 +28,8 @@ #include "localconsts.h" #ifdef USE_OPENGL -#define NO_SDL_GLEXT +//#define NO_SDL_GLEXT +#define GL_GLEXT_PROTOTYPES 1 #include diff --git a/src/gui/setup_other.cpp b/src/gui/setup_other.cpp index 3ea5f4e4a..148037732 100644 --- a/src/gui/setup_other.cpp +++ b/src/gui/setup_other.cpp @@ -183,6 +183,11 @@ Setup_Other::Setup_Other() new SetupItemCheckBox(_("Hide shield sprite"), "", "hideShield", this, "hideShieldEvent"); +#if !defined(_WIN32) + new SetupItemCheckBox(_("Use FBO for screenshots (only for opengl)"), + "", "usefbo", this, "usefboEvent"); +#endif + new SetupItemCheckBox(_("Show background"), "", "showBackground", this, "showBackgroundEvent"); diff --git a/src/gui/setup_visual.cpp b/src/gui/setup_visual.cpp index 55e219bd7..68704956a 100644 --- a/src/gui/setup_visual.cpp +++ b/src/gui/setup_visual.cpp @@ -41,12 +41,16 @@ Setup_Visual::Setup_Visual() mPreferredFirstItemSize = 150; + new SetupItemLabel(_("Notifications"), "", this); + new SetupItemCheckBox(_("Show pickup notifications in chat"), "", "showpickupchat", this, "showpickupchatEvent"); new SetupItemCheckBox(_("Show pickup notifications as particle effects"), "", "showpickupparticle", this, "showpickupparticleEvent"); + new SetupItemLabel(_("Effects"), "", this); + new SetupItemCheckBox(_("Grab mouse and keyboard input"), "", "grabinput", this, "grabinputEvent"); @@ -80,6 +84,8 @@ Setup_Visual::Setup_Visual() this, "particleEmitterSkipEvent", 0, 3, mParticleList, true))->setInvertValue(3); + new SetupItemLabel(_("Other"), "", this); + new SetupItemSlider(_("Gamma"), "", "gamma", this, "gammeEvent", 1, 20, 350, true); diff --git a/src/opengl1graphics.h b/src/opengl1graphics.h index 8cc3c89a7..6ed2d7440 100644 --- a/src/opengl1graphics.h +++ b/src/opengl1graphics.h @@ -28,9 +28,11 @@ #include "graphics.h" -#define NO_SDL_GLEXT +//#define NO_SDL_GLEXT +#define GL_GLEXT_PROTOTYPES 1 #include +#include class OpenGL1Graphics : public Graphics { diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp index 242588473..684716aac 100644 --- a/src/openglgraphics.cpp +++ b/src/openglgraphics.cpp @@ -26,6 +26,7 @@ #include "graphicsvertexes.h" #include "openglgraphics.h" +#include "configuration.h" #include "logger.h" #include "resources/image.h" @@ -50,8 +51,8 @@ const unsigned int vertexBufSize = 500; GLuint OpenGLGraphics::mLastImage = 0; OpenGLGraphics::OpenGLGraphics(): - mAlpha(false), mTexture(false), mColorAlpha(false), - mSync(false) + mAlpha(false), mTexture(false), mColorAlpha(false), mSync(false), + mFboId(0), mTextureId(0), mRboId(0) { mOpenGL = 1; mFloatTexArray = new GLfloat[vertexBufSize * 4 + 30]; @@ -1039,6 +1040,50 @@ void OpenGLGraphics::_endDraw() popClipArea(); } +void OpenGLGraphics::prepareScreenshot() +{ +#if !defined(_WIN32) + if (config.getBoolValue("usefbo")) + { + int h = mTarget->h; + int w = mTarget->w; + + // create a texture object + glGenTextures(1, &mTextureId); + glBindTexture(GL_TEXTURE_2D, mTextureId); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); + glBindTexture(GL_TEXTURE_2D, 0); + + // create a renderbuffer object to store depth info + glGenRenderbuffersEXT(1, &mRboId); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mRboId); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_DEPTH_COMPONENT, w, h); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + + // create a framebuffer object + glGenFramebuffersEXT(1, &mFboId); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFboId); + + // attach the texture to FBO color attachment point + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, mTextureId, 0); + + // attach the renderbuffer to depth attachment point + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mRboId); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFboId); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } +#endif +} + SDL_Surface* OpenGLGraphics::getScreenshot() { int h = mTarget->h; @@ -1079,6 +1124,29 @@ SDL_Surface* OpenGLGraphics::getScreenshot() free(buf); +#if !defined(_WIN32) + if (config.getBoolValue("usefbo")) + { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + if (mFboId) + { + glDeleteFramebuffersEXT(1, &mFboId); + mFboId = 0; + } + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + if (mRboId) + { + glDeleteRenderbuffersEXT(1, &mRboId); + mRboId = 0; + } + if (mTextureId) + { + glDeleteTextures(1, &mTextureId); + mTextureId = 0; + } + } +#endif + glPixelStorei(GL_PACK_ALIGNMENT, pack); if (SDL_MUSTLOCK(screenshot)) diff --git a/src/openglgraphics.h b/src/openglgraphics.h index 02d628af0..650ad668a 100644 --- a/src/openglgraphics.h +++ b/src/openglgraphics.h @@ -28,9 +28,11 @@ #include "main.h" #include "graphics.h" -#define NO_SDL_GLEXT +//#define NO_SDL_GLEXT +#define GL_GLEXT_PROTOTYPES 1 #include +//#include class OpenGLGraphics : public Graphics { @@ -138,6 +140,8 @@ class OpenGLGraphics : public Graphics */ SDL_Surface *getScreenshot(); + void prepareScreenshot(); + bool drawNet(int x1, int y1, int x2, int y2, int width, int height); static void bindTexture(GLenum target, GLuint texture); @@ -154,6 +158,9 @@ class OpenGLGraphics : public Graphics bool mAlpha, mTexture; bool mColorAlpha; bool mSync; + GLuint mFboId; + GLuint mTextureId; + GLuint mRboId; }; #endif diff --git a/src/resources/image.h b/src/resources/image.h index 68ab09e58..89fe24d89 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -36,7 +36,8 @@ * gl.h headers, since they also include these definitions. As we're not using * extensions anyway it's safe to just disable the SDL version. */ -#define NO_SDL_GLEXT +//#define NO_SDL_GLEXT +#define GL_GLEXT_PROTOTYPES 1 #include #endif -- cgit v1.2.3-60-g2f50