From 8127238e3e06ff9d7952dde9f931c41c0947ba9c Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 11 Aug 2012 23:02:52 +0300 Subject: Extend FBO support. Use FBO only if it supported. Use better FBO functions if possible. --- src/CMakeLists.txt | 2 ++ src/Makefile.am | 2 ++ src/client.cpp | 1 + src/graphics.cpp | 1 + src/graphicsmanager.cpp | 70 +++++++++++++++++++++++++++++++++++++++++-------- src/graphicsmanager.h | 4 +++ src/mgl.cpp | 33 +++++++++++++++++++++++ src/mgl.h | 52 ++++++++++++++++++++++++++++++++++++ 8 files changed, 154 insertions(+), 11 deletions(-) create mode 100644 src/mgl.cpp create mode 100644 src/mgl.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0ce99f292..a048fa30e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -594,6 +594,8 @@ SET(SRCS map.h maplayer.cpp maplayer.h + mgl.cpp + mgl.h normalopenglgraphics.cpp normalopenglgraphics.h particle.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 699caf64c..60c1a3659 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -607,6 +607,8 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \ map.h \ maplayer.cpp \ maplayer.h \ + mgl.cpp \ + mgl.h \ normalopenglgraphics.cpp\ normalopenglgraphics.h \ particle.cpp \ diff --git a/src/client.cpp b/src/client.cpp index e35a6eca8..5d43afbf5 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -534,6 +534,7 @@ void Client::gameInit() applyVSync(); graphicsManager.setVideoMode(); + graphicsManager.initOpenGLFunctions(); applyGrabMode(); applyGamma(); diff --git a/src/graphics.cpp b/src/graphics.cpp index 43e73f236..2700df10a 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -173,6 +173,7 @@ bool Graphics::setOpenGLMode() logger->log1(glExtensions); graphicsManager.updateExtensions(glExtensions); + graphicsManager.setGLVersion(); graphicsManager.updateTextureFormat(); updateMemoryInfo(); diff --git a/src/graphicsmanager.cpp b/src/graphicsmanager.cpp index d18b79c41..79830294e 100644 --- a/src/graphicsmanager.cpp +++ b/src/graphicsmanager.cpp @@ -20,10 +20,17 @@ #include "graphicsmanager.h" +#define GL_GLEXT_PROTOTYPES 1 +#include "GL/glx.h" +// hack to hide warnings +#undef GL_GLEXT_VERSION +#undef GL_GLEXT_PROTOTYPES + #include "configuration.h" #include "graphics.h" #include "graphicsvertexes.h" #include "logger.h" +#include "mgl.h" #include "resources/fboinfo.h" #include "resources/imagehelper.h" @@ -176,7 +183,6 @@ void GraphicsManager::initGraphics(bool noOpenGL) mainGraphics = new SafeOpenGLGraphics; break; }; - #else // Create the graphics context imageHelper = new SDLImageHelper; @@ -284,6 +290,11 @@ std::string GraphicsManager::getGLString(int num) const #endif } +void GraphicsManager::setGLVersion() +{ + sscanf(getGLString(GL_VERSION).c_str(), "%5d.%5d", &mMajor, &mMinor); +} + void GraphicsManager::setVideoMode() { const int width = config.getIntValue("screenwidth"); @@ -348,25 +359,25 @@ void GraphicsManager::createFBO(int width, int height, FBOInfo *fbo) glBindTexture(GL_TEXTURE_2D, 0); // create a renderbuffer object to store depth info - glGenRenderbuffersEXT(1, &fbo->rboId); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->rboId); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + mglGenRenderbuffers(1, &fbo->rboId); + mglBindRenderbuffer(GL_RENDERBUFFER, fbo->rboId); + mglRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + mglBindRenderbuffer(GL_RENDERBUFFER, 0); // create a framebuffer object - glGenFramebuffersEXT(1, &fbo->fboId); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->fboId); + mglGenFramebuffers(1, &fbo->fboId); + mglBindFramebuffer(GL_FRAMEBUFFER, fbo->fboId); // attach the texture to FBO color attachment point - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + mglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->textureId, 0); // attach the renderbuffer to depth attachment point - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->rboId); + mglFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->rboId); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->fboId); + mglBindFramebuffer(GL_FRAMEBUFFER, fbo->fboId); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #endif } @@ -396,3 +407,40 @@ void GraphicsManager::deleteFBO(FBOInfo *fbo) } #endif } + +#ifdef WIN32 +#define getFunction(name) wglGetProcAddress(name); +#else +#define getFunction(name) glXGetProcAddress((const GLubyte*)(name)) +#endif + +void GraphicsManager::initOpenGLFunctions() +{ + if (!checkGLVersion(1, 1)) + return; + + if (supportExtension("GL_ARB_framebuffer_object")) + { // frame buffer supported + mglGenRenderbuffers = (glGenRenderbuffers_t)getFunction("glGenRenderbuffers"); + mglBindRenderbuffer = (glBindRenderbuffer_t)getFunction("glBindRenderbuffer"); + mglRenderbufferStorage = (glRenderbufferStorage_t)getFunction("glRenderbufferStorage"); + mglGenFramebuffers = (glGenFramebuffers_t)getFunction("glGenFramebuffers"); + mglBindFramebuffer = (glBindFramebuffer_t)getFunction("glBindFramebuffer"); + mglFramebufferTexture2D = (glFramebufferTexture2D_t)getFunction("glFramebufferTexture2D"); + mglFramebufferRenderbuffer = (glFramebufferRenderbuffer_t)getFunction("glFramebufferRenderbuffer"); + } + else if (supportExtension("GL_EXT_framebuffer_object")) + { // old frame buffer extension + mglGenRenderbuffers = (glGenRenderbuffers_t)getFunction("glGenRenderbuffersEXT"); + mglBindRenderbuffer = (glBindRenderbuffer_t)getFunction("glBindRenderbufferEXT"); + mglRenderbufferStorage = (glRenderbufferStorage_t)getFunction("glRenderbufferStorageEXT"); + mglGenFramebuffers = (glGenFramebuffers_t)getFunction("glGenFramebuffersEXT"); + mglBindFramebuffer = (glBindFramebuffer_t)getFunction("glBindFramebufferEXT"); + mglFramebufferTexture2D = (glFramebufferTexture2D_t)getFunction("glFramebufferTexture2DEXT"); + mglFramebufferRenderbuffer = (glFramebufferRenderbuffer_t)getFunction("glFramebufferRenderbufferEXT"); + } + else + { // no frame buffer support + config.setValue("usefbo", false); + } +} diff --git a/src/graphicsmanager.h b/src/graphicsmanager.h index a82739bc5..9b7a40a29 100644 --- a/src/graphicsmanager.h +++ b/src/graphicsmanager.h @@ -51,6 +51,8 @@ class GraphicsManager std::string getGLString(int num) const; + void setGLVersion(); + void setVideoMode(); bool checkGLVersion(int major, int minor) const; @@ -59,6 +61,8 @@ class GraphicsManager void deleteFBO(FBOInfo *fbo); + void initOpenGLFunctions(); + private: std::set mExtensions; diff --git a/src/mgl.cpp b/src/mgl.cpp new file mode 100644 index 000000000..856a3575c --- /dev/null +++ b/src/mgl.cpp @@ -0,0 +1,33 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 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 . + */ + +#include "mgl.h" + +#include "localconsts.h" + +#define defName(name) name##_t m##name = nullptr + +defName(glGenRenderbuffers); +defName(glBindRenderbuffer); +defName(glRenderbufferStorage); +defName(glGenFramebuffers); +defName(glBindFramebuffer); +defName(glFramebufferTexture2D); +defName(glFramebufferRenderbuffer); diff --git a/src/mgl.h b/src/mgl.h new file mode 100644 index 000000000..3721c6a9f --- /dev/null +++ b/src/mgl.h @@ -0,0 +1,52 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 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 . + */ + +#ifndef MGL_H +#define MGL_H + +#define GL_GLEXT_PROTOTYPES 1 + +#include +#include + +#define defNameE(name) extern name##_t m##name + +typedef void (APIENTRY *glGenRenderbuffers_t)(GLsizei, GLuint *); +typedef void (APIENTRY *glBindRenderbuffer_t)(GLenum target, + GLuint renderbuffer); +typedef void (APIENTRY *glRenderbufferStorage_t)(GLenum target, + GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRY *glGenFramebuffers_t)(GLsizei n, GLuint *framebuffers); +typedef void (APIENTRY *glBindFramebuffer_t)(GLenum target, + GLuint framebuffer); +typedef void (APIENTRY *glFramebufferTexture2D_t)(GLenum target, + GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRY *glFramebufferRenderbuffer_t)(GLenum target, + GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + +defNameE(glGenRenderbuffers); +defNameE(glBindRenderbuffer); +defNameE(glRenderbufferStorage); +defNameE(glGenFramebuffers); +defNameE(glBindFramebuffer); +defNameE(glFramebufferTexture2D); +defNameE(glFramebufferRenderbuffer); + +#endif -- cgit v1.2.3-60-g2f50