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