Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-07-13 |
2 | // Created by: Sergey ZERCHANINOV | |
de75ed09 | 3 | // Copyright (c) 2011-2013 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
11 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
b311480e | 15 | |
2166f0fa | 16 | #include <OpenGl_AspectFace.hxx> |
30f0ad28 | 17 | #include <OpenGl_Context.hxx> |
2166f0fa | 18 | #include <OpenGl_GraphicDriver.hxx> |
30f0ad28 | 19 | #include <OpenGl_IndexBuffer.hxx> |
a577aaab | 20 | #include <OpenGl_PointSprite.hxx> |
30f0ad28 | 21 | #include <OpenGl_PrimitiveArray.hxx> |
22 | #include <OpenGl_ShaderManager.hxx> | |
23 | #include <OpenGl_ShaderProgram.hxx> | |
2166f0fa | 24 | #include <OpenGl_Structure.hxx> |
7d3e64ef | 25 | #include <OpenGl_VertexBufferCompat.hxx> |
bf75be98 | 26 | #include <OpenGl_Workspace.hxx> |
6c6aadb1 | 27 | #include <Graphic3d_TextureParams.hxx> |
e99a2f7c | 28 | #include <NCollection_AlignedAllocator.hxx> |
2166f0fa | 29 | |
30f0ad28 | 30 | namespace |
31 | { | |
871fa103 | 32 | //! Convert data type to GL info |
33 | inline GLenum toGlDataType (const Graphic3d_TypeOfData theType, | |
34 | GLint& theNbComp) | |
35 | { | |
36 | switch (theType) | |
37 | { | |
38 | case Graphic3d_TOD_USHORT: | |
39 | theNbComp = 1; | |
40 | return GL_UNSIGNED_SHORT; | |
41 | case Graphic3d_TOD_UINT: | |
42 | theNbComp = 1; | |
43 | return GL_UNSIGNED_INT; | |
44 | case Graphic3d_TOD_VEC2: | |
45 | theNbComp = 2; | |
46 | return GL_FLOAT; | |
47 | case Graphic3d_TOD_VEC3: | |
48 | theNbComp = 3; | |
49 | return GL_FLOAT; | |
50 | case Graphic3d_TOD_VEC4: | |
51 | theNbComp = 4; | |
52 | return GL_FLOAT; | |
53 | case Graphic3d_TOD_VEC4UB: | |
54 | theNbComp = 4; | |
55 | return GL_UNSIGNED_BYTE; | |
56 | } | |
57 | theNbComp = 0; | |
58 | return GL_NONE; | |
59 | } | |
60 | ||
30f0ad28 | 61 | } |
62 | ||
871fa103 | 63 | //! Auxiliary template for VBO with interleaved attributes. |
7d3e64ef | 64 | template<class TheBaseClass, int NbAttributes> |
65 | class OpenGl_VertexBufferT : public TheBaseClass | |
7fd59977 | 66 | { |
871fa103 | 67 | |
68 | public: | |
69 | ||
70 | //! Create uninitialized VBO. | |
71 | OpenGl_VertexBufferT (const Graphic3d_Attribute* theAttribs, | |
72 | const Standard_Integer theStride) | |
73 | : Stride (theStride) | |
74 | { | |
75 | memcpy (Attribs, theAttribs, sizeof(Graphic3d_Attribute) * NbAttributes); | |
76 | } | |
77 | ||
78 | //! Create uninitialized VBO. | |
79 | OpenGl_VertexBufferT (const Graphic3d_Buffer& theAttribs) | |
80 | : Stride (theAttribs.Stride) | |
81 | { | |
82 | memcpy (Attribs, theAttribs.AttributesArray(), sizeof(Graphic3d_Attribute) * NbAttributes); | |
83 | } | |
84 | ||
85 | virtual bool HasColorAttribute() const | |
86 | { | |
87 | for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) | |
88 | { | |
89 | const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter]; | |
90 | if (anAttrib.Id == Graphic3d_TOA_COLOR) | |
91 | { | |
92 | return true; | |
93 | } | |
94 | } | |
95 | return false; | |
96 | } | |
97 | ||
7d3e64ef | 98 | virtual bool HasNormalAttribute() const |
99 | { | |
100 | for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) | |
101 | { | |
102 | const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter]; | |
103 | if (anAttrib.Id == Graphic3d_TOA_NORM) | |
104 | { | |
105 | return true; | |
106 | } | |
107 | } | |
108 | return false; | |
109 | } | |
110 | ||
111 | virtual void BindPositionAttribute (const Handle(OpenGl_Context)& theGlCtx) const | |
871fa103 | 112 | { |
7d3e64ef | 113 | if (!TheBaseClass::IsValid()) |
871fa103 | 114 | { |
115 | return; | |
116 | } | |
117 | ||
7d3e64ef | 118 | TheBaseClass::Bind (theGlCtx); |
871fa103 | 119 | GLint aNbComp; |
7d3e64ef | 120 | const GLubyte* anOffset = TheBaseClass::myOffset; |
871fa103 | 121 | for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) |
122 | { | |
123 | const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter]; | |
124 | const GLenum aDataType = toGlDataType (anAttrib.DataType, aNbComp); | |
125 | if (aDataType == GL_NONE) | |
126 | { | |
127 | continue; | |
128 | } | |
129 | else if (anAttrib.Id == Graphic3d_TOA_POS) | |
130 | { | |
7d3e64ef | 131 | TheBaseClass::bindAttribute (theGlCtx, Graphic3d_TOA_POS, aNbComp, aDataType, Stride, anOffset); |
871fa103 | 132 | break; |
133 | } | |
134 | ||
135 | anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType); | |
136 | } | |
137 | } | |
138 | ||
7d3e64ef | 139 | virtual void BindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const |
871fa103 | 140 | { |
7d3e64ef | 141 | if (!TheBaseClass::IsValid()) |
871fa103 | 142 | { |
143 | return; | |
144 | } | |
145 | ||
7d3e64ef | 146 | TheBaseClass::Bind (theGlCtx); |
871fa103 | 147 | GLint aNbComp; |
7d3e64ef | 148 | const GLubyte* anOffset = TheBaseClass::myOffset; |
871fa103 | 149 | for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) |
150 | { | |
151 | const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter]; | |
152 | const GLenum aDataType = toGlDataType (anAttrib.DataType, aNbComp); | |
153 | if (aDataType == GL_NONE) | |
154 | { | |
155 | continue; | |
156 | } | |
157 | ||
7d3e64ef | 158 | TheBaseClass::bindAttribute (theGlCtx, anAttrib.Id, aNbComp, aDataType, Stride, anOffset); |
871fa103 | 159 | anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType); |
160 | } | |
161 | } | |
162 | ||
7d3e64ef | 163 | virtual void UnbindAllAttributes (const Handle(OpenGl_Context)& theGlCtx) const |
871fa103 | 164 | { |
7d3e64ef | 165 | if (!TheBaseClass::IsValid()) |
871fa103 | 166 | { |
167 | return; | |
168 | } | |
7d3e64ef | 169 | TheBaseClass::Unbind (theGlCtx); |
871fa103 | 170 | |
171 | for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter) | |
172 | { | |
173 | const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter]; | |
7d3e64ef | 174 | TheBaseClass::unbindAttribute (theGlCtx, anAttrib.Id); |
871fa103 | 175 | } |
176 | } | |
177 | ||
178 | public: | |
179 | ||
180 | Graphic3d_Attribute Attribs[NbAttributes]; | |
181 | Standard_Integer Stride; | |
182 | ||
183 | }; | |
7fd59977 | 184 | |
2166f0fa SK |
185 | // ======================================================================= |
186 | // function : clearMemoryGL | |
187 | // purpose : | |
188 | // ======================================================================= | |
5e27df78 | 189 | void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlCtx) const |
7fd59977 | 190 | { |
871fa103 | 191 | if (!myVboIndices.IsNull()) |
2166f0fa | 192 | { |
871fa103 | 193 | myVboIndices->Release (theGlCtx.operator->()); |
194 | myVboIndices.Nullify(); | |
195 | } | |
196 | if (!myVboAttribs.IsNull()) | |
197 | { | |
198 | myVboAttribs->Release (theGlCtx.operator->()); | |
199 | myVboAttribs.Nullify(); | |
2166f0fa | 200 | } |
7fd59977 | 201 | } |
202 | ||
2166f0fa | 203 | // ======================================================================= |
7d3e64ef | 204 | // function : initNormalVbo |
2166f0fa SK |
205 | // purpose : |
206 | // ======================================================================= | |
7d3e64ef | 207 | Standard_Boolean OpenGl_PrimitiveArray::initNormalVbo (const Handle(OpenGl_Context)& theCtx) const |
7fd59977 | 208 | { |
7d3e64ef | 209 | switch (myAttribs->NbAttributes) |
2166f0fa | 210 | { |
7d3e64ef | 211 | case 1: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 1> (*myAttribs); break; |
212 | case 2: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 2> (*myAttribs); break; | |
213 | case 3: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 3> (*myAttribs); break; | |
214 | case 4: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 4> (*myAttribs); break; | |
215 | case 5: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 5> (*myAttribs); break; | |
216 | case 6: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 6> (*myAttribs); break; | |
217 | case 7: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 7> (*myAttribs); break; | |
218 | case 8: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 8> (*myAttribs); break; | |
219 | case 9: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 9> (*myAttribs); break; | |
220 | case 10: myVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBuffer, 10>(*myAttribs); break; | |
221 | } | |
222 | ||
223 | if (!myVboAttribs->init (theCtx, 0, myAttribs->NbElements, myAttribs->Data(), GL_NONE, myAttribs->Stride)) | |
224 | { | |
225 | TCollection_ExtendedString aMsg; | |
226 | aMsg += "VBO creation for Primitive Array has failed for "; | |
227 | aMsg += myAttribs->NbElements; | |
228 | aMsg += " vertices. Out of memory?"; | |
229 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg); | |
230 | ||
231 | clearMemoryGL (theCtx); | |
5e27df78 | 232 | return Standard_False; |
2166f0fa | 233 | } |
7d3e64ef | 234 | else if (myIndices.IsNull()) |
235 | { | |
236 | return Standard_True; | |
237 | } | |
7fd59977 | 238 | |
7d3e64ef | 239 | myVboIndices = new OpenGl_IndexBuffer(); |
240 | bool isOk = false; | |
241 | switch (myIndices->Stride) | |
242 | { | |
243 | case 2: | |
244 | { | |
245 | isOk = myVboIndices->Init (theCtx, 1, myIndices->NbElements, reinterpret_cast<const GLushort*> (myIndices->Data())); | |
246 | break; | |
247 | } | |
248 | case 4: | |
249 | { | |
250 | isOk = myVboIndices->Init (theCtx, 1, myIndices->NbElements, reinterpret_cast<const GLuint*> (myIndices->Data())); | |
251 | break; | |
252 | } | |
253 | default: | |
254 | { | |
255 | clearMemoryGL (theCtx); | |
256 | return Standard_False; | |
257 | } | |
258 | } | |
259 | if (!isOk) | |
2166f0fa | 260 | { |
7d3e64ef | 261 | TCollection_ExtendedString aMsg; |
262 | aMsg += "VBO creation for Primitive Array has failed for "; | |
263 | aMsg += myIndices->NbElements; | |
264 | aMsg += " indices. Out of memory?"; | |
265 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg); | |
266 | clearMemoryGL (theCtx); | |
267 | return Standard_False; | |
7fd59977 | 268 | } |
7d3e64ef | 269 | return Standard_True; |
270 | } | |
871fa103 | 271 | |
7d3e64ef | 272 | // ======================================================================= |
273 | // function : buildVBO | |
274 | // purpose : | |
275 | // ======================================================================= | |
276 | Standard_Boolean OpenGl_PrimitiveArray::buildVBO (const Handle(OpenGl_Context)& theCtx, | |
277 | const Standard_Boolean theToKeepData) const | |
278 | { | |
279 | bool isNormalMode = theCtx->ToUseVbo(); | |
536d98e2 | 280 | clearMemoryGL (theCtx); |
7d3e64ef | 281 | if (myAttribs.IsNull() |
282 | || myAttribs->IsEmpty() | |
283 | || myAttribs->NbElements < 1 | |
284 | || myAttribs->NbAttributes < 1 | |
285 | || myAttribs->NbAttributes > 10) | |
2166f0fa | 286 | { |
7d3e64ef | 287 | // vertices should be always defined - others are optional |
871fa103 | 288 | return Standard_False; |
7fd59977 | 289 | } |
871fa103 | 290 | |
7d3e64ef | 291 | if (isNormalMode |
292 | && initNormalVbo (theCtx)) | |
293 | { | |
294 | if (!theCtx->caps->keepArrayData | |
295 | && !theToKeepData) | |
296 | { | |
297 | myIndices.Nullify(); | |
298 | myAttribs.Nullify(); | |
299 | } | |
300 | return Standard_True; | |
301 | } | |
302 | ||
303 | Handle(OpenGl_VertexBufferCompat) aVboAttribs; | |
304 | switch (myAttribs->NbAttributes) | |
305 | { | |
306 | case 1: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 1> (*myAttribs); break; | |
307 | case 2: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 2> (*myAttribs); break; | |
308 | case 3: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 3> (*myAttribs); break; | |
309 | case 4: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 4> (*myAttribs); break; | |
310 | case 5: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 5> (*myAttribs); break; | |
311 | case 6: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 6> (*myAttribs); break; | |
312 | case 7: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 7> (*myAttribs); break; | |
313 | case 8: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 8> (*myAttribs); break; | |
314 | case 9: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 9> (*myAttribs); break; | |
315 | case 10: aVboAttribs = new OpenGl_VertexBufferT<OpenGl_VertexBufferCompat, 10>(*myAttribs); break; | |
316 | } | |
317 | aVboAttribs->initLink (myAttribs, 0, myAttribs->NbElements, GL_NONE); | |
871fa103 | 318 | if (!myIndices.IsNull()) |
2166f0fa | 319 | { |
7d3e64ef | 320 | Handle(OpenGl_VertexBufferCompat) aVboIndices = new OpenGl_VertexBufferCompat(); |
871fa103 | 321 | switch (myIndices->Stride) |
5e27df78 | 322 | { |
871fa103 | 323 | case 2: |
324 | { | |
7d3e64ef | 325 | aVboIndices->initLink (myIndices, 1, myIndices->NbElements, GL_UNSIGNED_SHORT); |
871fa103 | 326 | break; |
327 | } | |
328 | case 4: | |
329 | { | |
7d3e64ef | 330 | aVboIndices->initLink (myIndices, 1, myIndices->NbElements, GL_UNSIGNED_INT); |
871fa103 | 331 | break; |
332 | } | |
7d3e64ef | 333 | default: |
334 | { | |
335 | return Standard_False; | |
336 | } | |
5e27df78 | 337 | } |
7d3e64ef | 338 | myVboIndices = aVboIndices; |
2166f0fa | 339 | } |
7d3e64ef | 340 | myVboAttribs = aVboAttribs; |
341 | if (!theCtx->caps->keepArrayData | |
342 | && !theToKeepData) | |
e276548b | 343 | { |
7d3e64ef | 344 | // does not make sense for compatibility mode |
345 | //myIndices.Nullify(); | |
346 | //myAttribs.Nullify(); | |
e276548b | 347 | } |
7d3e64ef | 348 | |
2166f0fa | 349 | return Standard_True; |
7fd59977 | 350 | } |
351 | ||
2166f0fa | 352 | // ======================================================================= |
7d3e64ef | 353 | // function : drawArray |
2166f0fa SK |
354 | // purpose : |
355 | // ======================================================================= | |
7d3e64ef | 356 | void OpenGl_PrimitiveArray::drawArray (const Handle(OpenGl_Workspace)& theWorkspace, |
8625ef7e | 357 | const Graphic3d_Vec4* theFaceColors, |
358 | const Standard_Boolean theHasVertColor) const | |
7fd59977 | 359 | { |
871fa103 | 360 | const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext(); |
871fa103 | 361 | const bool toHilight = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) != 0; |
8625ef7e | 362 | bool hasVColors = theHasVertColor && !toHilight; |
7d3e64ef | 363 | if (myVboAttribs.IsNull()) |
2166f0fa | 364 | { |
ca3c13d1 | 365 | #if !defined(GL_ES_VERSION_2_0) |
7d3e64ef | 366 | if (myDrawMode == GL_POINTS) |
367 | { | |
368 | // extreme compatibility mode - without sprites but with markers | |
369 | drawMarkers (theWorkspace); | |
370 | } | |
ca3c13d1 | 371 | #endif |
7d3e64ef | 372 | return; |
7fd59977 | 373 | } |
374 | ||
7d3e64ef | 375 | myVboAttribs->BindAllAttributes (aGlContext); |
8625ef7e | 376 | if (theHasVertColor && toHilight) |
2166f0fa | 377 | { |
8625ef7e | 378 | // disable per-vertex color |
379 | OpenGl_VertexBuffer::unbindAttribute (aGlContext, Graphic3d_TOA_COLOR); | |
7d3e64ef | 380 | } |
381 | if (!myVboIndices.IsNull()) | |
382 | { | |
383 | myVboIndices->Bind (aGlContext); | |
384 | GLubyte* anOffset = myVboIndices->GetDataOffset(); | |
385 | if (!myBounds.IsNull()) | |
2166f0fa | 386 | { |
7d3e64ef | 387 | // draw primitives by vertex count with the indices |
388 | const size_t aStride = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int); | |
389 | for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) | |
2166f0fa | 390 | { |
7d3e64ef | 391 | const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; |
8625ef7e | 392 | if (theFaceColors != NULL) aGlContext->SetColor4fv (theFaceColors[aGroupIter]); |
7d3e64ef | 393 | glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset); |
394 | anOffset += aStride * aNbElemsInGroup; | |
762aacae | 395 | } |
bf75be98 | 396 | } |
2166f0fa SK |
397 | else |
398 | { | |
7d3e64ef | 399 | // draw one (or sequential) primitive by the indices |
400 | glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), anOffset); | |
5e27df78 | 401 | } |
7d3e64ef | 402 | myVboIndices->Unbind (aGlContext); |
7fd59977 | 403 | } |
7d3e64ef | 404 | else if (!myBounds.IsNull()) |
871fa103 | 405 | { |
7d3e64ef | 406 | GLint aFirstElem = 0; |
407 | for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) | |
408 | { | |
409 | const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; | |
8625ef7e | 410 | if (theFaceColors != NULL) aGlContext->SetColor4fv (theFaceColors[aGroupIter]); |
7d3e64ef | 411 | glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup); |
412 | aFirstElem += aNbElemsInGroup; | |
413 | } | |
871fa103 | 414 | } |
7d3e64ef | 415 | else |
2166f0fa | 416 | { |
7d3e64ef | 417 | if (myDrawMode == GL_POINTS) |
418 | { | |
419 | drawMarkers (theWorkspace); | |
420 | } | |
421 | else | |
422 | { | |
423 | glDrawArrays (myDrawMode, 0, myVboAttribs->GetElemsNb()); | |
424 | } | |
2166f0fa SK |
425 | } |
426 | ||
7d3e64ef | 427 | // bind with 0 |
428 | myVboAttribs->UnbindAllAttributes (aGlContext); | |
429 | ||
430 | if (hasVColors) | |
431 | { | |
432 | theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; | |
433 | } | |
7fd59977 | 434 | } |
435 | ||
2166f0fa | 436 | // ======================================================================= |
7d3e64ef | 437 | // function : drawEdges |
2166f0fa SK |
438 | // purpose : |
439 | // ======================================================================= | |
7d3e64ef | 440 | void OpenGl_PrimitiveArray::drawEdges (const TEL_COLOUR* theEdgeColour, |
2166f0fa | 441 | const Handle(OpenGl_Workspace)& theWorkspace) const |
7fd59977 | 442 | { |
65360da3 | 443 | const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext(); |
7d3e64ef | 444 | if (myVboAttribs.IsNull()) |
445 | { | |
446 | return; | |
447 | } | |
448 | ||
ca3c13d1 | 449 | #if !defined(GL_ES_VERSION_2_0) |
65360da3 | 450 | if (aGlContext->core11 != NULL) |
451 | { | |
452 | glDisable (GL_LIGHTING); | |
453 | } | |
ca3c13d1 | 454 | #endif |
7fd59977 | 455 | |
2166f0fa | 456 | const OpenGl_AspectLine* anAspectLineOld = NULL; |
7fd59977 | 457 | |
7d3e64ef | 458 | anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge()); |
459 | const OpenGl_AspectLine* anAspect = theWorkspace->AspectLine (Standard_True); | |
30f0ad28 | 460 | |
ca3c13d1 | 461 | #if !defined(GL_ES_VERSION_2_0) |
7d3e64ef | 462 | glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); |
ca3c13d1 | 463 | #endif |
7d3e64ef | 464 | |
4e1523ef | 465 | if (aGlContext->core20fwd != NULL) |
7d3e64ef | 466 | { |
8625ef7e | 467 | aGlContext->ShaderManager()->BindProgram (anAspect, NULL, Standard_False, Standard_False, anAspect->ShaderProgramRes (aGlContext)); |
2166f0fa | 468 | } |
7fd59977 | 469 | |
5e27df78 | 470 | /// OCC22236 NOTE: draw edges for all situations: |
871fa103 | 471 | /// 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indices array |
472 | /// 2) draw elements from vertex array, when bounds defines count of primitive's vertices. | |
5e27df78 | 473 | /// 3) draw primitive's edges by vertexes if no edges and bounds array is specified |
7d3e64ef | 474 | myVboAttribs->BindPositionAttribute (aGlContext); |
ac116c22 | 475 | |
476 | aGlContext->SetColor4fv (*(const OpenGl_Vec4* )theEdgeColour->rgb); | |
477 | aGlContext->SetTypeOfLine (anAspect->Type()); | |
478 | aGlContext->SetLineWidth (anAspect->Width()); | |
479 | ||
7d3e64ef | 480 | if (!myVboIndices.IsNull()) |
bf75be98 | 481 | { |
7d3e64ef | 482 | myVboIndices->Bind (aGlContext); |
483 | GLubyte* anOffset = myVboIndices->GetDataOffset(); | |
2166f0fa | 484 | |
7d3e64ef | 485 | // draw primitives by vertex count with the indices |
486 | if (!myBounds.IsNull()) | |
2166f0fa | 487 | { |
7d3e64ef | 488 | const size_t aStride = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int); |
871fa103 | 489 | for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) |
2166f0fa | 490 | { |
871fa103 | 491 | const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; |
7d3e64ef | 492 | glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset); |
493 | anOffset += aStride * aNbElemsInGroup; | |
7fd59977 | 494 | } |
495 | } | |
7d3e64ef | 496 | // draw one (or sequential) primitive by the indices |
2166f0fa SK |
497 | else |
498 | { | |
7d3e64ef | 499 | glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), anOffset); |
762aacae | 500 | } |
7d3e64ef | 501 | myVboIndices->Unbind (aGlContext); |
2166f0fa | 502 | } |
7d3e64ef | 503 | else if (!myBounds.IsNull()) |
2166f0fa | 504 | { |
7d3e64ef | 505 | GLint aFirstElem = 0; |
506 | for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter) | |
2166f0fa | 507 | { |
7d3e64ef | 508 | const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter]; |
509 | glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup); | |
510 | aFirstElem += aNbElemsInGroup; | |
7fd59977 | 511 | } |
2166f0fa | 512 | } |
7d3e64ef | 513 | else |
514 | { | |
515 | glDrawArrays (myDrawMode, 0, myAttribs->NbElements); | |
516 | } | |
517 | ||
518 | // unbind buffers | |
519 | myVboAttribs->UnbindAttribute (aGlContext, Graphic3d_TOA_POS); | |
2166f0fa | 520 | |
8625ef7e | 521 | // restore line context |
8625ef7e | 522 | theWorkspace->SetAspectLine (anAspectLineOld); |
7fd59977 | 523 | } |
524 | ||
a577aaab | 525 | // ======================================================================= |
7d3e64ef | 526 | // function : drawMarkers |
a577aaab | 527 | // purpose : |
528 | // ======================================================================= | |
7d3e64ef | 529 | void OpenGl_PrimitiveArray::drawMarkers (const Handle(OpenGl_Workspace)& theWorkspace) const |
a577aaab | 530 | { |
531 | const OpenGl_AspectMarker* anAspectMarker = theWorkspace->AspectMarker (Standard_True); | |
532 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); | |
8625ef7e | 533 | const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx); |
534 | if (!aSpriteNorm.IsNull() | |
535 | && !aSpriteNorm->IsDisplayList()) | |
a577aaab | 536 | { |
537 | // Textured markers will be drawn with the point sprites | |
8625ef7e | 538 | aCtx->SetPointSize (anAspectMarker->MarkerSize()); |
ca3c13d1 | 539 | #if !defined(GL_ES_VERSION_2_0) |
4e1523ef | 540 | if (aCtx->core11 != NULL) |
541 | { | |
542 | aCtx->core11fwd->glEnable (GL_ALPHA_TEST); | |
543 | aCtx->core11fwd->glAlphaFunc (GL_GEQUAL, 0.1f); | |
544 | } | |
ca3c13d1 | 545 | #endif |
a577aaab | 546 | |
8625ef7e | 547 | aCtx->core11fwd->glEnable (GL_BLEND); |
548 | aCtx->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
a577aaab | 549 | |
8625ef7e | 550 | aCtx->core11fwd->glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements); |
a577aaab | 551 | |
8625ef7e | 552 | aCtx->core11fwd->glDisable (GL_BLEND); |
ca3c13d1 | 553 | #if !defined(GL_ES_VERSION_2_0) |
4e1523ef | 554 | if (aCtx->core11 != NULL) |
555 | { | |
556 | aCtx->core11fwd->glDisable (GL_ALPHA_TEST); | |
557 | } | |
ca3c13d1 | 558 | #endif |
8625ef7e | 559 | aCtx->SetPointSize (1.0f); |
a577aaab | 560 | return; |
561 | } | |
8625ef7e | 562 | else if (anAspectMarker->Type() == Aspect_TOM_POINT) |
a577aaab | 563 | { |
8625ef7e | 564 | aCtx->SetPointSize (anAspectMarker->MarkerSize()); |
565 | aCtx->core11fwd->glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements); | |
566 | aCtx->SetPointSize (1.0f); | |
a577aaab | 567 | } |
ca3c13d1 | 568 | #if !defined(GL_ES_VERSION_2_0) |
8625ef7e | 569 | // Textured markers will be drawn with the glBitmap |
570 | else if (anAspectMarker->Type() != Aspect_TOM_POINT | |
571 | && !aSpriteNorm.IsNull()) | |
a577aaab | 572 | { |
871fa103 | 573 | /**if (!isHilight && (myPArray->vcolours != NULL)) |
a577aaab | 574 | { |
871fa103 | 575 | for (Standard_Integer anIter = 0; anIter < myAttribs->NbElements; anIter++) |
a577aaab | 576 | { |
871fa103 | 577 | glColor4ubv (myPArray->vcolours[anIter].GetData()); |
578 | glRasterPos3fv (myAttribs->Value<Graphic3d_Vec3> (anIter).GetData()); | |
a577aaab | 579 | aSpriteNorm->DrawBitmap (theWorkspace->GetGlContext()); |
580 | } | |
581 | } | |
871fa103 | 582 | else*/ |
a577aaab | 583 | { |
871fa103 | 584 | for (Standard_Integer anIter = 0; anIter < myAttribs->NbElements; anIter++) |
a577aaab | 585 | { |
8625ef7e | 586 | aCtx->core11->glRasterPos3fv (myAttribs->Value<Graphic3d_Vec3> (anIter).GetData()); |
a577aaab | 587 | aSpriteNorm->DrawBitmap (theWorkspace->GetGlContext()); |
588 | } | |
589 | } | |
590 | } | |
ca3c13d1 | 591 | #endif |
a577aaab | 592 | } |
593 | ||
e1c659da | 594 | // ======================================================================= |
595 | // function : OpenGl_PrimitiveArray | |
596 | // purpose : | |
597 | // ======================================================================= | |
598 | OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (const OpenGl_GraphicDriver* theDriver) | |
599 | ||
600 | : myDrawMode (DRAW_MODE_NONE), | |
601 | myIsVboInit (Standard_False) | |
602 | { | |
603 | if (theDriver != NULL) | |
604 | { | |
605 | myUID = theDriver->GetNextPrimitiveArrayUID(); | |
606 | } | |
607 | } | |
608 | ||
2166f0fa SK |
609 | // ======================================================================= |
610 | // function : OpenGl_PrimitiveArray | |
611 | // purpose : | |
612 | // ======================================================================= | |
8d3f219f | 613 | OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (const OpenGl_GraphicDriver* theDriver, |
614 | const Graphic3d_TypeOfPrimitiveArray theType, | |
871fa103 | 615 | const Handle(Graphic3d_IndexBuffer)& theIndices, |
616 | const Handle(Graphic3d_Buffer)& theAttribs, | |
617 | const Handle(Graphic3d_BoundBuffer)& theBounds) | |
8d3f219f | 618 | |
871fa103 | 619 | : myIndices (theIndices), |
620 | myAttribs (theAttribs), | |
621 | myBounds (theBounds), | |
622 | myDrawMode (DRAW_MODE_NONE), | |
c827ea3a | 623 | myIsVboInit (Standard_False) |
2166f0fa | 624 | { |
871fa103 | 625 | if (!myIndices.IsNull() |
626 | && myIndices->NbElements < 1) | |
627 | { | |
628 | // dummy index buffer? | |
629 | myIndices.Nullify(); | |
630 | } | |
871fa103 | 631 | |
e99a2f7c | 632 | if (theDriver != NULL) |
633 | { | |
634 | myUID = theDriver->GetNextPrimitiveArrayUID(); | |
635 | #if defined (GL_ES_VERSION_2_0) | |
636 | const Handle(OpenGl_Context)& aCtx = theDriver->GetSharedContext(); | |
637 | if (!aCtx.IsNull()) | |
638 | { | |
639 | processIndices (aCtx); | |
640 | } | |
641 | #endif | |
642 | } | |
643 | ||
a79f67f8 | 644 | setDrawMode (theType); |
2166f0fa SK |
645 | } |
646 | ||
647 | // ======================================================================= | |
648 | // function : ~OpenGl_PrimitiveArray | |
649 | // purpose : | |
650 | // ======================================================================= | |
5e27df78 | 651 | OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray() |
2166f0fa | 652 | { |
5e27df78 | 653 | // |
654 | } | |
2166f0fa | 655 | |
5e27df78 | 656 | // ======================================================================= |
657 | // function : Release | |
658 | // purpose : | |
659 | // ======================================================================= | |
10b9c7df | 660 | void OpenGl_PrimitiveArray::Release (OpenGl_Context* theContext) |
5e27df78 | 661 | { |
c827ea3a | 662 | myIsVboInit = Standard_False; |
871fa103 | 663 | if (!myVboIndices.IsNull()) |
2166f0fa | 664 | { |
10b9c7df | 665 | if (theContext) |
5e27df78 | 666 | { |
871fa103 | 667 | theContext->DelayedRelease (myVboIndices); |
668 | } | |
669 | myVboIndices.Nullify(); | |
670 | } | |
671 | if (!myVboAttribs.IsNull()) | |
672 | { | |
10b9c7df | 673 | if (theContext) |
871fa103 | 674 | { |
675 | theContext->DelayedRelease (myVboAttribs); | |
5e27df78 | 676 | } |
871fa103 | 677 | myVboAttribs.Nullify(); |
2166f0fa SK |
678 | } |
679 | } | |
680 | ||
681 | // ======================================================================= | |
682 | // function : Render | |
683 | // purpose : | |
684 | // ======================================================================= | |
685 | void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const | |
686 | { | |
871fa103 | 687 | if (myDrawMode == DRAW_MODE_NONE) |
bf75be98 | 688 | { |
2166f0fa | 689 | return; |
bf75be98 | 690 | } |
2166f0fa | 691 | |
a577aaab | 692 | const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_True); |
693 | const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True); | |
694 | const OpenGl_AspectMarker* anAspectMarker = theWorkspace->AspectMarker (myDrawMode == GL_POINTS); | |
695 | ||
2166f0fa | 696 | // create VBOs on first render call |
58655684 | 697 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); |
7d3e64ef | 698 | if (!myIsVboInit) |
2166f0fa | 699 | { |
7d3e64ef | 700 | // compatibility - keep data to draw markers using display lists |
701 | const Standard_Boolean toKeepData = myDrawMode == GL_POINTS | |
8625ef7e | 702 | && !anAspectMarker->SpriteRes (aCtx).IsNull() |
703 | && anAspectMarker->SpriteRes (aCtx)->IsDisplayList(); | |
e99a2f7c | 704 | #if defined (GL_ES_VERSION_2_0) |
705 | processIndices (aCtx); | |
706 | #endif | |
7d3e64ef | 707 | buildVBO (aCtx, toKeepData); |
5e27df78 | 708 | myIsVboInit = Standard_True; |
2166f0fa SK |
709 | } |
710 | ||
fd4a6963 | 711 | Tint aFrontLightingModel = anAspectFace->IntFront().color_mask; |
712 | const TEL_COLOUR* anInteriorColor = &anAspectFace->IntFront().matcol; | |
2166f0fa | 713 | const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color(); |
871fa103 | 714 | const TEL_COLOUR* aLineColor = myDrawMode == GL_POINTS ? &anAspectMarker->Color() : &anAspectLine->Color(); |
2166f0fa SK |
715 | |
716 | // Use highlight colors | |
717 | if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) | |
bf75be98 | 718 | { |
2166f0fa SK |
719 | anEdgeColor = anInteriorColor = aLineColor = theWorkspace->HighlightColor; |
720 | aFrontLightingModel = 0; | |
721 | } | |
722 | ||
8625ef7e | 723 | const Standard_Boolean hasColorAttrib = !myVboAttribs.IsNull() |
724 | && myVboAttribs->HasColorAttribute(); | |
725 | const Standard_Boolean isLightOn = aFrontLightingModel != 0 | |
726 | && !myVboAttribs.IsNull() | |
727 | && myVboAttribs->HasNormalAttribute(); | |
ca3c13d1 | 728 | #if !defined(GL_ES_VERSION_2_0) |
7d3e64ef | 729 | // manage FFP lighting |
4e1523ef | 730 | if (aCtx->core11 != NULL) |
7d3e64ef | 731 | { |
4e1523ef | 732 | if (!isLightOn) |
733 | { | |
734 | glDisable (GL_LIGHTING); | |
735 | } | |
736 | else | |
737 | { | |
738 | glEnable (GL_LIGHTING); | |
739 | } | |
7d3e64ef | 740 | } |
ca3c13d1 | 741 | #endif |
8625ef7e | 742 | // Temporarily disable environment mapping |
743 | Handle(OpenGl_Texture) aTextureBack; | |
744 | if (myDrawMode <= GL_LINE_STRIP) | |
745 | { | |
746 | aTextureBack = theWorkspace->DisableTexture(); | |
747 | } | |
7d3e64ef | 748 | |
749 | if ((myDrawMode > GL_LINE_STRIP && anAspectFace->InteriorStyle() != Aspect_IS_EMPTY) || | |
750 | (myDrawMode <= GL_LINE_STRIP)) | |
751 | { | |
752 | const bool toHilight = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) != 0; | |
753 | const Graphic3d_Vec4* aFaceColors = !myBounds.IsNull() && !toHilight && anAspectFace->InteriorStyle() != Aspect_IS_HIDDENLINE | |
754 | ? myBounds->Colors | |
755 | : NULL; | |
8625ef7e | 756 | const Standard_Boolean hasVertColor = hasColorAttrib && !toHilight; |
4e1523ef | 757 | if (aCtx->core20fwd != NULL) |
8625ef7e | 758 | { |
759 | switch (myDrawMode) | |
760 | { | |
761 | case GL_POINTS: | |
762 | { | |
763 | const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx); | |
764 | if (!aSpriteNorm.IsNull() | |
765 | && !aSpriteNorm->IsDisplayList()) | |
766 | { | |
767 | const Handle(OpenGl_PointSprite)& aSprite = (toHilight && anAspectMarker->SpriteHighlightRes (aCtx)->IsValid()) | |
768 | ? anAspectMarker->SpriteHighlightRes (aCtx) | |
769 | : aSpriteNorm; | |
770 | theWorkspace->EnableTexture (aSprite); | |
771 | aCtx->ShaderManager()->BindProgram (anAspectMarker, aSprite, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx)); | |
772 | } | |
773 | else | |
774 | { | |
775 | aCtx->ShaderManager()->BindProgram (anAspectMarker, NULL, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx)); | |
776 | } | |
777 | break; | |
778 | } | |
779 | case GL_LINES: | |
780 | case GL_LINE_STRIP: | |
781 | { | |
782 | aCtx->ShaderManager()->BindProgram (anAspectLine, NULL, isLightOn, hasVertColor, anAspectLine->ShaderProgramRes (aCtx)); | |
783 | break; | |
784 | } | |
785 | default: | |
786 | { | |
6c6aadb1 | 787 | const Standard_Boolean isLightOnFace = isLightOn |
788 | && (theWorkspace->ActiveTexture().IsNull() | |
789 | || theWorkspace->ActiveTexture()->GetParams()->IsModulate()); | |
790 | aCtx->ShaderManager()->BindProgram (anAspectFace, theWorkspace->ActiveTexture(), isLightOnFace, hasVertColor, anAspectFace->ShaderProgramRes (aCtx)); | |
8625ef7e | 791 | break; |
792 | } | |
793 | } | |
794 | } | |
795 | ||
796 | aCtx->SetColor4fv (*(const OpenGl_Vec4* )(myDrawMode <= GL_LINE_STRIP ? aLineColor->rgb : anInteriorColor->rgb)); | |
ac116c22 | 797 | if (myDrawMode == GL_LINES |
798 | || myDrawMode == GL_LINE_STRIP) | |
799 | { | |
800 | aCtx->SetTypeOfLine (anAspectLine->Type()); | |
801 | aCtx->SetLineWidth (anAspectLine->Width()); | |
802 | } | |
7d3e64ef | 803 | |
8625ef7e | 804 | drawArray (theWorkspace, aFaceColors, hasColorAttrib); |
7d3e64ef | 805 | } |
806 | ||
8625ef7e | 807 | if (myDrawMode <= GL_LINE_STRIP) |
808 | { | |
809 | theWorkspace->EnableTexture (aTextureBack); | |
810 | } | |
811 | else | |
7d3e64ef | 812 | { |
813 | if (anAspectFace->Edge() | |
814 | || anAspectFace->InteriorStyle() == Aspect_IS_HIDDENLINE) | |
30f0ad28 | 815 | { |
7d3e64ef | 816 | drawEdges (anEdgeColor, theWorkspace); |
b34efb62 | 817 | |
b34efb62 | 818 | // restore OpenGL polygon mode if needed |
65360da3 | 819 | #if !defined(GL_ES_VERSION_2_0) |
b34efb62 | 820 | if (anAspectFace->InteriorStyle() >= Aspect_IS_HATCH) |
821 | { | |
822 | glPolygonMode (GL_FRONT_AND_BACK, | |
823 | anAspectFace->InteriorStyle() == Aspect_IS_POINT ? GL_POINT : GL_FILL); | |
824 | } | |
825 | #endif | |
30f0ad28 | 826 | } |
827 | } | |
828 | ||
7d3e64ef | 829 | aCtx->BindProgram (NULL); |
2166f0fa | 830 | } |
a79f67f8 | 831 | |
832 | // ======================================================================= | |
833 | // function : setDrawMode | |
834 | // purpose : | |
835 | // ======================================================================= | |
836 | void OpenGl_PrimitiveArray::setDrawMode (const Graphic3d_TypeOfPrimitiveArray theType) | |
837 | { | |
838 | if (myAttribs.IsNull()) | |
839 | { | |
840 | myDrawMode = DRAW_MODE_NONE; | |
841 | return; | |
842 | } | |
843 | ||
844 | switch (theType) | |
845 | { | |
846 | case Graphic3d_TOPA_POINTS: | |
847 | myDrawMode = GL_POINTS; | |
848 | break; | |
849 | case Graphic3d_TOPA_POLYLINES: | |
850 | myDrawMode = GL_LINE_STRIP; | |
851 | break; | |
852 | case Graphic3d_TOPA_SEGMENTS: | |
853 | myDrawMode = GL_LINES; | |
854 | break; | |
855 | case Graphic3d_TOPA_TRIANGLES: | |
856 | myDrawMode = GL_TRIANGLES; | |
857 | break; | |
858 | case Graphic3d_TOPA_TRIANGLESTRIPS: | |
859 | myDrawMode = GL_TRIANGLE_STRIP; | |
860 | break; | |
861 | case Graphic3d_TOPA_TRIANGLEFANS: | |
862 | myDrawMode = GL_TRIANGLE_FAN; | |
863 | break; | |
864 | #if !defined(GL_ES_VERSION_2_0) | |
865 | case Graphic3d_TOPA_POLYGONS: | |
866 | myDrawMode = GL_POLYGON; | |
867 | break; | |
868 | case Graphic3d_TOPA_QUADRANGLES: | |
869 | myDrawMode = GL_QUADS; | |
870 | break; | |
871 | case Graphic3d_TOPA_QUADRANGLESTRIPS: | |
872 | myDrawMode = GL_QUAD_STRIP; | |
873 | break; | |
874 | #else | |
875 | case Graphic3d_TOPA_POLYGONS: | |
876 | case Graphic3d_TOPA_QUADRANGLES: | |
877 | case Graphic3d_TOPA_QUADRANGLESTRIPS: | |
878 | #endif | |
879 | case Graphic3d_TOPA_UNDEFINED: | |
880 | break; | |
881 | } | |
882 | } | |
883 | ||
e99a2f7c | 884 | // ======================================================================= |
885 | // function : processIndices | |
886 | // purpose : | |
887 | // ======================================================================= | |
888 | Standard_Boolean OpenGl_PrimitiveArray::processIndices (const Handle(OpenGl_Context)& theContext) const | |
889 | { | |
890 | if (myIndices.IsNull() | |
891 | || theContext->hasUintIndex) | |
892 | { | |
893 | return Standard_True; | |
894 | } | |
895 | ||
896 | if (myIndices->NbElements > std::numeric_limits<GLushort>::max()) | |
897 | { | |
898 | Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (new NCollection_AlignedAllocator (16)); | |
899 | if (!anAttribs->Init (myIndices->NbElements, myAttribs->AttributesArray(), myAttribs->NbAttributes)) | |
900 | { | |
901 | return Standard_False; // failed to initialize attribute array | |
902 | } | |
903 | ||
904 | for (Standard_Integer anIdxIdx = 0; anIdxIdx < myIndices->NbElements; ++anIdxIdx) | |
905 | { | |
906 | const Standard_Integer anIndex = myIndices->Index (anIdxIdx); | |
907 | memcpy (anAttribs->ChangeData() + myAttribs->Stride * anIdxIdx, | |
908 | myAttribs->Data() + myAttribs->Stride * anIndex, | |
909 | myAttribs->Stride); | |
910 | } | |
911 | ||
912 | myIndices.Nullify(); | |
913 | myAttribs = anAttribs; | |
914 | } | |
915 | ||
916 | return Standard_True; | |
917 | } | |
918 | ||
a79f67f8 | 919 | // ======================================================================= |
920 | // function : InitBuffers | |
921 | // purpose : | |
922 | // ======================================================================= | |
923 | void OpenGl_PrimitiveArray::InitBuffers (const Handle(OpenGl_Context)& theContext, | |
924 | const Graphic3d_TypeOfPrimitiveArray theType, | |
925 | const Handle(Graphic3d_IndexBuffer)& theIndices, | |
926 | const Handle(Graphic3d_Buffer)& theAttribs, | |
927 | const Handle(Graphic3d_BoundBuffer)& theBounds) | |
928 | { | |
929 | // Release old graphic resources | |
930 | Release (theContext.operator->()); | |
931 | ||
932 | myIndices = theIndices; | |
933 | myAttribs = theAttribs; | |
934 | myBounds = theBounds; | |
e99a2f7c | 935 | #if defined(GL_ES_VERSION_2_0) |
936 | processIndices (theContext); | |
937 | #endif | |
a79f67f8 | 938 | |
939 | setDrawMode (theType); | |
940 | } |