0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / OpenGl / OpenGl_TextureBuffer.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_TextureBuffer.hxx>
16
17 #include <OpenGl_ArbTBO.hxx>
18 #include <OpenGl_GlCore20.hxx>
19 #include <OpenGl_Context.hxx>
20 #include <Standard_Assert.hxx>
21
22 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_TextureBuffer, OpenGl_Buffer)
23
24 // =======================================================================
25 // function : OpenGl_TextureBuffer
26 // purpose  :
27 // =======================================================================
28 OpenGl_TextureBuffer::OpenGl_TextureBuffer()
29 : OpenGl_Buffer(),
30   myTextureId (NO_TEXTURE),
31   myTexFormat (GL_RGBA32F)
32 {
33   //
34 }
35
36 // =======================================================================
37 // function : ~OpenGl_TextureBuffer
38 // purpose  :
39 // =======================================================================
40 OpenGl_TextureBuffer::~OpenGl_TextureBuffer()
41 {
42   Release (NULL);
43 }
44
45 // =======================================================================
46 // function : GetTarget
47 // purpose  :
48 // =======================================================================
49 unsigned int OpenGl_TextureBuffer::GetTarget() const
50 {
51   return GL_TEXTURE_BUFFER; // GL_TEXTURE_BUFFER for OpenGL 3.1+, OpenGL ES 3.2
52 }
53
54 // =======================================================================
55 // function : Release
56 // purpose  :
57 // =======================================================================
58 void OpenGl_TextureBuffer::Release (OpenGl_Context* theGlCtx)
59 {
60   if (myTextureId != NO_TEXTURE)
61   {
62     // application can not handle this case by exception - this is bug in code
63     Standard_ASSERT_RETURN (theGlCtx != NULL,
64       "OpenGl_TextureBuffer destroyed without GL context! Possible GPU memory leakage...",);
65
66     if (theGlCtx->IsValid())
67     {
68       theGlCtx->core20fwd->glDeleteTextures (1, &myTextureId);
69     }
70     myTextureId = NO_TEXTURE;
71   }
72   base_type::Release (theGlCtx);
73 }
74
75 // =======================================================================
76 // function : Create
77 // purpose  :
78 // =======================================================================
79 bool OpenGl_TextureBuffer::Create (const Handle(OpenGl_Context)& theGlCtx)
80 {
81   if (!base_type::Create (theGlCtx))
82   {
83     return false;
84   }
85
86   if (myTextureId == NO_TEXTURE)
87   {
88     theGlCtx->core20fwd->glGenTextures (1, &myTextureId);
89   }
90   return myTextureId != NO_TEXTURE;
91 }
92
93 // =======================================================================
94 // function : Init
95 // purpose  :
96 // =======================================================================
97 bool OpenGl_TextureBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
98                                  const unsigned int     theComponentsNb,
99                                  const Standard_Integer theElemsNb,
100                                  const float* theData)
101 {
102   if (theGlCtx->arbTBO == NULL)
103   {
104     return false;
105   }
106   else if (theComponentsNb < 1
107         || theComponentsNb > 4)
108   {
109     // unsupported format
110     return false;
111   }
112   else if (theComponentsNb == 3
113        && !theGlCtx->arbTboRGB32)
114   {
115     return false;
116   }
117   else if (!Create (theGlCtx)
118         || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
119   {
120     return false;
121   }
122
123   switch (theComponentsNb)
124   {
125     case 1: myTexFormat = GL_R32F;    break;
126     case 2: myTexFormat = GL_RG32F;   break;
127     case 3: myTexFormat = GL_RGB32F;  break; // GL_ARB_texture_buffer_object_rgb32
128     case 4: myTexFormat = GL_RGBA32F; break;
129   }
130
131   Bind (theGlCtx);
132   BindTexture  (theGlCtx, Graphic3d_TextureUnit_0);
133   theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
134   UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
135   Unbind (theGlCtx);
136   return true;
137 }
138
139 // =======================================================================
140 // function : Init
141 // purpose  :
142 // =======================================================================
143 bool OpenGl_TextureBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
144                                  const unsigned int     theComponentsNb,
145                                  const Standard_Integer theElemsNb,
146                                  const unsigned int*    theData)
147 {
148   if (theGlCtx->arbTBO == NULL)
149   {
150     return false;
151   }
152   else if (theComponentsNb < 1
153         || theComponentsNb > 4)
154   {
155     // unsupported format
156     return false;
157   }
158   else if (theComponentsNb == 3
159        && !theGlCtx->arbTboRGB32)
160   {
161     return false;
162   }
163   else if (!Create (theGlCtx)
164         || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
165   {
166     return false;
167   }
168
169   switch (theComponentsNb)
170   {
171     case 1: myTexFormat = GL_R32I;    break;
172     case 2: myTexFormat = GL_RG32I;   break;
173     case 3: myTexFormat = GL_RGB32I;  break;
174     case 4: myTexFormat = GL_RGBA32I; break;
175   }
176
177   Bind (theGlCtx);
178   BindTexture  (theGlCtx, Graphic3d_TextureUnit_0);
179   theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
180   UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
181   Unbind (theGlCtx);
182   return true;
183 }
184
185 // =======================================================================
186 // function : Init
187 // purpose  :
188 // =======================================================================
189 bool OpenGl_TextureBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
190                                  const unsigned int     theComponentsNb,
191                                  const Standard_Integer theElemsNb,
192                                  const unsigned short*  theData)
193 {
194   if (theGlCtx->arbTBO == NULL)
195   {
196     return false;
197   }
198   else if (theComponentsNb < 1
199         || theComponentsNb > 4)
200   {
201     // unsupported format
202     return false;
203   }
204   else if (!Create (theGlCtx)
205         || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
206   {
207     return false;
208   }
209
210   switch (theComponentsNb)
211   {
212     case 1: myTexFormat = GL_R16I;    break;
213     case 2: myTexFormat = GL_RG16I;   break;
214     case 3: myTexFormat = GL_RGB16I;  break;
215     case 4: myTexFormat = GL_RGBA16I; break;
216   }
217
218   Bind (theGlCtx);
219   BindTexture  (theGlCtx, Graphic3d_TextureUnit_0);
220   theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
221   UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
222   Unbind (theGlCtx);
223   return true;
224 }
225
226 // =======================================================================
227 // function : Init
228 // purpose  :
229 // =======================================================================
230 bool OpenGl_TextureBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
231                                  const unsigned int     theComponentsNb,
232                                  const Standard_Integer theElemsNb,
233                                  const Standard_Byte*   theData)
234 {
235   if (theGlCtx->arbTBO == NULL)
236   {
237     return false;
238   }
239   else if (theComponentsNb < 1
240         || theComponentsNb > 4)
241   {
242     // unsupported format
243     return false;
244   }
245   else if (!Create (theGlCtx)
246         || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
247   {
248     return false;
249   }
250
251   switch (theComponentsNb)
252   {
253     case 1: myTexFormat = GL_R8;    break;
254     case 2: myTexFormat = GL_RG8;   break;
255     case 3: myTexFormat = GL_RGB8;  break;
256     case 4: myTexFormat = GL_RGBA8; break;
257   }
258
259   Bind (theGlCtx);
260   BindTexture  (theGlCtx, Graphic3d_TextureUnit_0);
261   theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
262   UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
263   Unbind (theGlCtx);
264   return true;
265 }
266
267 // =======================================================================
268 // function : BindTexture
269 // purpose  :
270 // =======================================================================
271 void OpenGl_TextureBuffer::BindTexture (const Handle(OpenGl_Context)& theGlCtx,
272                                         const Graphic3d_TextureUnit   theTextureUnit) const
273 {
274   theGlCtx->core20fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
275   theGlCtx->core20fwd->glBindTexture (GetTarget(), myTextureId);
276 }
277
278 // =======================================================================
279 // function : UnbindTexture
280 // purpose  :
281 // =======================================================================
282 void OpenGl_TextureBuffer::UnbindTexture (const Handle(OpenGl_Context)& theGlCtx,
283                                           const Graphic3d_TextureUnit   theTextureUnit) const
284 {
285   theGlCtx->core20fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
286   theGlCtx->core20fwd->glBindTexture (GetTarget(), NO_TEXTURE);
287 }