0030748: Visualization - Marker displayed in immediate layer ruins QT Quick view...
[occt.git] / src / OpenGl / OpenGl_TextureBufferArb.cxx
1 // Created by: Kirill GAVRILOV
2 // Copyright (c) 2013-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <OpenGl_TextureBufferArb.hxx>
16
17 #include <OpenGl_Context.hxx>
18 #include <Standard_Assert.hxx>
19
20
21 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_TextureBufferArb,OpenGl_VertexBuffer)
22
23 // =======================================================================
24 // function : OpenGl_TextureBufferArb
25 // purpose  :
26 // =======================================================================
27 OpenGl_TextureBufferArb::OpenGl_TextureBufferArb()
28 : OpenGl_VertexBuffer(),
29   myTextureId (NO_TEXTURE),
30   myTexFormat (GL_RGBA32F)
31 {
32   //
33 }
34
35 // =======================================================================
36 // function : ~OpenGl_TextureBufferArb
37 // purpose  :
38 // =======================================================================
39 OpenGl_TextureBufferArb::~OpenGl_TextureBufferArb()
40 {
41   Release (NULL);
42 }
43
44 // =======================================================================
45 // function : GetTarget
46 // purpose  :
47 // =======================================================================
48 GLenum OpenGl_TextureBufferArb::GetTarget() const
49 {
50   return GL_TEXTURE_BUFFER; // GL_TEXTURE_BUFFER for OpenGL 3.1+, OpenGL ES 3.2
51 }
52
53 // =======================================================================
54 // function : Release
55 // purpose  :
56 // =======================================================================
57 void OpenGl_TextureBufferArb::Release (OpenGl_Context* theGlCtx)
58 {
59   if (myTextureId != NO_TEXTURE)
60   {
61     // application can not handle this case by exception - this is bug in code
62     Standard_ASSERT_RETURN (theGlCtx != NULL,
63       "OpenGl_TextureBufferExt destroyed without GL context! Possible GPU memory leakage...",);
64
65     if (theGlCtx->IsValid())
66     {
67       glDeleteTextures (1, &myTextureId);
68     }
69     myTextureId = NO_TEXTURE;
70   }
71   OpenGl_VertexBuffer::Release (theGlCtx);
72 }
73
74 // =======================================================================
75 // function : Create
76 // purpose  :
77 // =======================================================================
78 bool OpenGl_TextureBufferArb::Create (const Handle(OpenGl_Context)& theGlCtx)
79 {
80   if (!OpenGl_VertexBuffer::Create (theGlCtx))
81   {
82     return false;
83   }
84
85   if (myTextureId == NO_TEXTURE)
86   {
87     glGenTextures (1, &myTextureId);
88   }
89   return myTextureId != NO_TEXTURE;
90 }
91
92 // =======================================================================
93 // function : Init
94 // purpose  :
95 // =======================================================================
96 bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
97                                     const GLuint   theComponentsNb,
98                                     const GLsizei  theElemsNb,
99                                     const GLfloat* theData)
100 {
101   if (theGlCtx->arbTBO == NULL)
102   {
103     return false;
104   }
105   else if (theComponentsNb < 1
106         || theComponentsNb > 4)
107   {
108     // unsupported format
109     return false;
110   }
111   else if (theComponentsNb == 3
112        && !theGlCtx->arbTboRGB32)
113   {
114     return false;
115   }
116   else if (!Create (theGlCtx)
117         || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
118   {
119     return false;
120   }
121
122   switch (theComponentsNb)
123   {
124     case 1: myTexFormat = GL_R32F;    break;
125     case 2: myTexFormat = GL_RG32F;   break;
126     case 3: myTexFormat = GL_RGB32F;  break; // GL_ARB_texture_buffer_object_rgb32
127     case 4: myTexFormat = GL_RGBA32F; break;
128   }
129
130   Bind (theGlCtx);
131   BindTexture  (theGlCtx, Graphic3d_TextureUnit_0);
132   theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
133   UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
134   Unbind (theGlCtx);
135   return true;
136 }
137
138 // =======================================================================
139 // function : Init
140 // purpose  :
141 // =======================================================================
142 bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
143                                     const GLuint   theComponentsNb,
144                                     const GLsizei  theElemsNb,
145                                     const GLuint*  theData)
146 {
147   if (theGlCtx->arbTBO == NULL)
148   {
149     return false;
150   }
151   else if (theComponentsNb < 1
152         || theComponentsNb > 4)
153   {
154     // unsupported format
155     return false;
156   }
157   else if (theComponentsNb == 3
158        && !theGlCtx->arbTboRGB32)
159   {
160     return false;
161   }
162   else if (!Create (theGlCtx)
163         || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
164   {
165     return false;
166   }
167
168   switch (theComponentsNb)
169   {
170     case 1: myTexFormat = GL_R32I;    break;
171     case 2: myTexFormat = GL_RG32I;   break;
172     case 3: myTexFormat = GL_RGB32I;  break;
173     case 4: myTexFormat = GL_RGBA32I; break;
174   }
175
176   Bind (theGlCtx);
177   BindTexture  (theGlCtx, Graphic3d_TextureUnit_0);
178   theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
179   UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
180   Unbind (theGlCtx);
181   return true;
182 }
183
184 // =======================================================================
185 // function : Init
186 // purpose  :
187 // =======================================================================
188 bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
189                                     const GLuint theComponentsNb,
190                                     const GLsizei theElemsNb,
191                                     const GLushort* theData)
192 {
193   if (theGlCtx->arbTBO == NULL)
194   {
195     return false;
196   }
197   else if (theComponentsNb < 1
198         || theComponentsNb > 4)
199   {
200     // unsupported format
201     return false;
202   }
203   else if (!Create (theGlCtx)
204         || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
205   {
206     return false;
207   }
208
209   switch (theComponentsNb)
210   {
211     case 1: myTexFormat = GL_R16I;    break;
212     case 2: myTexFormat = GL_RG16I;   break;
213     case 3: myTexFormat = GL_RGB16I;  break;
214     case 4: myTexFormat = GL_RGBA16I; break;
215   }
216
217   Bind (theGlCtx);
218   BindTexture  (theGlCtx, Graphic3d_TextureUnit_0);
219   theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
220   UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
221   Unbind (theGlCtx);
222   return true;
223 }
224
225 // =======================================================================
226 // function : Init
227 // purpose  :
228 // =======================================================================
229 bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
230                                     const GLuint   theComponentsNb,
231                                     const GLsizei  theElemsNb,
232                                     const GLubyte*  theData)
233 {
234   if (theGlCtx->arbTBO == NULL)
235   {
236     return false;
237   }
238   else if (theComponentsNb < 1
239         || theComponentsNb > 4)
240   {
241     // unsupported format
242     return false;
243   }
244   else if (!Create (theGlCtx)
245         || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
246   {
247     return false;
248   }
249
250   switch (theComponentsNb)
251   {
252     case 1: myTexFormat = GL_R8;    break;
253     case 2: myTexFormat = GL_RG8;   break;
254     case 3: myTexFormat = GL_RGB8;  break;
255     case 4: myTexFormat = GL_RGBA8; break;
256   }
257
258   Bind (theGlCtx);
259   BindTexture  (theGlCtx, Graphic3d_TextureUnit_0);
260   theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
261   UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
262   Unbind (theGlCtx);
263   return true;
264 }
265
266 // =======================================================================
267 // function : BindTexture
268 // purpose  :
269 // =======================================================================
270 void OpenGl_TextureBufferArb::BindTexture (const Handle(OpenGl_Context)& theGlCtx,
271                                            const Graphic3d_TextureUnit   theTextureUnit) const
272 {
273   theGlCtx->core20fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
274   glBindTexture (GetTarget(), myTextureId);
275 }
276
277 // =======================================================================
278 // function : UnbindTexture
279 // purpose  :
280 // =======================================================================
281 void OpenGl_TextureBufferArb::UnbindTexture (const Handle(OpenGl_Context)& theGlCtx,
282                                              const Graphic3d_TextureUnit   theTextureUnit) const
283 {
284   theGlCtx->core20fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
285   glBindTexture (GetTarget(), NO_TEXTURE);
286 }