glVertex  5.5.2
glvertex_fbo.h
Go to the documentation of this file.
1 // (c) by Stefan Roettger, licensed under MIT license
2 
5 #ifndef GLVERTEX_FBO_H
6 #define GLVERTEX_FBO_H
7 
8 #include <string.h>
9 
10 #include "glvertex_gl.h"
11 #include "glvertex_fbo_gl.h"
12 
13 #ifdef __APPLE__
14 #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
15 #include <QApplication>
16 #endif
17 #endif
18 
21 {
22 public:
23 
26  : init_(false)
27  {}
28 
29 protected:
30 
31  bool init_;
32 
33 #ifdef _WIN32
34 
35  #undef WGL_MACRO
36  #define WGL_MACRO(proc,proctype) PFN##proctype##PROC proc;
37  #include "glvertex_fbo_wgl.h"
38 
39  void initWGLprocs()
40  {
41  if (!init_)
42  {
43  #undef WGL_MACRO
44  #define WGL_MACRO(proc,proctype) if ((proc=(PFN##proctype##PROC)wglGetProcAddress(#proc))==NULL) lglWarning(#proc" not supported");
45  #include "glvertex_fbo_wgl.h"
46  init_ = true;
47  }
48  }
49 
50 #endif
51 };
52 
54 class lglFBO: public lglFBO_base
55 {
56 public:
57 
60  : lglFBO_base()
61  {
62  hasFBO_ = false;
63  fboWidth_ = fboHeight_ = 0;
64  fboMipmap_ = false;
65  fboFloat_ = false;
66  textureId_ = 0;
67  rboId_ = fboId_ = 0;
68  prev_ = 0;
69  }
70 
71  ~lglFBO()
72  {
73  destroyFBO();
74  }
75 
77  bool setupFBO(int width, int height, bool fbomipmap = false, bool fbofloat = false, bool force = false)
78  {
79 #ifdef _WIN32
80  initWGLprocs();
81 #endif
82 
83 #ifdef __APPLE__
84 #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
85  float factor = qApp->devicePixelRatio();
86  width = (int)(width * factor + 0.5f);
87  height = (int)(height * factor + 0.5f);
88 #endif
89 #endif
90 
91 #if (LGL_OPENGL_VERSION < 32)
92  char *GL_EXTs;
93 
94  if ((GL_EXTs=(char *)glGetString(GL_EXTENSIONS)) != NULL)
95  if (strstr(GL_EXTs, "EXT_framebuffer_object") != NULL)
96 #endif
97  if (width>0 && height>0)
98  if (!hasFBO_ ||
99  width!=fboWidth_ || height!=fboHeight_ ||
100  fbomipmap!=fboMipmap_ || fbofloat!=fboFloat_)
101  {
102 #ifdef GL_EXT_framebuffer_object
103 
104  destroyFBO();
105 
106  hasFBO_ = true;
107 
108  // query actual binding
109  prev_ = 0;
110  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_);
111 
112  // save actual size and state
113  fboWidth_ = width;
114  fboHeight_ = height;
115  fboMipmap_ = fbomipmap;
116  fboFloat_ = fbofloat;
117 
118  // create a texture object
119  glGenTextures(1, &textureId_);
120  glBindTexture(GL_TEXTURE_2D, textureId_);
121  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
122 #if (LGL_OPENGL_VERSION >= 30)
123  if (fbomipmap) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
124  else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
125 #else
126  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
127 #endif
128  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
129  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
130  if (fbofloat) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, width, height, 0, GL_RGBA, GL_HALF_FLOAT_ARB, 0);
131  else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
132  glBindTexture(GL_TEXTURE_2D, 0);
133 
134  // create a renderbuffer object to store depth info
135  glGenRenderbuffers(1, &rboId_);
136  glBindRenderbuffer(GL_RENDERBUFFER, rboId_);
137  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
138  glBindRenderbuffer(GL_RENDERBUFFER, 0);
139 
140  // create a framebuffer object
141  glGenFramebuffers(1, &fboId_);
142  glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
143 
144  // attach texture to color attachment point
145  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId_, 0);
146 
147  // attach renderbuffer to depth attachment point
148  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId_);
149 
150  // get framebuffer status
151  GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
152 
153  // switch back to window-system-provided framebuffer
154  glBindFramebuffer(GL_FRAMEBUFFER, prev_);
155 
156  // check framebuffer status
157  if (status != GL_FRAMEBUFFER_COMPLETE) destroyFBO();
158 
159 #endif
160  }
161 
162 #if (LGL_OPENGL_VERSION < 30)
163  if (fbomipmap && force) destroyFBO();
164 #endif
165 
166  return(hasFBO_);
167  }
168 
170  void destroyFBO()
171  {
172 #ifdef GL_EXT_framebuffer_object
173 
174  if (textureId_ != 0) glDeleteTextures(1, &textureId_);
175  if (rboId_ != 0) glDeleteRenderbuffers(1, &rboId_);
176  if (fboId_ != 0) glDeleteFramebuffers(1, &fboId_);
177 
178  textureId_ = 0;
179  rboId_ = 0;
180  fboId_ = 0;
181 
182  hasFBO_ = false;
183  fboWidth_ = fboHeight_ = 0;
184  fboMipmap_ = false;
185  fboFloat_ = false;
186 
187 #endif
188  }
189 
191  void activateFBO()
192  {
193 #ifdef GL_EXT_framebuffer_object
194 
195  if (hasFBO_)
196  {
197  // query actual binding
198  prev_ = 0;
199  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_);
200 
201  // bind framebuffer
202  glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
203  }
204 
205 #endif
206  }
207 
209  GLuint deactivateFBO()
210  {
211 #ifdef GL_EXT_framebuffer_object
212 
213  if (hasFBO_)
214  {
215  // restore previous binding
216  glBindFramebuffer(GL_FRAMEBUFFER, prev_);
217 
218 #if (LGL_OPENGL_VERSION >= 30)
219  if (fboMipmap_)
220  {
221  glBindTexture(GL_TEXTURE_2D, textureId_);
222  glGenerateMipmap(GL_TEXTURE_2D);
223  glBindTexture(GL_TEXTURE_2D, 0);
224  }
225 #endif
226  }
227 
228 #endif
229 
230  return(getFBOTextureId());
231  }
232 
234  GLuint getFBOId()
235  {
236 #ifdef GL_EXT_framebuffer_object
237 
238  if (hasFBO_)
239  return(fboId_);
240 
241 #endif
242 
243  return(0);
244  }
245 
248  {
249 #ifdef GL_EXT_framebuffer_object
250 
251  if (hasFBO_)
252  return(textureId_);
253 
254 #endif
255 
256  return(0);
257  }
258 
260  int width()
261  {
262  return(fboWidth_);
263  }
264 
266  int height()
267  {
268  return(fboHeight_);
269  }
270 
273  {
274  return(fboMipmap_);
275  }
276 
278  int fbo_float()
279  {
280  return(fboMipmap_);
281  }
282 
283 protected:
284 
285  bool hasFBO_;
286  int fboWidth_, fboHeight_;
287  bool fboMipmap_;
288  bool fboFloat_;
289  GLuint textureId_;
290  GLuint rboId_;
291  GLuint fboId_;
292  GLint prev_;
293 };
294 
296 class lglDBO: public lglFBO_base
297 {
298 public:
299 
302  : lglFBO_base()
303  {
304  hasDBO_ = false;
305  dboWidth_ = dboHeight_ = 0;
306  dboMipmap_ = false;
307  textureId_ = 0;
308  dboId_ = 0;
309  prev_ = 0;
310  }
311 
312  ~lglDBO()
313  {
314  destroyDBO();
315  }
316 
318  bool setupDBO(int width, int height, bool dbomipmap = false, bool force = false)
319  {
320 #ifdef _WIN32
321  initWGLprocs();
322 #endif
323 
324 #if (LGL_OPENGL_VERSION < 32)
325  char *GL_EXTs;
326 
327  if ((GL_EXTs=(char *)glGetString(GL_EXTENSIONS)) != NULL)
328  if (strstr(GL_EXTs, "EXT_framebuffer_object") != NULL)
329 #endif
330  if (width>0 && height>0)
331  if (!hasDBO_ ||
332  width!=dboWidth_ || height!=dboHeight_ ||
333  dbomipmap!=dboMipmap_)
334  {
335 #ifdef GL_EXT_framebuffer_object
336 
337  destroyDBO();
338 
339  hasDBO_ = true;
340 
341  // query actual binding
342  prev_ = 0;
343  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_);
344 
345  // save actual size and state
346  dboWidth_ = width;
347  dboHeight_ = height;
348  dboMipmap_ = dbomipmap;
349 
350  // create a depth texture object
351  glGenTextures(1, &textureId_);
352  glBindTexture(GL_TEXTURE_2D, textureId_);
353  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
354 #if (LGL_OPENGL_VERSION >= 30)
355  if (dbomipmap) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
356  else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
357 #else
358  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
359 #endif
360  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
361  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
362 #if (LGL_OPENGL_VERSION < 30)
363  glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
364 #endif
365  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
366  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
367  glBindTexture(GL_TEXTURE_2D, 0);
368 
369  // create a framebuffer object
370  glGenFramebuffers(1, &dboId_);
371  glBindFramebuffer(GL_FRAMEBUFFER, dboId_);
372 
373  // no color buffer is drawn to
374  glDrawBuffer(GL_NONE);
375  glReadBuffer(GL_NONE);
376 
377  // attach texture to depth attachment point
378  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textureId_, 0);
379 
380  // get framebuffer status
381  GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
382 
383  // switch back to window-system-provided framebuffer
384  glBindFramebuffer(GL_FRAMEBUFFER, prev_);
385 
386  // re-enable back buffer
387  glDrawBuffer(GL_BACK);
388  glReadBuffer(GL_BACK);
389 
390  // check framebuffer status
391  if (status != GL_FRAMEBUFFER_COMPLETE) destroyDBO();
392 
393 #endif
394  }
395 
396 #if (LGL_OPENGL_VERSION < 30)
397  if (dbomipmap && force) destroyDBO();
398 #endif
399 
400  return(hasDBO_);
401  }
402 
404  void destroyDBO()
405  {
406 #ifdef GL_EXT_framebuffer_object
407 
408  if (textureId_ != 0) glDeleteTextures(1, &textureId_);
409  if (dboId_ != 0) glDeleteFramebuffers(1, &dboId_);
410 
411  textureId_ = 0;
412  dboId_ = 0;
413 
414  hasDBO_ = false;
415  dboWidth_ = dboHeight_ = 0;
416  dboMipmap_ = false;
417 
418 #endif
419  }
420 
422  void activateDBO()
423  {
424 #ifdef GL_EXT_framebuffer_object
425 
426  if (hasDBO_)
427  {
428  // query actual binding
429  prev_ = 0;
430  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_);
431 
432  // bind framebuffer
433  glBindFramebuffer(GL_FRAMEBUFFER, dboId_);
434 
435  // no color buffer is drawn to
436  glDrawBuffer(GL_NONE);
437  glReadBuffer(GL_NONE);
438  }
439 
440 #endif
441  }
442 
444  GLuint deactivateDBO()
445  {
446 #ifdef GL_EXT_framebuffer_object
447 
448  if (hasDBO_)
449  {
450  // restore previous binding
451  glBindFramebuffer(GL_FRAMEBUFFER, prev_);
452 
453  // re-enable back buffer
454  glDrawBuffer(GL_BACK);
455  glReadBuffer(GL_BACK);
456 
457 #if (LGL_OPENGL_VERSION >= 30)
458  if (dboMipmap_)
459  {
460  glBindTexture(GL_TEXTURE_2D, textureId_);
461  glGenerateMipmap(GL_TEXTURE_2D);
462  glBindTexture(GL_TEXTURE_2D, 0);
463  }
464 #endif
465  }
466 
467 #endif
468 
469  return(getDBOTextureId());
470  }
471 
473  GLuint getDBOId()
474  {
475 #ifdef GL_EXT_framebuffer_object
476 
477  if (hasDBO_)
478  return(dboId_);
479 
480 #endif
481 
482  return(0);
483  }
484 
487  {
488 #ifdef GL_EXT_framebuffer_object
489 
490  if (hasDBO_)
491  return(textureId_);
492 
493 #endif
494 
495  return(0);
496  }
497 
499  int width()
500  {
501  return(dboWidth_);
502  }
503 
505  int height()
506  {
507  return(dboHeight_);
508  }
509 
512  {
513  return(dboMipmap_);
514  }
515 
516 protected:
517 
518  bool hasDBO_;
519  int dboWidth_, dboHeight_;
520  bool dboMipmap_;
521  GLuint textureId_;
522  GLuint dboId_;
523  GLint prev_;
524 };
525 
526 #endif
lglFBO_base
frame buffer object base class
Definition: glvertex_fbo.h:20
lglFBO::lglFBO
lglFBO()
ctor
Definition: glvertex_fbo.h:59
lglDBO::getDBOTextureId
GLuint getDBOTextureId()
get dbo texture id
Definition: glvertex_fbo.h:486
lglFBO::setupFBO
bool setupFBO(int width, int height, bool fbomipmap=false, bool fbofloat=false, bool force=false)
create fbo
Definition: glvertex_fbo.h:77
lglFBO::activateFBO
void activateFBO()
enable fbo
Definition: glvertex_fbo.h:191
lglFBO::destroyFBO
void destroyFBO()
destroy fbo
Definition: glvertex_fbo.h:170
lglFBO::getFBOTextureId
GLuint getFBOTextureId()
get fbo texture id
Definition: glvertex_fbo.h:247
lglFBO::getFBOId
GLuint getFBOId()
get fbo id
Definition: glvertex_fbo.h:234
lglFBO::height
int height()
get fbo texture height
Definition: glvertex_fbo.h:266
lglDBO::height
int height()
get dbo texture height
Definition: glvertex_fbo.h:505
lglFBO::deactivateFBO
GLuint deactivateFBO()
disable fbo
Definition: glvertex_fbo.h:209
lglDBO::deactivateDBO
GLuint deactivateDBO()
disable dbo
Definition: glvertex_fbo.h:444
lglDBO::lglDBO
lglDBO()
ctor
Definition: glvertex_fbo.h:301
lglDBO::width
int width()
get dbo texture width
Definition: glvertex_fbo.h:499
lglDBO::getDBOId
GLuint getDBOId()
get dbo id
Definition: glvertex_fbo.h:473
lglFBO
frame buffer object
Definition: glvertex_fbo.h:54
lglDBO
depth buffer object
Definition: glvertex_fbo.h:296
lglFBO::fbo_mipmap
int fbo_mipmap()
query fbo texture mip-mapping
Definition: glvertex_fbo.h:272
lglFBO_base::lglFBO_base
lglFBO_base()
ctor
Definition: glvertex_fbo.h:25
lglDBO::setupDBO
bool setupDBO(int width, int height, bool dbomipmap=false, bool force=false)
create dbo
Definition: glvertex_fbo.h:318
lglDBO::destroyDBO
void destroyDBO()
destroy dbo
Definition: glvertex_fbo.h:404
lglFBO::fbo_float
int fbo_float()
query fbo float mode
Definition: glvertex_fbo.h:278
lglFBO::width
int width()
get fbo texture width
Definition: glvertex_fbo.h:260
lglDBO::dbo_mipmap
int dbo_mipmap()
query dbo texture mip-mapping
Definition: glvertex_fbo.h:511
lglDBO::activateDBO
void activateDBO()
enable dbo
Definition: glvertex_fbo.h:422