0024023: Revamp the OCCT Handle -- automatic
[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 // =======================================================================
22 // function : OpenGl_TextureBufferArb
23 // purpose  :
24 // =======================================================================
25 OpenGl_TextureBufferArb::OpenGl_TextureBufferArb()
26 : OpenGl_VertexBuffer(),
27   myTextureId (NO_TEXTURE),
28   myTexFormat (GL_RGBA32F)
29 {
30   //
31 }
32
33 // =======================================================================
34 // function : ~OpenGl_TextureBufferArb
35 // purpose  :
36 // =======================================================================
37 OpenGl_TextureBufferArb::~OpenGl_TextureBufferArb()
38 {
39   Release (NULL);
40 }
41
42 // =======================================================================
43 // function : GetTarget
44 // purpose  :
45 // =======================================================================
46 GLenum OpenGl_TextureBufferArb::GetTarget() const
47 {
48   return GL_TEXTURE_BUFFER_ARB; // GL_TEXTURE_BUFFER for OpenGL 3.1+
49 }
50
51 // =======================================================================
52 // function : Release
53 // purpose  :
54 // =======================================================================
55 void OpenGl_TextureBufferArb::Release (OpenGl_Context* theGlCtx)
56 {
57   if (myTextureId != NO_TEXTURE)
58   {
59     // application can not handle this case by exception - this is bug in code
60     Standard_ASSERT_RETURN (theGlCtx != NULL,
61       "OpenGl_TextureBufferExt destroyed without GL context! Possible GPU memory leakage...",);
62
63     if (theGlCtx->IsValid())
64     {
65       glDeleteTextures (1, &myTextureId);
66     }
67     myTextureId = NO_TEXTURE;
68   }
69   OpenGl_VertexBuffer::Release (theGlCtx);
70 }
71
72 // =======================================================================
73 // function : Create
74 // purpose  :
75 // =======================================================================
76 bool OpenGl_TextureBufferArb::Create (const Handle(OpenGl_Context)& theGlCtx)
77 {
78   if (!OpenGl_VertexBuffer::Create (theGlCtx))
79   {
80     return false;
81   }
82
83   if (myTextureId == NO_TEXTURE)
84   {
85     glGenTextures (1, &myTextureId);
86   }
87   return myTextureId != NO_TEXTURE;
88 }
89
90 // =======================================================================
91 // function : Init
92 // purpose  :
93 // =======================================================================
94 bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
95                                     const GLuint   theComponentsNb,
96                                     const GLsizei  theElemsNb,
97                                     const GLfloat* theData)
98 {
99 #if !defined(GL_ES_VERSION_2_0)
100   if (theComponentsNb < 1
101    || theComponentsNb > 4)
102   {
103     // unsupported format
104     return false;
105   }
106   else if (theComponentsNb == 3
107        && !theGlCtx->arbTboRGB32)
108   {
109     return false;
110   }
111   else if (!Create (theGlCtx)
112         || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
113   {
114     return false;
115   }
116
117   switch (theComponentsNb)
118   {
119     case 1: myTexFormat = GL_R32F;    break;
120     case 2: myTexFormat = GL_RG32F;   break;
121     case 3: myTexFormat = GL_RGB32F;  break; // GL_ARB_texture_buffer_object_rgb32
122     case 4: myTexFormat = GL_RGBA32F; break;
123   }
124
125   Bind (theGlCtx);
126   BindTexture (theGlCtx);
127   theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
128   UnbindTexture (theGlCtx);
129   Unbind (theGlCtx);
130   return true;
131 #else
132   return false;
133 #endif
134 }
135
136 // =======================================================================
137 // function : Init
138 // purpose  :
139 // =======================================================================
140 bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
141                                     const GLuint   theComponentsNb,
142                                     const GLsizei  theElemsNb,
143                                     const GLuint*  theData)
144 {
145 #if !defined(GL_ES_VERSION_2_0)
146   if (theComponentsNb < 1
147    || theComponentsNb > 4)
148   {
149     // unsupported format
150     return false;
151   }
152   else if (theComponentsNb == 3
153        && !theGlCtx->arbTboRGB32)
154   {
155     return false;
156   }
157   else if (!Create (theGlCtx)
158         || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
159   {
160     return false;
161   }
162
163   switch (theComponentsNb)
164   {
165     case 1: myTexFormat = GL_R32I;    break;
166     case 2: myTexFormat = GL_RG32I;   break;
167     case 3: myTexFormat = GL_RGB32I;  break;
168     case 4: myTexFormat = GL_RGBA32I; break;
169   }
170
171   Bind (theGlCtx);
172   BindTexture (theGlCtx);
173   theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
174   UnbindTexture (theGlCtx);
175   Unbind (theGlCtx);
176   return true;
177 #else
178   return false;
179 #endif
180 }
181
182 // =======================================================================
183 // function : BindTexture
184 // purpose  :
185 // =======================================================================
186 void OpenGl_TextureBufferArb::BindTexture (const Handle(OpenGl_Context)& theGlCtx,
187                                            const GLenum theTextureUnit) const
188 {
189   theGlCtx->core20fwd->glActiveTexture (theTextureUnit);
190   glBindTexture (GetTarget(), myTextureId);
191 }
192
193 // =======================================================================
194 // function : UnbindTexture
195 // purpose  :
196 // =======================================================================
197 void OpenGl_TextureBufferArb::UnbindTexture (const Handle(OpenGl_Context)& theGlCtx,
198                                              const GLenum theTextureUnit) const
199 {
200   theGlCtx->core20fwd->glActiveTexture (theTextureUnit);
201   glBindTexture (GetTarget(), NO_TEXTURE);
202 }