]> SALOME platform Git repositories - modules/gui.git/blob - src/OpenGLUtils/OpenGLUtils_FrameBuffer.cxx
Salome HOME
Start potring to the VTK OpenGL2 backend.
[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 # include <GL/glx.h>
38 # include <dlfcn.h>
39 #else
40 # include <wingdi.h>
41 #endif
42
43 #ifndef APIENTRY
44 #define APIENTRY
45 #endif
46 #ifndef APIENTRYP
47 #define APIENTRYP APIENTRY *
48 #endif
49
50 #ifndef GL_FRAMEBUFFER_EXT
51 #define GL_FRAMEBUFFER_EXT                0x8D40
52 #endif
53
54 #ifndef GL_RENDERBUFFER_EXT
55 #define GL_RENDERBUFFER_EXT               0x8D41
56 #endif
57
58 #ifndef GL_COLOR_ATTACHMENT0_EXT
59 #define GL_COLOR_ATTACHMENT0_EXT          0x8CE0
60 #endif
61
62 #ifndef GL_DEPTH_ATTACHMENT_EXT
63 #define GL_DEPTH_ATTACHMENT_EXT           0x8D00
64 #endif
65
66 #ifndef GL_FRAMEBUFFER_COMPLETE_EXT
67 #define GL_FRAMEBUFFER_COMPLETE_EXT       0x8CD5
68 #endif
69
70 typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
71 typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
72 typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
73 typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
74 typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
75 typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
76 typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
77 typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
78 typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
79 typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
80
81 static PFNGLGENFRAMEBUFFERSEXTPROC vglGenFramebuffersEXT = NULL;
82 static PFNGLBINDFRAMEBUFFEREXTPROC vglBindFramebufferEXT = NULL;
83 static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC vglFramebufferTexture2DEXT = NULL;
84 static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC vglCheckFramebufferStatusEXT = NULL;
85 static PFNGLDELETEFRAMEBUFFERSEXTPROC vglDeleteFramebuffersEXT = NULL;
86 static PFNGLGENRENDERBUFFERSEXTPROC vglGenRenderbuffersEXT = NULL;
87 static PFNGLBINDRENDERBUFFEREXTPROC vglBindRenderbufferEXT = NULL;
88 static PFNGLRENDERBUFFERSTORAGEEXTPROC vglRenderbufferStorageEXT = NULL;
89 static PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC vglFramebufferRenderbufferEXT = NULL;
90 static PFNGLDELETERENDERBUFFERSEXTPROC vglDeleteRenderbuffersEXT = NULL;
91
92 #ifndef WIN32
93 #define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
94 #else
95 #define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
96 #endif
97
98 bool InitializeEXT()
99 {
100   vglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glGenFramebuffersEXT" );
101   vglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)GL_GetProcAddress( "glBindFramebufferEXT" );
102   vglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)GL_GetProcAddress( "glFramebufferTexture2DEXT" );
103   vglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)GL_GetProcAddress( "glCheckFramebufferStatusEXT" );
104   vglDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteFramebuffersEXT" );
105   vglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)GL_GetProcAddress( "glGenRenderbuffersEXT" );
106   vglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)GL_GetProcAddress( "glBindRenderbufferEXT" );
107   vglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)GL_GetProcAddress( "glRenderbufferStorageEXT" );
108   vglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)GL_GetProcAddress( "glFramebufferRenderbufferEXT" );
109   vglDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteRenderbuffersEXT" );
110
111   bool ok = vglGenFramebuffersEXT && vglBindFramebufferEXT && vglFramebufferTexture2DEXT &&
112             vglCheckFramebufferStatusEXT && vglDeleteFramebuffersEXT && vglGenRenderbuffersEXT &&
113             vglBindRenderbufferEXT && vglRenderbufferStorageEXT && vglFramebufferRenderbufferEXT &&
114             vglDeleteRenderbuffersEXT;
115
116   return ok;
117 }
118
119 static bool IsEXTInitialized = InitializeEXT();
120
121 OpenGLUtils_FrameBuffer::OpenGLUtils_FrameBuffer()
122   : textureId( 0 ),
123     fboId( 0 ),
124     rboId( 0 )
125 {
126 }
127
128 OpenGLUtils_FrameBuffer::~OpenGLUtils_FrameBuffer()
129 {
130   release();
131 }
132
133 bool OpenGLUtils_FrameBuffer::init( const GLsizei& xSize, const GLsizei& ySize )
134 {
135 #ifdef VTK_OPENGL2
136   int n = 0;
137   std::ostringstream strm;
138   glGetIntegerv(GL_NUM_EXTENSIONS, &n);
139   for (int i = 0; i < n; i++)
140     {
141       const char *exti = (const char *)glGetStringi(GL_EXTENSIONS, i);
142       strm<< exti <<" ";
143     }
144   std::string s = strm.str();
145   const char* ext = s.c_str();
146 #else  
147   char* ext = (char*)glGetString( GL_EXTENSIONS );
148 #endif  
149   if( !IsEXTInitialized || !ext ||
150       strstr( ext, "GL_EXT_framebuffer_object" ) == NULL )
151   {
152     MESSAGE( "Initializing OpenGL FrameBuffer extension failed" );
153     return false;
154   }
155
156   // create a texture object
157   glEnable( GL_TEXTURE_2D );
158   glGenTextures( 1, &textureId );
159   glBindTexture( GL_TEXTURE_2D, textureId );
160   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
161   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
162   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, xSize, ySize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
163   glBindTexture( GL_TEXTURE_2D, 0 );
164
165   // create a renderbuffer object to store depth info
166   vglGenRenderbuffersEXT( 1, &rboId );
167   vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rboId );
168   vglRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, xSize, ySize );
169   vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
170
171   // create a framebuffer object
172   vglGenFramebuffersEXT( 1, &fboId );
173   vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
174
175   // attach the texture to FBO color attachment point
176   vglFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0 );
177
178   // attach the renderbuffer to depth attachment point
179   vglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId );
180
181   // check FBO status
182   GLenum status = vglCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
183
184   // Unbind FBO
185   vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
186
187   return status == GL_FRAMEBUFFER_COMPLETE_EXT;
188 }
189
190 void OpenGLUtils_FrameBuffer::release()
191 {
192   if( !IsEXTInitialized )
193     return;
194
195   glDeleteTextures( 1, &textureId );
196   textureId = 0;
197
198   vglDeleteFramebuffersEXT( 1, &fboId );
199   fboId = 0;
200
201   vglDeleteRenderbuffersEXT( 1, &rboId );
202   rboId = 0;
203 }
204
205 void OpenGLUtils_FrameBuffer::bind()
206 {
207   if( !IsEXTInitialized )
208     return;
209
210   vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
211 }
212
213 void OpenGLUtils_FrameBuffer::unbind()
214 {
215   if( !IsEXTInitialized )
216     return;
217
218   vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
219 }