0023226: Extend OpenGl_Context to store map of shared GPU resources
[occt.git] / src / OpenGl / OpenGl_VertexBuffer.cxx
CommitLineData
5e27df78 1// Created by: Kirill GAVRILOV
2// Copyright (c) 2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
19#include <OpenGl_VertexBuffer.hxx>
20
21#include <OpenGl_Context.hxx>
22#include <Standard_Assert.hxx>
23
24IMPLEMENT_STANDARD_HANDLE (OpenGl_VertexBuffer, OpenGl_Resource)
25IMPLEMENT_STANDARD_RTTIEXT(OpenGl_VertexBuffer, OpenGl_Resource)
26
27// =======================================================================
28// function : OpenGl_VertexBuffer
29// purpose :
30// =======================================================================
31OpenGl_VertexBuffer::OpenGl_VertexBuffer()
32: OpenGl_Resource(),
33 myBufferId (NO_BUFFER),
34 myComponentsNb (4),
35 myElemsNb (0),
36 myDataType (GL_FLOAT)
37{
38 //
39}
40
41// =======================================================================
42// function : ~OpenGl_VertexBuffer
43// purpose :
44// =======================================================================
45OpenGl_VertexBuffer::~OpenGl_VertexBuffer()
46{
47 Release (NULL);
48}
49
50// =======================================================================
51// function : GetTarget
52// purpose :
53// =======================================================================
54GLenum OpenGl_VertexBuffer::GetTarget() const
55{
56 return GL_ARRAY_BUFFER;
57}
58
59// =======================================================================
60// function : Create
61// purpose :
62// =======================================================================
63bool OpenGl_VertexBuffer::Create (const Handle(OpenGl_Context)& theGlCtx)
64{
65 if (myBufferId == NO_BUFFER)
66 {
67 theGlCtx->core15->glGenBuffers (1, &myBufferId);
68 }
69 return myBufferId != NO_BUFFER;
70}
71
72// =======================================================================
73// function : Release
74// purpose :
75// =======================================================================
76void OpenGl_VertexBuffer::Release (const OpenGl_Context* theGlCtx)
77{
78 if (myBufferId == NO_BUFFER)
79 {
80 return;
81 }
82
83 // application can not handle this case by exception - this is bug in code
84 Standard_ASSERT_RETURN (theGlCtx != NULL,
85 "OpenGl_VertexBuffer destroyed without GL context! Possible GPU memory leakage...",);
86
87 theGlCtx->core15->glDeleteBuffers (1, &myBufferId);
88 myBufferId = NO_BUFFER;
89}
90
91// =======================================================================
92// function : Bind
93// purpose :
94// =======================================================================
95void OpenGl_VertexBuffer::Bind (const Handle(OpenGl_Context)& theGlCtx) const
96{
97 theGlCtx->core15->glBindBuffer (GetTarget(), myBufferId);
98}
99
100// =======================================================================
101// function : Unbind
102// purpose :
103// =======================================================================
104void OpenGl_VertexBuffer::Unbind (const Handle(OpenGl_Context)& theGlCtx) const
105{
106 theGlCtx->core15->glBindBuffer (GetTarget(), NO_BUFFER);
107}
108
109// =======================================================================
110// function : Init
111// purpose :
112// =======================================================================
113bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
114 const GLuint theComponentsNb,
115 const GLsizei theElemsNb,
116 const GLfloat* theData)
117{
118 if (!Create (theGlCtx))
119 {
120 return false;
121 }
122
123 Bind (theGlCtx);
124 myDataType = GL_FLOAT;
125 myComponentsNb = theComponentsNb;
126 myElemsNb = theElemsNb;
127 theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLfloat), theData, GL_STATIC_DRAW);
128 bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
129 Unbind (theGlCtx);
130 return isDone;
131}
132
133// =======================================================================
134// function : SubData
135// purpose :
136// =======================================================================
137bool OpenGl_VertexBuffer::SubData (const Handle(OpenGl_Context)& theGlCtx,
138 const GLsizei theElemFrom,
139 const GLsizei theElemsNb,
140 const GLfloat* theData)
141{
142 if (!IsValid() || myDataType != GL_FLOAT ||
143 theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb))
144 {
145 return false;
146 }
147
148 Bind (theGlCtx);
149 theGlCtx->core15->glBufferSubData (GetTarget(),
150 GLintptr(theElemFrom) * GLintptr(myComponentsNb) * sizeof(GLfloat), // offset in bytes
151 GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLfloat), // size in bytes
152 theData);
153 bool isDone = (glGetError() == GL_NO_ERROR); // some dummy error
154 Unbind (theGlCtx);
155 return isDone;
156}
157
158// =======================================================================
159// function : Init
160// purpose :
161// =======================================================================
162bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
163 const GLuint theComponentsNb,
164 const GLsizei theElemsNb,
165 const GLuint* theData)
166{
167 if (!Create (theGlCtx))
168 {
169 return false;
170 }
171
172 Bind (theGlCtx);
173 myDataType = GL_UNSIGNED_INT;
174 myComponentsNb = theComponentsNb;
175 myElemsNb = theElemsNb;
176 theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLuint), theData, GL_STATIC_DRAW);
177 bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
178 Unbind (theGlCtx);
179 return isDone;
180}
181
182// =======================================================================
183// function : Init
184// purpose :
185// =======================================================================
186bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
187 const GLuint theComponentsNb,
188 const GLsizei theElemsNb,
189 const GLubyte* theData)
190{
191 if (!Create (theGlCtx))
192 {
193 return false;
194 }
195
196 Bind (theGlCtx);
197 myDataType = GL_UNSIGNED_BYTE;
198 myComponentsNb = theComponentsNb;
199 myElemsNb = theElemsNb;
200 theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLubyte), theData, GL_STATIC_DRAW);
201 bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
202 Unbind (theGlCtx);
203 return isDone;
204}
205
206// =======================================================================
207// function : BindVertexAttrib
208// purpose :
209// =======================================================================
210void OpenGl_VertexBuffer::BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
211 const GLuint theAttribLoc) const
212{
213 if (!IsValid() || theAttribLoc == GLuint (-1))
214 {
215 return;
216 }
217 Bind (theGlCtx);
218 theGlCtx->core20->glEnableVertexAttribArray (theAttribLoc);
219 theGlCtx->core20->glVertexAttribPointer (theAttribLoc, GLint (myComponentsNb), myDataType, GL_FALSE, 0, NULL);
220}
221
222// =======================================================================
223// function : UnbindVertexAttrib
224// purpose :
225// =======================================================================
226void OpenGl_VertexBuffer::UnbindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
227 const GLuint theAttribLoc) const
228{
229 if (!IsValid() || theAttribLoc == GLuint (-1))
230 {
231 return;
232 }
233 theGlCtx->core20->glDisableVertexAttribArray (theAttribLoc);
234 Unbind (theGlCtx);
235}
236
237// =======================================================================
238// function : BindFixed
239// purpose :
240// =======================================================================
241void OpenGl_VertexBuffer::BindFixed (const Handle(OpenGl_Context)& theGlCtx,
242 const GLenum theMode) const
243{
244 if (!IsValid())
245 {
246 return;
247 }
248
249 Bind (theGlCtx);
250 glEnableClientState (theMode);
251 switch (theMode)
252 {
253 case GL_VERTEX_ARRAY:
254 {
255 glVertexPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
256 break;
257 }
258 case GL_NORMAL_ARRAY:
259 {
260 glNormalPointer (myDataType, 0, NULL);
261 break;
262 }
263 case GL_TEXTURE_COORD_ARRAY:
264 {
265 glTexCoordPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
266 break;
267 }
268 case GL_COLOR_ARRAY:
269 {
270 glColorPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
271 break;
272 }
273 default: break;
274 }
275}
276
277// =======================================================================
278// function : UnbindFixed
279// purpose :
280// =======================================================================
281void OpenGl_VertexBuffer::UnbindFixed (const Handle(OpenGl_Context)& theGlCtx,
282 const GLenum theMode) const
283{
284 if (!IsValid())
285 {
286 return;
287 }
288 Unbind (theGlCtx);
289 glDisableClientState (theMode);
290}