2006-07-18 23:21:48 +08:00
|
|
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
2003-01-22 00:45:36 +08:00
|
|
|
*
|
|
|
|
* This library is open source and may be redistributed and/or modified under
|
|
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* OpenSceneGraph Public License for more details.
|
|
|
|
*/
|
2007-07-28 18:44:03 +08:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
2002-06-21 03:54:08 +08:00
|
|
|
#include <osg/Geometry>
|
2009-10-21 03:34:24 +08:00
|
|
|
#include <osg/ArrayDispatchers>
|
2002-07-18 08:53:03 +08:00
|
|
|
#include <osg/Notify>
|
2002-06-21 03:54:08 +08:00
|
|
|
|
|
|
|
using namespace osg;
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
const Geometry::ArrayData Geometry::s_InvalidArrayData;
|
|
|
|
|
2003-12-04 05:45:32 +08:00
|
|
|
Geometry::ArrayData::ArrayData(const ArrayData& data,const CopyOp& copyop):
|
2003-12-18 20:20:38 +08:00
|
|
|
array(copyop(data.array.get())),
|
|
|
|
indices(dynamic_cast<osg::IndexArray*>(copyop(data.indices.get()))),
|
2003-12-04 05:45:32 +08:00
|
|
|
binding(data.binding),
|
2007-05-02 02:03:32 +08:00
|
|
|
normalize(data.normalize)
|
2003-12-04 05:45:32 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Geometry::Vec3ArrayData::Vec3ArrayData(const Vec3ArrayData& data,const CopyOp& copyop):
|
2003-12-18 20:20:38 +08:00
|
|
|
array(dynamic_cast<osg::Vec3Array*>(copyop(data.array.get()))),
|
|
|
|
indices(dynamic_cast<osg::IndexArray*>(copyop(data.indices.get()))),
|
2003-12-04 05:45:32 +08:00
|
|
|
binding(data.binding),
|
2007-05-02 02:03:32 +08:00
|
|
|
normalize(data.normalize)
|
2003-12-04 05:45:32 +08:00
|
|
|
{
|
|
|
|
}
|
2002-10-02 21:12:16 +08:00
|
|
|
|
2002-06-21 03:54:08 +08:00
|
|
|
Geometry::Geometry()
|
|
|
|
{
|
2009-10-21 03:34:24 +08:00
|
|
|
// temporary test
|
2009-10-21 22:11:00 +08:00
|
|
|
// setSupportsDisplayList(false);
|
2009-10-21 03:34:24 +08:00
|
|
|
|
2002-10-02 21:12:16 +08:00
|
|
|
_fastPath = false;
|
2003-08-09 08:46:48 +08:00
|
|
|
_fastPathHint = true;
|
2002-06-21 03:54:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop):
|
|
|
|
Drawable(geometry,copyop),
|
2003-12-04 05:45:32 +08:00
|
|
|
_vertexData(geometry._vertexData,copyop),
|
|
|
|
_normalData(geometry._normalData,copyop),
|
|
|
|
_colorData(geometry._colorData,copyop),
|
|
|
|
_secondaryColorData(geometry._secondaryColorData,copyop),
|
|
|
|
_fogCoordData(geometry._fogCoordData,copyop),
|
2003-08-08 08:21:30 +08:00
|
|
|
_fastPath(geometry._fastPath),
|
2003-08-09 08:46:48 +08:00
|
|
|
_fastPathHint(geometry._fastPathHint)
|
2002-06-21 03:54:08 +08:00
|
|
|
{
|
2009-10-21 03:34:24 +08:00
|
|
|
// temporary test
|
2009-10-21 22:11:00 +08:00
|
|
|
// setSupportsDisplayList(false);
|
2009-10-21 03:34:24 +08:00
|
|
|
|
2002-10-02 21:12:16 +08:00
|
|
|
for(PrimitiveSetList::const_iterator pitr=geometry._primitives.begin();
|
2002-07-26 05:50:08 +08:00
|
|
|
pitr!=geometry._primitives.end();
|
|
|
|
++pitr)
|
|
|
|
{
|
2002-09-20 22:51:59 +08:00
|
|
|
PrimitiveSet* primitive = copyop(pitr->get());
|
2002-07-26 05:50:08 +08:00
|
|
|
if (primitive) _primitives.push_back(primitive);
|
|
|
|
}
|
|
|
|
|
2007-04-27 22:52:30 +08:00
|
|
|
for(ArrayDataList::const_iterator titr=geometry._texCoordList.begin();
|
2002-07-26 05:50:08 +08:00
|
|
|
titr!=geometry._texCoordList.end();
|
|
|
|
++titr)
|
|
|
|
{
|
2006-11-17 00:25:29 +08:00
|
|
|
_texCoordList.push_back(ArrayData(*titr, copyop));
|
2002-07-26 05:50:08 +08:00
|
|
|
}
|
2003-05-07 21:13:13 +08:00
|
|
|
|
2007-04-27 22:52:30 +08:00
|
|
|
for(ArrayDataList::const_iterator vitr=geometry._vertexAttribList.begin();
|
2003-05-07 21:13:13 +08:00
|
|
|
vitr!=geometry._vertexAttribList.end();
|
|
|
|
++vitr)
|
|
|
|
{
|
2006-11-17 00:25:29 +08:00
|
|
|
_vertexAttribList.push_back(ArrayData(*vitr, copyop));
|
2003-05-07 21:13:13 +08:00
|
|
|
}
|
2010-10-28 22:01:47 +08:00
|
|
|
|
|
|
|
if ((copyop.getCopyFlags() & osg::CopyOp::DEEP_COPY_ARRAYS))
|
|
|
|
{
|
|
|
|
if (_useVertexBufferObjects)
|
|
|
|
{
|
|
|
|
// copying of arrays doesn't set up buffer objects so we'll need to force
|
|
|
|
// Geometry to assign these, we'll do this by switching off VBO's then renabling them.
|
|
|
|
setUseVertexBufferObjects(false);
|
|
|
|
setUseVertexBufferObjects(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-21 03:54:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Geometry::~Geometry()
|
|
|
|
{
|
2004-09-23 20:27:56 +08:00
|
|
|
// do dirty here to keep the getGLObjectSizeHint() estimate on the ball
|
|
|
|
dirtyDisplayList();
|
|
|
|
|
2002-06-21 03:54:08 +08:00
|
|
|
// no need to delete, all automatically handled by ref_ptr :-)
|
|
|
|
}
|
|
|
|
|
2004-03-29 18:24:16 +08:00
|
|
|
bool Geometry::empty() const
|
|
|
|
{
|
|
|
|
if (!_primitives.empty()) return false;
|
|
|
|
if (!_vertexData.empty()) return false;
|
|
|
|
if (!_normalData.empty()) return false;
|
|
|
|
if (!_colorData.empty()) return false;
|
|
|
|
if (!_secondaryColorData.empty()) return false;
|
|
|
|
if (!_fogCoordData.empty()) return false;
|
|
|
|
if (!_texCoordList.empty()) return false;
|
|
|
|
if (!_vertexAttribList.empty()) return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-04-27 22:52:30 +08:00
|
|
|
void Geometry::setVertexArray(Array* array)
|
|
|
|
{
|
|
|
|
_vertexData.array = array;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
dirtyBound();
|
|
|
|
|
|
|
|
if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setVertexIndices(IndexArray* array)
|
|
|
|
{
|
|
|
|
_vertexData.indices = array;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
dirtyBound();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setVertexData(const ArrayData& arrayData)
|
|
|
|
{
|
|
|
|
_vertexData = arrayData;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
dirtyBound();
|
|
|
|
|
|
|
|
if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setNormalArray(Array* array)
|
|
|
|
{
|
|
|
|
_normalData.array = array;
|
|
|
|
if (!_normalData.array.valid()) _normalData.binding=BIND_OFF;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
|
|
|
|
if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setNormalIndices(IndexArray* array)
|
|
|
|
{
|
|
|
|
_normalData.indices = array;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setNormalData(const ArrayData& arrayData)
|
|
|
|
{
|
|
|
|
_normalData = arrayData;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
|
|
|
|
if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setColorArray(Array* array)
|
|
|
|
{
|
|
|
|
_colorData.array = array;
|
|
|
|
if (!_colorData.array.valid()) _colorData.binding=BIND_OFF;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
|
|
|
|
if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setColorIndices(IndexArray* array)
|
|
|
|
{
|
|
|
|
_colorData.indices = array;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setColorData(const ArrayData& arrayData)
|
|
|
|
{
|
|
|
|
_colorData = arrayData;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
|
|
|
|
if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Geometry::setSecondaryColorArray(Array* array)
|
|
|
|
{
|
|
|
|
_secondaryColorData.array = array;
|
|
|
|
if (!_secondaryColorData.array.valid()) _secondaryColorData.binding=BIND_OFF;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
|
|
|
|
if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setSecondaryColorIndices(IndexArray* array)
|
|
|
|
{
|
|
|
|
_secondaryColorData.indices = array;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setSecondaryColorData(const ArrayData& arrayData)
|
|
|
|
{
|
|
|
|
_secondaryColorData = arrayData;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
|
|
|
|
if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setFogCoordArray(Array* array)
|
|
|
|
{
|
|
|
|
_fogCoordData.array = array;
|
|
|
|
if (!_fogCoordData.array.valid()) _fogCoordData.binding=BIND_OFF;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
|
|
|
|
if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setFogCoordIndices(IndexArray* array)
|
|
|
|
{
|
|
|
|
_fogCoordData.indices = array;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setFogCoordData(const ArrayData& arrayData)
|
|
|
|
{
|
|
|
|
_fogCoordData = arrayData;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
|
|
|
|
if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get());
|
|
|
|
}
|
|
|
|
|
2006-05-15 19:48:05 +08:00
|
|
|
void Geometry::setNormalBinding(AttributeBinding ab)
|
|
|
|
{
|
|
|
|
if (_normalData.binding == ab) return;
|
|
|
|
|
|
|
|
_normalData.binding = ab;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setColorBinding(AttributeBinding ab)
|
|
|
|
{
|
|
|
|
if (_colorData.binding == ab) return;
|
|
|
|
|
|
|
|
_colorData.binding = ab;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setSecondaryColorBinding(AttributeBinding ab)
|
|
|
|
{
|
|
|
|
if (_secondaryColorData.binding == ab) return;
|
|
|
|
|
|
|
|
_secondaryColorData.binding = ab;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setFogCoordBinding(AttributeBinding ab)
|
|
|
|
{
|
|
|
|
if (_fogCoordData.binding == ab) return;
|
|
|
|
|
|
|
|
_fogCoordData.binding = ab;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
2003-10-01 17:18:24 +08:00
|
|
|
void Geometry::setTexCoordData(unsigned int unit,const ArrayData& arrayData)
|
|
|
|
{
|
2005-05-25 23:35:51 +08:00
|
|
|
if (_texCoordList.size()<=unit)
|
|
|
|
_texCoordList.resize(unit+1);
|
|
|
|
|
|
|
|
_texCoordList[unit] = arrayData;
|
2007-04-27 22:52:30 +08:00
|
|
|
|
|
|
|
if (_useVertexBufferObjects && arrayData.array.valid()) addVertexBufferObjectIfRequired(arrayData.array.get());
|
2003-10-01 17:18:24 +08:00
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
Geometry::ArrayData& Geometry::getTexCoordData(unsigned int unit)
|
2002-06-21 03:54:08 +08:00
|
|
|
{
|
2002-06-22 00:45:45 +08:00
|
|
|
if (_texCoordList.size()<=unit)
|
2002-10-02 21:12:16 +08:00
|
|
|
_texCoordList.resize(unit+1);
|
2002-06-21 03:54:08 +08:00
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
return _texCoordList[unit];
|
|
|
|
}
|
2002-06-26 04:27:51 +08:00
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
const Geometry::ArrayData& Geometry::getTexCoordData(unsigned int unit) const
|
|
|
|
{
|
|
|
|
if (_texCoordList.size()<=unit)
|
|
|
|
return s_InvalidArrayData;
|
|
|
|
|
|
|
|
return _texCoordList[unit];
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setTexCoordArray(unsigned int unit,Array* array)
|
|
|
|
{
|
2003-09-24 23:54:22 +08:00
|
|
|
getTexCoordData(unit).binding = BIND_PER_VERTEX;
|
2003-09-10 06:18:35 +08:00
|
|
|
getTexCoordData(unit).array = array;
|
|
|
|
|
|
|
|
computeFastPathsUsed();
|
2002-06-26 04:27:51 +08:00
|
|
|
dirtyDisplayList();
|
2007-04-27 22:52:30 +08:00
|
|
|
|
2007-04-29 16:12:29 +08:00
|
|
|
if (_useVertexBufferObjects && array)
|
|
|
|
{
|
|
|
|
addVertexBufferObjectIfRequired(array);
|
|
|
|
}
|
2002-06-21 03:54:08 +08:00
|
|
|
}
|
|
|
|
|
2002-06-27 21:15:34 +08:00
|
|
|
Array* Geometry::getTexCoordArray(unsigned int unit)
|
2002-06-21 03:54:08 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (unit<_texCoordList.size()) return _texCoordList[unit].array.get();
|
2002-06-21 03:54:08 +08:00
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
2002-07-18 08:53:03 +08:00
|
|
|
const Array* Geometry::getTexCoordArray(unsigned int unit) const
|
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (unit<_texCoordList.size()) return _texCoordList[unit].array.get();
|
2002-07-18 08:53:03 +08:00
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
2002-10-02 21:12:16 +08:00
|
|
|
void Geometry::setTexCoordIndices(unsigned int unit,IndexArray* array)
|
2002-06-21 03:54:08 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
getTexCoordData(unit).indices = array;
|
2002-10-02 21:12:16 +08:00
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
computeFastPathsUsed();
|
2002-10-02 21:12:16 +08:00
|
|
|
dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
|
|
|
IndexArray* Geometry::getTexCoordIndices(unsigned int unit)
|
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (unit<_texCoordList.size()) return _texCoordList[unit].indices.get();
|
2002-10-02 21:12:16 +08:00
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const IndexArray* Geometry::getTexCoordIndices(unsigned int unit) const
|
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (unit<_texCoordList.size()) return _texCoordList[unit].indices.get();
|
2002-10-02 21:12:16 +08:00
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
2003-05-09 21:07:06 +08:00
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
void Geometry::setVertexAttribData(unsigned int index, const Geometry::ArrayData& attrData)
|
2003-05-09 21:07:06 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (_vertexAttribList.size()<=index)
|
|
|
|
_vertexAttribList.resize(index+1);
|
2003-05-09 21:07:06 +08:00
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
_vertexAttribList[index] = attrData;
|
2007-04-27 22:52:30 +08:00
|
|
|
|
2005-11-22 21:56:50 +08:00
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
2007-04-27 22:52:30 +08:00
|
|
|
|
|
|
|
if (_useVertexBufferObjects && attrData.array.valid()) addVertexBufferObjectIfRequired(attrData.array.get());
|
2003-05-09 21:07:06 +08:00
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
Geometry::ArrayData& Geometry::getVertexAttribData(unsigned int index)
|
2003-05-09 21:07:06 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (_vertexAttribList.size()<=index)
|
|
|
|
_vertexAttribList.resize(index+1);
|
|
|
|
|
|
|
|
return _vertexAttribList[index];
|
2003-05-09 21:07:06 +08:00
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
const Geometry::ArrayData& Geometry::getVertexAttribData(unsigned int index) const
|
2003-05-09 21:07:06 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (_vertexAttribList.size()<=_vertexAttribList.size())
|
|
|
|
return s_InvalidArrayData;
|
|
|
|
|
|
|
|
return _vertexAttribList[index];
|
2003-05-09 21:07:06 +08:00
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
void Geometry::setVertexAttribArray(unsigned int index, Array* array)
|
2003-05-09 21:07:06 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
getVertexAttribData(index).array = array;
|
2003-05-09 21:07:06 +08:00
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
computeFastPathsUsed();
|
2003-05-09 21:07:06 +08:00
|
|
|
dirtyDisplayList();
|
2007-04-27 22:52:30 +08:00
|
|
|
|
|
|
|
if (_useVertexBufferObjects && array) addVertexBufferObjectIfRequired(array);
|
2003-05-09 21:07:06 +08:00
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
Array *Geometry::getVertexAttribArray(unsigned int index)
|
2003-05-09 21:07:06 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (index<_vertexAttribList.size()) return _vertexAttribList[index].array.get();
|
2003-05-09 21:07:06 +08:00
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
const Array *Geometry::getVertexAttribArray(unsigned int index) const
|
2003-05-09 21:07:06 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (index<_vertexAttribList.size()) return _vertexAttribList[index].array.get();
|
2003-05-09 21:07:06 +08:00
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
void Geometry::setVertexAttribIndices(unsigned int index,IndexArray* array)
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
getVertexAttribData(index).indices = array;
|
2003-05-07 21:13:13 +08:00
|
|
|
|
2003-06-30 05:41:57 +08:00
|
|
|
computeFastPathsUsed();
|
2003-05-07 21:13:13 +08:00
|
|
|
dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
IndexArray* Geometry::getVertexAttribIndices(unsigned int index)
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (index<_vertexAttribList.size()) return _vertexAttribList[index].indices.get();
|
2003-05-07 21:13:13 +08:00
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
const IndexArray* Geometry::getVertexAttribIndices(unsigned int index) const
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (index<_vertexAttribList.size()) return _vertexAttribList[index].indices.get();
|
2003-05-07 21:13:13 +08:00
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
void Geometry::setVertexAttribBinding(unsigned int index,AttributeBinding ab)
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
2006-05-15 19:48:05 +08:00
|
|
|
if (getVertexAttribData(index).binding == ab)
|
|
|
|
return;
|
2003-09-10 06:18:35 +08:00
|
|
|
getVertexAttribData(index).binding = ab;
|
|
|
|
computeFastPathsUsed();
|
|
|
|
dirtyDisplayList();
|
2003-05-07 21:13:13 +08:00
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
Geometry::AttributeBinding Geometry::getVertexAttribBinding(unsigned int index) const
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (index<_vertexAttribList.size()) return _vertexAttribList[index].binding;
|
|
|
|
else return BIND_OFF;
|
2003-05-07 21:13:13 +08:00
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
void Geometry::setVertexAttribNormalize(unsigned int index,GLboolean norm)
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
getVertexAttribData(index).normalize = norm;
|
2003-05-07 21:13:13 +08:00
|
|
|
|
|
|
|
dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
GLboolean Geometry::getVertexAttribNormalize(unsigned int index) const
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (index<_vertexAttribList.size()) return _vertexAttribList[index].normalize;
|
|
|
|
else return GL_FALSE;
|
2003-05-07 21:13:13 +08:00
|
|
|
}
|
|
|
|
|
2002-11-21 17:07:11 +08:00
|
|
|
bool Geometry::addPrimitiveSet(PrimitiveSet* primitiveset)
|
|
|
|
{
|
|
|
|
if (primitiveset)
|
|
|
|
{
|
2007-05-01 14:28:20 +08:00
|
|
|
if (_useVertexBufferObjects) addElementBufferObjectIfRequired(primitiveset);
|
2007-04-27 22:52:30 +08:00
|
|
|
|
2002-11-21 17:07:11 +08:00
|
|
|
_primitives.push_back(primitiveset);
|
|
|
|
dirtyDisplayList();
|
|
|
|
dirtyBound();
|
|
|
|
return true;
|
|
|
|
}
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_WARN<<"Warning: invalid index i or primitiveset passed to osg::Geometry::addPrimitiveSet(i,primitiveset), ignoring call."<<std::endl;
|
2002-11-21 17:07:11 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Geometry::setPrimitiveSet(unsigned int i,PrimitiveSet* primitiveset)
|
|
|
|
{
|
|
|
|
if (i<_primitives.size() && primitiveset)
|
|
|
|
{
|
2007-05-01 14:28:20 +08:00
|
|
|
if (_useVertexBufferObjects) addElementBufferObjectIfRequired(primitiveset);
|
2007-04-27 22:52:30 +08:00
|
|
|
|
2002-11-21 17:07:11 +08:00
|
|
|
_primitives[i] = primitiveset;
|
|
|
|
dirtyDisplayList();
|
|
|
|
dirtyBound();
|
|
|
|
return true;
|
|
|
|
}
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_WARN<<"Warning: invalid index i or primitiveset passed to osg::Geometry::setPrimitiveSet(i,primitiveset), ignoring call."<<std::endl;
|
2002-11-21 17:07:11 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Geometry::insertPrimitiveSet(unsigned int i,PrimitiveSet* primitiveset)
|
|
|
|
{
|
2007-04-27 22:52:30 +08:00
|
|
|
|
2002-11-21 17:07:11 +08:00
|
|
|
if (primitiveset)
|
|
|
|
{
|
2007-05-01 14:28:20 +08:00
|
|
|
if (_useVertexBufferObjects) addElementBufferObjectIfRequired(primitiveset);
|
2007-04-27 22:52:30 +08:00
|
|
|
|
2002-11-21 17:07:11 +08:00
|
|
|
if (i<_primitives.size())
|
|
|
|
{
|
|
|
|
_primitives.insert(_primitives.begin()+i,primitiveset);
|
|
|
|
dirtyDisplayList();
|
|
|
|
dirtyBound();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (i==_primitives.size())
|
|
|
|
{
|
|
|
|
return addPrimitiveSet(primitiveset);
|
|
|
|
}
|
2007-04-27 22:52:30 +08:00
|
|
|
|
2002-11-21 17:07:11 +08:00
|
|
|
}
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_WARN<<"Warning: invalid index i or primitiveset passed to osg::Geometry::insertPrimitiveSet(i,primitiveset), ignoring call."<<std::endl;
|
2002-11-21 17:07:11 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Geometry::removePrimitiveSet(unsigned int i, unsigned int numElementsToRemove)
|
|
|
|
{
|
2008-01-21 20:00:10 +08:00
|
|
|
if (numElementsToRemove==0) return false;
|
|
|
|
|
|
|
|
if (i<_primitives.size())
|
2002-11-21 17:07:11 +08:00
|
|
|
{
|
2003-04-01 23:08:30 +08:00
|
|
|
if (i+numElementsToRemove<=_primitives.size())
|
2002-11-21 17:07:11 +08:00
|
|
|
{
|
|
|
|
_primitives.erase(_primitives.begin()+i,_primitives.begin()+i+numElementsToRemove);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// asking to delete too many elements, report a warning, and delete to
|
|
|
|
// the end of the primitive list.
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_WARN<<"Warning: osg::Geometry::removePrimitiveSet(i,numElementsToRemove) has been asked to remove more elements than are available,"<<std::endl;
|
|
|
|
OSG_WARN<<" removing on from i to the end of the list of primitive sets."<<std::endl;
|
2002-11-21 17:07:11 +08:00
|
|
|
_primitives.erase(_primitives.begin()+i,_primitives.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
dirtyDisplayList();
|
|
|
|
dirtyBound();
|
|
|
|
return true;
|
|
|
|
}
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_WARN<<"Warning: invalid index i passed to osg::Geometry::removePrimitiveSet(i,numElementsToRemove), ignoring call."<<std::endl;
|
2002-11-21 17:07:11 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int Geometry::getPrimitiveSetIndex(const PrimitiveSet* primitiveset) const
|
|
|
|
{
|
|
|
|
for (unsigned int primitiveSetIndex=0;primitiveSetIndex<_primitives.size();++primitiveSetIndex)
|
|
|
|
{
|
|
|
|
if (_primitives[primitiveSetIndex]==primitiveset) return primitiveSetIndex;
|
|
|
|
}
|
|
|
|
return _primitives.size(); // node not found.
|
|
|
|
}
|
|
|
|
|
2003-06-30 05:41:57 +08:00
|
|
|
bool Geometry::computeFastPathsUsed()
|
2002-10-02 21:12:16 +08:00
|
|
|
{
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// check to see if fast path can be used.
|
|
|
|
//
|
|
|
|
_fastPath = true;
|
2003-09-10 06:18:35 +08:00
|
|
|
if (_vertexData.indices.valid()) _fastPath = false;
|
|
|
|
else if (_normalData.binding==BIND_PER_PRIMITIVE || (_normalData.binding==BIND_PER_VERTEX && _normalData.indices.valid())) _fastPath = false;
|
|
|
|
else if (_colorData.binding==BIND_PER_PRIMITIVE || (_colorData.binding==BIND_PER_VERTEX && _colorData.indices.valid())) _fastPath = false;
|
|
|
|
else if (_secondaryColorData.binding==BIND_PER_PRIMITIVE || (_secondaryColorData.binding==BIND_PER_VERTEX && _secondaryColorData.indices.valid())) _fastPath = false;
|
|
|
|
else if (_fogCoordData.binding==BIND_PER_PRIMITIVE || (_fogCoordData.binding==BIND_PER_VERTEX && _fogCoordData.indices.valid())) _fastPath = false;
|
2003-05-07 21:13:13 +08:00
|
|
|
else
|
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
for( unsigned int va = 0; va < _vertexAttribList.size(); ++va )
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (_vertexAttribList[va].binding==BIND_PER_PRIMITIVE)
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
|
|
|
_fastPath = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
const Array * array = _vertexAttribList[va].array.get();
|
|
|
|
const IndexArray * idxArray = _vertexAttribList[va].indices.get();
|
2003-05-07 21:13:13 +08:00
|
|
|
|
2003-09-10 06:18:35 +08:00
|
|
|
if( _vertexAttribList[va].binding==BIND_PER_VERTEX &&
|
2003-05-07 21:13:13 +08:00
|
|
|
array && array->getNumElements()>0 &&
|
|
|
|
idxArray && idxArray->getNumElements()>0 )
|
|
|
|
{
|
|
|
|
_fastPath = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-06-21 03:54:08 +08:00
|
|
|
|
2002-08-16 04:27:33 +08:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2002-10-02 21:12:16 +08:00
|
|
|
// Set up tex coords if required.
|
2002-08-16 04:27:33 +08:00
|
|
|
//
|
2003-12-18 20:20:38 +08:00
|
|
|
for(unsigned int unit=0;unit<_texCoordList.size();++unit)
|
2002-08-16 04:27:33 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
const ArrayData& texcoordData = _texCoordList[unit];
|
|
|
|
if (texcoordData.array.valid() && texcoordData.array->getNumElements()>0)
|
2002-08-16 04:27:33 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (texcoordData.indices.valid())
|
2002-08-16 04:27:33 +08:00
|
|
|
{
|
2003-09-10 06:18:35 +08:00
|
|
|
if (texcoordData.indices->getNumElements()>0)
|
2002-10-02 21:12:16 +08:00
|
|
|
{
|
2003-05-07 21:13:13 +08:00
|
|
|
_fastPath = false;
|
|
|
|
break;
|
2002-10-02 21:12:16 +08:00
|
|
|
}
|
2002-08-16 04:27:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-06-30 05:41:57 +08:00
|
|
|
|
|
|
|
_supportsVertexBufferObjects = _fastPath;
|
|
|
|
|
|
|
|
//_supportsVertexBufferObjects = false;
|
|
|
|
//_useVertexBufferObjects = false;
|
2002-10-02 21:12:16 +08:00
|
|
|
|
|
|
|
return _fastPath;
|
|
|
|
}
|
|
|
|
|
2004-09-22 01:26:08 +08:00
|
|
|
unsigned int Geometry::getGLObjectSizeHint() const
|
|
|
|
{
|
2004-09-23 20:27:56 +08:00
|
|
|
unsigned int totalSize = 0;
|
|
|
|
if (_vertexData.array.valid()) totalSize += _vertexData.array->getTotalDataSize();
|
|
|
|
|
|
|
|
if (_normalData.array.valid()) totalSize += _normalData.array->getTotalDataSize();
|
|
|
|
|
|
|
|
if (_colorData.array.valid()) totalSize += _colorData.array->getTotalDataSize();
|
|
|
|
|
|
|
|
if (_secondaryColorData.array.valid()) totalSize += _secondaryColorData.array->getTotalDataSize();
|
|
|
|
|
|
|
|
if (_fogCoordData.array.valid()) totalSize += _fogCoordData.array->getTotalDataSize();
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int unit;
|
|
|
|
for(unit=0;unit<_texCoordList.size();++unit)
|
|
|
|
{
|
|
|
|
const Array* array = _texCoordList[unit].array.get();
|
|
|
|
if (array) totalSize += array->getTotalDataSize();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool handleVertexAttributes = true;
|
|
|
|
if (handleVertexAttributes)
|
|
|
|
{
|
|
|
|
unsigned int index;
|
|
|
|
for( index = 0; index < _vertexAttribList.size(); ++index )
|
|
|
|
{
|
|
|
|
const Array* array = _vertexAttribList[index].array.get();
|
|
|
|
if (array) totalSize += array->getTotalDataSize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-04-29 16:12:29 +08:00
|
|
|
for(PrimitiveSetList::const_iterator itr=_primitives.begin();
|
|
|
|
itr!=_primitives.end();
|
|
|
|
++itr)
|
|
|
|
{
|
2004-09-23 20:27:56 +08:00
|
|
|
|
2007-04-29 16:12:29 +08:00
|
|
|
totalSize += 4*(*itr)->getNumIndices();
|
2004-09-23 20:27:56 +08:00
|
|
|
|
2007-04-29 16:12:29 +08:00
|
|
|
}
|
2004-09-23 20:27:56 +08:00
|
|
|
|
|
|
|
|
2004-09-22 01:26:08 +08:00
|
|
|
// do a very simply mapping of display list size proportional to vertex datasize.
|
2004-09-23 20:27:56 +08:00
|
|
|
return totalSize;
|
2004-09-22 01:26:08 +08:00
|
|
|
}
|
|
|
|
|
2007-05-02 02:03:32 +08:00
|
|
|
bool Geometry::getArrayList(ArrayList& arrayList) const
|
2007-04-27 22:52:30 +08:00
|
|
|
{
|
|
|
|
unsigned int startSize = arrayList.size();
|
|
|
|
|
|
|
|
if (_vertexData.array.valid()) arrayList.push_back(_vertexData.array.get());
|
|
|
|
if (_normalData.array.valid()) arrayList.push_back(_normalData.array.get());
|
|
|
|
if (_colorData.array.valid()) arrayList.push_back(_colorData.array.get());
|
|
|
|
if (_secondaryColorData.array.valid()) arrayList.push_back(_secondaryColorData.array.get());
|
|
|
|
if (_fogCoordData.array.valid()) arrayList.push_back(_fogCoordData.array.get());
|
|
|
|
|
2007-04-29 16:12:29 +08:00
|
|
|
for(unsigned int unit=0;unit<_texCoordList.size();++unit)
|
|
|
|
{
|
|
|
|
Array* array = _texCoordList[unit].array.get();
|
|
|
|
if (array) arrayList.push_back(array);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(unsigned int index = 0; index < _vertexAttribList.size(); ++index )
|
|
|
|
{
|
|
|
|
Array* array = _vertexAttribList[index].array.get();
|
|
|
|
if (array) arrayList.push_back(array);
|
|
|
|
}
|
|
|
|
|
2007-04-27 22:52:30 +08:00
|
|
|
return arrayList.size()!=startSize;
|
|
|
|
}
|
|
|
|
|
2007-05-02 02:03:32 +08:00
|
|
|
bool Geometry::getDrawElementsList(DrawElementsList& drawElementsList) const
|
2007-04-27 22:52:30 +08:00
|
|
|
{
|
|
|
|
unsigned int startSize = drawElementsList.size();
|
|
|
|
|
2007-05-02 02:03:32 +08:00
|
|
|
for(PrimitiveSetList::const_iterator itr = _primitives.begin();
|
2007-04-27 22:52:30 +08:00
|
|
|
itr != _primitives.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
osg::DrawElements* de = (*itr)->getDrawElements();
|
|
|
|
if (de) drawElementsList.push_back(de);
|
|
|
|
}
|
|
|
|
|
|
|
|
return drawElementsList.size()!=startSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::addVertexBufferObjectIfRequired(osg::Array* array)
|
|
|
|
{
|
|
|
|
if (_useVertexBufferObjects)
|
|
|
|
{
|
|
|
|
if (!array->getVertexBufferObject())
|
|
|
|
{
|
|
|
|
array->setVertexBufferObject(getOrCreateVertexBufferObject());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-01 14:28:20 +08:00
|
|
|
void Geometry::addElementBufferObjectIfRequired(osg::PrimitiveSet* primitiveSet)
|
2007-04-27 22:52:30 +08:00
|
|
|
{
|
|
|
|
if (_useVertexBufferObjects)
|
|
|
|
{
|
|
|
|
osg::DrawElements* drawElements = primitiveSet->getDrawElements();
|
2007-05-01 14:28:20 +08:00
|
|
|
if (drawElements && !drawElements->getElementBufferObject())
|
2007-04-27 22:52:30 +08:00
|
|
|
{
|
2007-05-01 14:28:20 +08:00
|
|
|
drawElements->setElementBufferObject(getOrCreateElementBufferObject());
|
2007-04-27 22:52:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
osg::VertexBufferObject* Geometry::getOrCreateVertexBufferObject()
|
|
|
|
{
|
|
|
|
ArrayList arrayList;
|
|
|
|
getArrayList(arrayList);
|
|
|
|
|
|
|
|
ArrayList::iterator vitr;
|
|
|
|
for(vitr = arrayList.begin();
|
2009-10-06 17:28:41 +08:00
|
|
|
vitr != arrayList.end();
|
2007-04-27 22:52:30 +08:00
|
|
|
++vitr)
|
|
|
|
{
|
|
|
|
osg::Array* array = *vitr;
|
2009-10-06 17:28:41 +08:00
|
|
|
if (array->getVertexBufferObject()) return array->getVertexBufferObject();
|
2007-04-27 22:52:30 +08:00
|
|
|
}
|
|
|
|
|
2009-10-06 17:28:41 +08:00
|
|
|
return new osg::VertexBufferObject;
|
2007-04-27 22:52:30 +08:00
|
|
|
}
|
|
|
|
|
2007-05-01 14:28:20 +08:00
|
|
|
osg::ElementBufferObject* Geometry::getOrCreateElementBufferObject()
|
2007-04-27 22:52:30 +08:00
|
|
|
{
|
|
|
|
DrawElementsList drawElementsList;
|
|
|
|
getDrawElementsList(drawElementsList);
|
|
|
|
|
|
|
|
DrawElementsList::iterator deitr;
|
|
|
|
for(deitr = drawElementsList.begin();
|
|
|
|
deitr != drawElementsList.end();
|
|
|
|
++deitr)
|
|
|
|
{
|
|
|
|
osg::DrawElements* elements = *deitr;
|
2009-10-06 17:28:41 +08:00
|
|
|
if (elements->getElementBufferObject()) return elements->getElementBufferObject();
|
2007-04-27 22:52:30 +08:00
|
|
|
}
|
|
|
|
|
2009-10-06 17:28:41 +08:00
|
|
|
return new osg::ElementBufferObject;
|
2007-04-27 22:52:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::setUseVertexBufferObjects(bool flag)
|
|
|
|
{
|
2007-05-02 02:03:32 +08:00
|
|
|
// flag = true;
|
2007-04-30 04:13:53 +08:00
|
|
|
|
2010-05-28 23:47:52 +08:00
|
|
|
// OSG_NOTICE<<"Geometry::setUseVertexBufferObjects("<<flag<<")"<<std::endl;
|
2007-04-27 22:52:30 +08:00
|
|
|
|
|
|
|
if (_useVertexBufferObjects==flag) return;
|
|
|
|
|
|
|
|
Drawable::setUseVertexBufferObjects(flag);
|
|
|
|
|
|
|
|
ArrayList arrayList;
|
|
|
|
getArrayList(arrayList);
|
|
|
|
|
|
|
|
DrawElementsList drawElementsList;
|
|
|
|
getDrawElementsList(drawElementsList);
|
|
|
|
|
|
|
|
typedef std::vector<osg::VertexBufferObject*> VertexBufferObjectList;
|
2007-05-01 14:28:20 +08:00
|
|
|
typedef std::vector<osg::ElementBufferObject*> ElementBufferObjectList;
|
2007-04-27 22:52:30 +08:00
|
|
|
|
|
|
|
if (_useVertexBufferObjects)
|
|
|
|
{
|
|
|
|
if (!arrayList.empty())
|
|
|
|
{
|
|
|
|
|
|
|
|
VertexBufferObjectList vboList;
|
|
|
|
|
|
|
|
osg::VertexBufferObject* vbo = 0;
|
|
|
|
|
|
|
|
ArrayList::iterator vitr;
|
|
|
|
for(vitr = arrayList.begin();
|
|
|
|
vitr != arrayList.end() && !vbo;
|
|
|
|
++vitr)
|
|
|
|
{
|
|
|
|
osg::Array* array = *vitr;
|
2007-10-19 17:58:11 +08:00
|
|
|
if (array->getVertexBufferObject()) vbo = array->getVertexBufferObject();
|
2007-04-27 22:52:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!vbo) vbo = new osg::VertexBufferObject;
|
|
|
|
|
|
|
|
for(vitr = arrayList.begin();
|
|
|
|
vitr != arrayList.end();
|
|
|
|
++vitr)
|
|
|
|
{
|
|
|
|
osg::Array* array = *vitr;
|
|
|
|
if (!array->getVertexBufferObject()) array->setVertexBufferObject(vbo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!drawElementsList.empty())
|
|
|
|
{
|
2007-05-01 14:28:20 +08:00
|
|
|
ElementBufferObjectList eboList;
|
2007-04-27 22:52:30 +08:00
|
|
|
|
2007-05-01 14:28:20 +08:00
|
|
|
osg::ElementBufferObject* ebo = 0;
|
2007-04-27 22:52:30 +08:00
|
|
|
|
|
|
|
DrawElementsList::iterator deitr;
|
|
|
|
for(deitr = drawElementsList.begin();
|
|
|
|
deitr != drawElementsList.end();
|
|
|
|
++deitr)
|
|
|
|
{
|
|
|
|
osg::DrawElements* elements = *deitr;
|
2007-10-19 17:58:11 +08:00
|
|
|
if (elements->getElementBufferObject()) ebo = elements->getElementBufferObject();
|
2007-04-27 22:52:30 +08:00
|
|
|
}
|
|
|
|
|
2007-05-01 14:28:20 +08:00
|
|
|
if (!ebo) ebo = new osg::ElementBufferObject;
|
2007-04-27 22:52:30 +08:00
|
|
|
|
|
|
|
for(deitr = drawElementsList.begin();
|
|
|
|
deitr != drawElementsList.end();
|
|
|
|
++deitr)
|
|
|
|
{
|
|
|
|
osg::DrawElements* elements = *deitr;
|
2007-05-01 14:28:20 +08:00
|
|
|
if (!elements->getElementBufferObject()) elements->setElementBufferObject(ebo);
|
2007-04-27 22:52:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for(ArrayList::iterator vitr = arrayList.begin();
|
|
|
|
vitr != arrayList.end();
|
|
|
|
++vitr)
|
|
|
|
{
|
|
|
|
osg::Array* array = *vitr;
|
2007-10-19 17:58:11 +08:00
|
|
|
if (array->getVertexBufferObject()) array->setVertexBufferObject(0);
|
2007-04-27 22:52:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for(DrawElementsList::iterator deitr = drawElementsList.begin();
|
|
|
|
deitr != drawElementsList.end();
|
|
|
|
++deitr)
|
|
|
|
{
|
|
|
|
osg::DrawElements* elements = *deitr;
|
2007-10-19 17:58:11 +08:00
|
|
|
if (elements->getElementBufferObject()) elements->setElementBufferObject(0);
|
2007-04-27 22:52:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::dirtyDisplayList()
|
|
|
|
{
|
|
|
|
Drawable::dirtyDisplayList();
|
|
|
|
}
|
|
|
|
|
2007-05-02 02:03:32 +08:00
|
|
|
void Geometry::resizeGLObjectBuffers(unsigned int maxSize)
|
|
|
|
{
|
|
|
|
Drawable::resizeGLObjectBuffers(maxSize);
|
|
|
|
|
|
|
|
ArrayList arrays;
|
|
|
|
if (getArrayList(arrays))
|
|
|
|
{
|
|
|
|
for(ArrayList::iterator itr = arrays.begin();
|
|
|
|
itr != arrays.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
(*itr)->resizeGLObjectBuffers(maxSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DrawElementsList drawElements;
|
|
|
|
if (getDrawElementsList(drawElements))
|
|
|
|
{
|
|
|
|
for(DrawElementsList::iterator itr = drawElements.begin();
|
|
|
|
itr != drawElements.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
(*itr)->resizeGLObjectBuffers(maxSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-04-29 16:12:29 +08:00
|
|
|
|
2007-05-02 02:03:32 +08:00
|
|
|
void Geometry::releaseGLObjects(State* state) const
|
|
|
|
{
|
|
|
|
Drawable::releaseGLObjects(state);
|
|
|
|
|
|
|
|
ArrayList arrays;
|
|
|
|
if (getArrayList(arrays))
|
|
|
|
{
|
|
|
|
for(ArrayList::iterator itr = arrays.begin();
|
|
|
|
itr != arrays.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
(*itr)->releaseGLObjects(state);
|
|
|
|
}
|
|
|
|
}
|
2007-04-29 16:12:29 +08:00
|
|
|
|
2007-05-02 02:03:32 +08:00
|
|
|
DrawElementsList drawElements;
|
|
|
|
if (getDrawElementsList(drawElements))
|
|
|
|
{
|
|
|
|
for(DrawElementsList::iterator itr = drawElements.begin();
|
|
|
|
itr != drawElements.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
(*itr)->releaseGLObjects(state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2007-04-29 16:12:29 +08:00
|
|
|
|
2009-12-09 21:51:02 +08:00
|
|
|
void Geometry::compileGLObjects(RenderInfo& renderInfo) const
|
|
|
|
{
|
|
|
|
bool useVertexArrays = _supportsVertexBufferObjects &&
|
|
|
|
_useVertexBufferObjects &&
|
|
|
|
renderInfo.getState()->isVertexBufferObjectSupported() &&
|
|
|
|
areFastPathsUsed();
|
|
|
|
if (useVertexArrays)
|
|
|
|
{
|
2010-05-28 23:47:52 +08:00
|
|
|
// OSG_NOTICE<<"Geometry::compileGLObjects() use VBO's "<<this<<std::endl;
|
2009-12-09 21:51:02 +08:00
|
|
|
State& state = *renderInfo.getState();
|
|
|
|
unsigned int contextID = state.getContextID();
|
|
|
|
GLBufferObject::Extensions* extensions = GLBufferObject::getExtensions(contextID, true);
|
|
|
|
if (!extensions) return;
|
|
|
|
|
|
|
|
typedef std::set<BufferObject*> BufferObjects;
|
|
|
|
BufferObjects bufferObjects;
|
|
|
|
|
|
|
|
// first collect all the active unique BufferObjects
|
|
|
|
if (_vertexData.array.valid() && _vertexData.array->getBufferObject()) bufferObjects.insert(_vertexData.array->getBufferObject());
|
|
|
|
if (_normalData.array.valid() && _normalData.array->getBufferObject()) bufferObjects.insert(_normalData.array->getBufferObject());
|
|
|
|
if (_colorData.array.valid() && _colorData.array->getBufferObject()) bufferObjects.insert(_colorData.array->getBufferObject());
|
|
|
|
if (_secondaryColorData.array.valid() && _secondaryColorData.array->getBufferObject()) bufferObjects.insert(_secondaryColorData.array->getBufferObject());
|
|
|
|
if (_fogCoordData.array.valid() && _fogCoordData.array->getBufferObject()) bufferObjects.insert(_fogCoordData.array->getBufferObject());
|
|
|
|
|
|
|
|
for(ArrayDataList::const_iterator itr = _texCoordList.begin();
|
|
|
|
itr != _texCoordList.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
if (itr->array.valid() && itr->array->getBufferObject()) bufferObjects.insert(itr->array->getBufferObject());
|
|
|
|
}
|
|
|
|
|
|
|
|
for(ArrayDataList::const_iterator itr = _vertexAttribList.begin();
|
|
|
|
itr != _vertexAttribList.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
if (itr->array.valid() && itr->array->getBufferObject()) bufferObjects.insert(itr->array->getBufferObject());
|
|
|
|
}
|
|
|
|
|
|
|
|
for(PrimitiveSetList::const_iterator itr = _primitives.begin();
|
|
|
|
itr != _primitives.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
if ((*itr)->getBufferObject()) bufferObjects.insert((*itr)->getBufferObject());
|
|
|
|
}
|
|
|
|
|
2010-10-22 00:29:23 +08:00
|
|
|
osg::ElapsedTime timer;
|
2009-12-09 21:51:02 +08:00
|
|
|
|
|
|
|
// now compile any buffer objects that require it.
|
|
|
|
for(BufferObjects::iterator itr = bufferObjects.begin();
|
|
|
|
itr != bufferObjects.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
GLBufferObject* glBufferObject = (*itr)->getOrCreateGLBufferObject(contextID);
|
|
|
|
if (glBufferObject && glBufferObject->isDirty())
|
|
|
|
{
|
2010-05-28 23:47:52 +08:00
|
|
|
// OSG_NOTICE<<"Compile buffer "<<glBufferObject<<std::endl;
|
2009-12-09 21:51:02 +08:00
|
|
|
glBufferObject->compileBuffer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 00:29:23 +08:00
|
|
|
// OSG_NOTICE<<"Time to compile "<<timer.elapsedTime_m()<<"ms"<<std::endl;
|
|
|
|
|
2009-12-09 21:51:02 +08:00
|
|
|
// unbind the BufferObjects
|
|
|
|
extensions->glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
|
|
|
|
extensions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Drawable::compileGLObjects(renderInfo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-21 03:34:24 +08:00
|
|
|
void Geometry::drawImplementation(RenderInfo& renderInfo) const
|
|
|
|
{
|
2009-10-23 17:24:44 +08:00
|
|
|
if (_internalOptimizedGeometry.valid())
|
|
|
|
{
|
|
|
|
_internalOptimizedGeometry->drawImplementation(renderInfo);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-10-21 03:34:24 +08:00
|
|
|
State& state = *renderInfo.getState();
|
2009-11-13 21:25:59 +08:00
|
|
|
|
|
|
|
bool checkForGLErrors = state.getCheckForGLErrors()==osg::State::ONCE_PER_ATTRIBUTE;
|
|
|
|
if (checkForGLErrors) state.checkGLErrors("start of Geometry::drawImplementation()");
|
|
|
|
|
2009-10-21 03:34:24 +08:00
|
|
|
bool useFastPath = areFastPathsUsed();
|
2009-11-13 21:25:59 +08:00
|
|
|
// useFastPath = false;
|
2009-10-23 17:24:44 +08:00
|
|
|
|
2009-10-21 03:34:24 +08:00
|
|
|
bool usingVertexBufferObjects = _useVertexBufferObjects && state.isVertexBufferObjectSupported();
|
2009-11-03 19:10:41 +08:00
|
|
|
bool handleVertexAttributes = !_vertexAttribList.empty();
|
2009-10-21 03:34:24 +08:00
|
|
|
|
2009-10-21 19:18:13 +08:00
|
|
|
ArrayDispatchers& arrayDispatchers = state.getArrayDispatchers();
|
2009-10-21 03:34:24 +08:00
|
|
|
|
|
|
|
arrayDispatchers.reset();
|
2009-11-13 21:25:59 +08:00
|
|
|
arrayDispatchers.setUseVertexAttribAlias(useFastPath && state.getUseVertexAttributeAliasing());
|
2009-10-23 17:24:44 +08:00
|
|
|
arrayDispatchers.setUseGLBeginEndAdapter(!useFastPath);
|
2009-10-21 03:34:24 +08:00
|
|
|
|
|
|
|
arrayDispatchers.activateNormalArray(_normalData.binding, _normalData.array.get(), _normalData.indices.get());
|
|
|
|
arrayDispatchers.activateColorArray(_colorData.binding, _colorData.array.get(), _colorData.indices.get());
|
|
|
|
arrayDispatchers.activateSecondaryColorArray(_secondaryColorData.binding, _secondaryColorData.array.get(), _secondaryColorData.indices.get());
|
|
|
|
arrayDispatchers.activateFogCoordArray(_fogCoordData.binding, _fogCoordData.array.get(), _fogCoordData.indices.get());
|
|
|
|
|
2009-10-21 19:18:13 +08:00
|
|
|
if (handleVertexAttributes)
|
2009-10-21 03:34:24 +08:00
|
|
|
{
|
2009-10-21 19:18:13 +08:00
|
|
|
for(unsigned int unit=0;unit<_vertexAttribList.size();++unit)
|
|
|
|
{
|
|
|
|
arrayDispatchers.activateVertexAttribArray(_vertexAttribList[unit].binding, unit, _vertexAttribList[unit].array.get(), _vertexAttribList[unit].indices.get());
|
|
|
|
}
|
2009-10-21 03:34:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// dispatch any attributes that are bound overall
|
2009-10-21 19:18:13 +08:00
|
|
|
arrayDispatchers.dispatch(BIND_OVERALL,0);
|
2009-10-21 03:34:24 +08:00
|
|
|
|
|
|
|
state.lazyDisablingOfVertexAttributes();
|
|
|
|
|
|
|
|
if (useFastPath)
|
|
|
|
{
|
|
|
|
// set up arrays
|
|
|
|
if( _vertexData.array.valid() )
|
|
|
|
state.setVertexPointer(_vertexData.array.get());
|
|
|
|
|
|
|
|
if (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid())
|
|
|
|
state.setNormalPointer(_normalData.array.get());
|
|
|
|
|
|
|
|
if (_colorData.binding==BIND_PER_VERTEX && _colorData.array.valid())
|
|
|
|
state.setColorPointer(_colorData.array.get());
|
|
|
|
|
|
|
|
if (_secondaryColorData.binding==BIND_PER_VERTEX && _secondaryColorData.array.valid())
|
|
|
|
state.setSecondaryColorPointer(_secondaryColorData.array.get());
|
|
|
|
|
|
|
|
if (_fogCoordData.binding==BIND_PER_VERTEX && _fogCoordData.array.valid())
|
|
|
|
state.setFogCoordPointer(_fogCoordData.array.get());
|
|
|
|
|
|
|
|
for(unsigned int unit=0;unit<_texCoordList.size();++unit)
|
|
|
|
{
|
|
|
|
const Array* array = _texCoordList[unit].array.get();
|
|
|
|
if (array) state.setTexCoordPointer(unit,array);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( handleVertexAttributes )
|
|
|
|
{
|
|
|
|
for(unsigned int index = 0; index < _vertexAttribList.size(); ++index )
|
|
|
|
{
|
|
|
|
const Array* array = _vertexAttribList[index].array.get();
|
|
|
|
const AttributeBinding ab = _vertexAttribList[index].binding;
|
|
|
|
if( ab == BIND_PER_VERTEX && array )
|
|
|
|
{
|
|
|
|
state.setVertexAttribPointer( index, array, _vertexAttribList[index].normalize );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-10-21 19:18:13 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
for(unsigned int unit=0;unit<_texCoordList.size();++unit)
|
|
|
|
{
|
|
|
|
arrayDispatchers.activateTexCoordArray(BIND_PER_VERTEX, unit, _texCoordList[unit].array.get(), _texCoordList[unit].indices.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
arrayDispatchers.activateVertexArray(BIND_PER_VERTEX, _vertexData.array.get(), _vertexData.indices.get());
|
|
|
|
}
|
2009-10-21 03:34:24 +08:00
|
|
|
|
|
|
|
state.applyDisablingOfVertexAttributes();
|
|
|
|
|
2009-10-23 20:24:22 +08:00
|
|
|
bool bindPerPrimitiveSetActive = arrayDispatchers.active(BIND_PER_PRIMITIVE_SET);
|
|
|
|
bool bindPerPrimitiveActive = arrayDispatchers.active(BIND_PER_PRIMITIVE);
|
2009-10-21 19:18:13 +08:00
|
|
|
|
|
|
|
unsigned int primitiveNum = 0;
|
|
|
|
|
2009-11-13 21:25:59 +08:00
|
|
|
if (checkForGLErrors) state.checkGLErrors("Geometry::drawImplementation() after vertex arrays setup.");
|
|
|
|
|
|
|
|
|
2009-10-21 03:34:24 +08:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// draw the primitives themselves.
|
|
|
|
//
|
2009-10-21 19:18:13 +08:00
|
|
|
for(unsigned int primitiveSetNum=0; primitiveSetNum!=_primitives.size(); ++primitiveSetNum)
|
2009-10-21 03:34:24 +08:00
|
|
|
{
|
2009-10-21 19:18:13 +08:00
|
|
|
|
2009-10-21 03:34:24 +08:00
|
|
|
// dispatch any attributes that are bound per primitive
|
2009-10-23 20:24:22 +08:00
|
|
|
if (bindPerPrimitiveSetActive) arrayDispatchers.dispatch(BIND_PER_PRIMITIVE_SET, primitiveSetNum);
|
2009-10-21 03:34:24 +08:00
|
|
|
|
2009-10-21 19:18:13 +08:00
|
|
|
const PrimitiveSet* primitiveset = _primitives[primitiveSetNum].get();
|
2009-10-21 03:34:24 +08:00
|
|
|
|
|
|
|
if (useFastPath)
|
|
|
|
{
|
|
|
|
primitiveset->draw(state, usingVertexBufferObjects);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GLenum mode=primitiveset->getMode();
|
|
|
|
|
|
|
|
unsigned int primLength;
|
|
|
|
switch(mode)
|
|
|
|
{
|
|
|
|
case(GL_POINTS): primLength=1; break;
|
|
|
|
case(GL_LINES): primLength=2; break;
|
|
|
|
case(GL_TRIANGLES): primLength=3; break;
|
|
|
|
case(GL_QUADS): primLength=4; break;
|
|
|
|
default: primLength=0; break; // compute later when =0.
|
|
|
|
}
|
|
|
|
|
|
|
|
// draw primitives by the more flexible "slow" path,
|
|
|
|
// sending OpenGL glBegin/glVertex.../glEnd().
|
|
|
|
switch(primitiveset->getType())
|
|
|
|
{
|
|
|
|
case(PrimitiveSet::DrawArraysPrimitiveType):
|
|
|
|
{
|
|
|
|
if (primLength==0) primLength=primitiveset->getNumIndices();
|
|
|
|
|
|
|
|
const DrawArrays* drawArray = static_cast<const DrawArrays*>(primitiveset);
|
|
|
|
arrayDispatchers.Begin(mode);
|
|
|
|
|
|
|
|
unsigned int primCount=0;
|
|
|
|
unsigned int indexEnd = drawArray->getFirst()+drawArray->getCount();
|
|
|
|
for(unsigned int vindex=drawArray->getFirst();
|
|
|
|
vindex<indexEnd;
|
|
|
|
++vindex,++primCount)
|
|
|
|
{
|
2009-10-23 20:24:22 +08:00
|
|
|
if (bindPerPrimitiveActive && (primCount%primLength)==0)
|
2009-10-21 03:34:24 +08:00
|
|
|
{
|
2009-10-23 20:24:22 +08:00
|
|
|
arrayDispatchers.dispatch(BIND_PER_PRIMITIVE,primitiveNum++);
|
2009-10-21 03:34:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex);
|
|
|
|
}
|
|
|
|
|
|
|
|
arrayDispatchers.End();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawArrayLengthsPrimitiveType):
|
|
|
|
{
|
|
|
|
const DrawArrayLengths* drawArrayLengths = static_cast<const DrawArrayLengths*>(primitiveset);
|
|
|
|
unsigned int vindex=drawArrayLengths->getFirst();
|
|
|
|
for(DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin();
|
|
|
|
primItr!=drawArrayLengths->end();
|
|
|
|
++primItr)
|
|
|
|
{
|
|
|
|
unsigned int localPrimLength;
|
|
|
|
if (primLength==0) localPrimLength=*primItr;
|
|
|
|
else localPrimLength=primLength;
|
|
|
|
|
|
|
|
arrayDispatchers.Begin(mode);
|
|
|
|
|
|
|
|
for(GLsizei primCount=0;
|
|
|
|
primCount<*primItr;
|
|
|
|
++vindex,++primCount)
|
|
|
|
{
|
2009-10-23 20:24:22 +08:00
|
|
|
if (bindPerPrimitiveActive && (primCount%localPrimLength)==0)
|
2009-10-21 03:34:24 +08:00
|
|
|
{
|
2009-10-23 20:24:22 +08:00
|
|
|
arrayDispatchers.dispatch(BIND_PER_PRIMITIVE, primitiveNum++);
|
2009-10-21 03:34:24 +08:00
|
|
|
}
|
|
|
|
arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex);
|
|
|
|
}
|
|
|
|
|
|
|
|
arrayDispatchers.End();
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawElementsUBytePrimitiveType):
|
|
|
|
{
|
|
|
|
if (primLength==0) primLength=primitiveset->getNumIndices();
|
|
|
|
|
|
|
|
const DrawElementsUByte* drawElements = static_cast<const DrawElementsUByte*>(primitiveset);
|
|
|
|
arrayDispatchers.Begin(mode);
|
|
|
|
|
|
|
|
unsigned int primCount=0;
|
|
|
|
for(DrawElementsUByte::const_iterator primItr=drawElements->begin();
|
|
|
|
primItr!=drawElements->end();
|
|
|
|
++primCount,++primItr)
|
|
|
|
{
|
|
|
|
|
2009-10-23 20:24:22 +08:00
|
|
|
if (bindPerPrimitiveActive && (primCount%primLength)==0)
|
2009-10-21 03:34:24 +08:00
|
|
|
{
|
2009-10-23 20:24:22 +08:00
|
|
|
arrayDispatchers.dispatch(BIND_PER_PRIMITIVE, primitiveNum++);
|
2009-10-21 03:34:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int vindex=*primItr;
|
|
|
|
arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex);
|
|
|
|
}
|
|
|
|
|
|
|
|
arrayDispatchers.End();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawElementsUShortPrimitiveType):
|
|
|
|
{
|
|
|
|
if (primLength==0) primLength=primitiveset->getNumIndices();
|
|
|
|
|
|
|
|
const DrawElementsUShort* drawElements = static_cast<const DrawElementsUShort*>(primitiveset);
|
|
|
|
arrayDispatchers.Begin(mode);
|
|
|
|
|
|
|
|
unsigned int primCount=0;
|
|
|
|
for(DrawElementsUShort::const_iterator primItr=drawElements->begin();
|
|
|
|
primItr!=drawElements->end();
|
|
|
|
++primCount,++primItr)
|
|
|
|
{
|
2009-10-23 20:24:22 +08:00
|
|
|
if (bindPerPrimitiveActive && (primCount%primLength)==0)
|
2009-10-21 03:34:24 +08:00
|
|
|
{
|
2009-10-23 20:24:22 +08:00
|
|
|
arrayDispatchers.dispatch(BIND_PER_PRIMITIVE, primitiveNum++);
|
2009-10-21 03:34:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int vindex=*primItr;
|
|
|
|
arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex);
|
|
|
|
}
|
|
|
|
|
|
|
|
arrayDispatchers.End();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawElementsUIntPrimitiveType):
|
|
|
|
{
|
|
|
|
if (primLength==0) primLength=primitiveset->getNumIndices();
|
|
|
|
|
|
|
|
const DrawElementsUInt* drawElements = static_cast<const DrawElementsUInt*>(primitiveset);
|
|
|
|
arrayDispatchers.Begin(mode);
|
|
|
|
|
|
|
|
unsigned int primCount=0;
|
|
|
|
for(DrawElementsUInt::const_iterator primItr=drawElements->begin();
|
|
|
|
primItr!=drawElements->end();
|
|
|
|
++primCount,++primItr)
|
|
|
|
{
|
2009-10-23 20:24:22 +08:00
|
|
|
if (bindPerPrimitiveActive && (primCount%primLength)==0)
|
2009-10-21 03:34:24 +08:00
|
|
|
{
|
2009-10-23 20:24:22 +08:00
|
|
|
arrayDispatchers.dispatch(BIND_PER_PRIMITIVE, primitiveNum++);
|
2009-10-21 03:34:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int vindex=*primItr;
|
|
|
|
arrayDispatchers.dispatch(BIND_PER_VERTEX, vindex);
|
|
|
|
}
|
|
|
|
|
|
|
|
arrayDispatchers.End();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-10-24 01:27:54 +08:00
|
|
|
|
|
|
|
// unbind the VBO's if any are used.
|
|
|
|
state.unbindVertexBufferObject();
|
|
|
|
state.unbindElementBufferObject();
|
2009-11-13 21:25:59 +08:00
|
|
|
|
|
|
|
if (checkForGLErrors) state.checkGLErrors("end of Geometry::drawImplementation().");
|
2009-10-21 03:34:24 +08:00
|
|
|
}
|
2007-03-28 19:30:38 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
class AttributeFunctorArrayVisitor : public ArrayVisitor
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
AttributeFunctorArrayVisitor(Drawable::AttributeFunctor& af):
|
|
|
|
_af(af) {}
|
|
|
|
|
|
|
|
virtual ~AttributeFunctorArrayVisitor() {}
|
2009-10-21 03:34:24 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
virtual void apply(ByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(ShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(IntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(UByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(UShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(UIntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(Vec4ubArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(FloatArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(Vec2Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(Vec3Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(Vec4Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(DoubleArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(Vec2dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(Vec3dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(Vec4dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
2007-04-29 16:12:29 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
|
|
|
|
inline void applyArray(Drawable::AttributeType type,Array* array)
|
|
|
|
{
|
|
|
|
if (array)
|
|
|
|
{
|
|
|
|
_type = type;
|
|
|
|
array->accept(*this);
|
|
|
|
}
|
|
|
|
}
|
2005-08-31 06:28:30 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
protected:
|
|
|
|
|
|
|
|
AttributeFunctorArrayVisitor& operator = (const AttributeFunctorArrayVisitor&) { return *this; }
|
|
|
|
Drawable::AttributeFunctor& _af;
|
|
|
|
Drawable::AttributeType _type;
|
|
|
|
};
|
2003-08-08 08:21:30 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
void Geometry::accept(AttributeFunctor& af)
|
|
|
|
{
|
|
|
|
AttributeFunctorArrayVisitor afav(af);
|
2003-05-07 21:13:13 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
if (_vertexData.array.valid())
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
afav.applyArray(VERTICES,_vertexData.array.get());
|
2003-05-07 21:13:13 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
else if (_vertexAttribList.size()>0)
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_INFO<<"Geometry::accept(AttributeFunctor& af): Using vertex attribute instead"<<std::endl;
|
2009-10-22 18:29:43 +08:00
|
|
|
afav.applyArray(VERTICES,_vertexAttribList[0].array.get());
|
2003-05-07 21:13:13 +08:00
|
|
|
}
|
2002-10-02 21:12:16 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
afav.applyArray(NORMALS,_normalData.array.get());
|
|
|
|
afav.applyArray(COLORS,_colorData.array.get());
|
|
|
|
afav.applyArray(SECONDARY_COLORS,_secondaryColorData.array.get());
|
|
|
|
afav.applyArray(FOG_COORDS,_fogCoordData.array.get());
|
|
|
|
|
|
|
|
for(unsigned unit=0;unit<_texCoordList.size();++unit)
|
2002-08-16 04:27:33 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
afav.applyArray((AttributeType)(TEXTURE_COORDS_0+unit),_texCoordList[unit].array.get());
|
2002-08-16 04:27:33 +08:00
|
|
|
}
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(unsigned int index=0; index<_vertexAttribList.size(); ++index)
|
2002-08-16 04:27:33 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
afav.applyArray(index,_vertexAttribList[index].array.get());
|
2002-08-16 04:27:33 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
}
|
2002-10-02 21:12:16 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
class ConstAttributeFunctorArrayVisitor : public ConstArrayVisitor
|
|
|
|
{
|
|
|
|
public:
|
2003-05-07 21:13:13 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
ConstAttributeFunctorArrayVisitor(Drawable::ConstAttributeFunctor& af):
|
|
|
|
_af(af) {}
|
|
|
|
|
|
|
|
virtual ~ConstAttributeFunctorArrayVisitor() {}
|
2009-10-17 00:26:27 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
virtual void apply(const ByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const ShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const IntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const UByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const UShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const UIntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const Vec4ubArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const FloatArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const Vec2Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const Vec3Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const Vec4Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const DoubleArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const Vec2dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const Vec3dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
virtual void apply(const Vec4dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
|
|
|
|
|
|
|
|
|
|
|
|
inline void applyArray(Drawable::AttributeType type,const Array* array)
|
2003-06-30 05:41:57 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
if (array)
|
2007-05-01 14:28:20 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
_type = type;
|
|
|
|
array->accept(*this);
|
2007-05-01 14:28:20 +08:00
|
|
|
}
|
2003-05-07 21:13:13 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
|
|
|
|
protected:
|
2003-06-30 05:41:57 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
ConstAttributeFunctorArrayVisitor& operator = (const ConstAttributeFunctorArrayVisitor&) { return *this; }
|
2003-06-30 05:41:57 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
Drawable::ConstAttributeFunctor& _af;
|
|
|
|
Drawable::AttributeType _type;
|
|
|
|
};
|
2003-06-30 05:41:57 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
void Geometry::accept(ConstAttributeFunctor& af) const
|
|
|
|
{
|
|
|
|
ConstAttributeFunctorArrayVisitor afav(af);
|
|
|
|
|
|
|
|
if (_vertexData.array.valid())
|
|
|
|
{
|
|
|
|
afav.applyArray(VERTICES,_vertexData.array.get());
|
|
|
|
}
|
|
|
|
else if (_vertexAttribList.size()>0)
|
|
|
|
{
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_INFO<<"Geometry::accept(ConstAttributeFunctor& af): Using vertex attribute instead"<<std::endl;
|
2009-10-22 18:29:43 +08:00
|
|
|
afav.applyArray(VERTICES,_vertexAttribList[0].array.get());
|
|
|
|
}
|
2003-06-30 05:41:57 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
afav.applyArray(NORMALS,_normalData.array.get());
|
|
|
|
afav.applyArray(COLORS,_colorData.array.get());
|
|
|
|
afav.applyArray(SECONDARY_COLORS,_secondaryColorData.array.get());
|
|
|
|
afav.applyArray(FOG_COORDS,_fogCoordData.array.get());
|
2003-06-30 05:41:57 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(unsigned unit=0;unit<_texCoordList.size();++unit)
|
|
|
|
{
|
|
|
|
afav.applyArray((AttributeType)(TEXTURE_COORDS_0+unit),_texCoordList[unit].array.get());
|
|
|
|
}
|
2003-06-30 05:41:57 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(unsigned int index=0; index<_vertexAttribList.size(); ++index)
|
|
|
|
{
|
|
|
|
afav.applyArray(index,_vertexAttribList[index].array.get());
|
|
|
|
}
|
|
|
|
}
|
2002-10-02 21:12:16 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
void Geometry::accept(PrimitiveFunctor& functor) const
|
|
|
|
{
|
|
|
|
const osg::Array* vertices = _vertexData.array.get();
|
|
|
|
const osg::IndexArray* indices = _vertexData.indices.get();
|
2009-10-17 00:26:27 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
if (!vertices && _vertexAttribList.size()>0)
|
|
|
|
{
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_INFO<<"Using vertex attribute instead"<<std::endl;
|
2009-10-22 18:29:43 +08:00
|
|
|
vertices = _vertexAttribList[0].array.get();
|
|
|
|
indices = _vertexAttribList[0].indices.get();
|
|
|
|
}
|
2009-10-17 00:26:27 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
if (!vertices || vertices->getNumElements()==0) return;
|
2009-10-17 00:26:27 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
if (!indices)
|
|
|
|
{
|
|
|
|
switch(vertices->getType())
|
2003-05-07 21:13:13 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
case(Array::Vec2ArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec2*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
case(Array::Vec3ArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec3*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
case(Array::Vec4ArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec4*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
case(Array::Vec2dArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec2d*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
case(Array::Vec3dArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec3d*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
case(Array::Vec4dArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec4d*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
default:
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_WARN<<"Warning: Geometry::accept(PrimitiveFunctor&) cannot handle Vertex Array type"<<vertices->getType()<<std::endl;
|
2009-10-22 18:29:43 +08:00
|
|
|
return;
|
2003-05-07 21:13:13 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
|
2002-11-06 23:43:11 +08:00
|
|
|
for(PrimitiveSetList::const_iterator itr=_primitives.begin();
|
2002-10-02 21:12:16 +08:00
|
|
|
itr!=_primitives.end();
|
|
|
|
++itr)
|
2002-06-22 00:45:45 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
(*itr)->accept(functor);
|
2003-06-30 05:41:57 +08:00
|
|
|
}
|
2002-10-02 21:12:16 +08:00
|
|
|
}
|
|
|
|
else
|
2009-10-22 18:29:43 +08:00
|
|
|
{
|
|
|
|
const Vec2* vec2Array = 0;
|
|
|
|
const Vec3* vec3Array = 0;
|
|
|
|
const Vec4* vec4Array = 0;
|
|
|
|
const Vec2d* vec2dArray = 0;
|
|
|
|
const Vec3d* vec3dArray = 0;
|
|
|
|
const Vec4d* vec4dArray = 0;
|
|
|
|
Array::Type type = vertices->getType();
|
|
|
|
switch(type)
|
2002-10-02 21:12:16 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
case(Array::Vec2ArrayType):
|
|
|
|
vec2Array = static_cast<const Vec2*>(vertices->getDataPointer());
|
|
|
|
break;
|
|
|
|
case(Array::Vec3ArrayType):
|
|
|
|
vec3Array = static_cast<const Vec3*>(vertices->getDataPointer());
|
|
|
|
break;
|
|
|
|
case(Array::Vec4ArrayType):
|
|
|
|
vec4Array = static_cast<const Vec4*>(vertices->getDataPointer());
|
|
|
|
break;
|
|
|
|
case(Array::Vec2dArrayType):
|
|
|
|
vec2dArray = static_cast<const Vec2d*>(vertices->getDataPointer());
|
|
|
|
break;
|
|
|
|
case(Array::Vec3dArrayType):
|
|
|
|
vec3dArray = static_cast<const Vec3d*>(vertices->getDataPointer());
|
|
|
|
break;
|
|
|
|
case(Array::Vec4dArrayType):
|
|
|
|
vec4dArray = static_cast<const Vec4d*>(vertices->getDataPointer());
|
|
|
|
break;
|
|
|
|
default:
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_WARN<<"Warning: Geometry::accept(PrimitiveFunctor&) cannot handle Vertex Array type"<<vertices->getType()<<std::endl;
|
2009-10-22 18:29:43 +08:00
|
|
|
return;
|
2002-10-02 21:12:16 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
|
|
|
|
for(PrimitiveSetList::const_iterator itr=_primitives.begin();
|
|
|
|
itr!=_primitives.end();
|
|
|
|
++itr)
|
2002-10-02 21:12:16 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
const PrimitiveSet* primitiveset = itr->get();
|
|
|
|
GLenum mode=primitiveset->getMode();
|
|
|
|
switch(primitiveset->getType())
|
2002-10-02 21:12:16 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
case(PrimitiveSet::DrawArraysPrimitiveType):
|
2002-10-02 21:12:16 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
const DrawArrays* drawArray = static_cast<const DrawArrays*>(primitiveset);
|
|
|
|
functor.begin(mode);
|
|
|
|
|
|
|
|
unsigned int indexEnd = drawArray->getFirst()+drawArray->getCount();
|
|
|
|
for(unsigned int vindex=drawArray->getFirst();
|
|
|
|
vindex<indexEnd;
|
|
|
|
++vindex)
|
2002-10-02 21:12:16 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
switch(type)
|
2002-10-02 21:12:16 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
case(Array::Vec2ArrayType):
|
|
|
|
functor.vertex(vec2Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec3ArrayType):
|
|
|
|
functor.vertex(vec3Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec4ArrayType):
|
|
|
|
functor.vertex(vec4Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec2dArrayType):
|
|
|
|
functor.vertex(vec2dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec3dArrayType):
|
|
|
|
functor.vertex(vec3dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec4dArrayType):
|
|
|
|
functor.vertex(vec4dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2002-10-02 21:12:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
|
|
|
|
functor.end();
|
2002-08-16 04:27:33 +08:00
|
|
|
break;
|
2002-10-02 21:12:16 +08:00
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawArrayLengthsPrimitiveType):
|
|
|
|
{
|
|
|
|
|
|
|
|
const DrawArrayLengths* drawArrayLengths = static_cast<const DrawArrayLengths*>(primitiveset);
|
|
|
|
unsigned int vindex=drawArrayLengths->getFirst();
|
|
|
|
for(DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin();
|
|
|
|
primItr!=drawArrayLengths->end();
|
|
|
|
++primItr)
|
|
|
|
{
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
functor.begin(mode);
|
2002-10-02 21:12:16 +08:00
|
|
|
|
|
|
|
for(GLsizei primCount=0;primCount<*primItr;++primCount)
|
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
switch(type)
|
2003-05-09 21:07:06 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
case(Array::Vec2ArrayType):
|
|
|
|
functor.vertex(vec2Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec3ArrayType):
|
|
|
|
functor.vertex(vec3Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec4ArrayType):
|
|
|
|
functor.vertex(vec4Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec2dArrayType):
|
|
|
|
functor.vertex(vec2dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec3dArrayType):
|
|
|
|
functor.vertex(vec3dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec4dArrayType):
|
|
|
|
functor.vertex(vec4dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2003-05-09 21:07:06 +08:00
|
|
|
}
|
2002-10-02 21:12:16 +08:00
|
|
|
++vindex;
|
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
|
|
|
|
functor.end();
|
2002-10-02 21:12:16 +08:00
|
|
|
|
|
|
|
}
|
2002-08-16 04:27:33 +08:00
|
|
|
break;
|
2002-10-02 21:12:16 +08:00
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawElementsUBytePrimitiveType):
|
|
|
|
{
|
|
|
|
const DrawElementsUByte* drawElements = static_cast<const DrawElementsUByte*>(primitiveset);
|
2009-10-22 18:29:43 +08:00
|
|
|
functor.begin(mode);
|
2002-10-02 21:12:16 +08:00
|
|
|
|
|
|
|
unsigned int primCount=0;
|
|
|
|
for(DrawElementsUByte::const_iterator primItr=drawElements->begin();
|
|
|
|
primItr!=drawElements->end();
|
|
|
|
++primCount,++primItr)
|
|
|
|
{
|
|
|
|
unsigned int vindex=*primItr;
|
2009-10-22 18:29:43 +08:00
|
|
|
switch(type)
|
2003-05-09 21:07:06 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
case(Array::Vec2ArrayType):
|
|
|
|
functor.vertex(vec2Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec3ArrayType):
|
|
|
|
functor.vertex(vec3Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec4ArrayType):
|
|
|
|
functor.vertex(vec4Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec2dArrayType):
|
|
|
|
functor.vertex(vec2dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec3dArrayType):
|
|
|
|
functor.vertex(vec3dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec4dArrayType):
|
|
|
|
functor.vertex(vec4dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2003-05-09 21:07:06 +08:00
|
|
|
}
|
2002-10-02 21:12:16 +08:00
|
|
|
}
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
functor.end();
|
2002-10-02 21:12:16 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawElementsUShortPrimitiveType):
|
|
|
|
{
|
|
|
|
const DrawElementsUShort* drawElements = static_cast<const DrawElementsUShort*>(primitiveset);
|
2009-10-22 18:29:43 +08:00
|
|
|
functor.begin(mode);
|
2002-10-02 21:12:16 +08:00
|
|
|
|
|
|
|
for(DrawElementsUShort::const_iterator primItr=drawElements->begin();
|
|
|
|
primItr!=drawElements->end();
|
2009-10-22 18:29:43 +08:00
|
|
|
++primItr)
|
2002-10-02 21:12:16 +08:00
|
|
|
{
|
|
|
|
unsigned int vindex=*primItr;
|
2009-10-22 18:29:43 +08:00
|
|
|
switch(type)
|
2003-05-09 21:07:06 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
case(Array::Vec2ArrayType):
|
|
|
|
functor.vertex(vec2Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec3ArrayType):
|
|
|
|
functor.vertex(vec3Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec4ArrayType):
|
|
|
|
functor.vertex(vec4Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec2dArrayType):
|
|
|
|
functor.vertex(vec2dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec3dArrayType):
|
|
|
|
functor.vertex(vec3dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec4dArrayType):
|
|
|
|
functor.vertex(vec4dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2003-05-09 21:07:06 +08:00
|
|
|
}
|
2002-10-02 21:12:16 +08:00
|
|
|
}
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
functor.end();
|
2002-10-02 21:12:16 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawElementsUIntPrimitiveType):
|
|
|
|
{
|
|
|
|
const DrawElementsUInt* drawElements = static_cast<const DrawElementsUInt*>(primitiveset);
|
2009-10-22 18:29:43 +08:00
|
|
|
functor.begin(mode);
|
2002-10-02 21:12:16 +08:00
|
|
|
|
|
|
|
for(DrawElementsUInt::const_iterator primItr=drawElements->begin();
|
|
|
|
primItr!=drawElements->end();
|
2009-10-22 18:29:43 +08:00
|
|
|
++primItr)
|
2002-10-02 21:12:16 +08:00
|
|
|
{
|
|
|
|
unsigned int vindex=*primItr;
|
2009-10-22 18:29:43 +08:00
|
|
|
switch(type)
|
2003-05-09 21:07:06 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
case(Array::Vec2ArrayType):
|
|
|
|
functor.vertex(vec2Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec3ArrayType):
|
|
|
|
functor.vertex(vec3Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec4ArrayType):
|
|
|
|
functor.vertex(vec4Array[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec2dArrayType):
|
|
|
|
functor.vertex(vec2dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec3dArrayType):
|
|
|
|
functor.vertex(vec3dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
case(Array::Vec4dArrayType):
|
|
|
|
functor.vertex(vec4dArray[_vertexData.indices->index(vindex)]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
functor.end();
|
|
|
|
break;
|
2002-10-02 21:12:16 +08:00
|
|
|
}
|
2002-08-16 04:27:33 +08:00
|
|
|
default:
|
2002-10-02 21:12:16 +08:00
|
|
|
{
|
2002-08-16 04:27:33 +08:00
|
|
|
break;
|
2002-10-02 21:12:16 +08:00
|
|
|
}
|
2002-08-16 04:27:33 +08:00
|
|
|
}
|
|
|
|
}
|
2002-06-22 00:45:45 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
return;
|
2002-06-21 03:54:08 +08:00
|
|
|
}
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
void Geometry::accept(PrimitiveIndexFunctor& functor) const
|
2002-06-26 04:27:51 +08:00
|
|
|
{
|
2009-10-09 21:39:11 +08:00
|
|
|
const osg::Array* vertices = _vertexData.array.get();
|
|
|
|
const osg::IndexArray* indices = _vertexData.indices.get();
|
2003-06-24 23:40:09 +08:00
|
|
|
|
2009-10-09 21:39:11 +08:00
|
|
|
if (!vertices && _vertexAttribList.size()>0)
|
|
|
|
{
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_INFO<<"Geometry::accept(PrimitiveIndexFunctor& functor): Using vertex attribute instead"<<std::endl;
|
2009-10-09 21:39:11 +08:00
|
|
|
vertices = _vertexAttribList[0].array.get();
|
|
|
|
indices = _vertexAttribList[0].indices.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!vertices || vertices->getNumElements()==0) return;
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
switch(vertices->getType())
|
|
|
|
{
|
|
|
|
case(Array::Vec2ArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec2*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
case(Array::Vec3ArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec3*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
case(Array::Vec4ArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec4*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
case(Array::Vec2dArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec2d*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
case(Array::Vec3dArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec3d*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
case(Array::Vec4dArrayType):
|
|
|
|
functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec4d*>(vertices->getDataPointer()));
|
|
|
|
break;
|
|
|
|
default:
|
2010-05-28 23:47:52 +08:00
|
|
|
OSG_WARN<<"Warning: Geometry::accept(PrimitiveIndexFunctor&) cannot handle Vertex Array type"<<vertices->getType()<<std::endl;
|
2009-10-22 18:29:43 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!_vertexData.indices.valid())
|
2002-06-26 04:27:51 +08:00
|
|
|
{
|
2002-11-06 18:24:33 +08:00
|
|
|
for(PrimitiveSetList::const_iterator itr=_primitives.begin();
|
2002-10-08 22:10:55 +08:00
|
|
|
itr!=_primitives.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
(*itr)->accept(functor);
|
|
|
|
}
|
2002-06-26 04:27:51 +08:00
|
|
|
}
|
2002-10-08 22:10:55 +08:00
|
|
|
else
|
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
for(PrimitiveSetList::const_iterator itr=_primitives.begin();
|
|
|
|
itr!=_primitives.end();
|
|
|
|
++itr)
|
2002-10-08 22:10:55 +08:00
|
|
|
{
|
2002-11-06 18:24:33 +08:00
|
|
|
const PrimitiveSet* primitiveset = itr->get();
|
2002-10-08 22:10:55 +08:00
|
|
|
GLenum mode=primitiveset->getMode();
|
|
|
|
switch(primitiveset->getType())
|
|
|
|
{
|
|
|
|
case(PrimitiveSet::DrawArraysPrimitiveType):
|
|
|
|
{
|
|
|
|
const DrawArrays* drawArray = static_cast<const DrawArrays*>(primitiveset);
|
|
|
|
functor.begin(mode);
|
|
|
|
|
|
|
|
unsigned int indexEnd = drawArray->getFirst()+drawArray->getCount();
|
|
|
|
for(unsigned int vindex=drawArray->getFirst();
|
|
|
|
vindex<indexEnd;
|
|
|
|
++vindex)
|
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
functor.vertex(_vertexData.indices->index(vindex));
|
2002-10-08 22:10:55 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
|
2002-10-08 22:10:55 +08:00
|
|
|
functor.end();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawArrayLengthsPrimitiveType):
|
|
|
|
{
|
|
|
|
|
|
|
|
const DrawArrayLengths* drawArrayLengths = static_cast<const DrawArrayLengths*>(primitiveset);
|
|
|
|
unsigned int vindex=drawArrayLengths->getFirst();
|
|
|
|
for(DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin();
|
|
|
|
primItr!=drawArrayLengths->end();
|
|
|
|
++primItr)
|
|
|
|
{
|
|
|
|
|
|
|
|
functor.begin(mode);
|
|
|
|
|
|
|
|
for(GLsizei primCount=0;primCount<*primItr;++primCount)
|
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
functor.vertex(_vertexData.indices->index(vindex));
|
2002-10-08 22:10:55 +08:00
|
|
|
++vindex;
|
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
|
2002-10-08 22:10:55 +08:00
|
|
|
functor.end();
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawElementsUBytePrimitiveType):
|
|
|
|
{
|
|
|
|
const DrawElementsUByte* drawElements = static_cast<const DrawElementsUByte*>(primitiveset);
|
|
|
|
functor.begin(mode);
|
|
|
|
|
|
|
|
unsigned int primCount=0;
|
|
|
|
for(DrawElementsUByte::const_iterator primItr=drawElements->begin();
|
|
|
|
primItr!=drawElements->end();
|
|
|
|
++primCount,++primItr)
|
|
|
|
{
|
|
|
|
unsigned int vindex=*primItr;
|
2009-10-22 18:29:43 +08:00
|
|
|
functor.vertex(_vertexData.indices->index(vindex));
|
2002-10-08 22:10:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
functor.end();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawElementsUShortPrimitiveType):
|
|
|
|
{
|
|
|
|
const DrawElementsUShort* drawElements = static_cast<const DrawElementsUShort*>(primitiveset);
|
|
|
|
functor.begin(mode);
|
|
|
|
|
|
|
|
for(DrawElementsUShort::const_iterator primItr=drawElements->begin();
|
|
|
|
primItr!=drawElements->end();
|
|
|
|
++primItr)
|
|
|
|
{
|
|
|
|
unsigned int vindex=*primItr;
|
2009-10-22 18:29:43 +08:00
|
|
|
functor.vertex(_vertexData.indices->index(vindex));
|
2002-10-08 22:10:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
functor.end();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case(PrimitiveSet::DrawElementsUIntPrimitiveType):
|
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
const DrawElementsUInt* drawElements = static_cast<const DrawElementsUInt*>(primitiveset);
|
|
|
|
functor.begin(mode);
|
2003-08-08 08:21:30 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(DrawElementsUInt::const_iterator primItr=drawElements->begin();
|
|
|
|
primItr!=drawElements->end();
|
|
|
|
++primItr)
|
|
|
|
{
|
|
|
|
unsigned int vindex=*primItr;
|
|
|
|
functor.vertex(_vertexData.indices->index(vindex));
|
|
|
|
}
|
|
|
|
|
|
|
|
functor.end();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-08-08 08:21:30 +08:00
|
|
|
}
|
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
return;
|
2003-08-08 08:21:30 +08:00
|
|
|
}
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
unsigned int _computeNumberOfPrimitives(const osg::Geometry& geom)
|
2008-09-14 18:31:27 +08:00
|
|
|
{
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
unsigned int totalNumberOfPrimitives = 0;
|
2008-09-14 18:31:27 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(Geometry::PrimitiveSetList::const_iterator itr=geom.getPrimitiveSetList().begin();
|
|
|
|
itr!=geom.getPrimitiveSetList().end();
|
|
|
|
++itr)
|
2008-09-14 18:31:27 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
const PrimitiveSet* primitiveset = itr->get();
|
|
|
|
GLenum mode=primitiveset->getMode();
|
2008-09-14 18:31:27 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
unsigned int primLength;
|
|
|
|
switch(mode)
|
2008-09-14 18:31:27 +08:00
|
|
|
{
|
2010-05-28 23:47:52 +08:00
|
|
|
case(GL_POINTS): primLength=1; OSG_INFO<<"prim=GL_POINTS"<<std::endl; break;
|
|
|
|
case(GL_LINES): primLength=2; OSG_INFO<<"prim=GL_LINES"<<std::endl; break;
|
|
|
|
case(GL_TRIANGLES): primLength=3; OSG_INFO<<"prim=GL_TRIANGLES"<<std::endl; break;
|
|
|
|
case(GL_QUADS): primLength=4; OSG_INFO<<"prim=GL_QUADS"<<std::endl; break;
|
|
|
|
default: primLength=0; OSG_INFO<<"prim="<<std::hex<<mode<<std::dec<<std::endl; break; // compute later when =0.
|
2008-09-14 18:31:27 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
|
|
|
|
// draw primitives by the more flexible "slow" path,
|
|
|
|
// sending OpenGL Begin/glVertex.../End().
|
|
|
|
switch(primitiveset->getType())
|
2008-09-14 18:31:27 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
case(PrimitiveSet::DrawArrayLengthsPrimitiveType):
|
|
|
|
{
|
2008-09-14 18:31:27 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
const DrawArrayLengths* drawArrayLengths = static_cast<const DrawArrayLengths*>(primitiveset);
|
|
|
|
for(DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin();
|
|
|
|
primItr!=drawArrayLengths->end();
|
|
|
|
++primItr)
|
|
|
|
{
|
|
|
|
if (primLength==0) totalNumberOfPrimitives += 1;
|
|
|
|
else totalNumberOfPrimitives += *primItr/primLength;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
2010-05-28 23:47:52 +08:00
|
|
|
if (primLength==0) { totalNumberOfPrimitives += 1; OSG_INFO<<" totalNumberOfPrimitives="<<totalNumberOfPrimitives<<std::endl;}
|
|
|
|
else { totalNumberOfPrimitives += primitiveset->getNumIndices()/primLength; OSG_INFO<<" primitiveset->getNumIndices()="<<primitiveset->getNumIndices()<<" totalNumberOfPrimitives="<<totalNumberOfPrimitives<<std::endl; }
|
2003-08-08 08:21:30 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
}
|
|
|
|
}
|
2003-08-08 08:21:30 +08:00
|
|
|
}
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
return totalNumberOfPrimitives;
|
|
|
|
}
|
2003-06-25 05:57:13 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
template<class A>
|
|
|
|
bool _verifyBindings(const osg::Geometry& geom, const A& arrayData)
|
2003-06-25 05:57:13 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
unsigned int numElements = arrayData.indices.valid()?arrayData.indices->getNumElements():
|
|
|
|
arrayData.array.valid()?arrayData.array->getNumElements():0;
|
2003-06-25 05:57:13 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
switch(arrayData.binding)
|
|
|
|
{
|
|
|
|
case(osg::Geometry::BIND_OFF):
|
|
|
|
if (numElements>0) return false;
|
|
|
|
break;
|
|
|
|
case(osg::Geometry::BIND_OVERALL):
|
|
|
|
if (numElements!=1) return false;
|
|
|
|
break;
|
|
|
|
case(osg::Geometry::BIND_PER_PRIMITIVE_SET):
|
|
|
|
if (numElements!=geom.getPrimitiveSetList().size()) return false;
|
|
|
|
break;
|
|
|
|
case(osg::Geometry::BIND_PER_PRIMITIVE):
|
|
|
|
if (numElements!=_computeNumberOfPrimitives(geom)) return false;
|
|
|
|
break;
|
|
|
|
case(osg::Geometry::BIND_PER_VERTEX):
|
|
|
|
{
|
|
|
|
unsigned int numVertices = geom.getVertexIndices()?geom.getVertexIndices()->getNumElements():
|
|
|
|
geom.getVertexArray()?geom.getVertexArray()->getNumElements():0;
|
|
|
|
if (numElements!=numVertices) return false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
2003-06-25 05:57:13 +08:00
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
template<class A>
|
|
|
|
void _computeCorrectBindingsAndArraySizes(std::ostream& out, const osg::Geometry& geom, A& arrayData, const char* arrayName)
|
|
|
|
{
|
|
|
|
unsigned int numElements = arrayData.indices.valid()?arrayData.indices->getNumElements():
|
|
|
|
arrayData.array.valid()?arrayData.array->getNumElements():0;
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
// check to see if binding matches 0 elements required.
|
|
|
|
if (numElements==0)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
// correct binding if not correct.
|
|
|
|
if (arrayData.binding!=osg::Geometry::BIND_OFF)
|
|
|
|
{
|
|
|
|
out<<"Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() "<<std::endl
|
|
|
|
<<" "<<arrayName<<" binding has been reset to BIND_OFF"<<std::endl;
|
|
|
|
arrayData.binding=osg::Geometry::BIND_OFF;
|
2003-09-01 06:08:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
return;
|
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
// check to see if binding matches 1 elements required.
|
|
|
|
if (numElements==1)
|
|
|
|
{
|
|
|
|
// correct binding if not correct.
|
|
|
|
if (arrayData.binding!=osg::Geometry::BIND_OVERALL)
|
|
|
|
{
|
|
|
|
out<<"Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() "<<std::endl
|
|
|
|
<<" "<<arrayName<<" binding has been reset to BIND_OVERALL"<<std::endl;
|
|
|
|
arrayData.binding=osg::Geometry::BIND_OVERALL;
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
return;
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
unsigned int numVertices = geom.getVertexIndices()?geom.getVertexIndices()->getNumElements():
|
|
|
|
geom.getVertexArray()?geom.getVertexArray()->getNumElements():0;
|
|
|
|
|
|
|
|
if ( numVertices==0 )
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
if (arrayData.binding!=osg::Geometry::BIND_OFF)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
arrayData.array = 0;
|
|
|
|
arrayData.indices = 0;
|
|
|
|
arrayData.binding = osg::Geometry::BIND_OFF;
|
|
|
|
out<<"Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() vertex array is empty but "<<std::endl
|
|
|
|
<<" vertex array is empty but"<<arrayName<<" is set"<<std::endl
|
|
|
|
<<" reseting "<<arrayName<< " binding to BIND_OFF and array & indices to 0."<<std::endl;
|
2003-09-01 06:08:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (numElements==numVertices)
|
|
|
|
{
|
|
|
|
// correct the binding to per vertex.
|
|
|
|
if (arrayData.binding!=osg::Geometry::BIND_PER_VERTEX)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
out<<"Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() "<<std::endl
|
|
|
|
<<" "<<arrayName<<" binding has been reset to BIND_PER_VERTEX"<<std::endl;
|
|
|
|
arrayData.binding = osg::Geometry::BIND_PER_VERTEX;
|
2003-09-01 06:08:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
return;
|
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
|
|
|
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
// check to see if binding might be per primitive set
|
|
|
|
unsigned int numPrimitiveSets = geom.getPrimitiveSetList().size();
|
|
|
|
|
|
|
|
if (numElements==numPrimitiveSets)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
if (arrayData.binding != osg::Geometry::BIND_PER_PRIMITIVE_SET)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
out<<"Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() "<<std::endl
|
|
|
|
<<" "<<arrayName<<" binding has been reset to BIND_PER_PRIMITIVE_SET"<<std::endl;
|
|
|
|
arrayData.binding = osg::Geometry::BIND_PER_PRIMITIVE_SET;
|
2003-09-01 06:08:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check to see if binding might be per primitive
|
|
|
|
unsigned int numPrimitives = _computeNumberOfPrimitives(geom);
|
|
|
|
if (numElements==numPrimitives)
|
|
|
|
{
|
|
|
|
if (arrayData.binding != osg::Geometry::BIND_PER_PRIMITIVE)
|
2003-09-24 23:54:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
out<<"Warning: in osg::Geometry::computeCorrectBindingsAndArraySizes() "<<std::endl
|
|
|
|
<<" "<<arrayName<<" binding has been reset to BIND_PER_PRIMITIVE"<<std::endl;
|
|
|
|
arrayData.binding = osg::Geometry::BIND_PER_PRIMITIVE;
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
return;
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
if (numElements>numVertices)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
arrayData.binding = osg::Geometry::BIND_PER_VERTEX;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (numElements>numPrimitives)
|
|
|
|
{
|
|
|
|
arrayData.binding = osg::Geometry::BIND_PER_PRIMITIVE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (numElements>numPrimitiveSets)
|
|
|
|
{
|
|
|
|
arrayData.binding = osg::Geometry::BIND_PER_PRIMITIVE_SET;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (numElements>=1)
|
|
|
|
{
|
|
|
|
arrayData.binding = osg::Geometry::BIND_OVERALL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
arrayData.binding = osg::Geometry::BIND_OFF;
|
|
|
|
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
bool Geometry::verifyBindings(const ArrayData& arrayData) const
|
|
|
|
{
|
|
|
|
return _verifyBindings(*this,arrayData);
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
bool Geometry::verifyBindings(const Vec3ArrayData& arrayData) const
|
|
|
|
{
|
|
|
|
return _verifyBindings(*this,arrayData);
|
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
void Geometry::computeCorrectBindingsAndArraySizes(ArrayData& arrayData, const char* arrayName)
|
|
|
|
{
|
|
|
|
_computeCorrectBindingsAndArraySizes(osg::notify(osg::INFO),*this,arrayData,arrayName);
|
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
void Geometry::computeCorrectBindingsAndArraySizes(Vec3ArrayData& arrayData, const char* arrayName)
|
|
|
|
{
|
|
|
|
_computeCorrectBindingsAndArraySizes(osg::notify(osg::INFO),*this,arrayData,arrayName);
|
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
bool Geometry::verifyBindings() const
|
|
|
|
{
|
|
|
|
if (!verifyBindings(_normalData)) return false;
|
|
|
|
if (!verifyBindings(_colorData)) return false;
|
|
|
|
if (!verifyBindings(_secondaryColorData)) return false;
|
|
|
|
if (!verifyBindings(_fogCoordData)) return false;
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(ArrayDataList::const_iterator titr=_texCoordList.begin();
|
|
|
|
titr!=_texCoordList.end();
|
|
|
|
++titr)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
if (!verifyBindings(*titr)) return false;
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(ArrayDataList::const_iterator vitr=_vertexAttribList.begin();
|
|
|
|
vitr!=_vertexAttribList.end();
|
|
|
|
++vitr)
|
|
|
|
{
|
|
|
|
if (!verifyBindings(*vitr)) return false;
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
return true;
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
void Geometry::computeCorrectBindingsAndArraySizes()
|
|
|
|
{
|
|
|
|
// if (verifyBindings()) return;
|
|
|
|
|
|
|
|
computeCorrectBindingsAndArraySizes(_normalData,"_normalData");
|
|
|
|
computeCorrectBindingsAndArraySizes(_colorData,"_colorData");
|
|
|
|
computeCorrectBindingsAndArraySizes(_secondaryColorData,"_secondaryColorData");
|
|
|
|
computeCorrectBindingsAndArraySizes(_fogCoordData,"_fogCoordData");
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(ArrayDataList::iterator titr=_texCoordList.begin();
|
|
|
|
titr!=_texCoordList.end();
|
|
|
|
++titr)
|
|
|
|
{
|
|
|
|
computeCorrectBindingsAndArraySizes(*titr,"_texCoordList[]");
|
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(ArrayDataList::iterator vitr=_vertexAttribList.begin();
|
|
|
|
vitr!=_vertexAttribList.end();
|
|
|
|
++vitr)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
computeCorrectBindingsAndArraySizes(*vitr,"_vertAttribList[]");
|
|
|
|
}
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
class ExpandIndexedArray : public osg::ConstArrayVisitor
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ExpandIndexedArray(const osg::IndexArray& indices,Array* targetArray):
|
|
|
|
_indices(indices),
|
|
|
|
_targetArray(targetArray) {}
|
|
|
|
|
|
|
|
virtual ~ExpandIndexedArray() {}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
// Create when both of the arrays are predefined templated classes. We
|
|
|
|
// can do some optimizations in this case that aren't possible in the general
|
|
|
|
// case.
|
|
|
|
template <class T,class I>
|
|
|
|
T* create_inline(const T& array,const I& indices)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
T* newArray = 0;
|
|
|
|
|
|
|
|
// if source array type and target array type are equal but arrays arn't equal
|
|
|
|
if (_targetArray && _targetArray->getType()==array.getType() && _targetArray!=(osg::Array*)(&array))
|
|
|
|
{
|
|
|
|
// reuse exisiting target array
|
|
|
|
newArray = static_cast<T*>(_targetArray);
|
|
|
|
if (newArray->size()!=indices.size())
|
|
|
|
{
|
|
|
|
// make sure its the right size
|
|
|
|
newArray->resize(indices.size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2003-09-24 23:54:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
// else create a new array.
|
|
|
|
newArray = new T(indices.size());
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(unsigned int i=0;i<indices.size();++i)
|
2003-09-24 23:54:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
(*newArray)[i]= array[indices[i]];
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
return newArray;
|
2003-09-01 06:08:22 +08:00
|
|
|
}
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
// Create when one of the arrays isn't one of the predefined templated classes. The
|
|
|
|
// template parameter is the type of the array that will get created. This is always
|
|
|
|
// one of the predefined classes. We could call clone to get one of the same type as
|
|
|
|
// the input array, but the interface of the osg::Array class doesn't include a way
|
|
|
|
// to set an element.
|
|
|
|
template <class T>
|
|
|
|
osg::Array* create_noinline(const osg::Array& array, const osg::IndexArray& indices)
|
|
|
|
{
|
|
|
|
T* newArray = 0;
|
|
|
|
typedef typename T::ElementDataType EDT;
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
unsigned int num_indices = indices.getNumElements();
|
|
|
|
newArray = new T(num_indices);
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
const EDT* src = static_cast<const EDT*>(array.getDataPointer());
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(unsigned int i=0;i<num_indices;++i)
|
2003-09-24 23:54:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
(*newArray)[i]= src[indices.index(i)];
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
return newArray;
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
osg::Array* create_noinline(const osg::Array& array, const osg::IndexArray& indices)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
switch (array.getType())
|
2003-09-24 23:54:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
case(osg::Array::ByteArrayType): return create_noinline<osg::ByteArray>(array,indices);
|
|
|
|
case(osg::Array::ShortArrayType): return create_noinline<osg::ShortArray>(array,indices);
|
|
|
|
case(osg::Array::IntArrayType): return create_noinline<osg::IntArray>(array,indices);
|
|
|
|
case(osg::Array::UByteArrayType): return create_noinline<osg::UByteArray>(array,indices);
|
|
|
|
case(osg::Array::UShortArrayType): return create_noinline<osg::UShortArray>(array,indices);
|
|
|
|
case(osg::Array::UIntArrayType): return create_noinline<osg::UIntArray>(array,indices);
|
|
|
|
case(osg::Array::Vec4ubArrayType): return create_noinline<osg::Vec4ubArray>(array,indices);
|
|
|
|
case(osg::Array::FloatArrayType): return create_noinline<osg::FloatArray>(array,indices);
|
|
|
|
case(osg::Array::Vec2ArrayType): return create_noinline<osg::Vec2Array>(array,indices);
|
|
|
|
case(osg::Array::Vec3ArrayType): return create_noinline<osg::Vec3Array>(array,indices);
|
|
|
|
case(osg::Array::Vec4ArrayType): return create_noinline<osg::Vec4Array>(array,indices);
|
|
|
|
case(osg::Array::Vec2dArrayType): return create_noinline<osg::Vec2dArray>(array,indices);
|
|
|
|
case(osg::Array::Vec3dArrayType): return create_noinline<osg::Vec3dArray>(array,indices);
|
|
|
|
case(osg::Array::Vec4dArrayType): return create_noinline<osg::Vec4dArray>(array,indices);
|
|
|
|
default:
|
|
|
|
return NULL;
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
template <class TA, class TI>
|
|
|
|
osg::Array* create(const TA& array, const osg::IndexArray& indices)
|
|
|
|
{
|
|
|
|
// We know that indices.getType returned the same thing as TI, but
|
|
|
|
// we need to determine whether it is really an instance of TI, or
|
|
|
|
// perhaps another subclass of osg::Array that contains the same
|
|
|
|
// type of data.
|
|
|
|
const TI* ba(dynamic_cast<const TI*>(&indices));
|
|
|
|
if (ba != NULL) {
|
|
|
|
return create_inline(array,*ba);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return create_noinline(array, _indices);
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
}
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
template <class T>
|
|
|
|
osg::Array* create(const T& array)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
switch(_indices.getType())
|
|
|
|
{
|
|
|
|
case(osg::Array::ByteArrayType): return create<T, osg::ByteArray>(array, _indices);
|
|
|
|
case(osg::Array::ShortArrayType): return create<T, osg::ShortArray>(array, _indices);
|
|
|
|
case(osg::Array::IntArrayType): return create<T, osg::IntArray>(array, _indices);
|
|
|
|
case(osg::Array::UByteArrayType): return create<T, osg::UByteArray>(array, _indices);
|
|
|
|
case(osg::Array::UShortArrayType): return create<T, osg::UShortArray>(array, _indices);
|
|
|
|
case(osg::Array::UIntArrayType): return create<T, osg::UIntArray>(array, _indices);
|
|
|
|
default: return create_noinline(array, _indices);
|
|
|
|
}
|
|
|
|
|
2003-09-01 06:08:22 +08:00
|
|
|
}
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
// applys for the predefined classes go through 1-arg create to do indexing
|
|
|
|
virtual void apply(const osg::ByteArray& array) { _targetArray = create(array); }
|
|
|
|
virtual void apply(const osg::ShortArray& array) { _targetArray = create(array); }
|
|
|
|
virtual void apply(const osg::IntArray& array) { _targetArray = create(array); }
|
|
|
|
virtual void apply(const osg::UByteArray& array) { _targetArray = create(array); }
|
|
|
|
virtual void apply(const osg::UShortArray& array) { _targetArray = create(array); }
|
|
|
|
virtual void apply(const osg::UIntArray& array) { _targetArray = create(array); }
|
|
|
|
virtual void apply(const osg::Vec4ubArray& array) { _targetArray = create(array); }
|
|
|
|
virtual void apply(const osg::FloatArray& array) { _targetArray = create(array); }
|
|
|
|
virtual void apply(const osg::Vec2Array& array) { _targetArray = create(array); }
|
|
|
|
virtual void apply(const osg::Vec3Array& array) { _targetArray = create(array); }
|
|
|
|
virtual void apply(const osg::Vec4Array& array) { _targetArray = create(array); }
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
// other subclasses of osg::Array end up here
|
|
|
|
virtual void apply(const osg::Array& array) { _targetArray = create_noinline(array, _indices); }
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
const osg::IndexArray& _indices;
|
|
|
|
osg::Array* _targetArray;
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
protected:
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
ExpandIndexedArray& operator = (const ExpandIndexedArray&) { return *this; }
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
};
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
bool Geometry::suitableForOptimization() const
|
|
|
|
{
|
|
|
|
bool hasIndices = false;
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
if (getVertexIndices()) hasIndices = true;
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
if (getNormalIndices()) hasIndices = true;
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
if (getColorIndices()) hasIndices = true;
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
if (getSecondaryColorIndices()) hasIndices = true;
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
if (getFogCoordIndices()) hasIndices = true;
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(unsigned int ti=0;ti<getNumTexCoordArrays();++ti)
|
|
|
|
{
|
|
|
|
if (getTexCoordIndices(ti)) hasIndices = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(unsigned int vi=0;vi<getNumVertexAttribArrays();++vi)
|
|
|
|
{
|
|
|
|
if (getVertexAttribIndices(vi)) hasIndices = true;
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
return hasIndices;
|
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
void Geometry::copyToAndOptimize(Geometry& target)
|
|
|
|
{
|
|
|
|
bool copyToSelf = (this==&target);
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
// copy over primitive sets.
|
|
|
|
if (!copyToSelf) target.getPrimitiveSetList() = getPrimitiveSetList();
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
// copy over attribute arrays.
|
|
|
|
if (getVertexIndices() && getVertexArray())
|
|
|
|
{
|
|
|
|
ExpandIndexedArray eia(*(getVertexIndices()),target.getVertexArray());
|
|
|
|
getVertexArray()->accept(eia);
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
target.setVertexArray(eia._targetArray);
|
|
|
|
target.setVertexIndices(0);
|
|
|
|
}
|
|
|
|
else if (getVertexArray())
|
|
|
|
{
|
|
|
|
if (!copyToSelf) target.setVertexArray(getVertexArray());
|
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
target.setNormalBinding(getNormalBinding());
|
|
|
|
if (getNormalIndices() && getNormalArray())
|
|
|
|
{
|
|
|
|
ExpandIndexedArray eia(*(getNormalIndices()),target.getNormalArray());
|
|
|
|
getNormalArray()->accept(eia);
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
target.setNormalArray(dynamic_cast<osg::Vec3Array*>(eia._targetArray));
|
|
|
|
target.setNormalIndices(0);
|
|
|
|
}
|
|
|
|
else if (getNormalArray())
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
if (!copyToSelf) target.setNormalArray(getNormalArray());
|
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
target.setColorBinding(getColorBinding());
|
|
|
|
if (getColorIndices() && getColorArray())
|
|
|
|
{
|
|
|
|
ExpandIndexedArray eia(*(getColorIndices()),target.getColorArray());
|
|
|
|
getColorArray()->accept(eia);
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
target.setColorArray(eia._targetArray);
|
|
|
|
target.setColorIndices(0);
|
|
|
|
}
|
|
|
|
else if (getColorArray())
|
|
|
|
{
|
|
|
|
if (!copyToSelf) target.setColorArray(getColorArray());
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
target.setSecondaryColorBinding(getSecondaryColorBinding());
|
|
|
|
if (getSecondaryColorIndices() && getSecondaryColorArray())
|
|
|
|
{
|
|
|
|
ExpandIndexedArray eia(*(getSecondaryColorIndices()),target.getSecondaryColorArray());
|
|
|
|
getSecondaryColorArray()->accept(eia);
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
target.setSecondaryColorArray(eia._targetArray);
|
|
|
|
target.setSecondaryColorIndices(0);
|
|
|
|
}
|
|
|
|
else if (getSecondaryColorArray())
|
|
|
|
{
|
|
|
|
if (!copyToSelf) target.setSecondaryColorArray(getSecondaryColorArray());
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
target.setFogCoordBinding(getFogCoordBinding());
|
|
|
|
if (getFogCoordIndices() && getFogCoordArray())
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
ExpandIndexedArray eia(*(getFogCoordIndices()),target.getFogCoordArray());
|
|
|
|
getFogCoordArray()->accept(eia);
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
target.setFogCoordArray(eia._targetArray);
|
|
|
|
target.setFogCoordIndices(0);
|
|
|
|
}
|
|
|
|
else if (getFogCoordArray())
|
|
|
|
{
|
|
|
|
if (!copyToSelf) target.setFogCoordArray(getFogCoordArray());
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(unsigned int ti=0;ti<getNumTexCoordArrays();++ti)
|
|
|
|
{
|
|
|
|
if (getTexCoordIndices(ti) && getTexCoordArray(ti))
|
2003-09-24 23:54:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
ExpandIndexedArray eia(*(getTexCoordIndices(ti)),target.getTexCoordArray(ti));
|
|
|
|
|
|
|
|
getTexCoordArray(ti)->accept(eia);
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
target.setTexCoordArray(ti,eia._targetArray);
|
|
|
|
target.setTexCoordIndices(ti,0);
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
else if (getTexCoordArray(ti))
|
2003-09-24 23:54:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
if (!copyToSelf) target.setTexCoordArray(ti,getTexCoordArray(ti));
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for(unsigned int vi=0;vi<_vertexAttribList.size();++vi)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
ArrayData& arrayData = _vertexAttribList[vi];
|
|
|
|
if (arrayData.indices.valid())
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
ExpandIndexedArray eia(*arrayData.indices,target.getVertexAttribArray(vi));
|
|
|
|
arrayData.array->accept(eia);
|
|
|
|
target.setVertexAttribData(vi,ArrayData(eia._targetArray, 0, arrayData.binding, arrayData.normalize));
|
2003-09-01 06:08:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
else if (arrayData.array.valid())
|
2003-09-24 23:54:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
if (!copyToSelf) target.setVertexAttribData(vi,arrayData);
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
}
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
bool Geometry::containsSharedArrays() const
|
|
|
|
{
|
|
|
|
unsigned int numSharedArrays = 0;
|
|
|
|
|
|
|
|
if (getVertexArray() && getVertexArray()->referenceCount()>1) ++numSharedArrays;
|
|
|
|
if (getNormalArray() && getNormalArray()->referenceCount()>1) ++numSharedArrays;
|
|
|
|
if (getColorArray() && getColorArray()->referenceCount()>1) ++numSharedArrays;
|
|
|
|
if (getSecondaryColorArray() && getSecondaryColorArray()->referenceCount()>1) ++numSharedArrays;
|
|
|
|
if (getFogCoordArray() && getFogCoordArray()->referenceCount()>1) ++numSharedArrays;
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(unsigned int ti=0;ti<getNumTexCoordArrays();++ti)
|
2003-09-01 06:08:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
if (getTexCoordArray(ti) && getTexCoordArray(ti)->referenceCount()>1) ++numSharedArrays;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(unsigned int vi=0;vi<_vertexAttribList.size();++vi)
|
|
|
|
{
|
|
|
|
const ArrayData& arrayData = _vertexAttribList[vi];
|
|
|
|
if (arrayData.array.valid() && arrayData.array->referenceCount()>1) ++numSharedArrays;
|
|
|
|
}
|
|
|
|
return numSharedArrays!=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Geometry::duplicateSharedArrays()
|
|
|
|
{
|
|
|
|
#define DUPLICATE_IF_REQUIRED(A) \
|
|
|
|
if (get##A() && get##A()->referenceCount()>1) \
|
|
|
|
{ \
|
|
|
|
set##A(dynamic_cast<osg::Array*>(get##A()->clone(osg::CopyOp::DEEP_COPY_ARRAYS))); \
|
2003-09-01 06:08:22 +08:00
|
|
|
}
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
DUPLICATE_IF_REQUIRED(VertexArray)
|
|
|
|
DUPLICATE_IF_REQUIRED(NormalArray)
|
|
|
|
DUPLICATE_IF_REQUIRED(ColorArray)
|
|
|
|
DUPLICATE_IF_REQUIRED(SecondaryColorArray)
|
|
|
|
DUPLICATE_IF_REQUIRED(FogCoordArray)
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
for(unsigned int ti=0;ti<getNumTexCoordArrays();++ti)
|
|
|
|
{
|
|
|
|
if (getTexCoordArray(ti) && getTexCoordArray(ti)->referenceCount()>1)
|
2003-09-24 23:54:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
setTexCoordArray(ti, dynamic_cast<osg::Array*>(getTexCoordArray(ti)->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for(unsigned int vi=0;vi<_vertexAttribList.size();++vi)
|
|
|
|
{
|
|
|
|
ArrayData& arrayData = _vertexAttribList[vi];
|
|
|
|
if (arrayData.array.valid() && arrayData.array->referenceCount()>1)
|
2003-09-24 23:54:22 +08:00
|
|
|
{
|
2009-10-22 18:29:43 +08:00
|
|
|
arrayData.array = dynamic_cast<osg::Array*>(arrayData.array->clone(osg::CopyOp::DEEP_COPY_ARRAYS));
|
2003-09-24 23:54:22 +08:00
|
|
|
}
|
2009-10-22 18:29:43 +08:00
|
|
|
}
|
|
|
|
}
|
2003-09-24 23:54:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
void Geometry::computeInternalOptimizedGeometry()
|
|
|
|
{
|
|
|
|
if (suitableForOptimization())
|
|
|
|
{
|
|
|
|
if (!_internalOptimizedGeometry) _internalOptimizedGeometry = new Geometry;
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
copyToAndOptimize(*_internalOptimizedGeometry);
|
|
|
|
}
|
|
|
|
}
|
2003-09-01 06:08:22 +08:00
|
|
|
|
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
Geometry* osg::createTexturedQuadGeometry(const Vec3& corner,const Vec3& widthVec,const Vec3& heightVec, float l, float b, float r, float t)
|
|
|
|
{
|
|
|
|
Geometry* geom = new Geometry;
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
Vec3Array* coords = new Vec3Array(4);
|
|
|
|
(*coords)[0] = corner+heightVec;
|
|
|
|
(*coords)[1] = corner;
|
|
|
|
(*coords)[2] = corner+widthVec;
|
|
|
|
(*coords)[3] = corner+widthVec+heightVec;
|
|
|
|
geom->setVertexArray(coords);
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
Vec2Array* tcoords = new Vec2Array(4);
|
|
|
|
(*tcoords)[0].set(l,t);
|
|
|
|
(*tcoords)[1].set(l,b);
|
|
|
|
(*tcoords)[2].set(r,b);
|
|
|
|
(*tcoords)[3].set(r,t);
|
|
|
|
geom->setTexCoordArray(0,tcoords);
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
osg::Vec4Array* colours = new osg::Vec4Array(1);
|
|
|
|
(*colours)[0].set(1.0f,1.0f,1.0,1.0f);
|
|
|
|
geom->setColorArray(colours);
|
|
|
|
geom->setColorBinding(Geometry::BIND_OVERALL);
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
osg::Vec3Array* normals = new osg::Vec3Array(1);
|
|
|
|
(*normals)[0] = widthVec^heightVec;
|
|
|
|
(*normals)[0].normalize();
|
|
|
|
geom->setNormalArray(normals);
|
|
|
|
geom->setNormalBinding(Geometry::BIND_OVERALL);
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
geom->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS,0,4));
|
2003-09-01 06:08:22 +08:00
|
|
|
|
2009-10-22 18:29:43 +08:00
|
|
|
return geom;
|
|
|
|
}
|