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