Salome HOME
Merge branch 'master' into pre/V8_2_BR
[modules/gui.git] / src / OpenGLUtils / OpenGLUtils_FrameBuffer.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //  File   : OpenGLUtils_FrameBuffer.cxx
21 //  Module : SALOME
22 //
23 #ifdef VTK_OPENGL2
24 #define GL_GLEXT_PROTOTYPES
25 #endif
26
27 #include "OpenGLUtils_FrameBuffer.h"
28
29 #include <utilities.h>
30
31 #include <cstring>
32
33 #ifndef WIN32
34 # ifndef GLX_GLXEXT_LEGACY
35 #  define GLX_GLXEXT_LEGACY
36 # endif
37 #ifdef __APPLE__
38 #import <mach-o/dyld.h>
39 #import <stdlib.h>
40 #import <string.h>
41 void * glXGetProcAddressARB (const GLubyte *name)
42
43 {
44     NSSymbol symbol;
45     char *symbolName;
46     symbolName = (char *)malloc (strlen ((const char *)name) + 2); // 1
47     strcpy(symbolName + 1, (const char *)name); // 2
48     symbolName[0] = '_'; // 3
49     symbol = NULL;
50     if (NSIsSymbolNameDefined (symbolName)) // 4
51         symbol = NSLookupAndBindSymbol (symbolName);
52     free (symbolName); // 5
53     return symbol ? NSAddressOfSymbol (symbol) : NULL; // 6
54 }
55 #else
56 # include <GL/glx.h>
57 #endif
58 # include <dlfcn.h>
59 #else
60 # include <wingdi.h>
61 #endif
62
63 #ifndef APIENTRY
64 #define APIENTRY
65 #endif
66 #ifndef APIENTRYP
67 #define APIENTRYP APIENTRY *
68 #endif
69
70 #ifndef GL_FRAMEBUFFER_EXT
71 #define GL_FRAMEBUFFER_EXT                0x8D40
72 #endif
73
74 #ifndef GL_RENDERBUFFER_EXT
75 #define GL_RENDERBUFFER_EXT               0x8D41
76 #endif
77
78 #ifndef GL_COLOR_ATTACHMENT0_EXT
79 #define GL_COLOR_ATTACHMENT0_EXT          0x8CE0
80 #endif
81
82 #ifndef GL_DEPTH_ATTACHMENT_EXT
83 #define GL_DEPTH_ATTACHMENT_EXT           0x8D00
84 #endif
85
86 #ifndef GL_FRAMEBUFFER_COMPLETE_EXT
87 #define GL_FRAMEBUFFER_COMPLETE_EXT       0x8CD5
88 #endif
89
90 typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
91 typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
92 typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
93 typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
94 typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
95 typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
96 typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
97 typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
98 typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
99 typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
100
101 static PFNGLGENFRAMEBUFFERSEXTPROC vglGenFramebuffersEXT = NULL;
102 static PFNGLBINDFRAMEBUFFEREXTPROC vglBindFramebufferEXT = NULL;
103 static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC vglFramebufferTexture2DEXT = NULL;
104 static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC vglCheckFramebufferStatusEXT = NULL;
105 static PFNGLDELETEFRAMEBUFFERSEXTPROC vglDeleteFramebuffersEXT = NULL;
106 static PFNGLGENRENDERBUFFERSEXTPROC vglGenRenderbuffersEXT = NULL;
107 static PFNGLBINDRENDERBUFFEREXTPROC vglBindRenderbufferEXT = NULL;
108 static PFNGLRENDERBUFFERSTORAGEEXTPROC vglRenderbufferStorageEXT = NULL;
109 static PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC vglFramebufferRenderbufferEXT = NULL;
110 static PFNGLDELETERENDERBUFFERSEXTPROC vglDeleteRenderbuffersEXT = NULL;
111
112 #ifndef WIN32
113 #define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
114 #else
115 #define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
116 #endif
117
118 bool InitializeEXT()
119 {
120   vglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glGenFramebuffersEXT" );
121   vglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)GL_GetProcAddress( "glBindFramebufferEXT" );
122   vglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)GL_GetProcAddress( "glFramebufferTexture2DEXT" );
123   vglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)GL_GetProcAddress( "glCheckFramebufferStatusEXT" );
124   vglDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteFramebuffersEXT" );
125   vglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)GL_GetProcAddress( "glGenRenderbuffersEXT" );
126   vglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)GL_GetProcAddress( "glBindRenderbufferEXT" );
127   vglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)GL_GetProcAddress( "glRenderbufferStorageEXT" );
128   vglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)GL_GetProcAddress( "glFramebufferRenderbufferEXT" );
129   vglDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteRenderbuffersEXT" );
130
131   bool ok = vglGenFramebuffersEXT && vglBindFramebufferEXT && vglFramebufferTexture2DEXT &&
132             vglCheckFramebufferStatusEXT && vglDeleteFramebuffersEXT && vglGenRenderbuffersEXT &&
133             vglBindRenderbufferEXT && vglRenderbufferStorageEXT && vglFramebufferRenderbufferEXT &&
134             vglDeleteRenderbuffersEXT;
135
136   return ok;
137 }
138
139 static bool IsEXTInitialized = InitializeEXT();
140
141 OpenGLUtils_FrameBuffer::OpenGLUtils_FrameBuffer()
142   : textureId( 0 ),
143     fboId( 0 ),
144     rboId( 0 )
145 {
146 }
147
148 OpenGLUtils_FrameBuffer::~OpenGLUtils_FrameBuffer()
149 {
150   release();
151 }
152
153 bool OpenGLUtils_FrameBuffer::init( const GLsizei& xSize, const GLsizei& ySize )
154 {
155 #ifdef VTK_OPENGL2
156   int n = 0;
157   std::ostringstream strm;
158   glGetIntegerv(GL_NUM_EXTENSIONS, &n);
159   for (int i = 0; i < n; i++)
160     {
161       const char *exti = (const char *)glGetStringi(GL_EXTENSIONS, i);
162       strm<< exti <<" ";
163     }
164   std::string s = strm.str();
165   const char* ext = s.c_str();
166 #else  
167   char* ext = (char*)glGetString( GL_EXTENSIONS );
168 #endif  
169   if( !IsEXTInitialized || !ext ||
170       strstr( ext, "GL_EXT_framebuffer_object" ) == NULL )
171   {
172     MESSAGE( "Initializing OpenGL FrameBuffer extension failed" );
173     return false;
174   }
175
176   // create a texture object
177   glEnable( GL_TEXTURE_2D );
178   glGenTextures( 1, &textureId );
179   glBindTexture( GL_TEXTURE_2D, textureId );
180   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
181   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
182   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, xSize, ySize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
183   glBindTexture( GL_TEXTURE_2D, 0 );
184
185   // create a renderbuffer object to store depth info
186   vglGenRenderbuffersEXT( 1, &rboId );
187   vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rboId );
188   vglRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, xSize, ySize );
189   vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
190
191   // create a framebuffer object
192   vglGenFramebuffersEXT( 1, &fboId );
193   vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
194
195   // attach the texture to FBO color attachment point
196   vglFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0 );
197
198   // attach the renderbuffer to depth attachment point
199   vglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId );
200
201   // check FBO status
202   GLenum status = vglCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
203
204   // Unbind FBO
205   vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
206
207   return status == GL_FRAMEBUFFER_COMPLETE_EXT;
208 }
209
210 void OpenGLUtils_FrameBuffer::release()
211 {
212   if( !IsEXTInitialized )
213     return;
214
215   glDeleteTextures( 1, &textureId );
216   textureId = 0;
217
218   vglDeleteFramebuffersEXT( 1, &fboId );
219   fboId = 0;
220
221   vglDeleteRenderbuffersEXT( 1, &rboId );
222   rboId = 0;
223 }
224
225 void OpenGLUtils_FrameBuffer::bind()
226 {
227   if( !IsEXTInitialized )
228     return;
229
230   vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
231 }
232
233 void OpenGLUtils_FrameBuffer::unbind()
234 {
235   if( !IsEXTInitialized )
236     return;
237
238   vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
239 }