ROOT  6.06/09
Reference Guide
TGLFBO.cxx
Go to the documentation of this file.
1 // @(#)root/gl:$Id$
2 // Author: Matevz Tadel, Aug 2009
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TGLFBO.h"
13 #include <TMath.h>
14 #include <TString.h>
15 #include <TError.h>
16 
17 #include <GL/glew.h>
18 
19 #include <stdexcept>
20 
21 /** \class TGLFBO
22 \ingroup opengl
23 Frame-buffer object.
24 
25 Requires GL-1.5.
26 
27 Taken from Gled project, see:
28 
29  http://www.gled.org/cgi-bin/viewcvs.cgi/trunk/libsets/GledCore/Pupils/
30 
31 See also:
32 
33  http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt
34 */
35 
37 
40 
41 ////////////////////////////////////////////////////////////////////////////////
42 /// Constructor.
43 
45  fFrameBuffer (0),
46  fColorTexture (0),
47  fDepthBuffer (0),
48  fMSFrameBuffer(0),
49  fMSColorBuffer(0),
50  fW (-1),
51  fH (-1),
52  fReqW (-1),
53  fReqH (-1),
54  fMSSamples (0),
55  fMSCoverageSamples (0),
56  fWScale (1),
57  fHScale (1),
58  fIsRescaled (kFALSE)
59 {
60 }
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// Destructor.
64 
66 {
67  Release();
68 }
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// Acquire GL resources for given width, height and number of
72 /// multi-sampling samples.
73 
74 void TGLFBO::Init(int w, int h, int ms_samples)
75 {
76  static const std::string eh("TGLFBO::Init ");
77 
78  // Should be replaced with ARB_framebuffer_object (SLC6).
79  if (!GLEW_EXT_framebuffer_object)
80  {
81  throw std::runtime_error(eh + "GL_EXT_framebuffer_object extension required for FBO.");
82  }
83 
84  fReqW = w; fReqH = h;
85 
87  if (fgRescaleToPow2)
88  {
89  Int_t nw = 1 << TMath::CeilNint(TMath::Log2(w));
90  Int_t nh = 1 << TMath::CeilNint(TMath::Log2(h));
91  if (nw != w || nh != h)
92  {
93  fWScale = ((Float_t)w) / nw;
94  fHScale = ((Float_t)h) / nh;
95  w = nw; h = nh;
97  }
98  }
99 
100  if (ms_samples > 0 && ! GLEW_EXT_framebuffer_multisample)
101  {
103  {
104  Info(eh.c_str(), "GL implementation does not support multi-sampling for FBOs.");
106  }
107  ms_samples = 0;
108  }
109 
110  if (fFrameBuffer != 0)
111  {
112  if (fW == w && fH == h && fMSSamples == ms_samples)
113  return;
114  Release();
115  }
116 
117  Int_t maxSize;
118  glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &maxSize);
119  if (w > maxSize || h > maxSize)
120  {
121  throw std::runtime_error(eh + Form("maximum size supported by GL implementation is %d.", maxSize));
122  }
123 
124  fW = w; fH = h; fMSSamples = ms_samples;
125 
126  if (fMSSamples > 0)
127  {
128  if (GLEW_NV_framebuffer_multisample_coverage)
129  {
130  GLint n_modes;
131  glGetIntegerv(GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV, &n_modes);
132  GLint *modes = new GLint[2*n_modes];
133  glGetIntegerv(GL_MULTISAMPLE_COVERAGE_MODES_NV, modes);
134 
135  for (int i = 0; i < n_modes; ++i)
136  {
137  if (modes[i*2+1] == fMSSamples && modes[i*2] > fMSCoverageSamples)
138  fMSCoverageSamples = modes[i*2];
139  }
140 
141  delete [] modes;
142  }
143  if (gDebug > 0) {
144  Info(eh.c_str(), "InitMultiSample coverage_samples=%d, color_samples=%d.", fMSCoverageSamples, fMSSamples);
145  }
146  InitMultiSample();
147  }
148  else
149  {
150  if (gDebug > 0) {
151  Info(eh.c_str(), "InitStandard (no multi-sampling).");
152  }
153  InitStandard();
154  }
155 
156  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
157 
158  glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
159  glBindTexture (GL_TEXTURE_2D, 0);
160 
161  switch (status)
162  {
163  case GL_FRAMEBUFFER_COMPLETE_EXT:
164  if (gDebug > 0)
165  printf("%sConstructed TGLFBO ... all fine.\n", eh.c_str());
166  break;
167  case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
168  Release();
169  throw std::runtime_error(eh + "Constructed TGLFBO not supported, choose different formats.");
170  break;
171  default:
172  Release();
173  throw std::runtime_error(eh + "Constructed TGLFBO is not complete, unexpected error.");
174  break;
175  }
176 }
177 
178 ////////////////////////////////////////////////////////////////////////////////
179 /// Release the allocated GL resources.
180 
182 {
183  glDeleteFramebuffersEXT (1, &fFrameBuffer);
184  glDeleteRenderbuffersEXT(1, &fDepthBuffer);
185 
186  if (fMSFrameBuffer) glDeleteFramebuffersEXT (1, &fMSFrameBuffer);
187  if (fMSColorBuffer) glDeleteRenderbuffersEXT(1, &fMSColorBuffer);
188  if (fColorTexture) glDeleteTextures (1, &fColorTexture);
189 
190  fW = fH = -1; fMSSamples = fMSCoverageSamples = 0;
192 
193 }
194 
195 ////////////////////////////////////////////////////////////////////////////////
196 /// Bind the frame-buffer object.
197 
199 {
200  if (fMSSamples > 0) {
201  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fMSFrameBuffer);
202  // On by default
203  // glEnable(GL_MULTISAMPLE);
204  // Experimenting:
205  // glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
206  // glEnable(GL_SAMPLE_COVERAGE_ARB);
207  } else {
208  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fFrameBuffer);
209  }
210 }
211 
212 ////////////////////////////////////////////////////////////////////////////////
213 /// Unbind the frame-buffer object.
214 
216 {
217  if (fMSSamples > 0)
218  {
219  glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fMSFrameBuffer);
220  glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fFrameBuffer);
221  glBlitFramebufferEXT(0, 0, fW, fH, 0, 0, fW, fH, GL_COLOR_BUFFER_BIT, GL_NEAREST);
222  }
223 
224  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
225 }
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 /// Bind texture.
229 
231 {
232  glPushAttrib(GL_TEXTURE_BIT);
233  glBindTexture(GL_TEXTURE_2D, fColorTexture);
234  glEnable(GL_TEXTURE_2D);
235 
236  if (fIsRescaled)
237  {
238  glMatrixMode(GL_TEXTURE);
239  glPushMatrix();
240  glScalef(fWScale, fHScale, 1);
241  glMatrixMode(GL_MODELVIEW);
242  }
243 }
244 
245 ////////////////////////////////////////////////////////////////////////////////
246 /// Unbind texture.
247 
249 {
250  if (fIsRescaled)
251  {
252  glMatrixMode(GL_TEXTURE);
253  glPopMatrix();
254  glMatrixMode(GL_MODELVIEW);
255  }
256 
257  glPopAttrib();
258 }
259 
260 ////////////////////////////////////////////////////////////////////////////////
261 
263 {
264  glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fFrameBuffer);
265 }
266 
267 //==============================================================================
268 
269 ////////////////////////////////////////////////////////////////////////////////
270 
272 {
273  glGenFramebuffersEXT(1, &fFrameBuffer);
274  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fFrameBuffer);
275 
276  fDepthBuffer = CreateAndAttachRenderBuffer(GL_DEPTH_COMPONENT24, GL_DEPTH_ATTACHMENT);
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 
283 {
284  glGenFramebuffersEXT(1, &fMSFrameBuffer);
285  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fMSFrameBuffer);
286 
287  fMSColorBuffer = CreateAndAttachRenderBuffer(GL_RGBA8, GL_COLOR_ATTACHMENT0);
288  fDepthBuffer = CreateAndAttachRenderBuffer(GL_DEPTH_COMPONENT24, GL_DEPTH_ATTACHMENT);
289  // fDepthBuffer = CreateAndAttachRenderBuffer(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL_ATTACHMENT);
290 
291  glGenFramebuffersEXT(1, &fFrameBuffer);
292  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fFrameBuffer);
293 
295 }
296 
297 ////////////////////////////////////////////////////////////////////////////////
298 
300 {
301  UInt_t id = 0;
302 
303  glGenRenderbuffersEXT(1, &id);
304  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, id);
305 
306  if (fMSSamples > 0)
307  {
308  if (fMSCoverageSamples > 0)
309  glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, fMSCoverageSamples, fMSSamples, format, fW, fH);
310  else
311  glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, fMSSamples, format, fW, fH);
312  }
313  else
314  {
315  glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, fW, fH);
316  }
317 
318  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, type, GL_RENDERBUFFER_EXT, id);
319 
320  return id;
321 }
322 
323 ////////////////////////////////////////////////////////////////////////////////
324 /// Initialize color-texture and attach it to current FB.
325 
327 {
328  UInt_t id = 0;
329 
330  glGenTextures(1, &id);
331 
332  glBindTexture(GL_TEXTURE_2D, id);
333  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
334  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
335  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
336  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
337  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, fW, fH, 0, GL_RGBA,
338  GL_UNSIGNED_BYTE, NULL);
339 
340  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
341  GL_TEXTURE_2D, id, 0);
342 
343  return id;
344 }
345 
346 ////////////////////////////////////////////////////////////////////////////////
347 /// Return state of fgRescaleToPow2 static member.
348 
350 {
351  return fgRescaleToPow2;
352 }
353 
354 ////////////////////////////////////////////////////////////////////////////////
355 /// Set state of fgRescaleToPow2 static member.
356 /// Default is kTRUE as this works better on older hardware, especially ATI.
357 
359 {
360  fgRescaleToPow2 = r;
361 }
static void SetRescaleToPow2(Bool_t r)
Set state of fgRescaleToPow2 static member.
Definition: TGLFBO.cxx:358
UInt_t CreateAndAttachRenderBuffer(Int_t format, Int_t type)
Definition: TGLFBO.cxx:299
UInt_t CreateAndAttachColorTexture()
Initialize color-texture and attach it to current FB.
Definition: TGLFBO.cxx:326
Int_t fMSSamples
Definition: TGLFBO.h:30
float Float_t
Definition: RtypesCore.h:53
void Unbind()
Unbind the frame-buffer object.
Definition: TGLFBO.cxx:215
TGLFBO()
Constructor.
Definition: TGLFBO.cxx:44
Int_t fW
Definition: TGLFBO.h:30
TH1 * h
Definition: legend2.C:5
void Bind()
Bind the frame-buffer object.
Definition: TGLFBO.cxx:198
virtual ~TGLFBO()
Destructor.
Definition: TGLFBO.cxx:65
Double_t Log2(Double_t x)
Definition: TMath.cxx:104
TAlienJobStatus * status
Definition: TAlienJob.cxx:51
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
void Release()
Release the allocated GL resources.
Definition: TGLFBO.cxx:181
static std::string format(double x, double y, int digits, int width)
void SetAsReadBuffer()
Definition: TGLFBO.cxx:262
static Bool_t GetRescaleToPow2()
Return state of fgRescaleToPow2 static member.
Definition: TGLFBO.cxx:349
ClassImp(TGLFBO)
void Info(const char *location, const char *msgfmt,...)
XFontStruct * id
Definition: TGX11.cxx:108
Float_t fHScale
Definition: TGLFBO.h:32
UInt_t fDepthBuffer
Definition: TGLFBO.h:26
ROOT::R::TRInterface & r
Definition: Object.C:4
void Init(int w, int h, int ms_samples=0)
Acquire GL resources for given width, height and number of multi-sampling samples.
Definition: TGLFBO.cxx:74
UInt_t fMSFrameBuffer
Definition: TGLFBO.h:27
unsigned int UInt_t
Definition: RtypesCore.h:42
Int_t fH
Definition: TGLFBO.h:30
char * Form(const char *fmt,...)
Float_t fWScale
Definition: TGLFBO.h:32
Bool_t fIsRescaled
Definition: TGLFBO.h:33
static Bool_t fgMultiSampleNAWarned
Definition: TGLFBO.h:36
void InitMultiSample()
Definition: TGLFBO.cxx:282
void BindTexture()
Bind texture.
Definition: TGLFBO.cxx:230
UInt_t fColorTexture
Definition: TGLFBO.h:25
int type
Definition: TGX11.cxx:120
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
Int_t fMSCoverageSamples
Definition: TGLFBO.h:30
Int_t fReqW
Definition: TGLFBO.h:30
void UnbindTexture()
Unbind texture.
Definition: TGLFBO.cxx:248
UInt_t fMSColorBuffer
Definition: TGLFBO.h:28
UInt_t fFrameBuffer
Definition: TGLFBO.h:24
#define NULL
Definition: Rtypes.h:82
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
static Bool_t fgRescaleToPow2
Definition: TGLFBO.h:35
Frame-buffer object.
Definition: TGLFBO.h:17
const Bool_t kTRUE
Definition: Rtypes.h:91
void InitStandard()
Definition: TGLFBO.cxx:271
Int_t CeilNint(Double_t x)
Definition: TMath.h:470
Int_t fReqH
Definition: TGLFBO.h:30