1 // OpenCSG - library for image-based CSG rendering for OpenGL 2 // Copyright (C) 2006-2016, Florian Kirsch 3 // 4 // This library is free software; you can redistribute it and/or 5 // modify it under the terms of the GNU General Public License, 6 // Version 2, as published by the Free Software Foundation. 7 // As a special exception, you have permission to link this library 8 // with the CGAL library and distribute executables. 9 // 10 // This library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 19 // 20 // frameBufferObject.cpp 21 // 22 23 #include "opencsgConfig.h" 24 #include "frameBufferObject.h" 25 26 namespace OpenCSG { 27 28 namespace OpenGL { 29 30 // ctor / dtor FrameBufferObject()31 FrameBufferObject::FrameBufferObject() 32 : width(-1), 33 height(-1), 34 textureID(0), 35 depthID(0), 36 framebufferID(0), 37 oldFramebufferID(0), 38 initialized(false) 39 { 40 } 41 ~FrameBufferObject()42 FrameBufferObject::~FrameBufferObject() { 43 Reset(); 44 } 45 ReadCurrent()46 bool FrameBufferObject::ReadCurrent() 47 { 48 bool haveFBO = GLEW_ARB_framebuffer_object != 0; 49 50 if (haveFBO) 51 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferID); 52 53 return haveFBO; 54 } 55 56 // Creates frame buffer texture and combined depth/stencil render buffer. 57 // shareObjects and copyContext do not make sense here, context remains the same. Initialize(int width,int height,bool,bool)58 bool FrameBufferObject::Initialize(int width, int height, bool /* shareObjects */, bool /* copyContext */ ) 59 { 60 bool haveFBO = GLEW_ARB_framebuffer_object != 0; 61 if (!haveFBO) 62 return false; 63 64 this->width = width; 65 this->height = height; 66 67 glGenFramebuffers(1, &framebufferID); 68 glGenRenderbuffers(1, &depthID); 69 glGenTextures(1, &textureID); 70 71 glBindFramebuffer(GL_FRAMEBUFFER, framebufferID); 72 73 GLenum target = (GLEW_ARB_texture_rectangle || GLEW_EXT_texture_rectangle || GLEW_NV_texture_rectangle) 74 ? GL_TEXTURE_RECTANGLE_ARB 75 : GL_TEXTURE_2D; // implicitely asks for GL_ARB_texture_non_power_of_two. 76 // this should have been checked in channelManager.cpp 77 78 glBindTexture(target, textureID); 79 glTexImage2D(target, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_INT, 0); 80 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 81 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 82 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, textureID, 0); 83 84 glBindRenderbuffer(GL_RENDERBUFFER, depthID); 85 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height); 86 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthID); 87 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthID); 88 89 GLenum status; 90 status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 91 if (status == GL_FRAMEBUFFER_UNSUPPORTED) { 92 Reset(); 93 return false; 94 } 95 96 glBindFramebuffer(GL_FRAMEBUFFER, oldFramebufferID); 97 glBindTexture(target, 0); 98 99 textureTarget = target; 100 101 initialized = true; 102 103 return true; 104 } 105 106 // Releases frame buffer objects Reset()107 bool FrameBufferObject::Reset() 108 { 109 if (textureID) { 110 glDeleteTextures(1, &textureID); 111 textureID = 0; 112 } 113 if (depthID) { 114 glDeleteRenderbuffers(1, &depthID); 115 depthID = 0; 116 } 117 if (framebufferID) { 118 glDeleteFramebuffers(1, &framebufferID); 119 framebufferID = 0; 120 } 121 122 this->width = -1; 123 this->height = -1; 124 125 initialized = false; 126 127 return true; 128 } 129 130 // If new requested size differs, regenerate FBO texture objects Resize(int width,int height)131 bool FrameBufferObject::Resize(int width, int height) 132 { 133 if ( this->width == width 134 && this->height == height 135 ) { 136 return true; 137 } 138 139 Reset(); 140 return Initialize(width, height); 141 } 142 143 // Binds the created frame buffer texture such we can render into it. BeginCapture()144 bool FrameBufferObject::BeginCapture() 145 { 146 glBindFramebuffer(GL_FRAMEBUFFER, framebufferID); 147 return true; 148 } 149 150 // Unbinds frame buffer texture. EndCapture()151 bool FrameBufferObject::EndCapture() 152 { 153 glBindFramebuffer(GL_FRAMEBUFFER, oldFramebufferID); 154 return true; 155 } 156 157 // Sets the frame buffer texture as active texture object. Bind() const158 void FrameBufferObject::Bind() const 159 { 160 glBindTexture(textureTarget, textureID); 161 } 162 163 } // namespace OpenGL 164 165 } // namespace OpenCSG 166