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