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 "OSGGeoPumpGroup.h"
62 #include "OSGGeoImmediatePumpGroup.h"
63 #include "OSGGeoVertexArrayPumpGroup.h"
64 #include "OSGGeoSplitVertexArrayPumpGroup.h"
69 /***************************************************************************\
71 \***************************************************************************/
73 /* \class OSG::GeoPumpGroup
74 \ingroup GrpSystemNodeCoresDrawablesGeometry
76 The PumpGroup is responsible for selecting the most appropriate pump
77 function to send the geometry's data to OpenGL in the most efficient manner.
79 The pump is selected inside the rendering function and should not be accessed
82 \dev The pump factory chooses the pump based on the used properties. For
83 non- and single-indexed geometry OpenGL VertexArrays are used, for
84 multi-indexed geometry an immediate mode pump has to be used. Specialized Pumps
85 for all combinations of properties are created to optimizie this case as much
90 std::vector
<GeoPumpGroup
*> *GeoPumpGroup::_activeGroups
;
92 /*! Initialize the _activeGroups at startup.
94 InitFuncWrapper
GeoPumpGroup::actInit(GeoPumpGroup::initActiveGroups
);
96 bool GeoPumpGroup::initActiveGroups(void)
98 _activeGroups
= new std::vector
<GeoPumpGroup
*>;
100 _activeGroups
->push_back(new GeoVertexArrayPumpGroup
);
101 _activeGroups
->push_back(new GeoSplitVertexArrayPumpGroup
);
102 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
103 _activeGroups
->push_back(new GeoImmediatePumpGroup
);
106 addPostFactoryExitFunction(&GeoPumpGroup::terminateActiveGroups
);
111 bool GeoPumpGroup::terminateActiveGroups(void)
113 for(UInt32 i
= 0; i
< _activeGroups
->size(); ++i
)
115 delete (*_activeGroups
)[i
];
118 delete _activeGroups
;
123 /*! PropertyCharacteristics handling.
126 std::string
GeoPumpGroup::describePropertyCharacteristics(
127 PropertyCharacteristics ac
)
131 if(ac
& GeoPumpGroup::NonIndexed
) result
+= "NonIndexed,";
132 if(ac
& GeoPumpGroup::SingleIndexed
) result
+= "SingleIndexed,";
133 if(ac
& GeoPumpGroup::MultiIndexed
) result
+= "MultiIndexed,";
134 if(ac
& GeoPumpGroup::NonTraditionalProperties
)
135 result
+= "NonTraditionalProperties,";
137 if(result
.empty() == true)
138 result
+= "unknown,";
140 result
.resize(result
.length()-1);
145 GeoPumpGroup::PropertyCharacteristics
146 GeoPumpGroup::characterizeGeometry(Geometry
* geo
)
148 return characterizeGeometry(geo
->getMFProperties(),
149 geo
->getMFPropIndices());
152 GeoPumpGroup::PropertyCharacteristics
153 GeoPumpGroup::characterizeGeometry(const Geometry::MFPropertiesType
*prop
,
154 const Geometry::MFPropIndicesType
*propIdx
)
156 PropertyCharacteristics retVal
= 0;
158 Int16 natt
= prop
->size32();
159 Int16 nind
= propIdx
->size32();
161 // Check for single- and multi-indexed
162 GeoIntegralProperty
*ind
= NULL
;
167 bool allPropVAO
= true;
168 bool allIdxVAO
= true;
170 for(Int16 i
= 0; i
< natt
; ++i
)
172 // Only count actual attributes
173 if((*prop
)[i
] != NULL
&& (*prop
)[i
]->getDivisor() == 0)
175 if((*prop
)[i
]->getUseVBO() == false)
182 if((*propIdx
)[i
] == NULL
)
184 if((*prop
)[i
]->size() != 1)
192 if((*propIdx
)[i
]->getUseVBO() == false)
202 if((*propIdx
)[i
] != ind
&& (*prop
)[i
]->size() != 1)
215 retVal
|= GeoPumpGroup::NonIndexed
;
217 retVal
|= GeoPumpGroup::SingleIndexed
;
219 retVal
|= GeoPumpGroup::MultiIndexed
;
221 if(allPropVAO
== true)
223 retVal
|= AllPropsVAO
;
226 if(allIdxVAO
== true)
228 retVal
|= AllPropIdxVAO
;
232 // check double single + multi char
234 "single %d | no %d | multi %d | prop vao %d | idx vao %d\n",
242 // Check for non-traditional properties.
243 // Right now just check existence of attribs 6&7
244 // To be complete this would also have to check
245 // type compatibility! *DR*
247 if(natt
> 6 && (*prop
)[6] != NULL
)
248 retVal
|= GeoPumpGroup::NonTraditionalProperties
;
249 if(natt
> 7 && (*prop
)[7] != NULL
)
250 retVal
|= GeoPumpGroup::NonTraditionalProperties
;
255 /*! Find the actual pumps for the given Window/Geometry.
258 GeoPumpGroup::GeoPump
GeoPumpGroup::findGeoPump(DrawEnv
*pEnv
,
259 PropertyCharacteristics acset
)
262 Window
*win
= pEnv
->getWindow();
264 for(std::vector
<GeoPumpGroup
*>::iterator it
= _activeGroups
->begin();
265 it
!= _activeGroups
->end() && pump
== NULL
;
268 pump
= (*it
)->getGeoPump(pEnv
,acset
);
273 FWARNING(("GeoPumpGroup::findGeoPump: Couldn't find pump for"
274 "Window %p and characteristics %s!\n",
275 static_cast<void *>(win
),
276 describePropertyCharacteristics(acset
).c_str() ));
282 GeoPumpGroup::SplitGeoPump
GeoPumpGroup::findSplitGeoPump(
284 PropertyCharacteristics acset
)
286 SplitGeoPump pump
= { NULL
, NULL
, NULL
};
287 Window
*win
= pEnv
->getWindow();
289 std::vector
<GeoPumpGroup
*>::const_iterator pIt
= _activeGroups
->begin();
290 std::vector
<GeoPumpGroup
*>::const_iterator pEnd
= _activeGroups
->end ();
292 for(; pIt
!= pEnd
&& pump
.setupPump
== NULL
; ++pIt
)
294 pump
= (*pIt
)->getSplitGeoPump(pEnv
, acset
);
297 if(pump
.setupPump
== NULL
)
299 FWARNING(("GeoPumpGroup::findSplitGeoPump: Couldn't find pump for"
300 "Window %p and characteristics %s!\n",
301 static_cast<void *>(win
),
302 describePropertyCharacteristics(acset
).c_str() ));
308 GeoPumpGroup::SplitGeoPump
GeoPumpGroup::getSplitGeoPump(
310 PropertyCharacteristics
)
312 SplitGeoPump pump
= { NULL
, NULL
, NULL
};
317 GeoPumpGroup::~GeoPumpGroup()