Ticket #211: OSGFBOViewport.cpp

File OSGFBOViewport.cpp, 66.0 kB (added by rstanchak, 1 year ago)

Patched FBOViewport implementation

Line 
1 /*---------------------------------------------------------------------------*\
2  *                                OpenSG                                     *
3  *                                                                           *
4  *                                                                           *
5  *               Copyright (C) 2000-2002 by the OpenSG Forum                 *
6  *                                                                           *
7  *                            www.opensg.org                                 *
8  *                                                                           *
9  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
10  *                                                                           *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13  *                                License                                    *
14  *                                                                           *
15  * This library is free software; you can redistribute it and/or modify it   *
16  * under the terms of the GNU Library General Public License as published    *
17  * by the Free Software Foundation, version 2.                               *
18  *                                                                           *
19  * This library is distributed in the hope that it will be useful, but       *
20  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
22  * Library General Public License for more details.                          *
23  *                                                                           *
24  * You should have received a copy of the GNU Library General Public         *
25  * License along with this library; if not, write to the Free Software       *
26  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
27  *                                                                           *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30  *                                Changes                                    *
31  *                                                                           *
32  *                                                                           *
33  *                                                                           *
34  *                                                                           *
35  *                                                                           *
36  *                                                                           *
37 \*---------------------------------------------------------------------------*/
38
39 //---------------------------------------------------------------------------
40 //  Includes
41 //---------------------------------------------------------------------------
42
43 #include <stdlib.h>
44 #include <stdio.h>
45
46 #include <OSGConfig.h>
47 #include <OSGTextureChunk.h>
48 #include <OSGImage.h>
49 #include <OSGMatrixCameraDecorator.h>
50 #include <OSGTileCameraDecorator.h>
51 #include <OSGRenderAction.h>
52 #include <OSGSimpleAttachments.h>
53 #include <OSGRemoteAspect.h>
54
55 #include "OSGFBOViewport.h"
56
57 /* ----------------------- GL_EXT_framebuffer_object ----------------------- */
58
59 #ifndef GL_ARB_draw_buffers
60     #define GL_ARB_draw_buffers 1
61 #endif
62
63 #ifndef GL_EXT_framebuffer_object
64     #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
65     #define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
66     #define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
67     #define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
68     #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
69     #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
70     #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
71     #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
72     #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
73     #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
74     #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
75     #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
76     #define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8
77     #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
78     #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
79     #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
80     #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
81     #define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
82     #define GL_FRAMEBUFFER_STATUS_ERROR_EXT 0x8CDE
83     #define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
84     #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
85     #define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
86     #define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
87     #define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
88     #define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
89     #define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
90     #define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
91     #define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
92     #define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
93     #define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
94     #define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
95     #define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
96     #define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
97     #define GL_COLOR_ATTACHMENT13_EXT 0x8CED
98     #define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
99     #define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
100     #define GL_DEPTH_ATTACHMENT_EXT 0x8D00
101     #define GL_STENCIL_ATTACHMENT_EXT 0x8D20
102     #define GL_FRAMEBUFFER_EXT 0x8D40
103     #define GL_RENDERBUFFER_EXT 0x8D41
104     #define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
105     #define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
106     #define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
107     #define GL_STENCIL_INDEX_EXT 0x8D45
108     #define GL_STENCIL_INDEX1_EXT 0x8D46
109     #define GL_STENCIL_INDEX4_EXT 0x8D47
110     #define GL_STENCIL_INDEX8_EXT 0x8D48
111     #define GL_STENCIL_INDEX16_EXT 0x8D49
112 #endif
113
114 #ifndef GL_TEXTURE_RECTANGLE_ARB
115     #define GL_TEXTURE_RECTANGLE_ARB 0x84F5
116 #endif
117
118 #ifndef GL_DEPTH_COMPONENT_ARB
119     #define GL_DEPTH_COMPONENT_ARB 0x1902
120 #endif
121
122 #ifndef GL_ARB_depth_texture
123     #define GL_DEPTH_COMPONENT16_ARB 0x81A5
124     #define GL_DEPTH_COMPONENT24_ARB 0x81A6
125     #define GL_DEPTH_COMPONENT32_ARB 0x81A7
126     #define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A
127     #define GL_DEPTH_TEXTURE_MODE_ARB 0x884B
128 #endif
129
130 #ifndef GL_ARB_shadow
131     #define GL_TEXTURE_COMPARE_MODE_ARB 0x884C
132     #define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D
133     #define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E
134 #endif
135
136 #ifndef GL_EXT_depth_stencil
137     #define GL_DEPTH_STENCIL_EXT        0x84F9
138     #define GL_UNSIGNED_INT_24_8_EXT    0x84FA
139     #define GL_DEPTH24_STENCIL8_EXT     0x88F0
140     #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
141 #endif
142
143 //
144 #include <OSGShadowViewport.h>
145 #include <OSGForeground.h>
146 #include <OSGTextureGrabForeground.h>
147 //
148
149 OSG_USING_NAMESPACE
150
151 /***************************************************************************\
152  *                            Description                                  *
153 \***************************************************************************/
154
155 /*! \class osg::FBOViewport
156 First Release of FramebufferObjects-Viewport.
157 */
158
159 /***************************************************************************\
160  *                           Class variables                               *
161 \***************************************************************************/
162
163 UInt32 FBOViewport::_tex3D_extension;
164 UInt32 FBOViewport::_framebuffer_object_extension;
165 UInt32 FBOViewport::_draw_buffers_extension;
166
167 UInt32 FBOViewport::_funcDrawBuffers                         = Window::invalidFunctionID;
168
169 UInt32 FBOViewport::_funcBindFramebuffer                     = Window::invalidFunctionID;
170 UInt32 FBOViewport::_funcBindRenderbuffer                    = Window::invalidFunctionID;
171 UInt32 FBOViewport::_funcCheckFramebufferStatus              = Window::invalidFunctionID;
172 UInt32 FBOViewport::_funcDeleteFramebuffers                  = Window::invalidFunctionID;
173 UInt32 FBOViewport::_funcDeleteRenderbuffers                 = Window::invalidFunctionID;
174 UInt32 FBOViewport::_funcFramebufferRenderbuffer             = Window::invalidFunctionID;
175 UInt32 FBOViewport::_funcFramebufferTexture1D                = Window::invalidFunctionID;
176 UInt32 FBOViewport::_funcFramebufferTexture2D                = Window::invalidFunctionID;
177 UInt32 FBOViewport::_funcFramebufferTexture3D                = Window::invalidFunctionID;
178 UInt32 FBOViewport::_funcGenFramebuffers                     = Window::invalidFunctionID;
179 UInt32 FBOViewport::_funcGenRenderbuffers                    = Window::invalidFunctionID;
180 UInt32 FBOViewport::_funcGenerateMipmap                      = Window::invalidFunctionID;
181 UInt32 FBOViewport::_funcGetFramebufferAttachmentParameteriv = Window::invalidFunctionID;
182 UInt32 FBOViewport::_funcGetRenderbufferParameteriv          = Window::invalidFunctionID;
183 UInt32 FBOViewport::_funcIsFramebuffer                       = Window::invalidFunctionID;
184 UInt32 FBOViewport::_funcIsRenderbuffer                      = Window::invalidFunctionID;
185 UInt32 FBOViewport::_funcRenderbufferStorage                 = Window::invalidFunctionID;
186 UInt32 FBOViewport::_funcCopyTexSubImage3D                   = Window::invalidFunctionID;
187
188 FBOViewport::renderparamscbfp FBOViewport::_renderParamsFP   = NULL;
189
190 typedef void (OSG_APIENTRY * OSGGLCOPYTEXSUBIMAGE3DPROC)
191     (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
192
193 typedef void (OSG_APIENTRY * OSGGLDRAWBUFFERSARBPROC)
194     (GLsizei n, const GLenum* bufs);
195
196 typedef void (OSG_APIENTRY * OSGGLBINDFRAMEBUFFEREXTPROC)
197     (GLenum target, GLuint framebuffer);
198 typedef void (OSG_APIENTRY * OSGGLBINDRENDERBUFFEREXTPROC)
199     (GLenum target, GLuint renderbuffer);
200 typedef GLenum (OSG_APIENTRY * OSGGLCHECKFRAMEBUFFERSTATUSEXTPROC)
201     (GLenum target);
202 typedef void (OSG_APIENTRY * OSGGLDELETEFRAMEBUFFERSEXTPROC)
203     (GLsizei n, const GLuint* framebuffers);
204 typedef void (OSG_APIENTRY * OSGGLDELETERENDERBUFFERSEXTPROC)
205     (GLsizei n, const GLuint* renderbuffers);
206 typedef void (OSG_APIENTRY * OSGGLFRAMEBUFFERRENDERBUFFEREXTPROC)
207     (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
208 typedef void (OSG_APIENTRY * OSGGLFRAMEBUFFERTEXTURE1DEXTPROC)
209     (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
210 typedef void (OSG_APIENTRY * OSGGLFRAMEBUFFERTEXTURE2DEXTPROC)
211     (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
212 typedef void (OSG_APIENTRY * OSGGLFRAMEBUFFERTEXTURE3DEXTPROC)
213     (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
214 typedef void (OSG_APIENTRY * OSGGLGENFRAMEBUFFERSEXTPROC)
215     (GLsizei n, GLuint* framebuffers);
216 typedef void (OSG_APIENTRY * OSGGLGENRENDERBUFFERSEXTPROC)
217     (GLsizei n, GLuint* renderbuffers);
218 typedef void (OSG_APIENTRY * OSGGLGENERATEMIPMAPEXTPROC)
219     (GLenum target);
220 typedef void (OSG_APIENTRY * OSGGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)
221     (GLenum target, GLenum attachment, GLenum pname, GLint* params);
222 typedef void (OSG_APIENTRY * OSGGLGETRENDERBUFFERPARAMETERIVEXTPROC)
223     (GLenum target, GLenum pname, GLint* params);
224 typedef GLboolean (OSG_APIENTRY * OSGGLISFRAMEBUFFEREXTPROC)
225     (GLuint framebuffer);
226 typedef GLboolean (OSG_APIENTRY * OSGGLISRENDERBUFFEREXTPROC)
227     (GLuint renderbuffer);
228 typedef void (OSG_APIENTRY * OSGGLRENDERBUFFERSTORAGEEXTPROC)
229     (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
230
231
232 namespace
233 {
234   bool checkGLError(const char* where)
235   {
236     GLenum errCode = 0;
237     if ((errCode = glGetError()) != GL_NO_ERROR)
238     {
239         const GLubyte *errString = gluErrorString(errCode);
240         FWARNING(("%s OpenGL Error: %s!\n", where, errString));
241     }
242
243     return errCode == GL_NO_ERROR;
244   }
245 }
246
247 /***************************************************************************\
248  *                           Class methods                                 *
249 \***************************************************************************/
250
251 void FBOViewport::initMethod (void)
252 {
253 }
254
255 void FBOViewport::setRenderParamsCB(renderparamscbfp fp)
256 {
257     _renderParamsFP = fp;
258 }
259
260 /***************************************************************************\
261  *                           Instance methods                              *
262 \***************************************************************************/
263
264 /*-------------------------------------------------------------------------*\
265  -  private                                                                 -
266 \*-------------------------------------------------------------------------*/
267
268 /*----------------------- constructors & destructors ----------------------*/
269
270 FBOViewport::FBOViewport(void) :
271     Inherited()
272 {
273 }
274
275 FBOViewport::FBOViewport(const FBOViewport &source) :
276     Inherited(source)
277 {
278     _tex3D_extension = Window::registerExtension("GL_EXT_texture3D");
279    
280     _framebuffer_object_extension = Window::registerExtension("GL_EXT_framebuffer_object");
281
282     _draw_buffers_extension = Window::registerExtension("GL_ARB_draw_buffers");
283
284     _funcDrawBuffers =
285         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glDrawBuffers",
286                                   GL_ARB_draw_buffers);
287
288     _funcBindFramebuffer =
289         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glBindFramebufferEXT",
290                                   _framebuffer_object_extension);
291     _funcBindRenderbuffer =
292         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glBindRenderbufferEXT",
293                                   _framebuffer_object_extension);
294     _funcCheckFramebufferStatus =
295         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glCheckFramebufferStatusEXT",
296                                   _framebuffer_object_extension);
297     _funcDeleteFramebuffers =
298         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glDeleteFramebuffersEXT",
299                                   _framebuffer_object_extension);
300     _funcDeleteRenderbuffers =
301         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glDeleteRenderbuffersEXT",
302                                   _framebuffer_object_extension);
303     _funcFramebufferRenderbuffer =
304         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glFramebufferRenderbufferEXT",
305                                   _framebuffer_object_extension);
306     _funcFramebufferTexture1D =
307         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glFramebufferTexture1DEXT",
308                                   _framebuffer_object_extension);
309     _funcFramebufferTexture2D =
310         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glFramebufferTexture2DEXT",
311                                   _framebuffer_object_extension);
312     _funcFramebufferTexture3D =
313         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glFramebufferTexture3DEXT",
314                                   _framebuffer_object_extension);
315     _funcGenFramebuffers =
316         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGenFramebuffersEXT",
317                                   _framebuffer_object_extension);
318     _funcGenRenderbuffers =
319         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGenRenderbuffersEXT",
320                                   _framebuffer_object_extension);
321     _funcGenerateMipmap =
322         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGenerateMipmapEXT",
323                                   _framebuffer_object_extension);
324     _funcGetFramebufferAttachmentParameteriv =
325         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetFramebufferAttachmentParameterivEXT",
326                                   _framebuffer_object_extension);
327     _funcGetRenderbufferParameteriv =
328         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glGetRenderbufferParameterivEXT",
329                                   _framebuffer_object_extension);
330     _funcIsFramebuffer =
331         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glIsFramebufferEXT",
332                                   _framebuffer_object_extension);
333     _funcIsRenderbuffer =
334         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glIsRenderbufferEXT",
335                                   _framebuffer_object_extension);
336     _funcRenderbufferStorage =
337         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glRenderbufferStorageEXT",
338                                   _framebuffer_object_extension);
339                                  
340     _funcCopyTexSubImage3D =
341         Window::registerFunction (OSG_DLSYM_UNDERSCORE"glCopyTexSubImage3D",
342                                   _tex3D_extension);
343 }
344    
345
346 FBOViewport::~FBOViewport(void)
347 {
348 }
349
350 /*----------------------------- class specific ----------------------------*/
351
352 void FBOViewport::changed(BitVector whichField, UInt32 origin)
353 {
354     Inherited::changed(whichField, origin);
355 }
356
357 void FBOViewport::dump(      UInt32    ,
358                          const BitVector ) const
359 {
360     SLOG << "Dump FBOViewport NI" << std::endl;
361 }
362
363 void FBOViewport::onCreate(const FBOViewport *source)
364 {
365     // if we're in startup this is the prototype ...
366     if (OSG::GlobalSystemState == OSG::Startup)
367         return;
368
369     // TODO; get maxBuffers - but window is needed
370         
371         // we need this for clustering. Without it FBO's are continuously allocated
372         RemoteAspect::addFieldFilter(FBOViewport::getClassType().getId(),
373                                              FBOViewport::FrameBufferIndexFieldMask   |
374                                                                  FBOViewport::DirtyFieldMask              |
375                                                                  FBOViewport::StencilBufferIndexFieldMask |
376                                                                  FBOViewport::DepthBufferIndexFieldMask );
377        
378 }
379
380 void FBOViewport::onDestroy(void)
381 {
382     // TODO; delete buffers - but window is needed
383 }
384
385 bool FBOViewport::initialize(Window *win, Int32 format)
386 {
387     GLuint fbIndex, dbIndex, sbIndex;
388    
389     Int32 width  = getStorageWidth();
390     Int32 height = getStorageHeight();
391
392     if (width <= 0 || height <= 0)
393         return false;
394
395     checkGLError("FBO initalize pre");
396
397        
398     if (getFrameBufferIndex() && !getDirty())
399         return true;
400    
401     FBOViewportPtr thisP(*this);
402    
403     beginEditCP(thisP);
404    
405     setDirty(false);    // force re-initialization
406
407     OSGGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT =
408         (OSGGLBINDFRAMEBUFFEREXTPROC)win->getFunction(_funcBindFramebuffer);
409     OSGGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT =
410         (OSGGLBINDRENDERBUFFEREXTPROC)win->getFunction(_funcBindRenderbuffer);
411     OSGGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT =
412         (OSGGLCHECKFRAMEBUFFERSTATUSEXTPROC)win->getFunction(_funcCheckFramebufferStatus);
413     OSGGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT =
414         (OSGGLFRAMEBUFFERRENDERBUFFEREXTPROC)win->getFunction(_funcFramebufferRenderbuffer);
415     OSGGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT =
416         (OSGGLGENFRAMEBUFFERSEXTPROC)win->getFunction(_funcGenFramebuffers);
417     OSGGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT =
418         (OSGGLGENRENDERBUFFERSEXTPROC)win->getFunction(_funcGenRenderbuffers);
419     OSGGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT =
420         (OSGGLRENDERBUFFERSTORAGEEXTPROC)win->getFunction(_funcRenderbufferStorage);
421    
422
423         glGenFramebuffersEXT(1, &fbIndex);
424         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbIndex);
425
426         setFrameBufferIndex(fbIndex);
427
428     glDrawBuffer (GL_FALSE);
429     glReadBuffer (GL_FALSE);
430    
431     GLuint depth = (format & FBO_DEPTH_16) ? GL_DEPTH_COMPONENT16_ARB :
432                    (format & FBO_DEPTH_24) ? GL_DEPTH_COMPONENT24_ARB :
433                    (format & FBO_DEPTH_32) ? GL_DEPTH_COMPONENT32_ARB : 0;
434    
435     GLuint stencil = (format & FBO_STENCIL_1 ) ? GL_STENCIL_INDEX1_EXT  :
436                      (format & FBO_STENCIL_4 ) ? GL_STENCIL_INDEX4_EXT  :
437                      (format & FBO_STENCIL_8 ) ? GL_STENCIL_INDEX8_EXT  :
438                      (format & FBO_STENCIL_16) ? GL_STENCIL_INDEX16_EXT : 0;
439
440     checkGLError("FBO initalize pre depth");
441            
442     if (depth)
443     {
444         glGenRenderbuffersEXT(1, &dbIndex);
445         glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, dbIndex);
446         setDepthBufferIndex(dbIndex);
447        
448         glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, depth, width, height);
449         glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,  GL_DEPTH_ATTACHMENT_EXT,
450                                      GL_RENDERBUFFER_EXT, dbIndex);
451     }
452
453     checkGLError("FBO initalize pre stencil");
454    
455     if (stencil)
456     {
457         glGenRenderbuffersEXT(1, &sbIndex);
458         glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, sbIndex);
459         setStencilBufferIndex(sbIndex);
460        
461         glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, stencil, width, height);
462         glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,  GL_STENCIL_ATTACHMENT_EXT,
463                                      GL_RENDERBUFFER_EXT, sbIndex);
464     }
465    
466     checkGLError("FBO initalize post stencil");
467    
468     endEditCP(thisP);
469    
470     bool result = true; //checkFrameBufferStatus(win);
471     
472     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
473     glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
474
475     checkGLError("FBO initalize post");
476    
477     return result;
478 }
479
480 void FBOViewport::setTarget(Window *win, UInt32 id, GLenum attachment, GLenum target, GLint zoffset)
481 {
482     OSGGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT =
483         (OSGGLFRAMEBUFFERTEXTURE1DEXTPROC)win->getFunction(_funcFramebufferTexture1D);
484     OSGGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT =
485         (OSGGLFRAMEBUFFERTEXTURE2DEXTPROC)win->getFunction(_funcFramebufferTexture2D);
486     OSGGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT =
487         (OSGGLFRAMEBUFFERTEXTURE3DEXTPROC)win->getFunction(_funcFramebufferTexture3D);
488
489     if (getFrameBufferIndex())
490     {
491         if (target == GL_TEXTURE_3D) {
492             glFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, attachment, target, id, 0, zoffset);
493         }
494         else {
495             glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, target, id, 0);
496         }
497        
498         if (!checkGLError("setTarget post"))
499         {
500             SWARNING << "Error with attachment: " << attachment
501                      << ", id: " << id << ", target: " << target
502                      << endLog;
503         }
504     }
505     else
506         FWARNING(("Invalid FrameBufferObject index!\n"));
507 }
508
509 void FBOViewport::bind(Window *win)
510 {
511     OSGGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT =
512         (OSGGLBINDFRAMEBUFFEREXTPROC)win->getFunction(_funcBindFramebuffer);
513        
514     if (getFrameBufferIndex())
515         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, getFrameBufferIndex());
516     else
517         FWARNING(("Invalid FrameBufferObject index!\n"));
518 }
519
520 /// unbind the frambuffer object, so subsequent drawing ops are not drawn
521 /// into the fbo targets; '0' means windowing system provided framebuffer
522 void FBOViewport::stop(Window *win)
523 {
524     OSGGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT =
525         (OSGGLBINDFRAMEBUFFEREXTPROC)win->getFunction(_funcBindFramebuffer);
526        
527     if (getFrameBufferIndex())
528         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
529 }
530
531 void FBOViewport::render(RenderActionBase* action)
532 {
533     if (!getEnabled())
534         return;
535        
536     Window *win = action->getWindow();
537
538    
539     static GLenum targets[6] = {
540                           GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
541                           GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
542                           GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
543                           GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
544                           GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
545                           GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
546                         };
547
548     static Matrix transforms[6] = {
549                              Matrix( 1, 0, 0, 0,
550                                      0,-1, 0, 0,
551                                      0, 0,-1, 0,
552                                      0, 0, 0, 1 ),
553                                      
554                              Matrix(-1, 0, 0, 0,
555                                      0,-1, 0, 0,
556                                      0, 0, 1, 0,
557                                      0, 0, 0, 1 ),
558                                      
559                              Matrix( 1, 0, 0, 0,
560                                      0, 0, 1, 0,
561                                      0,-1, 0, 0,
562                                      0, 0, 0, 1 ),
563                                      
564                              Matrix( 1, 0, 0, 0,
565                                      0, 0,-1, 0,
566                                      0, 1, 0, 0,
567                                      0, 0, 0, 1 ),
568                                      
569                              Matrix( 0, 0,-1, 0,
570                                      0,-1, 0, 0,
571                                     -1, 0, 0, 0,
572                                      0, 0, 0, 1 ),
573                                      
574                              Matrix( 0, 0, 1, 0,
575                                      0,-1, 0, 0,
576                                      1, 0, 0, 0,
577                                      0, 0, 0, 1 ),
578                            };
579
580     if (win == NULL)
581     {
582         SWARNING << "FBOViewport::render: no window!" << std::endl;
583         return;
584     }
585     if (getCamera() == NullFC)
586     {
587         SWARNING << "FBOViewport::render: no camera!" << std::endl;
588         return;
589     }
590     if (getBackground() == NullFC)
591     {
592         SWARNING << "FBOViewport::render: no background!" << std::endl;
593         return;
594     }
595     if (getRoot() == NullFC && getRenderNodes().empty())
596     {
597         SWARNING << "FBOViewport::render: no root(s)!" << std::endl;
598         return;
599     }
600
601     // Let the window handle resizes, to avoid interfering with the
602     // FBOViewports settings
603     win->resizeGL();
604
605     GLint maxTexSize = 0;
606     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
607    
608     beginEditCP(getPtr(), StorageWidthFieldMask | StorageHeightFieldMask);
609         if (getStorageWidth() > maxTexSize)
610             setStorageWidth( maxTexSize );
611         if (getStorageHeight() > maxTexSize)
612             setStorageHeight( maxTexSize );
613     endEditCP(getPtr(), StorageWidthFieldMask | StorageHeightFieldMask);
614
615     // set special render state
616     if (_renderParamsFP != NULL)
617         _renderParamsFP(FBO_RP_EFFECTS);
618
619     bool depth = getGenDepthmaps();
620     RenderAction *rAct = dynamic_cast<RenderAction*>(action);
621     bool zWriteTransSave = rAct ? rAct->getZWriteTrans() : true;
622
623     if (depth)
624         rAct->setZWriteTrans(true);
625            
626     if (!getFboOn()  && extensionCheck())
627     {
628         UInt32 i, numBuffers = (getTextures().getSize()) ? 1 : 0;
629        
630         if ( !win->hasExtension("GL_ARB_texture_non_power_of_two") )
631         {
632             beginEditCP(getPtr(), StorageWidthFieldMask | StorageHeightFieldMask);
633            
634             i = 1;
635             do {
636                 i <<= 1;
637             } while (getStorageHeight() >= i);
638             setStorageHeight( i>>1 );
639            
640             i = 1;
641             do {
642                 i <<= 1;
643             } while (getStorageWidth() >= i);
644             setStorageWidth( i>>1 );
645            
646             endEditCP(getPtr(), StorageWidthFieldMask | StorageHeightFieldMask);
647         }
648
649         if (numBuffers > 0)
650         {
651             Int32 j, sides = getGenCubemaps() ? 6 : 1;
652            
653             // invalid mode, used as workaround until a better idea for setting/ rendering env
654             if (getGenDepthmaps() && getGenCubemaps())
655                 sides = 0;
656
657             FDEBUG(( "Using standard GL (%d maxTexSize) with %d %sTextures and %d views...\n",
658                      maxTexSize, numBuffers, (depth ? "depth" : ""), sides ));
659        
660             for (i=0; i<getExcludeNodes().getSize(); i++)
661             {
662                 NodePtr exnode = getExcludeNodes()[i];
663                 if (exnode != NullFC)
664                     exnode->setActive(false);
665             }
666            
667             CameraPtr cP = getCamera();
668              
669             if( getIgnoreCameraDecorators() )
670             {
671                 // Ignore decorators passed to the viewport
672                 // Motivation:
673                 // Ignorance of Decorators is primarily used in order to ignore special
674                 // decorators for stereo views or the tiles for cluster rendering: If e.g.
675                 // you are rendering onto a tiled wall you usually don't want to have your
676                 // FBO-rendered texture tiled.
677
678                 CameraDecoratorPtr cdP = CameraDecoratorPtr::dcast(cP);
679
680                 // ignore decorators!
681                 while (cdP != NullFC)
682                 {
683                     cP = cdP->getDecoratee();
684                     cdP = CameraDecoratorPtr::dcast(cP);
685                 }
686             }
687                  
688             //action->setCamera    (cp.getCPtr()             );
689             action->setBackground(getBackground().getCPtr());
690             action->setViewport  (this                     );
691             action->setTravMask  (getTravMask()            );
692            
693             Int32 winWidth  = getParent()->getWidth ();
694             Int32 winHeight = getParent()->getHeight();
695            
696             Int32 imgWidth  = getStorageWidth ();
697             Int32 imgHeight = getStorageHeight();
698            
699             UInt32 x1, x2, y1, y2, tw, th;
700            
701             ShadowViewportPtr shadowVptPtr = NullFC;
702             MFForegroundPtr fgndBag;
703             MFForegroundPtr::iterator fgndIt;
704             std::vector< Int32 > pos;
705             Int32 n = 0;
706             Real32 svpL, svpB, svpR, svpT;
707            
708             // there seems to be s.th. wrong with the svp init, only render if done
709             static bool check = false;
710            
711             if (!sides)
712             {
713                 if (imgWidth <= 1 || imgHeight <= 1)
714                 {
715                     imgWidth = winWidth;
716                     imgHeight = winHeight;
717                     //SWARNING << "noDim: " << imgWidth << ", " << imgHeight << std::endl;
718                 }
719                
720                 // TODO; introduce special mode instead of searching for this type
721                 for (j=0; j<win->getPort().size(); j++)
722                 {
723                     shadowVptPtr = ShadowViewportPtr::dcast(win->getPort(j));
724                    
725                     if (shadowVptPtr != NullFC)
726                         break;
727                 }
728                
729                 if (shadowVptPtr != NullFC)
730                 {
731                     n = shadowVptPtr->getForegrounds().size();
732                    
733                     for (j=n-1; j>=0; j--) {
734                         TextureGrabForegroundPtr grab = TextureGrabForegroundPtr::dcast(
735                                                         shadowVptPtr->getForegrounds(j));
736                         if (grab == NullFC) {
737                             fgndBag.push_back(shadowVptPtr->getForegrounds(j));
738                             fgndIt = shadowVptPtr->getForegrounds().begin() + j;
739                             shadowVptPtr->getForegrounds().erase(fgndIt);
740                         }
741                         else {
742                             grab->setActive(false);
743                             pos.push_back(j);
744                         }
745                     }
746                    
747                     svpL = shadowVptPtr->getLeft();
748                     svpB = shadowVptPtr->getBottom();
749                     svpR = shadowVptPtr->getRight();
750                     svpT = shadowVptPtr->getTop();
751                    
752                     beginEditCP(shadowVptPtr, LeftFieldMask | RightFieldMask |
753                                               BottomFieldMask | TopFieldMask);
754                         shadowVptPtr->setSize(0, 0, imgWidth-1, imgHeight-1);
755                     endEditCP(shadowVptPtr, LeftFieldMask | RightFieldMask |
756                                             BottomFieldMask | TopFieldMask);
757                    
758                     beginEditCP(getPtr(), LeftFieldMask | RightFieldMask |
759                                           BottomFieldMask | TopFieldMask);
760                         setSize(0, 0, imgWidth-1, imgHeight-1);
761                     endEditCP(getPtr(), LeftFieldMask | RightFieldMask |
762                                         BottomFieldMask | TopFieldMask);
763                    
764                     ImagePtr i = getTextures(0)->getImage();
765                    
766                     if (i->getWidth() != imgWidth || i->getHeight() != imgHeight)
767                     {
768                         beginEditCP(getTextures(0), TextureChunk::ImageFieldMask);
769                             i->set(i->getPixelFormat(), imgWidth, imgHeight);
770                         endEditCP(getTextures(0), TextureChunk::ImageFieldMask);
771                     }
772                 }
773             }
774            
775             TileCameraDecoratorPtr tiledeco = TileCameraDecorator::create();
776            
777             beginEditCP(tiledeco);
778                 tiledeco->setFullSize(imgWidth, imgHeight);
779             endEditCP(tiledeco);
780            
781             // render cubemaps
782             if (sides == 6)
783             {
784                 MatrixCameraDecoratorPtr deco = MatrixCameraDecorator::create();
785                
786                 for (j=0; j<sides; j++)
787                 {
788                     beginEditCP(deco);
789                         deco->setDecoratee(cP);
790                         deco->setPreProjection(transforms[j]);
791                     endEditCP(deco);
792                    
793                     beginEditCP(tiledeco);
794                         tiledeco->setDecoratee(deco);
795                     endEditCP(tiledeco);
796                    
797                     action->setCamera(tiledeco.getCPtr());
798                    
799                     for (y1=0; y1 < imgHeight; y1 += winHeight)
800                     {
801                         y2 = osgMin((float)(y1+winHeight-1), (float)(imgHeight-1));
802                         th = y2 - y1 + 1;
803                        
804                         for (x1=0; x1 < imgWidth; x1 += winWidth)
805                         {
806                             x2 = osgMin((float)(x1+winWidth-1), (float)(imgWidth-1));
807                             tw = x2 - x1 + 1;
808                            
809                             // set tile size to maximal renderable size
810                             beginEditCP(tiledeco);
811                                 tiledeco->setSize(  x1/(float)imgWidth,     y1/(float)imgHeight,
812                                                 (x2+1)/(float)imgWidth, (y2+1)/(float)imgHeight);
813                             endEditCP(tiledeco);
814                            
815