1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
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. *
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. *
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. *
31 \*---------------------------------------------------------------------------*/
32 /*---------------------------------------------------------------------------*\
40 \*---------------------------------------------------------------------------*/
42 //---------------------------------------------------------------------------
44 //---------------------------------------------------------------------------
49 #include "OSGConfig.h"
56 #include "OSGGeometry.h"
57 #include "OSGDrawEnv.h"
59 #include "OSGMaterial.h"
61 #include "OSGGeoSplitVertexArrayPumpGroup.h"
63 #include "OSGGLFuncProtos.h"
67 #define OSG_COMPILE_SPLIT_PUMP 1
69 // Intentionally INSIDE the namespace
70 #include "OSGGeoPumpCommon.inl"
72 //#define DEBUG_WHICH_PUMP 1
74 /***************************************************************************\
76 \***************************************************************************/
78 /***************************************************************************\
80 \***************************************************************************/
82 /*! An InitFuncWrapper to initialize the GeoVertexArrayPumpGroup.
85 InitFuncWrapper
GeoSplitVertexArrayPumpGroup::_glextInitFuncWrapper(
86 GeoSplitVertexArrayPumpGroup::glextInitFunction
);
88 /*! OpenGL extension indices.
91 UInt32
GeoSplitVertexArrayPumpGroup::_arbVertexProgram
;
92 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
93 UInt32
GeoSplitVertexArrayPumpGroup::_extSecondaryColor
;
94 UInt32
GeoSplitVertexArrayPumpGroup::_extMultitexture
;
97 /***************************************************************************\
99 \***************************************************************************/
101 /*------------- constructors & destructors --------------------------------*/
103 GeoSplitVertexArrayPumpGroup::GeoSplitVertexArrayPumpGroup(void)
107 GeoSplitVertexArrayPumpGroup::~GeoSplitVertexArrayPumpGroup(void)
111 /*-------------------------------------------------------------------------*\
113 \*-------------------------------------------------------------------------*/
115 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
119 // collect info for property in 'slot'
120 bool pumpGLSetup(PumpData
&info
, UInt16 slot
)
124 if(slot
< info
.prop
->size())
125 info
.attribPtr
[slot
] = (*info
.prop
)[slot
];
127 if(slot
< info
.propIdx
->size())
128 info
.attribIndex
[slot
] = (*info
.propIdx
)[slot
];
130 if(info
.attribPtr
[slot
] != NULL
&&
131 info
.attribPtr
[slot
]->getIgnore() == false )
133 info
.attribData
[slot
] = info
.attribPtr
[slot
]->getData();
134 info
.attribStride
[slot
] = info
.attribPtr
[slot
]->getStride();
136 if(info
.attribStride
[slot
] == 0)
138 info
.attribStride
[slot
] =
139 info
.attribPtr
[slot
]->getFormatSize() *
140 info
.attribPtr
[slot
]->getDimension();
149 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
150 // handle vertex attrib with global value
151 void globalAttrib(PumpData
&info
, UInt16 slot
, UInt16 pumpSlot
)
153 if(info
.attribData
[slot
] != NULL
&&
154 info
.attribPtr
[slot
]->size() == 1 )
156 UInt16 formatIdx
= info
.attribPtr
[slot
]->getFormat() - formatBase
;
157 UInt32 dimIdx
= info
.attribPtr
[slot
]->getDimension() - 1;
159 pumpFunc pump
= pumpFuncs
[pumpSlot
][formatIdx
][dimIdx
];
163 SWARNING
<< "GeoVertexArrayPumpGroup - globalExtAttrib: "
164 << "Invalid pump function for property " << slot
165 << " type " << info
.attribPtr
[slot
]->getDimension()
166 << "D " << formatNames
[formatIdx
]
171 pump(info
.attribData
[slot
]);
172 info
.attribData
[slot
] = NULL
;
173 info
.attribPtr
[slot
] = NULL
;
178 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
179 // handle vertex attrib with global value - using GL extension
180 void globalExtAttrib(PumpData
&info
, UInt16 slot
,
181 UInt16 pumpSlot
, Window
*win
)
183 if(info
.attribData
[slot
] != NULL
&&
184 info
.attribPtr
[slot
]->size() == 1 )
186 UInt16 formatIdx
= info
.attribPtr
[slot
]->getFormat() - formatBase
;
187 UInt32 dimIdx
= info
.attribPtr
[slot
]->getDimension() - 1;
188 UInt32 funcId
= pumpFuncIDs
[pumpSlot
][formatIdx
][dimIdx
];
190 if(funcId
== Window::invalidFunctionID
)
192 SWARNING
<< "GeoVertexArrayPumpGroup - globalExtAttrib: "
193 << "Invalid extension function for property " << slot
194 << " type " << info
.attribPtr
[slot
]->getDimension()
195 << "D " << formatNames
[formatIdx
]
201 reinterpret_cast<pumpFunc
>(win
->getFunction(funcId
));
205 SWARNING
<< "GeoVertexArrayPumpGroup - globalExtAttrib: "
206 << "Extension function for property " << slot
207 << " type " << info
.attribPtr
[slot
]->getDimension()
208 << "D " << formatNames
[formatIdx
]
209 << " not supported by Window " << win
214 pump(info
.attribData
[slot
]);
215 info
.attribData
[slot
] = NULL
;
216 info
.attribPtr
[slot
] = NULL
;
221 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
222 // handle vertex attrib with global value - using GL extension, multi
223 void globalExtMultiAttrib(PumpData
&info
, UInt16 slot
,
224 UInt16 pumpSlot
, GLenum attrib
,
227 if(info
.attribData
[slot
] != NULL
&&
228 info
.attribPtr
[slot
]->size() == 1 )
230 UInt16 formatIdx
= info
.attribPtr
[slot
]->getFormat() - formatBase
;
231 UInt32 dimIdx
= info
.attribPtr
[slot
]->getDimension() - 1;
232 UInt32 funcId
= pumpFuncIDs
[pumpSlot
][formatIdx
][dimIdx
];
234 if(funcId
== Window::invalidFunctionID
)
236 SWARNING
<< "GeoVertexArrayPumpGroup - globalExtMultiAttrib: "
237 << "Invalid extension function for property " << slot
238 << " type " << info
.attribPtr
[slot
]->getDimension()
239 << "D " << formatNames
[formatIdx
]
245 reinterpret_cast<multiPumpFunc
>(win
->getFunction(funcId
));
249 SWARNING
<< "GeoVertexArrayPumpGroup - globalExtMutliAttrib: "
250 << "Extension function for property " << slot
251 << " type " << info
.attribPtr
[slot
]->getDimension()
252 << "D " << formatNames
[formatIdx
]
253 << " not supported by Window " << win
258 pump(attrib
, info
.attribData
[slot
]);
259 info
.attribData
[slot
] = NULL
;
260 info
.attribPtr
[slot
] = NULL
;
267 #endif // remove from all but dev docs
271 GeoPumpGroup::SplitGeoPump
GeoSplitVertexArrayPumpGroup::getSplitGeoPump(
273 PropertyCharacteristics acset
)
275 SplitGeoPump pump
= { NULL
, NULL
, NULL
};
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
,
287 0x0200 ) && (acset
& UsesShader
))
289 pump
.setupPump
= masterAttribGeoSetupPumpFull
;
290 pump
.drawPump
= masterAttribGeoJustDrawPump
;
291 pump
.shutdownPump
= masterAttribGeoShutdownPump
;
293 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
296 pump
.setupPump
= masterClassicGeoSetupPumpFull
;
297 pump
.drawPump
= masterClassicGeoJustDrawPump
;
298 pump
.shutdownPump
= masterClassicGeoShutdownPump
;
306 GeoPumpGroup::GeoPump
GeoSplitVertexArrayPumpGroup::getGeoPump(
308 PropertyCharacteristics acset
)
313 bool GeoSplitVertexArrayPumpGroup::glextInitFunction(void)
315 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
317 Window::registerExtension("GL_EXT_secondary_color");
319 Window::registerExtension("GL_ARB_multitexture");
322 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
323 for(UInt16 i
= 0; i
< numFormats
; ++i
)
325 for(UInt16 j
= 0; j
< 4; ++j
)
327 pumpFuncIDs
[0][i
][j
] = Window::invalidFunctionID
;
328 pumpFuncIDs
[1][i
][j
] = Window::invalidFunctionID
;
332 for(UInt16 i
= 0; i
< uiNumSecColFunc
; ++i
)
333 secondaryColorInitFuncs
[i
].init(pumpFuncIDs
[SecColorsPumpSlot
],
334 _extSecondaryColor
);
336 for(UInt16 i
= 0; i
< uiNumMTexFuncs
; ++i
)
337 multiTexCoordsInitFuncs
[i
].init(pumpFuncIDs
[TexCoords1PumpSlot
],
342 Window::registerExtension("GL_ARB_vertex_program");
344 for(UInt16 i
= 0; i
< uiNumAttribFuncs
; ++i
)
345 attribInitFuncs
[i
].init(attribPumpFuncIDs
, _arbVertexProgram
);
347 for(UInt16 i
= 0; i
< uiNumNormAttribFuncs
; ++i
)
348 normAttribInitFuncs
[i
].init(normAttribPumpFuncIDs
, _arbVertexProgram
);
355 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
356 bool GeoSplitVertexArrayPumpGroup::masterClassicGeoSetupPump(
358 const GeoIntegralProperty
*lengths
,
359 const GeoIntegralProperty
*types
,
360 const Geometry::MFPropertiesType
*prop
,
361 const Geometry::MFPropIndicesType
*propIdx
,
364 #ifdef DEBUG_WHICH_PUMP
365 static bool bPrinted
= false;
367 if(bPrinted
== false)
370 "GeoSplitVertexArrayPumpGroup::masterClassicGeoSetupPump\n");
375 // Setup: get all the data
378 pumpData
.lengths
= lengths
;
379 pumpData
.types
= types
;
380 pumpData
.prop
= prop
;
381 pumpData
.propIdx
= propIdx
;
383 UInt16 nattrib
= prop
->size32();
385 for(UInt16 i
= 0; i
< nattrib
; ++i
)
387 if(pumpGLSetup(pumpData
, i
) == false)
392 if(pumpData
.attribPtr
[0] == NULL
||
393 pumpData
.attribPtr
[0]->getUseVBO() == false)
395 #ifdef DEBUG_WHICH_PUMP
396 static bool bPrinted1
= false;
398 if(bPrinted1
== false)
401 if(withFallback
== false)
403 SWARNING
<< "GeoSplitVertexArrayPumpGroup::masterAttribGeoPump: "
404 << "No positions, or positions not in vbo." << endLog
;
406 #ifdef DEBUG_WHICH_PUMP
414 for(Int16 i
= nattrib
- 1; i
>= 0; --i
)
416 if(pumpData
.attribPtr
[i
] != NULL
&&
417 pumpData
.attribPtr
[i
]->size() != 1 )
419 pumpData
.attribPtr
[i
]->activate(pEnv
, i
);
427 void GeoSplitVertexArrayPumpGroup::masterClassicGeoDrawPump(
429 const GeoIntegralProperty
*lengths
,
430 const GeoIntegralProperty
*types
,
431 const Geometry::MFPropertiesType
*prop
,
432 const Geometry::MFPropIndicesType
*propIdx
)
434 #ifdef DEBUG_WHICH_PUMP
435 static bool bPrinted
= false;
437 if(bPrinted
== false)
440 "GeoSplitVertexArrayPumpGroup::masterClassicGeoDrawPump\n");
445 Window
*win
= pEnv
->getWindow();
447 // check for empty geometry
448 if(types
== NULL
|| types
->size() == 0)
451 if(!pumpInternalSetup(types
, true))
453 if(!pumpInternalSetup(lengths
, false))
458 pumpData
.lengths
= lengths
;
459 pumpData
.types
= types
;
460 pumpData
.prop
= prop
;
461 pumpData
.propIdx
= propIdx
;
463 UInt16 nattrib
= prop
->size32();
465 for(UInt16 i
= 0; i
< nattrib
; ++i
)
467 if(pumpGLSetup(pumpData
, i
) == false)
471 // Length handling. Special case: no length given
476 // no lengths? use all available data for the first type
479 if(types
->size() != 1)
481 SWARNING
<< "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
482 << "No lengths, but more than one type?!"
489 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
491 curlen
= (*propIdx
)[0]->size32();
495 curlen
= (*prop
)[0]->size32();
500 nprims
= types
->size32();
501 lengths
->getValue(curlen
, 0);
505 globalAttrib(pumpData
, Geometry::NormalsIndex
, NormalsPumpSlot
);
506 globalAttrib(pumpData
, Geometry::ColorsIndex
, ColorsPumpSlot
);
507 globalAttrib(pumpData
, Geometry::TexCoordsIndex
, TexCoordsPumpSlot
);
509 if(win
->hasExtOrVersion(_extSecondaryColor
, 0x0104) == true)
511 globalExtAttrib(pumpData
, Geometry::SecondaryColorsIndex
,
512 SecColorsPumpSlot
, win
);
515 if(win
->hasExtOrVersion(_extMultitexture
, 0x0103, 0x0200) == true)
517 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
518 TexCoords1PumpSlot
, GL_TEXTURE1_ARB
, win
);
519 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
520 TexCoords2PumpSlot
, GL_TEXTURE2_ARB
, win
);
521 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
522 TexCoords3PumpSlot
, GL_TEXTURE3_ARB
, win
);
523 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
524 TexCoords4PumpSlot
, GL_TEXTURE4_ARB
, win
);
525 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
526 TexCoords5PumpSlot
, GL_TEXTURE5_ARB
, win
);
527 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
528 TexCoords6PumpSlot
, GL_TEXTURE6_ARB
, win
);
529 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
530 TexCoords7PumpSlot
, GL_TEXTURE7_ARB
, win
);
533 UInt32 vertindex
= 0;
535 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
539 GeoIntegralProperty
*index
= (*propIdx
)[0];
540 const UInt8
*indexData
= index
->getData();
541 GLenum indexFormat
= index
->getFormat();
543 index
->getStride() ? index
->getStride() : index
->getFormatSize() *
544 index
->getDimension();
546 index
->activate(pEnv
, 0);
548 if(index
->isInVBO(pEnv
))
553 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
555 if(primindex
< lengths
->size())
556 curlen
= lengths
->getValue
<UInt32
>(primindex
);
560 glDrawElements(types
->getValue
<UInt16
>(primindex
),
563 indexData
+ vertindex
* indexStride
);
569 index
->deactivate(pEnv
, 0);
574 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
576 if(primindex
< lengths
->size())
577 curlen
= lengths
->getValue
<UInt32
>(primindex
);
581 glDrawArrays(types
->getValue
<UInt16
>(primindex
), vertindex
,
590 bool GeoSplitVertexArrayPumpGroup::masterClassicGeoSetupPumpFull(
592 const GeoIntegralProperty
*lengths
,
593 const GeoIntegralProperty
*types
,
594 const Geometry::MFPropertiesType
*prop
,
595 const Geometry::MFPropIndicesType
*propIdx
,
598 #ifdef DEBUG_WHICH_PUMP
599 static bool bPrinted
= false;
601 if(bPrinted
== false)
604 "GeoSplitVertexArrayPumpGroup::masterClassicGeoSetupPumpFull\n");
609 // Setup: get all the data
612 pumpData
.lengths
= lengths
;
613 pumpData
.types
= types
;
614 pumpData
.prop
= prop
;
615 pumpData
.propIdx
= propIdx
;
617 UInt16 nattrib
= prop
->size32();
619 for(UInt16 i
= 0; i
< nattrib
; ++i
)
621 if(pumpGLSetup(pumpData
, i
) == false)
626 if(pumpData
.attribPtr
[0] == NULL
||
627 pumpData
.attribPtr
[0]->getUseVBO() == false)
629 #ifdef DEBUG_WHICH_PUMP
630 static bool bPrinted1
= false;
632 if(bPrinted1
== false)
635 if(withFallback
== false)
637 SWARNING
<< "GeoSplitVertexArrayPumpGroup::masterAttribGeoPump: "
638 << "No positions." << endLog
;
640 #ifdef DEBUG_WHICH_PUMP
647 for(Int16 i
= nattrib
- 1; i
>= 0; --i
)
649 if(pumpData
.attribPtr
[i
] != NULL
&&
650 pumpData
.attribPtr
[i
]->size() != 1 )
652 pumpData
.attribPtr
[i
]->activate(pEnv
, i
);
656 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
658 (*propIdx
)[0]->activate(pEnv
, 0);
664 void GeoSplitVertexArrayPumpGroup::masterClassicGeoJustDrawPump(
666 const GeoIntegralProperty
*lengths
,
667 const GeoIntegralProperty
*types
,
668 const Geometry::MFPropertiesType
*prop
,
669 const Geometry::MFPropIndicesType
*propIdx
,
670 UInt32 uiNumInstances
)
672 #ifdef DEBUG_WHICH_PUMP
673 static bool bPrinted
= false;
675 if(bPrinted
== false)
678 "GeoSplitVertexArrayPumpGroup::masterClassicGeoJustDrawPump\n");
683 Window
*win
= pEnv
->getWindow();
685 // check for empty geometry
686 if(types
== NULL
|| types
->size() == 0)
689 if(!pumpInternalSetup(types
, true))
691 if(!pumpInternalSetup(lengths
, false))
696 pumpData
.lengths
= lengths
;
697 pumpData
.types
= types
;
698 pumpData
.prop
= prop
;
699 pumpData
.propIdx
= propIdx
;
701 UInt16 nattrib
= prop
->size32();
703 for(UInt16 i
= 0; i
< nattrib
; ++i
)
705 if(pumpGLSetup(pumpData
, i
) == false)
709 // Length handling. Special case: no length given
714 // no lengths? use all available data for the first type
717 if(types
->size() != 1)
719 SWARNING
<< "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
720 << "No lengths, but more than one type?!"
727 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
729 curlen
= (*propIdx
)[0]->size32();
733 curlen
= (*prop
)[0]->size32();
738 nprims
= types
->size32();
739 lengths
->getValue(curlen
, 0);
743 globalAttrib(pumpData
, Geometry::NormalsIndex
, NormalsPumpSlot
);
744 globalAttrib(pumpData
, Geometry::ColorsIndex
, ColorsPumpSlot
);
745 globalAttrib(pumpData
, Geometry::TexCoordsIndex
, TexCoordsPumpSlot
);
747 if(win
->hasExtOrVersion(_extSecondaryColor
, 0x0104) == true)
749 globalExtAttrib(pumpData
, Geometry::SecondaryColorsIndex
,
750 SecColorsPumpSlot
, win
);
753 if(win
->hasExtOrVersion(_extMultitexture
, 0x0103, 0x0200) == true)
755 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
756 TexCoords1PumpSlot
, GL_TEXTURE1_ARB
, win
);
757 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
758 TexCoords2PumpSlot
, GL_TEXTURE2_ARB
, win
);
759 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
760 TexCoords3PumpSlot
, GL_TEXTURE3_ARB
, win
);
761 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
762 TexCoords4PumpSlot
, GL_TEXTURE4_ARB
, win
);
763 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
764 TexCoords5PumpSlot
, GL_TEXTURE5_ARB
, win
);
765 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
766 TexCoords6PumpSlot
, GL_TEXTURE6_ARB
, win
);
767 globalExtMultiAttrib(pumpData
, Geometry::TexCoords1Index
,
768 TexCoords7PumpSlot
, GL_TEXTURE7_ARB
, win
);
771 UInt32 vertindex
= 0;
773 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
777 GeoIntegralProperty
*index
= (*propIdx
)[0];
778 const UInt8
*indexData
= index
->getData();
779 GLenum indexFormat
= index
->getFormat();
781 index
->getStride() ? index
->getStride() : index
->getFormatSize() *
782 index
->getDimension();
785 index
->activate(pEnv
, 0);
787 if(index
->isInVBO(pEnv
))
795 if(uiNumInstances
> 1)
797 OSGGETGLFUNCBYID_GL3_ES(glDrawElementsInstanced
,
798 osgGlDrawElementsInstanced
,
799 Geometry::getFuncIdDrawElementsInstanced(),
802 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
804 if(primindex
< lengths
->size())
805 curlen
= lengths
->getValue
<UInt32
>(primindex
);
809 osgGlDrawElementsInstanced(
810 types
->getValue
<UInt16
>(primindex
),
813 indexData
+ vertindex
* indexStride
,
822 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
824 if(primindex
< lengths
->size())
825 curlen
= lengths
->getValue
<UInt32
>(primindex
);
829 glDrawElements(types
->getValue
<UInt16
>(primindex
),
832 indexData
+ vertindex
* indexStride
);
840 index
->deactivate(pEnv
, 0);
845 if(uiNumInstances
> 1)
847 OSGGETGLFUNCBYID_GL3_ES(glDrawArraysInstanced
,
848 osgGlDrawArraysInstanced
,
849 Geometry::getFuncIdDrawArraysInstanced(),
852 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
854 if(primindex
< lengths
->size())
855 curlen
= lengths
->getValue
<UInt32
>(primindex
);
859 osgGlDrawArraysInstanced(
860 types
->getValue
<UInt16
>(primindex
),
872 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
874 if(primindex
< lengths
->size())
875 curlen
= lengths
->getValue
<UInt32
>(primindex
);
879 glDrawArrays(types
->getValue
<UInt16
>(primindex
), vertindex
,
888 bool GeoSplitVertexArrayPumpGroup::masterClassicGeoShutdownPump(
890 const GeoIntegralProperty
*lengths
,
891 const GeoIntegralProperty
*types
,
892 const Geometry::MFPropertiesType
*prop
,
893 const Geometry::MFPropIndicesType
*propIdx
)
895 #ifdef DEBUG_WHICH_PUMP
896 static bool bPrinted
= false;
898 if(bPrinted
== false)
901 "GeoSplitVertexArrayPumpGroup::masterClassicGeoShutdownPump\n");
906 // Setup: get all the data
909 pumpData
.lengths
= lengths
;
910 pumpData
.types
= types
;
911 pumpData
.prop
= prop
;
912 pumpData
.propIdx
= propIdx
;
914 UInt16 nattrib
= prop
->size32();
916 for(UInt16 i
= 0; i
< nattrib
; ++i
)
918 if(pumpGLSetup(pumpData
, i
) == false)
923 if(pumpData
.attribPtr
[0] == NULL
||
924 pumpData
.attribPtr
[0]->getUseVBO() == false)
926 #ifdef DEBUG_WHICH_PUMP
927 static bool bPrinted1
= false;
929 if(bPrinted1
== false)
932 SWARNING
<< "GeoSplitVertexArrayPumpGroup::masterAttribGeoPump: "
933 << "No positions." << endLog
;
936 #ifdef DEBUG_WHICH_PUMP
942 for(Int16 i
= nattrib
- 1; i
>= 0; --i
)
944 if(pumpData
.attribPtr
[i
] != NULL
&&
945 pumpData
.attribPtr
[i
]->size() != 1 )
947 pumpData
.attribPtr
[i
]->deactivate(pEnv
, i
);
951 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
953 (*propIdx
)[0]->deactivate(pEnv
, 0);
962 bool GeoSplitVertexArrayPumpGroup::masterAttribGeoSetupPump(
964 const GeoIntegralProperty
*lengths
,
965 const GeoIntegralProperty
*types
,
966 const Geometry::MFPropertiesType
*prop
,
967 const Geometry::MFPropIndicesType
*propIdx
,
970 #ifdef DEBUG_WHICH_PUMP
971 static bool bPrinted
= false;
973 if(bPrinted
== false)
976 "GeoSplitVertexArrayPumpGroup::masterAttribGeoSetupPump\n");
981 // Setup: get all the data
984 pumpData
.lengths
= lengths
;
985 pumpData
.types
= types
;
986 pumpData
.prop
= prop
;
987 pumpData
.propIdx
= propIdx
;
989 UInt16 nattrib
= prop
->size32();
991 for(UInt16 i
= 0; i
< nattrib
; ++i
)
993 if(pumpGLSetup(pumpData
, i
) == false)
998 if(pumpData
.attribPtr
[0] == NULL
||
999 pumpData
.attribPtr
[0]->getUseVBO() == false)
1001 #ifdef DEBUG_WHICH_PUMP
1002 static bool bPrinted1
= false;
1004 if(bPrinted1
== false)
1007 if(withFallback
== false)
1009 SWARNING
<< "GeoSplitVertexArrayPumpGroup::masterAttribGeoPump: "
1010 << "No positions." << endLog
;
1012 #ifdef DEBUG_WHICH_PUMP
1019 for(Int16 i
= nattrib
- 1; i
>= 0; --i
)
1021 if(pumpData
.attribPtr
[i
] != NULL
&&
1022 pumpData
.attribPtr
[i
]->size() != 1 )
1024 pumpData
.attribPtr
[i
]->activate(pEnv
, i
+ 16); // XXX HACK
1032 void GeoSplitVertexArrayPumpGroup::masterAttribGeoDrawPump(
1034 const GeoIntegralProperty
*lengths
,
1035 const GeoIntegralProperty
*types
,
1036 const Geometry::MFPropertiesType
*prop
,
1037 const Geometry::MFPropIndicesType
*propIdx
)
1039 #ifdef DEBUG_WHICH_PUMP
1040 static bool bPrinted
= false;
1042 if(bPrinted
== false)
1045 "GeoSplitVertexArrayPumpGroup::masterAttribGeoDrawPump\n");
1050 Window
*win
= pEnv
->getWindow();
1052 // check for empty geometry
1053 if(types
== NULL
|| types
->size() == 0)
1056 if(!pumpInternalSetup(types
, true))
1058 if(!pumpInternalSetup(lengths
, false))
1061 attribPumpFunc attribFunc
[Geometry::MaxAttribs
];
1064 pumpData
.lengths
= lengths
;
1065 pumpData
.types
= types
;
1066 pumpData
.prop
= prop
;
1067 pumpData
.propIdx
= propIdx
;
1069 UInt16 nattrib
= prop
->size32();
1071 for(UInt16 i
= 0; i
< nattrib
; ++i
)
1073 if(pumpGLSetup(pumpData
, i
) == false)
1076 UInt16 formatIdx
= pumpData
.attribPtr
[i
]->getFormat () - formatBase
;
1077 UInt16 dimIdx
= pumpData
.attribPtr
[i
]->getDimension() - 1;
1079 #if !defined(OSG_USE_OGLES_PROTOS) && !defined(OSG_USE_OGL3_PROTOS) && \
1080 !defined(OSG_USE_OGL4_PROTOS)
1081 UInt32 funcId
= Window::invalidFunctionID
;
1083 if(pumpData
.attribPtr
[i
]->getNormalize() == true)
1085 funcId
= normAttribPumpFuncIDs
[formatIdx
][dimIdx
];
1087 if(funcId
== Window::invalidFunctionID
)
1089 SWARNING
<< "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
1090 << "Invalid pump function for property " << i
1091 << " type " << pumpData
.attribPtr
[i
]->getDimension()
1092 << "D " << formatNames
[formatIdx
] << " (normalizing)."
1095 pumpData
.attribData
[i
] = NULL
;
1096 pumpData
.attribPtr
[i
] = NULL
;
1102 funcId
= attribPumpFuncIDs
[formatIdx
][dimIdx
];
1104 if(funcId
== Window::invalidFunctionID
)
1106 SWARNING
<< "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
1107 << "Invalid pump function for property " << i
1108 << " type " << pumpData
.attribPtr
[i
]->getDimension()
1109 << "D " << formatNames
[formatIdx
]
1112 pumpData
.attribData
[i
] = NULL
;
1113 pumpData
.attribPtr
[i
] = NULL
;
1118 attribFunc
[i
] = reinterpret_cast<attribPumpFunc
>(
1119 win
->getFunction(funcId
));
1122 if(pumpData
.attribPtr
[i
]->getNormalize() == true)
1124 attribFunc
[i
] = attribNormPumpFuncs
[formatIdx
][dimIdx
];
1128 attribFunc
[i
] = attribPumpFuncs
[formatIdx
][dimIdx
];
1132 if(attribFunc
[i
] == NULL
)
1134 SWARNING
<< "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
1135 << "Extension function for property " << i
1136 << " type " << pumpData
.attribPtr
[i
]->getDimension()
1137 << "D " << formatNames
[formatIdx
]
1138 << " not supported by Window " << win
1141 pumpData
.attribData
[i
] = NULL
;
1142 pumpData
.attribPtr
[i
] = NULL
;
1147 // Length handling. Special case: no length given
1152 // no lengths? use all available data for the first type
1155 if(types
->size() != 1)
1157 SWARNING
<< "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
1158 << "No lengths, but more than one type?!"
1165 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
1167 curlen
= (*propIdx
)[0]->size32();
1171 curlen
= (*prop
)[0]->size32();
1176 nprims
= types
->size32();
1177 lengths
->getValue(curlen
, 0);
1181 for(Int16 i
= 0; i
< nattrib
; ++i
)
1183 if(pumpData
.attribData
[i
] != NULL
&&
1184 pumpData
.attribPtr
[i
]->size() == 1 )
1186 attribFunc
[i
](i
, pumpData
.attribData
[i
]);
1187 pumpData
.attribData
[i
] = NULL
;
1191 UInt32 vertindex
= 0;
1193 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
1197 GeoIntegralProperty
*index
= (*propIdx
)[0];
1198 const UInt8
*indexData
= index
->getData();
1199 GLenum indexFormat
= index
->getFormat();
1200 UInt32 indexStride
=
1201 index
->getStride() ? index
->getStride() : index
->getFormatSize() *
1202 index
->getDimension();
1204 index
->activate(pEnv
, 0);
1206 if(index
->isInVBO(pEnv
))
1211 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
1213 if(primindex
< lengths
->size())
1214 curlen
= lengths
->getValue
<UInt32
>(primindex
);
1218 glDrawElements(types
->getValue
<UInt16
>(primindex
),
1221 indexData
+ vertindex
* indexStride
);
1223 vertindex
+= curlen
;
1227 index
->deactivate(pEnv
, 0);
1232 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
1234 if(primindex
< lengths
->size())
1235 curlen
= lengths
->getValue
<UInt32
>(primindex
);
1239 glDrawArrays(types
->getValue
<UInt16
>(primindex
), vertindex
,
1241 vertindex
+= curlen
;
1247 bool GeoSplitVertexArrayPumpGroup::masterAttribGeoSetupPumpFull(
1249 const GeoIntegralProperty
*lengths
,
1250 const GeoIntegralProperty
*types
,
1251 const Geometry::MFPropertiesType
*prop
,
1252 const Geometry::MFPropIndicesType
*propIdx
,
1255 #ifdef DEBUG_WHICH_PUMP
1256 static bool bPrinted
= false;
1258 if(bPrinted
== false)
1261 "GeoSplitVertexArrayPumpGroup::masterAttribGeoSetupPumpFull\n");
1266 // Setup: get all the data
1269 pumpData
.lengths
= lengths
;
1270 pumpData
.types
= types
;
1271 pumpData
.prop
= prop
;
1272 pumpData
.propIdx
= propIdx
;
1274 UInt16 nattrib
= prop
->size32();
1276 for(UInt16 i
= 0; i
< nattrib
; ++i
)
1278 if(pumpGLSetup(pumpData
, i
) == false)
1282 // we need positions
1283 if(pumpData
.attribPtr
[0] == NULL
||
1284 pumpData
.attribPtr
[0]->getUseVBO() == false)
1286 #ifdef DEBUG_WHICH_PUMP
1287 static bool bPrinted1
= false;
1289 if(bPrinted1
== false)
1292 if(withFallback
== false)
1294 SWARNING
<< "GeoSplitVertexArrayPumpGroup::masterAttribGeoPump: "
1295 << "No positions, or positions not in vbo." << endLog
;
1297 #ifdef DEBUG_WHICH_PUMP
1304 for(Int16 i
= nattrib
- 1; i
>= 0; --i
)
1306 if(pumpData
.attribPtr
[i
] != NULL
&&
1307 pumpData
.attribPtr
[i
]->size() != 1 )
1309 pumpData
.attribPtr
[i
]->activate(pEnv
, i
+ 16); // XXX HACK
1313 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
1315 (*propIdx
)[0]->activate(pEnv
, 0);
1321 void GeoSplitVertexArrayPumpGroup::masterAttribGeoJustDrawPump(
1323 const GeoIntegralProperty
*lengths
,
1324 const GeoIntegralProperty
*types
,
1325 const Geometry::MFPropertiesType
*prop
,
1326 const Geometry::MFPropIndicesType
*propIdx
,
1327 UInt32 uiNumInstances
)
1329 #ifdef DEBUG_WHICH_PUMP
1330 static bool bPrinted
= false;
1332 if(bPrinted
== false)
1335 "GeoSplitVertexArrayPumpGroup::masterAttribGeoJustDrawPump\n");
1340 Window
*win
= pEnv
->getWindow();
1342 // check for empty geometry
1343 if(types
== NULL
|| types
->size() == 0)
1346 if(!pumpInternalSetup(types
, true))
1348 if(!pumpInternalSetup(lengths
, false))
1351 attribPumpFunc attribFunc
[Geometry::MaxAttribs
];
1354 pumpData
.lengths
= lengths
;
1355 pumpData
.types
= types
;
1356 pumpData
.prop
= prop
;
1357 pumpData
.propIdx
= propIdx
;
1359 UInt16 nattrib
= prop
->size32();
1361 for(UInt16 i
= 0; i
< nattrib
; ++i
)
1363 if(pumpGLSetup(pumpData
, i
) == false)
1366 UInt16 formatIdx
= pumpData
.attribPtr
[i
]->getFormat () - formatBase
;
1367 UInt16 dimIdx
= pumpData
.attribPtr
[i
]->getDimension() - 1;
1369 #if !defined(OSG_USE_OGLES_PROTOS) && !defined(OSG_USE_OGL3_PROTOS) && \
1370 !defined(OSG_USE_OGL4_PROTOS)
1371 UInt32 funcId
= Window::invalidFunctionID
;
1373 if(pumpData
.attribPtr
[i
]->getNormalize() == true)
1375 funcId
= normAttribPumpFuncIDs
[formatIdx
][dimIdx
];
1377 if(funcId
== Window::invalidFunctionID
)
1379 SWARNING
<< "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
1380 << "Invalid pump function for property " << i
1381 << " type " << pumpData
.attribPtr
[i
]->getDimension()
1382 << "D " << formatNames
[formatIdx
] << " (normalizing)."
1385 pumpData
.attribData
[i
] = NULL
;
1386 pumpData
.attribPtr
[i
] = NULL
;
1392 funcId
= attribPumpFuncIDs
[formatIdx
][dimIdx
];
1394 if(funcId
== Window::invalidFunctionID
)
1396 SWARNING
<< "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
1397 << "Invalid pump function for property " << i
1398 << " type " << pumpData
.attribPtr
[i
]->getDimension()
1399 << "D " << formatNames
[formatIdx
]
1402 pumpData
.attribData
[i
] = NULL
;
1403 pumpData
.attribPtr
[i
] = NULL
;
1408 attribFunc
[i
] = reinterpret_cast<attribPumpFunc
>(
1409 win
->getFunction(funcId
));
1412 if(pumpData
.attribPtr
[i
]->getNormalize() == true)
1414 attribFunc
[i
] = attribNormPumpFuncs
[formatIdx
][dimIdx
];
1418 attribFunc
[i
] = attribPumpFuncs
[formatIdx
][dimIdx
];
1422 if(attribFunc
[i
] == NULL
)
1424 SWARNING
<< "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
1425 << "Extension function for property " << i
1426 << " type " << pumpData
.attribPtr
[i
]->getDimension()
1427 << "D " << formatNames
[formatIdx
]
1428 << " not supported by Window " << win
1431 pumpData
.attribData
[i
] = NULL
;
1432 pumpData
.attribPtr
[i
] = NULL
;
1437 // Length handling. Special case: no length given
1442 // no lengths? use all available data for the first type
1445 if(types
->size() != 1)
1447 SWARNING
<< "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
1448 << "No lengths, but more than one type?!"
1455 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
1457 curlen
= (*propIdx
)[0]->size32();
1461 curlen
= (*prop
)[0]->size32();
1466 nprims
= types
->size32();
1467 lengths
->getValue(curlen
, 0);
1471 for(Int16 i
= 0; i
< nattrib
; ++i
)
1473 if(pumpData
.attribData
[i
] != NULL
&&
1474 pumpData
.attribPtr
[i
]->size() == 1 )
1476 attribFunc
[i
](i
, pumpData
.attribData
[i
]);
1477 pumpData
.attribData
[i
] = NULL
;
1481 UInt32 vertindex
= 0;
1483 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
1487 GeoIntegralProperty
*index
= (*propIdx
)[0];
1488 const UInt8
*indexData
= index
->getData();
1489 GLenum indexFormat
= index
->getFormat();
1490 UInt32 indexStride
=
1491 index
->getStride() ? index
->getStride() : index
->getFormatSize() *
1492 index
->getDimension();
1495 index
->activate(pEnv
, 0);
1497 if(index
->isInVBO(pEnv
))
1505 if(uiNumInstances
> 1)
1507 OSGGETGLFUNCBYID_GL3_ES(glDrawElementsInstanced
,
1508 osgGlDrawElementsInstanced
,
1509 Geometry::getFuncIdDrawElementsInstanced(),
1512 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
1514 if(primindex
< lengths
->size())
1515 curlen
= lengths
->getValue
<UInt32
>(primindex
);
1519 osgGlDrawElementsInstanced(
1520 types
->getValue
<UInt16
>(primindex
),
1523 indexData
+ vertindex
* indexStride
,
1526 vertindex
+= curlen
;
1532 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
1534 if(primindex
< lengths
->size())
1535 curlen
= lengths
->getValue
<UInt32
>(primindex
);
1539 glDrawElements(types
->getValue
<UInt16
>(primindex
),
1542 indexData
+ vertindex
* indexStride
);
1544 vertindex
+= curlen
;
1550 index
->deactivate(pEnv
, 0);
1555 if(uiNumInstances
> 1)
1557 OSGGETGLFUNCBYID_GL3_ES(glDrawArraysInstanced
,
1558 osgGlDrawArraysInstanced
,
1559 Geometry::getFuncIdDrawArraysInstanced(),
1563 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
1565 if(primindex
< lengths
->size())
1566 curlen
= lengths
->getValue
<UInt32
>(primindex
);
1570 osgGlDrawArraysInstanced(
1571 types
->getValue
<UInt16
>(primindex
),
1576 vertindex
+= curlen
;
1583 for(UInt32 primindex
= 0; primindex
< nprims
; ++primindex
)
1585 if(primindex
< lengths
->size())
1586 curlen
= lengths
->getValue
<UInt32
>(primindex
);
1590 glDrawArrays(types
->getValue
<UInt16
>(primindex
), vertindex
,
1592 vertindex
+= curlen
;
1599 bool GeoSplitVertexArrayPumpGroup::masterAttribGeoShutdownPump(
1601 const GeoIntegralProperty
*lengths
,
1602 const GeoIntegralProperty
*types
,
1603 const Geometry::MFPropertiesType
*prop
,
1604 const Geometry::MFPropIndicesType
*propIdx
)
1606 #ifdef DEBUG_WHICH_PUMP
1607 static bool bPrinted
= false;
1609 if(bPrinted
== false)
1612 "GeoSplitVertexArrayPumpGroup::masterAttribGeoShutdownPump\n");
1617 // Setup: get all the data
1620 pumpData
.lengths
= lengths
;
1621 pumpData
.types
= types
;
1622 pumpData
.prop
= prop
;
1623 pumpData
.propIdx
= propIdx
;
1625 UInt16 nattrib
= prop
->size32();
1627 for(UInt16 i
= 0; i
< nattrib
; ++i
)
1629 if(pumpGLSetup(pumpData
, i
) == false)
1633 // we need positions
1634 if(pumpData
.attribPtr
[0] == NULL
||
1635 pumpData
.attribPtr
[0]->getUseVBO() == false)
1637 #ifdef DEBUG_WHICH_PUMP
1638 static bool bPrinted1
= false;
1640 if(bPrinted1
== false)
1643 SWARNING
<< "GeoSplitVertexArrayPumpGroup::masterAttribGeoPump: "
1644 << "No positions." << endLog
;
1646 #ifdef DEBUG_WHICH_PUMP
1653 for(Int16 i
= nattrib
- 1; i
>= 0; --i
)
1655 if(pumpData
.attribPtr
[i
] != NULL
&&
1656 pumpData
.attribPtr
[i
]->size() != 1 )
1658 pumpData
.attribPtr
[i
]->deactivate(pEnv
, i
+ 16); // XXX HACK
1662 if(propIdx
->size() != 0 && (*propIdx
)[0] != NULL
)
1664 (*propIdx
)[0]->deactivate(pEnv
, 0);