fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / NodeCores / Drawables / Geometry / Base / OSGGeoVertexArrayPumpGroup.cpp
blobbb4d34faab62f12565a20a7ac4b0b83c7825f283
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * *
16 * *
17 * This library is free software; you can redistribute it and/or modify it *
18 * under the terms of the GNU Library General Public License as published *
19 * by the Free Software Foundation, version 2. *
20 * *
21 * This library is distributed in the hope that it will be useful, but *
22 * WITHOUT ANY WARRANTY; without even the implied warranty of *
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
24 * Library General Public License for more details. *
25 * *
26 * You should have received a copy of the GNU Library General Public *
27 * License along with this library; if not, write to the Free Software *
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
29 * *
30 * *
31 \*---------------------------------------------------------------------------*/
32 /*---------------------------------------------------------------------------*\
33 * Changes *
34 * *
35 * *
36 * *
37 * *
38 * *
39 * *
40 \*---------------------------------------------------------------------------*/
42 //---------------------------------------------------------------------------
43 // Includes
44 //---------------------------------------------------------------------------
46 #include <cstdlib>
47 #include <cstdio>
49 #include "OSGConfig.h"
51 #include "OSGGL.h"
52 #include "OSGGLEXT.h"
54 #include "OSGLog.h"
56 #include "OSGGeometry.h"
57 #include "OSGDrawEnv.h"
59 #include "OSGMaterial.h"
61 #include "OSGGeoVertexArrayPumpGroup.h"
63 #include "OSGGLFuncProtos.h"
65 OSG_BEGIN_NAMESPACE
67 // Intentionally INSIDE the namespace
68 #include "OSGGeoPumpCommon.inl"
70 //#define DEBUG_WHICH_PUMP 1
72 /***************************************************************************\
73 * Description *
74 \***************************************************************************/
76 /***************************************************************************\
77 * Class variables *
78 \***************************************************************************/
80 /*! An InitFuncWrapper to initialize the GeoVertexArrayPumpGroup.
83 InitFuncWrapper GeoVertexArrayPumpGroup::_glextInitFuncWrapper(
84 GeoVertexArrayPumpGroup::glextInitFunction);
86 /*! OpenGL extension indices.
88 UInt32 GeoVertexArrayPumpGroup::_extSecondaryColor;
89 UInt32 GeoVertexArrayPumpGroup::_extMultitexture;
90 UInt32 GeoVertexArrayPumpGroup::_arbVertexProgram;
92 /*! OpenGL extension function indices.
94 UInt32 GeoVertexArrayPumpGroup::_funcglSecondaryColorPointer;
95 UInt32 GeoVertexArrayPumpGroup::_funcglClientActiveTextureARB;
96 UInt32 GeoVertexArrayPumpGroup::_funcglVertexAttribPointerARB;
97 UInt32 GeoVertexArrayPumpGroup::_funcglEnableVertexAttribArrayARB;
98 UInt32 GeoVertexArrayPumpGroup::_funcglDisableVertexAttribArrayARB;
100 /***************************************************************************\
101 * Instance methods *
102 \***************************************************************************/
104 /*------------- constructors & destructors --------------------------------*/
106 GeoVertexArrayPumpGroup::GeoVertexArrayPumpGroup(void)
110 GeoVertexArrayPumpGroup::~GeoVertexArrayPumpGroup(void)
114 /*-------------------------------------------------------------------------*\
115 - private -
116 \*-------------------------------------------------------------------------*/
118 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
120 namespace
122 // collect info for property in 'slot'
123 bool pumpGLSetup(PumpData &info, UInt16 slot)
125 bool retVal = false;
127 if(slot < info.prop->size())
128 info.attribPtr[slot] = (*info.prop)[slot];
130 if(slot < info.propIdx->size())
131 info.attribIndex[slot] = (*info.propIdx)[slot];
133 if(info.attribPtr[slot] != NULL &&
134 info.attribPtr[slot]->getIgnore() == false )
136 info.attribData [slot] = info.attribPtr[slot]->getData();
137 info.attribStride[slot] = info.attribPtr[slot]->getStride();
139 if(info.attribStride[slot] == 0)
141 info.attribStride[slot] =
142 info.attribPtr[slot]->getFormatSize() *
143 info.attribPtr[slot]->getDimension();
146 retVal = true;
149 return retVal;
152 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
153 // handle vertex attrib with global value
154 void globalAttrib(PumpData &info, UInt16 slot, UInt16 pumpSlot)
156 if(info.attribData[slot] != NULL &&
157 info.attribPtr [slot]->size() == 1 )
159 UInt16 formatIdx = info.attribPtr[slot]->getFormat() - formatBase;
160 UInt32 dimIdx = info.attribPtr[slot]->getDimension() - 1;
162 pumpFunc pump = pumpFuncs[pumpSlot][formatIdx][dimIdx];
164 if(pump == NULL)
166 SWARNING << "GeoVertexArrayPumpGroup - globalExtAttrib: "
167 << "Invalid pump function for property " << slot
168 << " type " << info.attribPtr[slot]->getDimension()
169 << "D " << formatNames[formatIdx]
170 << endLog;
171 return;
174 pump(info.attribData[slot]);
175 info.attribData[slot] = NULL;
176 info.attribPtr [slot] = NULL;
179 #endif
181 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
182 // handle vertex attrib with global value - using GL extension
183 void globalExtAttrib(PumpData &info, UInt16 slot,
184 UInt16 pumpSlot, Window *win)
186 if(info.attribData[slot] != NULL &&
187 info.attribPtr [slot]->size() == 1 )
189 UInt16 formatIdx = info.attribPtr[slot]->getFormat() - formatBase;
190 UInt32 dimIdx = info.attribPtr[slot]->getDimension() - 1;
191 UInt32 funcId = pumpFuncIDs[pumpSlot][formatIdx][dimIdx];
193 if(funcId == Window::invalidFunctionID)
195 SWARNING << "GeoVertexArrayPumpGroup - globalExtAttrib: "
196 << "Invalid extension function for property " << slot
197 << " type " << info.attribPtr[slot]->getDimension()
198 << "D " << formatNames[formatIdx]
199 << endLog;
200 return;
203 pumpFunc pump =
204 reinterpret_cast<pumpFunc>(win->getFunction(funcId));
206 if(pump == NULL)
208 SWARNING << "GeoVertexArrayPumpGroup - globalExtAttrib: "
209 << "Extension function for property " << slot
210 << " type " << info.attribPtr[slot]->getDimension()
211 << "D " << formatNames[formatIdx]
212 << " not supported by Window " << win
213 << endLog;
214 return;
217 pump(info.attribData[slot]);
218 info.attribData[slot] = NULL;
219 info.attribPtr [slot] = NULL;
222 #endif
224 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
225 // handle vertex attrib with global value - using GL extension, multi
226 void globalExtMultiAttrib(PumpData &info, UInt16 slot,
227 UInt16 pumpSlot, GLenum attrib,
228 Window *win )
230 if(info.attribData[slot] != NULL &&
231 info.attribPtr [slot]->size() == 1 )
233 UInt16 formatIdx = info.attribPtr[slot]->getFormat() - formatBase;
234 UInt32 dimIdx = info.attribPtr[slot]->getDimension() - 1;
235 UInt32 funcId = pumpFuncIDs[pumpSlot][formatIdx][dimIdx];
237 if(funcId == Window::invalidFunctionID)
239 SWARNING << "GeoVertexArrayPumpGroup - globalExtMultiAttrib: "
240 << "Invalid extension function for property " << slot
241 << " type " << info.attribPtr[slot]->getDimension()
242 << "D " << formatNames[formatIdx]
243 << endLog;
244 return;
247 multiPumpFunc pump =
248 reinterpret_cast<multiPumpFunc>(win->getFunction(funcId));
250 if(pump == NULL)
252 SWARNING << "GeoVertexArrayPumpGroup - globalExtMutliAttrib: "
253 << "Extension function for property " << slot
254 << " type " << info.attribPtr[slot]->getDimension()
255 << "D " << formatNames[formatIdx]
256 << " not supported by Window " << win
257 << endLog;
258 return;
261 pump(attrib, info.attribData[slot]);
262 info.attribData[slot] = NULL;
263 info.attribPtr [slot] = NULL;
266 #endif
268 } // namespace
270 #endif // remove from all but dev docs
273 GeoPumpGroup::GeoPump GeoVertexArrayPumpGroup::getGeoPump(
274 DrawEnv *pEnv,
275 PropertyCharacteristics acset)
277 // Remove the stuff we can handle
278 PropertyCharacteristics prop;
279 prop = acset & GeoPumpGroup::IndexMask;
281 if(prop == SingleIndexed || prop == NonIndexed)
283 Window *win = pEnv->getWindow();
285 if(win->hasExtOrVersion(_arbVertexProgram,
286 0x0200,
287 0x0200 ) && (acset & UsesShader))
289 return masterAttribGeoPump;
291 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
292 else
294 return masterClassicGeoPump;
296 #endif
299 return NULL;
302 bool GeoVertexArrayPumpGroup::glextInitFunction(void)
304 _extSecondaryColor =
305 Window::registerExtension("GL_EXT_secondary_color");
306 _extMultitexture =
307 Window::registerExtension("GL_ARB_multitexture");
308 _arbVertexProgram =
309 Window::registerExtension("GL_ARB_vertex_program");
311 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
312 for(UInt16 i = 0; i < numFormats; ++i)
314 for(UInt16 j = 0; j < 4; ++j)
316 pumpFuncIDs[0][i][j] = Window::invalidFunctionID;
317 pumpFuncIDs[1][i][j] = Window::invalidFunctionID;
321 for(UInt16 i = 0; i < uiNumSecColFunc; ++i)
322 secondaryColorInitFuncs[i].init(pumpFuncIDs[SecColorsPumpSlot],
323 _extSecondaryColor );
325 for(UInt16 i = 0; i < uiNumMTexFuncs; ++i)
326 multiTexCoordsInitFuncs[i].init(pumpFuncIDs[TexCoords1PumpSlot],
327 _extMultitexture );
328 #endif
330 for(UInt16 i = 0; i < uiNumAttribFuncs; ++i)
331 attribInitFuncs[i].init(attribPumpFuncIDs, _arbVertexProgram);
333 for(UInt16 i = 0; i < uiNumNormAttribFuncs; ++i)
334 normAttribInitFuncs[i].init(normAttribPumpFuncIDs, _arbVertexProgram);
336 _funcglSecondaryColorPointer = Window::registerFunction(
337 OSG_DLSYM_UNDERSCORE"glSecondaryColorPointerEXT",
338 _extSecondaryColor);
339 _funcglClientActiveTextureARB = Window::registerFunction(
340 OSG_DLSYM_UNDERSCORE"glClientActiveTextureARB",
341 _extMultitexture);
342 _funcglVertexAttribPointerARB = Window::registerFunction(
343 OSG_DLSYM_UNDERSCORE"glVertexAttribPointerARB",
344 _arbVertexProgram);
345 _funcglEnableVertexAttribArrayARB = Window::registerFunction(
346 OSG_DLSYM_UNDERSCORE"glEnableVertexAttribArrayARB",
347 _arbVertexProgram);
348 _funcglDisableVertexAttribArrayARB = Window::registerFunction(
349 OSG_DLSYM_UNDERSCORE"glDisableVertexAttribArrayARB",
350 _arbVertexProgram);
352 return true;
356 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
357 void GeoVertexArrayPumpGroup::masterClassicGeoPump(
358 DrawEnv *pEnv,
359 const GeoIntegralProperty *lengths,
360 const GeoIntegralProperty *types,
361 const Geometry::MFPropertiesType *prop,
362 const Geometry::MFPropIndicesType *propIdx,
363 UInt32 uiNumInstances)
365 #ifdef DEBUG_WHICH_PUMP
366 static bool bPrinted = false;
368 if(bPrinted == false)
370 fprintf(stderr, "GeoVertexArrayPumpGroup::masterClassicGeoPump\n");
371 bPrinted = true;
373 #endif
375 Window *win = pEnv->getWindow();
377 // Setup: get all the data
379 // check for empty geometry
380 if(types == NULL || types->size() == 0)
381 return;
383 if(!pumpInternalSetup(types, true))
384 return;
385 if(!pumpInternalSetup(lengths, false))
386 return;
388 PumpData pumpData;
389 pumpData.lengths = lengths;
390 pumpData.types = types;
391 pumpData.prop = prop;
392 pumpData.propIdx = propIdx;
394 // setup standard properties
395 pumpGLSetup(pumpData, Geometry::PositionsIndex);
396 pumpGLSetup(pumpData, Geometry::ColorsIndex);
397 pumpGLSetup(pumpData, Geometry::NormalsIndex);
398 pumpGLSetup(pumpData, Geometry::TexCoordsIndex);
400 // setup extension properties
401 pumpGLSetup(pumpData, Geometry::SecondaryColorsIndex);
402 pumpGLSetup(pumpData, Geometry::TexCoords1Index);
403 pumpGLSetup(pumpData, Geometry::TexCoords2Index);
404 pumpGLSetup(pumpData, Geometry::TexCoords3Index);
405 pumpGLSetup(pumpData, Geometry::TexCoords4Index);
406 pumpGLSetup(pumpData, Geometry::TexCoords5Index);
407 pumpGLSetup(pumpData, Geometry::TexCoords6Index);
408 pumpGLSetup(pumpData, Geometry::TexCoords7Index);
410 // we need positions
411 if(pumpData.attribPtr[Geometry::PositionsIndex] == NULL)
413 if(pumpData.attribPtr[Geometry::PositionsIndex] == NULL ||
414 pumpData.attribPtr[Geometry::PositionsIndex]->getUseVBO() == false)
416 SWARNING << "GeoVertexArrayPumpGroup::masterClassicGeoPump: "
417 << "No positions." << endLog;
418 return;
422 // global attribs?
423 globalAttrib(pumpData, Geometry::NormalsIndex, NormalsPumpSlot);
424 globalAttrib(pumpData, Geometry::ColorsIndex, ColorsPumpSlot);
425 globalAttrib(pumpData, Geometry::TexCoordsIndex, TexCoordsPumpSlot);
427 if(win->hasExtOrVersion(_extSecondaryColor, 0x0104) == true)
429 globalExtAttrib(pumpData, Geometry::SecondaryColorsIndex,
430 SecColorsPumpSlot, win );
433 if(win->hasExtOrVersion(_extMultitexture, 0x0103, 0x0200) == true)
435 globalExtMultiAttrib(pumpData, Geometry::TexCoords1Index,
436 TexCoords1PumpSlot, GL_TEXTURE1_ARB, win);
437 globalExtMultiAttrib(pumpData, Geometry::TexCoords1Index,
438 TexCoords2PumpSlot, GL_TEXTURE2_ARB, win);
439 globalExtMultiAttrib(pumpData, Geometry::TexCoords1Index,
440 TexCoords3PumpSlot, GL_TEXTURE3_ARB, win);
441 globalExtMultiAttrib(pumpData, Geometry::TexCoords1Index,
442 TexCoords4PumpSlot, GL_TEXTURE4_ARB, win);
443 globalExtMultiAttrib(pumpData, Geometry::TexCoords1Index,
444 TexCoords5PumpSlot, GL_TEXTURE5_ARB, win);
445 globalExtMultiAttrib(pumpData, Geometry::TexCoords1Index,
446 TexCoords6PumpSlot, GL_TEXTURE6_ARB, win);
447 globalExtMultiAttrib(pumpData, Geometry::TexCoords1Index,
448 TexCoords7PumpSlot, GL_TEXTURE7_ARB, win);
451 // activate vertex arrays
452 // !!! This should be using the global state to reduce state changes
453 // and to allow sharing data between objects
455 UInt16 nattrib = prop->size32();
457 for(Int16 i = nattrib - 1; i >= 0; --i)
459 if(pumpData.attribPtr[i] != NULL)
461 pumpData.attribPtr[i]->activate(pEnv, i);
465 // Length handling. Special case: no length given
467 UInt32 curlen;
468 UInt32 nprims;
470 // no lengths? use all available data for the first type
471 if(lengths == NULL)
473 if(types->size() != 1)
475 SWARNING << "GeoVertexArrayPumpGroup::masterClassicGeoPump: "
476 << "No lengths, but more than one type?!"
477 << endLog;
478 return;
481 nprims = 1;
482 if(pumpData.attribIndex[Geometry::PositionsIndex] != NULL)
484 curlen = pumpData.attribIndex[Geometry::PositionsIndex]->size32();
486 else
488 curlen = pumpData.attribPtr[Geometry::PositionsIndex]->size32();
491 else
493 nprims = types->size32();
494 lengths->getValue(curlen, 0);
497 UInt32 vertindex = 0;
499 if(pumpData.attribIndex[0] != NULL)
501 // Indexed, i.e. Single Indexed
503 GeoIntegralProperty *index = pumpData.attribIndex[0];
504 const UInt8 *indexData = index->getData();
505 GLenum indexFormat = index->getFormat();
506 UInt32 indexStride =
507 index->getStride() ? index->getStride() : index->getFormatSize() *
508 index->getDimension();
510 index->activate(pEnv, 0);
512 if(index->isInVBO(pEnv) == true)
514 indexData = NULL;
517 if(uiNumInstances > 1)
519 OSGGETGLFUNCBYID_GL3_ES(glDrawElementsInstanced,
520 osgGlDrawElementsInstanced,
521 Geometry::getFuncIdDrawElementsInstanced(),
522 win);
524 for(UInt32 primindex = 0; primindex < nprims; ++primindex)
526 if(primindex < lengths->size())
527 curlen = lengths->getValue<UInt32>(primindex);
529 if(curlen > 0)
531 osgGlDrawElementsInstanced(
532 types->getValue<UInt16>(primindex),
533 curlen,
534 indexFormat,
535 indexData + vertindex * indexStride,
536 uiNumInstances );
538 vertindex += curlen;
542 else
544 for(UInt32 primindex = 0; primindex < nprims; ++primindex)
546 if(primindex < lengths->size())
547 curlen = lengths->getValue<UInt32>(primindex);
549 if(curlen > 0)
551 glDrawElements(types->getValue<UInt16>(primindex),
552 curlen,
553 indexFormat,
554 indexData + vertindex * indexStride);
556 vertindex += curlen;
561 index->deactivate(pEnv, 0);
563 else
565 if(uiNumInstances > 1)
567 OSGGETGLFUNCBYID_GL3_ES(glDrawArraysInstanced,
568 osgGlDrawArraysInstanced,
569 Geometry::getFuncIdDrawArraysInstanced(),
570 win);
572 // Non-indexed
573 for(UInt32 primindex = 0; primindex < nprims; ++primindex)
575 if(primindex < lengths->size())
576 curlen = lengths->getValue<UInt32>(primindex);
578 if(curlen > 0)
580 osgGlDrawArraysInstanced(
581 types->getValue<UInt16>(primindex),
582 vertindex,
583 curlen,
584 uiNumInstances);
586 vertindex += curlen;
590 else
592 // Non-indexed
593 for(UInt32 primindex = 0; primindex < nprims; ++primindex)
595 if(primindex < lengths->size())
596 curlen = lengths->getValue<UInt32>(primindex);
598 if(curlen > 0)
600 glDrawArrays(types->getValue<UInt16>(primindex), vertindex,
601 curlen);
602 vertindex += curlen;
608 // disable arrays
609 for(Int16 i = nattrib - 1; i >= 0; --i)
611 if(pumpData.attribPtr[i] != NULL)
613 pumpData.attribPtr[i]->deactivate(pEnv, i);
617 #endif
619 void GeoVertexArrayPumpGroup::masterAttribGeoPump(
620 DrawEnv *pEnv,
621 const GeoIntegralProperty *lengths,
622 const GeoIntegralProperty *types,
623 const Geometry::MFPropertiesType *prop,
624 const Geometry::MFPropIndicesType *propIdx,
625 UInt32 uiNumInstances)
627 #ifdef DEBUG_WHICH_PUMP
628 static bool bPrinted = false;
630 if(bPrinted == false)
632 fprintf(stderr, "GeoVertexArrayPumpGroup::masterAttribGeoPump\n");
633 bPrinted = true;
635 #endif
637 Window *win = pEnv->getWindow();
639 // Setup: get all the data
641 // check for empty geometry
642 if(types == NULL || types->size() == 0)
643 return;
645 if(!pumpInternalSetup(types, true))
646 return;
647 if(!pumpInternalSetup(lengths, false))
648 return;
650 attribPumpFunc attribFunc[Geometry::MaxAttribs];
651 PumpData pumpData;
653 pumpData.lengths = lengths;
654 pumpData.types = types;
655 pumpData.prop = prop;
656 pumpData.propIdx = propIdx;
658 UInt16 nattrib = prop->size32();
660 for(UInt16 i = 0; i < nattrib; ++i)
662 if(pumpGLSetup(pumpData, i) == false)
663 continue;
665 UInt16 formatIdx = pumpData.attribPtr[i]->getFormat () - formatBase;
666 UInt16 dimIdx = pumpData.attribPtr[i]->getDimension() - 1;
668 #if !defined(OSG_USE_OGLES_PROTOS) && !defined(OSG_USE_OGL3_PROTOS) && \
669 !defined(OSG_USE_OGL4_PROTOS)
670 UInt32 funcId = Window::invalidFunctionID;
672 if(pumpData.attribPtr[i]->getNormalize() == true)
674 funcId = normAttribPumpFuncIDs[formatIdx][dimIdx];
676 if(funcId == Window::invalidFunctionID)
678 SWARNING << "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
679 << "Invalid pump function for property " << i
680 << " type " << pumpData.attribPtr[i]->getDimension()
681 << "D " << formatNames[formatIdx] << " (normalizing)."
682 << endLog;
684 pumpData.attribData[i] = NULL;
685 pumpData.attribPtr [i] = NULL;
686 continue;
689 else
691 funcId = attribPumpFuncIDs[formatIdx][dimIdx];
693 if(funcId == Window::invalidFunctionID)
695 SWARNING << "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
696 << "Invalid pump function for property " << i
697 << " type " << pumpData.attribPtr[i]->getDimension()
698 << "D " << formatNames[formatIdx]
699 << endLog;
701 pumpData.attribData[i] = NULL;
702 pumpData.attribPtr [i] = NULL;
703 continue;
707 attribFunc[i] = reinterpret_cast<attribPumpFunc>(
708 win->getFunction(funcId));
710 #else
711 if(pumpData.attribPtr[i]->getNormalize() == true)
713 attribFunc[i] = attribNormPumpFuncs[formatIdx][dimIdx];
715 else
717 attribFunc[i] = attribPumpFuncs[formatIdx][dimIdx];
719 #endif
721 if(attribFunc[i] == NULL)
723 SWARNING << "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
724 << "Extension function for property " << i
725 << " type " << pumpData.attribPtr[i]->getDimension()
726 << "D " << formatNames[formatIdx]
727 << " not supported by Window " << win
728 << endLog;
730 pumpData.attribData[i] = NULL;
731 pumpData.attribPtr [i] = NULL;
732 continue;
736 // we need positions
737 if(pumpData.attribPtr[0] == NULL)
739 if(pumpData.attribPtr[0] == NULL ||
740 pumpData.attribPtr[0]->getUseVBO() == false)
742 SWARNING << "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
743 << "No positions." << endLog;
744 return;
748 // global attribs?
749 for(Int16 i = 0; i < nattrib; ++i)
751 if(pumpData.attribData[i] != NULL &&
752 pumpData.attribPtr [i]->size() == 1 )
754 attribFunc[i](i, pumpData.attribData[i]);
755 pumpData.attribData[i] = NULL;
756 pumpData.attribPtr [i] = NULL;
760 // activate vertex arrays
761 // !!! This should be using the global state to reduce state changes
762 // and to allow sharing data between objects
764 for(Int16 i = nattrib - 1; i >= 0; --i)
766 if(pumpData.attribPtr[i] != NULL)
768 pumpData.attribPtr[i]->activate(pEnv, i + 16); // XXX HACK
772 // Length handling. Special case: no length given
774 UInt32 curlen;
775 UInt32 nprims;
777 // no lengths? use all available data for the first type
778 if(lengths == NULL)
780 if(types->size() != 1)
782 SWARNING << "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
783 << "No lengths, but more than one type?!"
784 << endLog;
785 return;
788 nprims = 1;
789 if(pumpData.attribIndex[0] != NULL)
791 curlen = pumpData.attribIndex[0]->size32();
793 else
795 curlen = pumpData.attribPtr[0]->size32();
798 else
800 nprims = types->size32();
801 lengths->getValue(curlen, 0);
804 UInt32 vertindex = 0;
806 if(pumpData.attribIndex[0] != NULL)
808 // Single Indexed
810 GeoIntegralProperty *index = pumpData.attribIndex[0];
811 const UInt8 *indexData = index->getData();
812 GLenum indexFormat = index->getFormat();
813 UInt32 indexStride =
814 index->getStride() ? index->getStride() : index->getFormatSize() *
815 index->getDimension();
817 index->activate(pEnv, 0);
819 if(index->isInVBO(pEnv))
821 indexData = NULL;
824 if(uiNumInstances > 1)
826 OSGGETGLFUNCBYID_GL3_ES(glDrawElementsInstanced,
827 osgGlDrawElementsInstanced,
828 Geometry::getFuncIdDrawElementsInstanced(),
829 win);
831 for(UInt32 primindex = 0; primindex < nprims; ++primindex)
833 if(primindex < lengths->size())
834 curlen = lengths->getValue<UInt32>(primindex);
836 if(curlen > 0)
838 osgGlDrawElementsInstanced(
839 types->getValue<UInt16>(primindex),
840 curlen,
841 indexFormat,
842 indexData + vertindex * indexStride,
843 uiNumInstances );
845 vertindex += curlen;
849 else
851 for(UInt32 primindex = 0; primindex < nprims; ++primindex)
853 if(primindex < lengths->size())
854 curlen = lengths->getValue<UInt32>(primindex);
856 if(curlen > 0)
858 glDrawElements(types->getValue<UInt16>(primindex),
859 curlen,
860 indexFormat,
861 indexData + vertindex * indexStride);
863 vertindex += curlen;
868 index->deactivate(pEnv, 0);
870 else
872 if(uiNumInstances > 1)
874 OSGGETGLFUNCBYID_GL3_ES(glDrawArraysInstanced,
875 osgGlDrawArraysInstanced,
876 Geometry::getFuncIdDrawArraysInstanced(),
877 win);
879 // Non-indexed
880 for(UInt32 primindex = 0; primindex < nprims; ++primindex)
882 if(primindex < lengths->size())
883 curlen = lengths->getValue<UInt32>(primindex);
885 if(curlen > 0)
887 osgGlDrawArraysInstanced(
888 types->getValue<UInt16>(primindex),
889 vertindex,
890 curlen,
891 uiNumInstances);
893 vertindex += curlen;
897 else
899 // Non-indexed
900 for(UInt32 primindex = 0; primindex < nprims; ++primindex)
902 if(primindex < lengths->size())
903 curlen = lengths->getValue<UInt32>(primindex);
905 if(curlen > 0)
907 glDrawArrays(types->getValue<UInt16>(primindex), vertindex,
908 curlen);
909 vertindex += curlen;
915 // disable arrays
916 for(Int16 i = nattrib - 1; i >= 0; --i)
918 if(pumpData.attribData[i] != NULL)
920 pumpData.attribPtr[i]->deactivate(pEnv, i + 16);
925 OSG_END_NAMESPACE