VMTK
vmtkFrameBufferObject.cpp
1 #include "vmtkFrameBufferObject.h"
2 
3 GLuint bound(const int &min, const int &val, const int &max)
4 {
5  return (GLuint) std::max(min, std::min(max, val));
6 }
7 
8 vmtkFrameBufferObject::vmtkFrameBufferObject()
9 {
10  fbo = 0;
11  texture = 0;
12 }
13 
14 vmtkFrameBufferObject::vmtkFrameBufferObject(int width, int height, GLenum target, Attachment option)
15 {
16  init(width, height, option, GL_RGBA, target);
17 }
18 
19 vmtkFrameBufferObject::~vmtkFrameBufferObject()
20 {
21  if(fbo != 0)
22  glDeleteFramebuffers (1, &fbo);
23 
24  if(texture != 0)
25  glDeleteTextures(1, &texture);
26 }
27 
29 {
30  return texture;
31 }
32 
34 {
35  return depthTexture;
36 }
37 
39 {
40  return fbo;
41 }
42 
44 {
45  if (!fbo) return false;
46 
47  glBindFramebuffer(GL_FRAMEBUFFER, fbo);
48  return true;
49 }
50 
52 {
53  if (!fbo) return false;
54  glBindFramebuffer(GL_FRAMEBUFFER, 0);
55  return true;
56 }
57 
58 
59 void vmtkFrameBufferObject::resizing(int width, int height)
60 {
61  glBindTexture(target, fbo);
62  glTexImage2D (target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
63  glBindTexture(target, 0);
64 }
65 
66 void vmtkFrameBufferObject::init(int width, int height, Attachment attachment, GLenum internal_format, GLenum target, GLint samples, bool mipmap)
67 {
68  this->target = target;
69  fbo = 0;
70  glGenFramebuffers(1, &fbo);
71  glBindFramebuffer(GL_FRAMEBUFFER, fbo);
72 
73  texture = 0;
74  depthTexture = 0;
75  GLuint color_buffer = 0;
76  GLuint depth_buffer = 0;
77  GLuint stencil_buffer = 0;
78 
79  if (samples == 0) {
80  glGenTextures(1, &texture);
81 
82  glBindTexture(target, texture);
83  glTexImage2D(target, 0, internal_format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
84  if (mipmap) {
85  int level = 0;
86  while (width > 1 || height > 1)
87  {
88  width = std::max(1, width >> 1);
89  height = std::max(1, height >> 1);
90  ++level;
91  glTexImage2D(target, level, internal_format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
92  }
93  }
94  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
95  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
96  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
97  glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
98  glBindTexture(target, 0);
99 
100  glGenTextures(1, &depthTexture);
101  glBindTexture(target, depthTexture);
102  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
103  glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
104  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
105  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
106  glTexImage2D(target, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
107  glBindTexture(target, 0);
108 
109  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, texture, 0);
110  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, target, depthTexture, 0);
111 
112  GLenum buffers[1] = {GL_COLOR_ATTACHMENT0};
113  glDrawBuffers(1, buffers);
114  if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
115  std::cerr << "Framebuffer is not ok!!!" << std::endl;
116  glBindTexture(target, 0);
117  color_buffer = 0;
118 
119  }
120  else
121  {
122  mipmap = false;
123  GLint maxSamples;
124  glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
125  samples = bound(0, int(samples), int(maxSamples));
126  glGenRenderbuffers(1, &color_buffer);
127  glBindRenderbuffer(GL_RENDERBUFFER, color_buffer);
128  glRenderbufferStorage(GL_RENDERBUFFER, internal_format, width, height);
129  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color_buffer);
130  glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
131  }
132 
133  if (attachment == vmtkFrameBufferObject::DepthStencil){
134 
135  glGenRenderbuffers(1, &depth_buffer);
136  glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
137  assert (glIsRenderbuffer(depth_buffer));
138  if (samples != 0)
139  glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, width, height);
140  else
141  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
142 
143  stencil_buffer = depth_buffer;
144  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer);
145  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil_buffer);
146 
147  bool valid = glCheckFramebufferStatus(GL_FRAMEBUFFER);
148  if (!valid) {
149  glDeleteRenderbuffers(1, &depth_buffer);
150  stencil_buffer = depth_buffer = 0;
151  }
152  }
153 
154  if (depth_buffer == 0 && (attachment == vmtkFrameBufferObject::DepthStencil
155  || (attachment == vmtkFrameBufferObject::Depth)))
156  {
157  glGenRenderbuffers(1, &depth_buffer);
158  depthTexture = depth_buffer;
159  glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
160  assert(glIsRenderbuffer(depth_buffer));
161  if (samples != 0) {
162  glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT16, width, height);
163  }
164  else{
165  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
166  }
167  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER, depth_buffer);
168 
169  if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
170  std::cerr << "Depth buffer is not ok!!!" << std::endl;
171  }
172  if (stencil_buffer == 0 && (attachment == vmtkFrameBufferObject::DepthStencil)) {
173  glGenRenderbuffers(1, &stencil_buffer);
174  glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
175  assert(glIsRenderbuffer(stencil_buffer));
176 
177  GLenum storage = GL_STENCIL_INDEX;
178  if (samples != 0)
179  {
180  glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, width, height);}
181  else{
182  glRenderbufferStorage(GL_RENDERBUFFER, storage, width, height);
183  }
184 
185  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil_buffer);
186  }
187 
188  if (depth_buffer && stencil_buffer) {
190  } else if (depth_buffer) {
191  attachment = vmtkFrameBufferObject::Depth;
192  } else {
194  }
195 
196  glBindFramebuffer(GL_FRAMEBUFFER, 0);
197 }
GLuint getTexture() const
gets the texture bound to the FBO.
GLuint getFbo() const
gets the Fbo name.
void resizing(int width, int height)
resizing FrameBufferObject dimensions ... It does not work!!!! (Ting)
Attachment
constructs a FrameBufferObject without arguments
GLuint getDepthTexture() const
gets the depth texture bound to the FBO.
bool binding()
binds the FBO to the framebuffer target.
bool releasing()
releases the FBO from the framebuffer target.