0025133: TKOpenGl - Crash on closing a view containing presentations with capping
[occt.git] / src / OpenGl / OpenGl_VertexBuffer.cxx
... / ...
CommitLineData
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_VertexBuffer.hxx>
16
17#include <OpenGl_Context.hxx>
18#include <Standard_Assert.hxx>
19
20IMPLEMENT_STANDARD_HANDLE (OpenGl_VertexBuffer, OpenGl_Resource)
21IMPLEMENT_STANDARD_RTTIEXT(OpenGl_VertexBuffer, OpenGl_Resource)
22
23// =======================================================================
24// function : OpenGl_VertexBuffer
25// purpose :
26// =======================================================================
27OpenGl_VertexBuffer::OpenGl_VertexBuffer()
28: OpenGl_Resource(),
29 myBufferId (NO_BUFFER),
30 myComponentsNb (4),
31 myElemsNb (0),
32 myDataType (GL_FLOAT)
33{
34 //
35}
36
37// =======================================================================
38// function : ~OpenGl_VertexBuffer
39// purpose :
40// =======================================================================
41OpenGl_VertexBuffer::~OpenGl_VertexBuffer()
42{
43 Release (NULL);
44}
45
46// =======================================================================
47// function : GetTarget
48// purpose :
49// =======================================================================
50GLenum OpenGl_VertexBuffer::GetTarget() const
51{
52 return GL_ARRAY_BUFFER;
53}
54
55// =======================================================================
56// function : Create
57// purpose :
58// =======================================================================
59bool OpenGl_VertexBuffer::Create (const Handle(OpenGl_Context)& theGlCtx)
60{
61 if (myBufferId == NO_BUFFER)
62 {
63 theGlCtx->core15->glGenBuffers (1, &myBufferId);
64 }
65 return myBufferId != NO_BUFFER;
66}
67
68// =======================================================================
69// function : Release
70// purpose :
71// =======================================================================
72void OpenGl_VertexBuffer::Release (OpenGl_Context* theGlCtx)
73{
74 if (myBufferId == NO_BUFFER)
75 {
76 return;
77 }
78
79 // application can not handle this case by exception - this is bug in code
80 Standard_ASSERT_RETURN (theGlCtx != NULL,
81 "OpenGl_VertexBuffer destroyed without GL context! Possible GPU memory leakage...",);
82
83 if (theGlCtx->IsValid())
84 {
85 theGlCtx->core15->glDeleteBuffers (1, &myBufferId);
86 }
87 myBufferId = NO_BUFFER;
88}
89
90// =======================================================================
91// function : Bind
92// purpose :
93// =======================================================================
94void OpenGl_VertexBuffer::Bind (const Handle(OpenGl_Context)& theGlCtx) const
95{
96 theGlCtx->core15->glBindBuffer (GetTarget(), myBufferId);
97}
98
99// =======================================================================
100// function : Unbind
101// purpose :
102// =======================================================================
103void OpenGl_VertexBuffer::Unbind (const Handle(OpenGl_Context)& theGlCtx) const
104{
105 theGlCtx->core15->glBindBuffer (GetTarget(), NO_BUFFER);
106}
107
108// =======================================================================
109// function : init
110// purpose :
111// =======================================================================
112bool OpenGl_VertexBuffer::init (const Handle(OpenGl_Context)& theGlCtx,
113 const GLuint theComponentsNb,
114 const GLsizei theElemsNb,
115 const void* theData,
116 const GLenum theDataType,
117 const GLsizei theStride)
118{
119 if (!Create (theGlCtx))
120 {
121 return false;
122 }
123
124 Bind (theGlCtx);
125 myDataType = theDataType;
126 myComponentsNb = theComponentsNb;
127 myElemsNb = theElemsNb;
128 theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * theStride, theData, GL_STATIC_DRAW);
129 bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
130 Unbind (theGlCtx);
131 return isDone;
132}
133
134// =======================================================================
135// function : subData
136// purpose :
137// =======================================================================
138bool OpenGl_VertexBuffer::subData (const Handle(OpenGl_Context)& theGlCtx,
139 const GLsizei theElemFrom,
140 const GLsizei theElemsNb,
141 const void* theData,
142 const GLenum theDataType)
143{
144 if (!IsValid() || myDataType != theDataType ||
145 theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb))
146 {
147 return false;
148 }
149
150 Bind (theGlCtx);
151 const size_t aDataSize = sizeOfGlType (theDataType);
152 theGlCtx->core15->glBufferSubData (GetTarget(),
153 GLintptr(theElemFrom) * GLintptr (myComponentsNb) * aDataSize, // offset in bytes
154 GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * aDataSize, // size in bytes
155 theData);
156 bool isDone = (glGetError() == GL_NO_ERROR); // some dummy error
157 Unbind (theGlCtx);
158 return isDone;
159}
160
161// =======================================================================
162// function : BindVertexAttrib
163// purpose :
164// =======================================================================
165void OpenGl_VertexBuffer::BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
166 const GLuint theAttribLoc) const
167{
168 if (!IsValid() || theAttribLoc == GLuint (-1))
169 {
170 return;
171 }
172 Bind (theGlCtx);
173 theGlCtx->core20->glEnableVertexAttribArray (theAttribLoc);
174 theGlCtx->core20->glVertexAttribPointer (theAttribLoc, GLint (myComponentsNb), myDataType, GL_FALSE, 0, NULL);
175}
176
177// =======================================================================
178// function : UnbindVertexAttrib
179// purpose :
180// =======================================================================
181void OpenGl_VertexBuffer::UnbindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
182 const GLuint theAttribLoc) const
183{
184 if (!IsValid() || theAttribLoc == GLuint (-1))
185 {
186 return;
187 }
188 theGlCtx->core20->glDisableVertexAttribArray (theAttribLoc);
189 Unbind (theGlCtx);
190}
191
192// =======================================================================
193// function : BindFixed
194// purpose :
195// =======================================================================
196void OpenGl_VertexBuffer::BindFixed (const Handle(OpenGl_Context)& theGlCtx,
197 const GLenum theMode) const
198{
199 if (!IsValid())
200 {
201 return;
202 }
203
204 Bind (theGlCtx);
205 glEnableClientState (theMode);
206 switch (theMode)
207 {
208 case GL_VERTEX_ARRAY:
209 {
210 glVertexPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
211 break;
212 }
213 case GL_NORMAL_ARRAY:
214 {
215 glNormalPointer (myDataType, 0, NULL);
216 break;
217 }
218 case GL_TEXTURE_COORD_ARRAY:
219 {
220 glTexCoordPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
221 break;
222 }
223 case GL_COLOR_ARRAY:
224 {
225 glColorPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
226 glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
227 glEnable (GL_COLOR_MATERIAL);
228 break;
229 }
230 default: break;
231 }
232}
233
234// =======================================================================
235// function : UnbindFixed
236// purpose :
237// =======================================================================
238void OpenGl_VertexBuffer::UnbindFixed (const Handle(OpenGl_Context)& theGlCtx,
239 const GLenum theMode) const
240{
241 if (!IsValid())
242 {
243 return;
244 }
245 Unbind (theGlCtx);
246 glDisableClientState (theMode);
247 if (theMode == GL_COLOR_ARRAY)
248 {
249 glDisable (GL_COLOR_MATERIAL);
250 }
251}
252
253// =======================================================================
254// function : BindFixed
255// purpose :
256// =======================================================================
257void OpenGl_VertexBuffer::BindFixed (const Handle(OpenGl_Context)& ) const
258{
259 //
260}
261
262// =======================================================================
263// function : BindFixedPosition
264// purpose :
265// =======================================================================
266void OpenGl_VertexBuffer::BindFixedPosition (const Handle(OpenGl_Context)& ) const
267{
268 //
269}
270
271// =======================================================================
272// function : UnbindFixed
273// purpose :
274// =======================================================================
275void OpenGl_VertexBuffer::UnbindFixed (const Handle(OpenGl_Context)& ) const
276{
277 //
278}
279
280// =======================================================================
281// function : HasColorAttribute
282// purpose :
283// =======================================================================
284bool OpenGl_VertexBuffer::HasColorAttribute() const
285{
286 return false;
287}