Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
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
35
38
39////////////////////////////////////////////////////////////////////////////////
40/// Constructor.
41
43 fFrameBuffer (0),
44 fColorTexture (0),
45 fDepthBuffer (0),
48 fW (-1),
49 fH (-1),
50 fReqW (-1),
51 fReqH (-1),
52 fMSSamples (0),
54 fWScale (1),
55 fHScale (1),
57{
58}
59
60////////////////////////////////////////////////////////////////////////////////
61/// Destructor.
62
64{
65 Release();
66}
67
68////////////////////////////////////////////////////////////////////////////////
69/// Acquire GL resources for given width, height and number of
70/// multi-sampling samples.
71
72void TGLFBO::Init(int w, int h, int ms_samples)
73{
74 static const std::string eh("TGLFBO::Init ");
75
76 // Should be replaced with ARB_framebuffer_object (SLC6).
77 // Similar for GL_EXT_framebuffer_multisample.
78 // This then requires changing all relevant EXT calls and enums.
79 if ( ! GLAD_GL_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
88 {
89 Int_t nw = 1 << TMath::CeilNint(TMath::Log2(w));
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 && ! GLAD_GL_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 (GLAD_GL_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 }
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, nullptr);
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
353
354////////////////////////////////////////////////////////////////////////////////
355/// Set state of fgRescaleToPow2 static member.
356/// Default is kTRUE as this works better on older hardware, especially ATI.
357
ROOT::R::TRInterface & r
Definition Object.C:4
#define h(i)
Definition RSha256.hxx:106
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
Definition RtypesCore.h:60
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
float Float_t
Float 4 bytes (float).
Definition RtypesCore.h:71
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
XFontStruct * id
Definition TGX11.cxx:147
Int_t gDebug
Definition TROOT.cxx:777
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2496
void InitStandard()
Definition TGLFBO.cxx:271
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:215
void UnbindTexture()
Unbind texture.
Definition TGLFBO.cxx:248
UInt_t CreateAndAttachRenderBuffer(Int_t format, Int_t type)
Definition TGLFBO.cxx:299
Int_t fMSCoverageSamples
Definition TGLFBO.h:30
virtual ~TGLFBO()
Destructor.
Definition TGLFBO.cxx:63
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:72
UInt_t fMSColorBuffer
Definition TGLFBO.h:28
UInt_t CreateAndAttachColorTexture()
Initialize color-texture and attach it to current FB.
Definition TGLFBO.cxx:326
void Bind()
Bind the frame-buffer object.
Definition TGLFBO.cxx:198
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:358
static Bool_t GetRescaleToPow2()
Return state of fgRescaleToPow2 static member.
Definition TGLFBO.cxx:349
Float_t fWScale
Definition TGLFBO.h:32
TGLFBO()
Constructor.
Definition TGLFBO.cxx:42
void SetAsReadBuffer()
Definition TGLFBO.cxx:262
void Release()
Release the allocated GL resources.
Definition TGLFBO.cxx:181
void InitMultiSample()
Definition TGLFBO.cxx:282
Int_t fReqW
Definition TGLFBO.h:30
void BindTexture()
Bind texture.
Definition TGLFBO.cxx:230
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)
Returns the binary (base-2) logarithm of x.
Definition TMath.cxx:107
Int_t CeilNint(Double_t x)
Returns the nearest integer of TMath::Ceil(x).
Definition TMath.h:685