Removed redundent TerrainGeometry classes, and adding double buffer of

internal data within GeometryTechinque in prep for support multi-threaded
set up and rendering of terrain.
This commit is contained in:
Robert Osfield
2007-07-12 20:12:38 +00:00
parent 92ffe6f74a
commit 03749d5e34
4 changed files with 59 additions and 372 deletions

View File

@@ -22,72 +22,6 @@
namespace osgTerrain {
class OSGTERRAIN_EXPORT TerrainGeometry : public osg::Drawable
{
public:
TerrainGeometry();
/** Copy constructor using CopyOp to manage deep vs shallow copy. */
TerrainGeometry(const TerrainGeometry& geometry,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
virtual osg::Object* cloneType() const { return new TerrainGeometry(); }
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new TerrainGeometry(*this,copyop); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const TerrainGeometry*>(obj)!=NULL; }
virtual const char* libraryName() const { return "osgTerrain"; }
virtual const char* className() const { return "TerrainGeometry"; }
void setVertices(osg::Vec3Array* vertices) { _vertices.first = vertices; }
osg::Vec3Array* getVertices() { return _vertices.first.get(); }
const osg::Vec3Array* getVertices() const { return _vertices.first.get(); }
void setNormals(osg::Vec3Array* normals) { _normals.first = normals; }
osg::Vec3Array* getNormals() { return _normals.first.get(); }
const osg::Vec3Array* getNormals() const { return _normals.first.get(); }
void setColors(osg::Vec4Array* colors) { _colors.first = colors; }
osg::Vec4Array* getColors() { return _colors.first.get(); }
const osg::Vec4Array* getColors() const { return _colors.first.get(); }
void setTexCoords(unsigned int unit, osg::Array* array) { _texcoords.resize(unit+1); _texcoords[unit].first = array; }
osg::Array* getTexCoords(unsigned int unit) { return _texcoords[unit].first.get(); }
const osg::Array* getTexCoords(unsigned int unit) const { return _texcoords[unit].first.get(); }
void addPrimitiveSet(osg::PrimitiveSet* primitiveSet) { _primitiveSets.push_back(primitiveSet); }
osg::PrimitiveSet* getPrimitiveSet(unsigned int i) { return _primitiveSets[i].get(); }
const osg::PrimitiveSet* getPrimitiveSet(unsigned int i) const { return _primitiveSets[i].get(); }
unsigned int getNumPrimitiveSets() const { return _primitiveSets.size(); }
virtual osg::BoundingBox computeBound() const;
/** Draw Geometry directly ignoring an OpenGL display list which could be attached.
* This is the internal draw method which does the drawing itself,
* and is the method to override when deriving from Geometry for user-drawn objects.
*/
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
protected:
typedef osg::Geometry::PrimitiveSetList PrimitiveSetList;
typedef std::pair< osg::ref_ptr<osg::Array>, GLvoid*> ArrayData;
typedef std::pair< osg::ref_ptr<osg::FloatArray>, GLvoid*> FloatArrayData;
typedef std::pair< osg::ref_ptr<osg::Vec2Array>, GLvoid*> Vec2ArrayData;
typedef std::pair< osg::ref_ptr<osg::Vec3Array>, GLvoid*> Vec3ArrayData;
typedef std::pair< osg::ref_ptr<osg::Vec4Array>, GLvoid*> Vec4ArrayData;
typedef std::vector< ArrayData > TexCoordsList;
Vec3ArrayData _vertices;
Vec3ArrayData _normals;
Vec4ArrayData _colors;
TexCoordsList _texcoords;
PrimitiveSetList _primitiveSets;
};
class OSGTERRAIN_EXPORT GeometryTechnique : public TerrainTechnique
{
public:
@@ -129,16 +63,28 @@ class OSGTERRAIN_EXPORT GeometryTechnique : public TerrainTechnique
void setFilterMatrixAs(FilterType filterType);
protected:
private:
virtual ~GeometryTechnique();
osg::ref_ptr<osg::MatrixTransform> _transform;
osg::ref_ptr<osg::Geode> _geode;
struct BufferData
{
osg::ref_ptr<osg::MatrixTransform> _transform;
osg::ref_ptr<osg::Geode> _geode;
osg::ref_ptr<osg::Geometry> _geometry;
};
osg::ref_ptr<TerrainGeometry> _terrainGeometry;
osg::ref_ptr<osg::Geometry> _geometry;
unsigned int _currentReadOnlyBuffer;
unsigned int _currentWriteBuffer;
BufferData _bufferData[2];
void swapBuffers();
inline BufferData& getReadOnlyBuffer() { return _bufferData[_currentReadOnlyBuffer]; }
inline BufferData& getWriteBuffer() { return _bufferData[_currentWriteBuffer]; }
float _filterBias;
osg::ref_ptr<osg::Uniform> _filterBiasUniform;
float _filterWidth;

View File

@@ -27,7 +27,10 @@
using namespace osgTerrain;
GeometryTechnique::GeometryTechnique()
GeometryTechnique::GeometryTechnique():
_currentReadOnlyBuffer(1),
_currentWriteBuffer(0)
{
setFilterBias(0);
setFilterWidth(0.1);
@@ -43,6 +46,11 @@ GeometryTechnique::~GeometryTechnique()
{
}
void GeometryTechnique::swapBuffers()
{
std::swap(_currentReadOnlyBuffer,_currentWriteBuffer);
}
void GeometryTechnique::setFilterBias(float filterBias)
{
_filterBias = filterBias;
@@ -95,6 +103,8 @@ void GeometryTechnique::init()
if (!_terrainNode) return;
BufferData& buffer = getWriteBuffer();
osgTerrain::Layer* elevationLayer = _terrainNode->getElevationLayer();
osgTerrain::Layer* colorLayer = _terrainNode->getColorLayer(0);
osg::TransferFunction* colorTF = _terrainNode->getColorTransferFunction(0);
@@ -158,23 +168,19 @@ void GeometryTechnique::init()
osg::notify(osg::NOTICE)<<"topRightNDC = "<<topRightNDC<<std::endl;
_geode = new osg::Geode;
buffer._geode = new osg::Geode;
_transform = new osg::MatrixTransform;
_transform->addChild(_geode.get());
buffer._transform = new osg::MatrixTransform;
buffer._transform->addChild(buffer._geode.get());
osg::Vec3d centerNDC = (bottomLeftNDC + topRightNDC)*0.5;
osg::Vec3d centerModel = (bottomLeftNDC + topRightNDC)*0.5;
masterLocator->convertLocalToModel(centerNDC, centerModel);
_transform->setMatrix(osg::Matrix::translate(centerModel));
buffer._transform->setMatrix(osg::Matrix::translate(centerModel));
_terrainGeometry = 0; // new osgTerrain::TerrainGeometry;
if (_terrainGeometry.valid()) _geode->addDrawable(_terrainGeometry.get());
_geometry = new osg::Geometry;
if (_geometry.valid()) _geode->addDrawable(_geometry.get());
buffer._geometry = new osg::Geometry;
if (buffer._geometry.valid()) buffer._geode->addDrawable(buffer._geometry.get());
unsigned int numRows = 100;
@@ -193,16 +199,14 @@ void GeometryTechnique::init()
// allocate and assign vertices
osg::Vec3Array* _vertices = new osg::Vec3Array;
if (_terrainGeometry.valid()) _terrainGeometry->setVertices(_vertices);
if (_geometry.valid()) _geometry->setVertexArray(_vertices);
if (buffer._geometry.valid()) buffer._geometry->setVertexArray(_vertices);
// allocate and assign normals
osg::Vec3Array* _normals = new osg::Vec3Array;
if (_terrainGeometry.valid()) _terrainGeometry->setNormals(_normals);
if (_geometry.valid())
if (buffer._geometry.valid())
{
_geometry->setNormalArray(_normals);
_geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
buffer._geometry->setNormalArray(_normals);
buffer._geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
}
int texcoord_index = 0;
@@ -221,9 +225,7 @@ void GeometryTechnique::init()
_texcoords = new osg::Vec2Array;
if (_terrainGeometry.valid()) _terrainGeometry->setTexCoords(color_index, _texcoords);
if (_geometry.valid()) _geometry->setTexCoordArray(color_index, _texcoords);
if (buffer._geometry.valid()) buffer._geometry->setTexCoordArray(color_index, _texcoords);
}
osg::FloatArray* _elevations = new osg::FloatArray;
@@ -236,8 +238,7 @@ void GeometryTechnique::init()
if (!colorLayer)
{
// _elevations = new osg::FloatArray(numVertices);
if (_terrainGeometry.valid()) _terrainGeometry->setTexCoords(tf_index, _elevations);
if (_geometry.valid()) _geometry->setTexCoordArray(tf_index, _elevations);
if (buffer._geometry.valid()) buffer._geometry->setTexCoordArray(tf_index, _elevations);
minHeight = tf->getMinimum();
scaleHeight = 1.0f/(tf->getMaximum()-tf->getMinimum());
@@ -253,11 +254,10 @@ void GeometryTechnique::init()
osg::Vec4Array* _colors = new osg::Vec4Array(1);
(*_colors)[0].set(1.0f,1.0f,1.0f,1.0f);
if (_terrainGeometry.valid()) _terrainGeometry->setColors(_colors);
if (_geometry.valid())
if (buffer._geometry.valid())
{
_geometry->setColorArray(_colors);
_geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
buffer._geometry->setColorArray(_colors);
buffer._geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
}
@@ -336,8 +336,7 @@ void GeometryTechnique::init()
osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLES);
elements->reserve((numRows-1) * (numColumns-1) * 6);
if (_terrainGeometry.valid()) _terrainGeometry->addPrimitiveSet(elements);
if (_geometry.valid()) _geometry->addPrimitiveSet(elements);
if (buffer._geometry.valid()) buffer._geometry->addPrimitiveSet(elements);
for(j=0; j<numRows-1; ++j)
{
@@ -419,7 +418,7 @@ void GeometryTechnique::init()
if (imageLayer)
{
osg::Image* image = imageLayer->getImage();
osg::StateSet* stateset = _geode->getOrCreateStateSet();
osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
osg::Texture2D* texture2D = new osg::Texture2D;
texture2D->setImage(image);
@@ -448,7 +447,7 @@ void GeometryTechnique::init()
{
osg::notify(osg::NOTICE)<<"Requires TransferFunction"<<std::endl;
osg::Image* image = tf->getImage();
osg::StateSet* stateset = _geode->getOrCreateStateSet();
osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
osg::Texture1D* texture1D = new osg::Texture1D;
texture1D->setImage(image);
texture1D->setResizeNonPowerOfTwoHint(false);
@@ -513,21 +512,23 @@ void GeometryTechnique::init()
if (containsTransparency)
{
osg::StateSet* stateset = _geode->getOrCreateStateSet();
osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
}
// if (_terrainGeometry.valid()) _terrainGeometry->setUseDisplayList(false);
if (_geometry.valid()) _geometry->setUseVertexBufferObjects(true);
if (buffer._geometry.valid()) buffer._geometry->setUseVertexBufferObjects(true);
if (_geometry.valid())
if (buffer._geometry.valid())
{
osgUtil::SmoothingVisitor smoother;
smoother.smooth(*_geometry);
smoother.smooth(*buffer._geometry);
}
_dirty = false;
swapBuffers();
}
@@ -539,12 +540,14 @@ void GeometryTechnique::update(osgUtil::UpdateVisitor* uv)
void GeometryTechnique::cull(osgUtil::CullVisitor* cv)
{
BufferData& buffer = getReadOnlyBuffer();
#if 0
if (_terrainNode) _terrainNode->osg::Group::traverse(*cv);
if (buffer._terrainNode) buffer._terrainNode->osg::Group::traverse(*cv);
#else
if (_transform.valid())
if (buffer._transform.valid())
{
_transform->accept(*cv);
buffer._transform->accept(*cv);
}
#endif
}
@@ -558,115 +561,3 @@ void GeometryTechnique::dirty()
TerrainTechnique::dirty();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TerrainGeometry
//
TerrainGeometry::TerrainGeometry()
{
}
TerrainGeometry::TerrainGeometry(const TerrainGeometry& geometry,const osg::CopyOp& copyop):
osg::Drawable(geometry, copyop),
_vertices(geometry._vertices),
_normals(geometry._normals),
_colors(geometry._colors),
_texcoords(geometry._texcoords),
_primitiveSets(geometry._primitiveSets)
{
}
osg::BoundingBox TerrainGeometry::computeBound() const
{
osg::BoundingBox bb;
if (_vertices.first.valid())
{
for(osg::Vec3Array::const_iterator itr = _vertices.first->begin();
itr != _vertices.first->end();
++itr)
{
bb.expandBy(*itr);
}
}
return bb;
}
void TerrainGeometry::drawImplementation(osg::RenderInfo& renderInfo) const
{
#if 0
osg::notify(osg::NOTICE)<<"TerrainGeometry::drawImplementation"<<std::endl;
if (_vertices.first.valid() && _vertices.first->getDataVariance()==DYNAMIC)
{
osg::notify(osg::NOTICE)<<" Vertices DYNAMIC"<<std::endl;
}
else
{
osg::notify(osg::NOTICE)<<" Vertices STATIC"<<std::endl;
}
#endif
osg::State& state = *renderInfo.getState();
const osg::Geometry::Extensions* extensions = osg::Geometry::getExtensions(state.getContextID(),true);
//
// Non Vertex Buffer Object path for defining vertex arrays.
//
if( _vertices.first.valid() )
state.setVertexPointer(_vertices.first->getDataSize(), _vertices.first->getDataType(), 0, _vertices.first->getDataPointer());
else
state.disableVertexPointer();
if (_normals.first.valid())
{
state.setNormalPointer(_normals.first->getDataType(),0,_normals.first->getDataPointer());
}
else
{
state.disableNormalPointer();
glNormal3f(0.0f,0.0f,1.0f);
}
if (_colors.first.valid() && _colors.first->getNumElements()==_vertices.first->getNumElements())
{
state.setColorPointer(_colors.first->getDataSize(),_colors.first->getDataType(),0,_colors.first->getDataPointer());
}
else
{
state.disableColorPointer();
if (_colors.first.valid() && _colors.first->getNumElements()>=1)
{
glColor4fv(static_cast<const GLfloat*>(_colors.first->getDataPointer()));
}
else
{
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
}
unsigned int unit;
for(unit=0;unit<_texcoords.size();++unit)
{
const osg::Array* array = _texcoords[unit].first.get();
if (array)
state.setTexCoordPointer(unit,array->getDataSize(),array->getDataType(),0,array->getDataPointer());
else
state.disableTexCoordPointer(unit);
}
state.disableTexCoordPointersAboveAndIncluding(unit);
bool usingVertexBufferObjects = false;
for(PrimitiveSetList::const_iterator itr = _primitiveSets.begin();
itr != _primitiveSets.end();
++itr)
{
(*itr)->draw(state, usingVertexBufferObjects);
}
}

View File

@@ -236,5 +236,7 @@ BEGIN_OBJECT_REFLECTOR(osg::RefBlock)
"");
END_REFLECTOR
TYPE_NAME_ALIAS(osg::OperationThread, osg::OperationsThread)
STD_SET_REFLECTOR(std::set< osg::OperationThread * >)

View File

@@ -10,12 +10,7 @@
#include <osgIntrospection/StaticMethodInfo>
#include <osgIntrospection/Attributes>
#include <osg/Array>
#include <osg/BoundingBox>
#include <osg/CopyOp>
#include <osg/Object>
#include <osg/PrimitiveSet>
#include <osg/RenderInfo>
#include <osg/Uniform>
#include <osgTerrain/GeometryTechnique>
#include <osgUtil/CullVisitor>
@@ -125,150 +120,3 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::GeometryTechnique)
__void__setFilterWidth__float);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgTerrain::TerrainGeometry)
I_DeclaringFile("osgTerrain/GeometryTechnique");
I_BaseType(osg::Drawable);
I_Constructor0(____TerrainGeometry,
"",
"");
I_ConstructorWithDefaults2(IN, const osgTerrain::TerrainGeometry &, geometry, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY,
____TerrainGeometry__C5_TerrainGeometry_R1__C5_osg_CopyOp_R1,
"Copy constructor using CopyOp to manage deep vs shallow copy. ",
"");
I_Method0(osg::Object *, cloneType,
Properties::VIRTUAL,
__osg_Object_P1__cloneType,
"Clone the type of an object, with Object* return type. ",
"Must be defined by derived classes. ");
I_Method1(osg::Object *, clone, IN, const osg::CopyOp &, copyop,
Properties::VIRTUAL,
__osg_Object_P1__clone__C5_osg_CopyOp_R1,
"Clone an object, with Object* return type. ",
"Must be defined by derived classes. ");
I_Method1(bool, isSameKindAs, IN, const osg::Object *, obj,
Properties::VIRTUAL,
__bool__isSameKindAs__C5_osg_Object_P1,
"",
"");
I_Method0(const char *, libraryName,
Properties::VIRTUAL,
__C5_char_P1__libraryName,
"return the name of the object's library. ",
"Must be defined by derived classes. The OpenSceneGraph convention is that the namespace of a library is the same as the library name. ");
I_Method0(const char *, className,
Properties::VIRTUAL,
__C5_char_P1__className,
"return the name of the object's class type. ",
"Must be defined by derived classes. ");
I_Method1(void, setVertices, IN, osg::Vec3Array *, vertices,
Properties::NON_VIRTUAL,
__void__setVertices__osg_Vec3Array_P1,
"",
"");
I_Method0(osg::Vec3Array *, getVertices,
Properties::NON_VIRTUAL,
__osg_Vec3Array_P1__getVertices,
"",
"");
I_Method0(const osg::Vec3Array *, getVertices,
Properties::NON_VIRTUAL,
__C5_osg_Vec3Array_P1__getVertices,
"",
"");
I_Method1(void, setNormals, IN, osg::Vec3Array *, normals,
Properties::NON_VIRTUAL,
__void__setNormals__osg_Vec3Array_P1,
"",
"");
I_Method0(osg::Vec3Array *, getNormals,
Properties::NON_VIRTUAL,
__osg_Vec3Array_P1__getNormals,
"",
"");
I_Method0(const osg::Vec3Array *, getNormals,
Properties::NON_VIRTUAL,
__C5_osg_Vec3Array_P1__getNormals,
"",
"");
I_Method1(void, setColors, IN, osg::Vec4Array *, colors,
Properties::NON_VIRTUAL,
__void__setColors__osg_Vec4Array_P1,
"",
"");
I_Method0(osg::Vec4Array *, getColors,
Properties::NON_VIRTUAL,
__osg_Vec4Array_P1__getColors,
"",
"");
I_Method0(const osg::Vec4Array *, getColors,
Properties::NON_VIRTUAL,
__C5_osg_Vec4Array_P1__getColors,
"",
"");
I_Method2(void, setTexCoords, IN, unsigned int, unit, IN, osg::Array *, array,
Properties::NON_VIRTUAL,
__void__setTexCoords__unsigned_int__osg_Array_P1,
"",
"");
I_Method1(osg::Array *, getTexCoords, IN, unsigned int, unit,
Properties::NON_VIRTUAL,
__osg_Array_P1__getTexCoords__unsigned_int,
"",
"");
I_Method1(const osg::Array *, getTexCoords, IN, unsigned int, unit,
Properties::NON_VIRTUAL,
__C5_osg_Array_P1__getTexCoords__unsigned_int,
"",
"");
I_Method1(void, addPrimitiveSet, IN, osg::PrimitiveSet *, primitiveSet,
Properties::NON_VIRTUAL,
__void__addPrimitiveSet__osg_PrimitiveSet_P1,
"",
"");
I_Method1(osg::PrimitiveSet *, getPrimitiveSet, IN, unsigned int, i,
Properties::NON_VIRTUAL,
__osg_PrimitiveSet_P1__getPrimitiveSet__unsigned_int,
"",
"");
I_Method1(const osg::PrimitiveSet *, getPrimitiveSet, IN, unsigned int, i,
Properties::NON_VIRTUAL,
__C5_osg_PrimitiveSet_P1__getPrimitiveSet__unsigned_int,
"",
"");
I_Method0(unsigned int, getNumPrimitiveSets,
Properties::NON_VIRTUAL,
__unsigned_int__getNumPrimitiveSets,
"",
"");
I_Method0(osg::BoundingBox, computeBound,
Properties::VIRTUAL,
__osg_BoundingBox__computeBound,
"Compute the bounding box around Drawables's geometry. ",
"");
I_Method1(void, drawImplementation, IN, osg::RenderInfo &, renderInfo,
Properties::VIRTUAL,
__void__drawImplementation__osg_RenderInfo_R1,
"Draw Geometry directly ignoring an OpenGL display list which could be attached. ",
"This is the internal draw method which does the drawing itself, and is the method to override when deriving from Geometry for user-drawn objects.");
I_SimpleProperty(osg::Vec4Array *, Colors,
__osg_Vec4Array_P1__getColors,
__void__setColors__osg_Vec4Array_P1);
I_SimpleProperty(osg::Vec3Array *, Normals,
__osg_Vec3Array_P1__getNormals,
__void__setNormals__osg_Vec3Array_P1);
I_ArrayProperty(osg::PrimitiveSet *, PrimitiveSet,
__osg_PrimitiveSet_P1__getPrimitiveSet__unsigned_int,
0,
__unsigned_int__getNumPrimitiveSets,
__void__addPrimitiveSet__osg_PrimitiveSet_P1,
0,
0);
I_IndexedProperty(osg::Array *, TexCoords,
__osg_Array_P1__getTexCoords__unsigned_int,
__void__setTexCoords__unsigned_int__osg_Array_P1,
0);
I_SimpleProperty(osg::Vec3Array *, Vertices,
__osg_Vec3Array_P1__getVertices,
__void__setVertices__osg_Vec3Array_P1);
END_REFLECTOR