From 033baf5710cc021acc93ff7dfce6eff6c2e26cd9 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Fri, 2 Mar 2012 21:47:15 +0300 Subject: Add FBO for screenshots to safe opengl also. --- src/opengl1graphics.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++++++-- src/opengl1graphics.h | 5 ++++ 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/opengl1graphics.cpp b/src/opengl1graphics.cpp index ea4d5e6f3..0386b4c7d 100644 --- a/src/opengl1graphics.cpp +++ b/src/opengl1graphics.cpp @@ -25,6 +25,7 @@ #ifdef USE_OPENGL #include "opengl1graphics.h" +#include "configuration.h" #include "graphicsvertexes.h" #include "logger.h" @@ -46,8 +47,8 @@ GLuint OpenGL1Graphics::mLastImage = 0; OpenGL1Graphics::OpenGL1Graphics(): - mAlpha(false), mTexture(false), mColorAlpha(false), - mSync(false) + mAlpha(false), mTexture(false), mColorAlpha(false), mSync(false), + mFboId(0), mTextureId(0), mRboId(0) { mOpenGL = 2; } @@ -493,6 +494,50 @@ void OpenGL1Graphics::_endDraw() popClipArea(); } +void OpenGL1Graphics::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* OpenGL1Graphics::getScreenshot() { int h = mTarget->h; @@ -504,6 +549,9 @@ SDL_Surface* OpenGL1Graphics::getScreenshot() w, h, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000); + if (!screenshot) + return nullptr; + if (SDL_MUSTLOCK(screenshot)) SDL_LockSurface(screenshot); @@ -530,6 +578,29 @@ SDL_Surface* OpenGL1Graphics::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/opengl1graphics.h b/src/opengl1graphics.h index 6ed2d7440..5a2d6c254 100644 --- a/src/opengl1graphics.h +++ b/src/opengl1graphics.h @@ -129,6 +129,8 @@ class OpenGL1Graphics : public Graphics */ SDL_Surface *getScreenshot(); + void prepareScreenshot(); + static void bindTexture(GLenum target, GLuint texture); static GLuint mLastImage; @@ -140,6 +142,9 @@ class OpenGL1Graphics : public Graphics bool mAlpha, mTexture; bool mColorAlpha; bool mSync; + GLuint mFboId; + GLuint mTextureId; + GLuint mRboId; }; #endif -- cgit v1.2.3-70-g09d2