summaryrefslogtreecommitdiff
path: root/src/resources/openglscreenshothelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/resources/openglscreenshothelper.cpp')
-rw-r--r--src/resources/openglscreenshothelper.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/resources/openglscreenshothelper.cpp b/src/resources/openglscreenshothelper.cpp
new file mode 100644
index 000000000..ec561476e
--- /dev/null
+++ b/src/resources/openglscreenshothelper.cpp
@@ -0,0 +1,106 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2015 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef USE_OPENGL
+
+#include "resources/openglscreenshothelper.h"
+
+#include "configuration.h"
+#include "graphicsmanager.h"
+
+#include "render/mgl.h"
+#ifdef __native_client__
+#include "render/naclglfunctions.h"
+#endif
+
+#include "debug.h"
+
+OpenGLScreenshotHelper::OpenGLScreenshotHelper() :
+ ScreenshotHelper(),
+ mFbo()
+{
+}
+
+OpenGLScreenshotHelper::~OpenGLScreenshotHelper()
+{
+}
+
+void OpenGLScreenshotHelper::prepare(const int width,
+ const int height)
+{
+ if (config.getBoolValue("usefbo"))
+ graphicsManager.createFBO(width, height, &mFbo);
+}
+
+SDL_Surface *OpenGLScreenshotHelper::getScreenshot(const int width,
+ const int height)
+{
+ const int h = height;
+ const int w = width - (width % 4);
+ GLint pack = 1;
+
+ SDL_Surface *const screenshot = MSDL_CreateRGBSurface(
+ SDL_SWSURFACE, w, h, 24,
+ 0xff0000, 0x00ff00, 0x0000ff, 0x000000);
+
+ if (!screenshot)
+ return nullptr;
+
+ if (SDL_MUSTLOCK(screenshot))
+ SDL_LockSurface(screenshot);
+
+ const size_t lineSize = 3 * w;
+ GLubyte *const buf = new GLubyte[lineSize];
+
+ // Grap the pixel buffer and write it to the SDL surface
+ mglGetIntegerv(GL_PACK_ALIGNMENT, &pack);
+ mglPixelStorei(GL_PACK_ALIGNMENT, 1);
+ mglReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, screenshot->pixels);
+
+ // Flip the screenshot, as OpenGL has 0,0 in bottom left
+ const int h2 = h / 2;
+ for (int i = 0; i < h2; i++)
+ {
+ GLubyte *const top = static_cast<GLubyte*>(
+ screenshot->pixels) + lineSize * i;
+ GLubyte *const bot = static_cast<GLubyte*>(
+ screenshot->pixels) + lineSize * (h - 1 - i);
+
+ memcpy(buf, top, lineSize);
+ memcpy(top, bot, lineSize);
+ memcpy(bot, buf, lineSize);
+ }
+
+ delete [] buf;
+
+ if (config.getBoolValue("usefbo"))
+ graphicsManager.deleteFBO(&mFbo);
+
+ mglPixelStorei(GL_PACK_ALIGNMENT, pack);
+
+ if (SDL_MUSTLOCK(screenshot))
+ SDL_UnlockSurface(screenshot);
+
+ return screenshot;
+}
+
+#endif // USE_OPENGL