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 | |
24 | IMPLEMENT_STANDARD_HANDLE (OpenGl_VertexBuffer, OpenGl_Resource) |
25 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_VertexBuffer, OpenGl_Resource) |
26 | |
27 | // ======================================================================= |
28 | // function : OpenGl_VertexBuffer |
29 | // purpose : |
30 | // ======================================================================= |
31 | OpenGl_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 | // ======================================================================= |
45 | OpenGl_VertexBuffer::~OpenGl_VertexBuffer() |
46 | { |
47 | Release (NULL); |
48 | } |
49 | |
50 | // ======================================================================= |
51 | // function : GetTarget |
52 | // purpose : |
53 | // ======================================================================= |
54 | GLenum OpenGl_VertexBuffer::GetTarget() const |
55 | { |
56 | return GL_ARRAY_BUFFER; |
57 | } |
58 | |
59 | // ======================================================================= |
60 | // function : Create |
61 | // purpose : |
62 | // ======================================================================= |
63 | bool 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 | // ======================================================================= |
76 | void 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 | // ======================================================================= |
95 | void 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 | // ======================================================================= |
104 | void 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 | // ======================================================================= |
113 | bool 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 | // ======================================================================= |
137 | bool 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 | // ======================================================================= |
162 | bool 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 | |
99d99a6d |
182 | // ======================================================================= |
183 | // function : SubData |
184 | // purpose : |
185 | // ======================================================================= |
186 | bool OpenGl_VertexBuffer::SubData (const Handle(OpenGl_Context)& theGlCtx, |
187 | const GLsizei theElemFrom, |
188 | const GLsizei theElemsNb, |
189 | const GLuint* theData) |
190 | { |
191 | if (!IsValid() || myDataType != GL_UNSIGNED_INT |
192 | || theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb)) |
193 | { |
194 | return false; |
195 | } |
196 | |
197 | Bind (theGlCtx); |
198 | theGlCtx->core15->glBufferSubData (GetTarget(), |
199 | GLintptr(theElemFrom) * GLintptr(myComponentsNb) * sizeof(GLuint), // offset in bytes |
200 | GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLuint), // size in bytes |
201 | theData); |
202 | bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY |
203 | Unbind (theGlCtx); |
204 | return isDone; |
205 | } |
206 | |
5e27df78 |
207 | // ======================================================================= |
208 | // function : Init |
209 | // purpose : |
210 | // ======================================================================= |
211 | bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx, |
212 | const GLuint theComponentsNb, |
213 | const GLsizei theElemsNb, |
214 | const GLubyte* theData) |
215 | { |
216 | if (!Create (theGlCtx)) |
217 | { |
218 | return false; |
219 | } |
220 | |
221 | Bind (theGlCtx); |
222 | myDataType = GL_UNSIGNED_BYTE; |
223 | myComponentsNb = theComponentsNb; |
224 | myElemsNb = theElemsNb; |
225 | theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLubyte), theData, GL_STATIC_DRAW); |
226 | bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY |
227 | Unbind (theGlCtx); |
228 | return isDone; |
229 | } |
230 | |
99d99a6d |
231 | // ======================================================================= |
232 | // function : SubData |
233 | // purpose : |
234 | // ======================================================================= |
235 | bool OpenGl_VertexBuffer::SubData (const Handle(OpenGl_Context)& theGlCtx, |
236 | const GLsizei theElemFrom, |
237 | const GLsizei theElemsNb, |
238 | const GLubyte* theData) |
239 | { |
240 | if (!IsValid() || myDataType != GL_UNSIGNED_BYTE |
241 | || theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb)) |
242 | { |
243 | return false; |
244 | } |
245 | |
246 | Bind (theGlCtx); |
247 | theGlCtx->core15->glBufferSubData (GetTarget(), |
248 | GLintptr(theElemFrom) * GLintptr(myComponentsNb) * sizeof(GLubyte), // offset in bytes |
249 | GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLubyte), // size in bytes |
250 | theData); |
251 | bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY |
252 | Unbind (theGlCtx); |
253 | return isDone; |
254 | } |
255 | |
5e27df78 |
256 | // ======================================================================= |
257 | // function : BindVertexAttrib |
258 | // purpose : |
259 | // ======================================================================= |
260 | void OpenGl_VertexBuffer::BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx, |
261 | const GLuint theAttribLoc) const |
262 | { |
263 | if (!IsValid() || theAttribLoc == GLuint (-1)) |
264 | { |
265 | return; |
266 | } |
267 | Bind (theGlCtx); |
268 | theGlCtx->core20->glEnableVertexAttribArray (theAttribLoc); |
269 | theGlCtx->core20->glVertexAttribPointer (theAttribLoc, GLint (myComponentsNb), myDataType, GL_FALSE, 0, NULL); |
270 | } |
271 | |
272 | // ======================================================================= |
273 | // function : UnbindVertexAttrib |
274 | // purpose : |
275 | // ======================================================================= |
276 | void OpenGl_VertexBuffer::UnbindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx, |
277 | const GLuint theAttribLoc) const |
278 | { |
279 | if (!IsValid() || theAttribLoc == GLuint (-1)) |
280 | { |
281 | return; |
282 | } |
283 | theGlCtx->core20->glDisableVertexAttribArray (theAttribLoc); |
284 | Unbind (theGlCtx); |
285 | } |
286 | |
287 | // ======================================================================= |
288 | // function : BindFixed |
289 | // purpose : |
290 | // ======================================================================= |
291 | void OpenGl_VertexBuffer::BindFixed (const Handle(OpenGl_Context)& theGlCtx, |
292 | const GLenum theMode) const |
293 | { |
294 | if (!IsValid()) |
295 | { |
296 | return; |
297 | } |
298 | |
299 | Bind (theGlCtx); |
300 | glEnableClientState (theMode); |
301 | switch (theMode) |
302 | { |
303 | case GL_VERTEX_ARRAY: |
304 | { |
305 | glVertexPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL); |
306 | break; |
307 | } |
308 | case GL_NORMAL_ARRAY: |
309 | { |
310 | glNormalPointer (myDataType, 0, NULL); |
311 | break; |
312 | } |
313 | case GL_TEXTURE_COORD_ARRAY: |
314 | { |
315 | glTexCoordPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL); |
316 | break; |
317 | } |
318 | case GL_COLOR_ARRAY: |
319 | { |
320 | glColorPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL); |
321 | break; |
322 | } |
323 | default: break; |
324 | } |
325 | } |
326 | |
327 | // ======================================================================= |
328 | // function : UnbindFixed |
329 | // purpose : |
330 | // ======================================================================= |
331 | void OpenGl_VertexBuffer::UnbindFixed (const Handle(OpenGl_Context)& theGlCtx, |
332 | const GLenum theMode) const |
333 | { |
334 | if (!IsValid()) |
335 | { |
336 | return; |
337 | } |
338 | Unbind (theGlCtx); |
339 | glDisableClientState (theMode); |
340 | } |