1 // Created by: Kirill GAVRILOV
2 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <OpenGl_TextureBuffer.hxx>
17 #include <OpenGl_ArbTBO.hxx>
18 #include <OpenGl_GlCore20.hxx>
19 #include <OpenGl_Context.hxx>
20 #include <Standard_Assert.hxx>
22 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_TextureBuffer, OpenGl_Buffer)
24 // =======================================================================
25 // function : OpenGl_TextureBuffer
27 // =======================================================================
28 OpenGl_TextureBuffer::OpenGl_TextureBuffer()
30 myTextureId (NO_TEXTURE),
31 myTexFormat (GL_RGBA32F)
36 // =======================================================================
37 // function : ~OpenGl_TextureBuffer
39 // =======================================================================
40 OpenGl_TextureBuffer::~OpenGl_TextureBuffer()
45 // =======================================================================
46 // function : GetTarget
48 // =======================================================================
49 unsigned int OpenGl_TextureBuffer::GetTarget() const
51 return GL_TEXTURE_BUFFER; // GL_TEXTURE_BUFFER for OpenGL 3.1+, OpenGL ES 3.2
54 // =======================================================================
57 // =======================================================================
58 void OpenGl_TextureBuffer::Release (OpenGl_Context* theGlCtx)
60 if (myTextureId != NO_TEXTURE)
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...",);
66 if (theGlCtx->IsValid())
68 theGlCtx->core20fwd->glDeleteTextures (1, &myTextureId);
70 myTextureId = NO_TEXTURE;
72 base_type::Release (theGlCtx);
75 // =======================================================================
78 // =======================================================================
79 bool OpenGl_TextureBuffer::Create (const Handle(OpenGl_Context)& theGlCtx)
81 if (!base_type::Create (theGlCtx))
86 if (myTextureId == NO_TEXTURE)
88 theGlCtx->core20fwd->glGenTextures (1, &myTextureId);
90 return myTextureId != NO_TEXTURE;
93 // =======================================================================
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)
102 if (theGlCtx->arbTBO == NULL)
106 else if (theComponentsNb < 1
107 || theComponentsNb > 4)
109 // unsupported format
112 else if (theComponentsNb == 3
113 && !theGlCtx->arbTboRGB32)
117 else if (!Create (theGlCtx)
118 || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
123 switch (theComponentsNb)
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;
132 BindTexture (theGlCtx, Graphic3d_TextureUnit_0);
133 theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
134 UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
139 // =======================================================================
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)
148 if (theGlCtx->arbTBO == NULL)
152 else if (theComponentsNb < 1
153 || theComponentsNb > 4)
155 // unsupported format
158 else if (theComponentsNb == 3
159 && !theGlCtx->arbTboRGB32)
163 else if (!Create (theGlCtx)
164 || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
169 switch (theComponentsNb)
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;
178 BindTexture (theGlCtx, Graphic3d_TextureUnit_0);
179 theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
180 UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
185 // =======================================================================
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)
194 if (theGlCtx->arbTBO == NULL)
198 else if (theComponentsNb < 1
199 || theComponentsNb > 4)
201 // unsupported format
204 else if (!Create (theGlCtx)
205 || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
210 switch (theComponentsNb)
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;
219 BindTexture (theGlCtx, Graphic3d_TextureUnit_0);
220 theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
221 UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
226 // =======================================================================
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)
235 if (theGlCtx->arbTBO == NULL)
239 else if (theComponentsNb < 1
240 || theComponentsNb > 4)
242 // unsupported format
245 else if (!Create (theGlCtx)
246 || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
251 switch (theComponentsNb)
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;
260 BindTexture (theGlCtx, Graphic3d_TextureUnit_0);
261 theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
262 UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
267 // =======================================================================
268 // function : BindTexture
270 // =======================================================================
271 void OpenGl_TextureBuffer::BindTexture (const Handle(OpenGl_Context)& theGlCtx,
272 const Graphic3d_TextureUnit theTextureUnit) const
274 theGlCtx->core20fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
275 theGlCtx->core20fwd->glBindTexture (GetTarget(), myTextureId);
278 // =======================================================================
279 // function : UnbindTexture
281 // =======================================================================
282 void OpenGl_TextureBuffer::UnbindTexture (const Handle(OpenGl_Context)& theGlCtx,
283 const Graphic3d_TextureUnit theTextureUnit) const
285 theGlCtx->core20fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
286 theGlCtx->core20fwd->glBindTexture (GetTarget(), NO_TEXTURE);