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_VertexBuffer.hxx>
17 #include <OpenGl_Context.hxx>
18 #include <OpenGl_ShaderManager.hxx>
19 #include <Standard_Assert.hxx>
21 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_VertexBuffer,OpenGl_Resource)
23 // =======================================================================
24 // function : OpenGl_VertexBuffer
26 // =======================================================================
27 OpenGl_VertexBuffer::OpenGl_VertexBuffer()
30 myBufferId (NO_BUFFER),
38 // =======================================================================
39 // function : ~OpenGl_VertexBuffer
41 // =======================================================================
42 OpenGl_VertexBuffer::~OpenGl_VertexBuffer()
47 // =======================================================================
48 // function : GetTarget
50 // =======================================================================
51 GLenum OpenGl_VertexBuffer::GetTarget() const
53 return GL_ARRAY_BUFFER;
56 // =======================================================================
59 // =======================================================================
60 bool OpenGl_VertexBuffer::Create (const Handle(OpenGl_Context)& theGlCtx)
62 if (myBufferId == NO_BUFFER && theGlCtx->core15fwd != NULL)
64 theGlCtx->core15fwd->glGenBuffers (1, &myBufferId);
66 return myBufferId != NO_BUFFER;
69 // =======================================================================
72 // =======================================================================
73 void OpenGl_VertexBuffer::Release (OpenGl_Context* theGlCtx)
75 if (myBufferId == NO_BUFFER)
80 // application can not handle this case by exception - this is bug in code
81 Standard_ASSERT_RETURN (theGlCtx != NULL,
82 "OpenGl_VertexBuffer destroyed without GL context! Possible GPU memory leakage...",);
84 if (theGlCtx->IsValid())
86 theGlCtx->core15fwd->glDeleteBuffers (1, &myBufferId);
89 myBufferId = NO_BUFFER;
92 // =======================================================================
95 // =======================================================================
96 void OpenGl_VertexBuffer::Bind (const Handle(OpenGl_Context)& theGlCtx) const
98 theGlCtx->core15fwd->glBindBuffer (GetTarget(), myBufferId);
101 // =======================================================================
104 // =======================================================================
105 void OpenGl_VertexBuffer::Unbind (const Handle(OpenGl_Context)& theGlCtx) const
107 theGlCtx->core15fwd->glBindBuffer (GetTarget(), NO_BUFFER);
110 // =======================================================================
113 // =======================================================================
114 bool OpenGl_VertexBuffer::init (const Handle(OpenGl_Context)& theGlCtx,
115 const GLuint theComponentsNb,
116 const GLsizei theElemsNb,
118 const GLenum theDataType,
119 const GLsizei theStride)
121 if (!Create (theGlCtx))
127 myDataType = theDataType;
128 myComponentsNb = theComponentsNb;
129 myElemsNb = theElemsNb;
130 theGlCtx->core15fwd->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * theStride, theData, GL_STATIC_DRAW);
131 bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
136 // =======================================================================
137 // function : subData
139 // =======================================================================
140 bool OpenGl_VertexBuffer::subData (const Handle(OpenGl_Context)& theGlCtx,
141 const GLsizei theElemFrom,
142 const GLsizei theElemsNb,
144 const GLenum theDataType)
146 if (!IsValid() || myDataType != theDataType ||
147 theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb))
153 const size_t aDataSize = sizeOfGlType (theDataType);
154 theGlCtx->core15fwd->glBufferSubData (GetTarget(),
155 GLintptr(theElemFrom) * GLintptr (myComponentsNb) * aDataSize, // offset in bytes
156 GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * aDataSize, // size in bytes
158 bool isDone = (glGetError() == GL_NO_ERROR); // some dummy error
163 // =======================================================================
164 // function : getSubData
166 // =======================================================================
167 bool OpenGl_VertexBuffer::getSubData (const Handle(OpenGl_Context)& theGlCtx,
168 const GLsizei theElemFrom,
169 const GLsizei theElemsNb,
171 const GLenum theDataType)
173 if (!IsValid() || myDataType != theDataType
174 || theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb)
175 || !theGlCtx->hasGetBufferData)
181 const size_t aDataSize = sizeOfGlType (theDataType);
182 const GLintptr anOffset = GLintptr (theElemFrom) * GLintptr (myComponentsNb) * aDataSize;
183 const GLsizeiptr aSize = GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * aDataSize;
184 bool isDone = theGlCtx->GetBufferSubData (GetTarget(), anOffset, aSize, theData);
185 isDone = isDone && (glGetError() == GL_NO_ERROR);
190 // =======================================================================
191 // function : BindVertexAttrib
193 // =======================================================================
194 void OpenGl_VertexBuffer::BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
195 const GLuint theAttribLoc) const
197 if (!IsValid() || theAttribLoc == GLuint (-1))
202 theGlCtx->core20fwd->glEnableVertexAttribArray (theAttribLoc);
203 theGlCtx->core20fwd->glVertexAttribPointer (theAttribLoc, GLint (myComponentsNb), myDataType, GL_FALSE, 0, myOffset);
206 // =======================================================================
207 // function : UnbindVertexAttrib
209 // =======================================================================
210 void OpenGl_VertexBuffer::UnbindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
211 const GLuint theAttribLoc) const
213 if (!IsValid() || theAttribLoc == GLuint (-1))
217 theGlCtx->core20fwd->glDisableVertexAttribArray (theAttribLoc);
221 // =======================================================================
222 // function : BindAllAttributes
224 // =======================================================================
225 void OpenGl_VertexBuffer::BindAllAttributes (const Handle(OpenGl_Context)& ) const
230 // =======================================================================
231 // function : BindPositionAttribute
233 // =======================================================================
234 void OpenGl_VertexBuffer::BindPositionAttribute (const Handle(OpenGl_Context)& ) const
239 // =======================================================================
240 // function : UnbindAllAttributes
242 // =======================================================================
243 void OpenGl_VertexBuffer::UnbindAllAttributes (const Handle(OpenGl_Context)& ) const
248 // =======================================================================
249 // function : HasColorAttribute
251 // =======================================================================
252 bool OpenGl_VertexBuffer::HasColorAttribute() const
257 // =======================================================================
258 // function : HasNormalAttribute
260 // =======================================================================
261 bool OpenGl_VertexBuffer::HasNormalAttribute() const
266 #if !defined(GL_ES_VERSION_2_0)
267 // =======================================================================
268 // function : unbindFixedColor
270 // =======================================================================
271 void OpenGl_VertexBuffer::unbindFixedColor (const Handle(OpenGl_Context)& theCtx)
273 theCtx->core11->glDisableClientState (GL_COLOR_ARRAY);
274 theCtx->core11fwd->glDisable (GL_COLOR_MATERIAL);
276 // invalidate FFP material state after GL_COLOR_MATERIAL has modified it (took values from the vertex color)
277 theCtx->ShaderManager()->UpdateMaterialState();
281 // =======================================================================
282 // function : DumpJson
284 // =======================================================================
285 void OpenGl_VertexBuffer::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
287 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
288 OCCT_DUMP_BASE_CLASS (theOStream, theDepth, OpenGl_Resource)
290 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, GetTarget())
291 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myOffset)
293 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myBufferId)
294 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myComponentsNb)
295 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myElemsNb)
296 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myDataType)