Added support for primitive instancing
This commit is contained in:
@@ -35,9 +35,10 @@ unsigned int PrimitiveSet::getNumPrimitives() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DrawArrays::draw(State&, bool) const
|
||||
void DrawArrays::draw(State& state, bool) const
|
||||
{
|
||||
glDrawArrays(_mode,_first,_count);
|
||||
if (_numInstances>=1) state.glDrawArraysInstanced(_mode,_first,_count, _numInstances);
|
||||
else glDrawArrays(_mode,_first,_count);
|
||||
}
|
||||
|
||||
void DrawArrays::accept(PrimitiveFunctor& functor) const
|
||||
@@ -129,16 +130,19 @@ void DrawElementsUByte::draw(State& state, bool useVertexBufferObjects) const
|
||||
state.bindElementBufferObject(ebo);
|
||||
if (ebo)
|
||||
{
|
||||
glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, getElementBufferObjectOffset());
|
||||
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, getElementBufferObjectOffset(), _numInstances);
|
||||
else glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, getElementBufferObjectOffset());
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, &front());
|
||||
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
|
||||
else glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, &front());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, &front());
|
||||
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
|
||||
else glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, &front());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,16 +180,19 @@ void DrawElementsUShort::draw(State& state, bool useVertexBufferObjects) const
|
||||
state.bindElementBufferObject(ebo);
|
||||
if (ebo)
|
||||
{
|
||||
glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, getElementBufferObjectOffset());
|
||||
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, getElementBufferObjectOffset(), _numInstances);
|
||||
else glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, getElementBufferObjectOffset());
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, &front());
|
||||
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
|
||||
else glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, &front());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, &front());
|
||||
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
|
||||
else glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, &front());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,16 +230,19 @@ void DrawElementsUInt::draw(State& state, bool useVertexBufferObjects) const
|
||||
state.bindElementBufferObject(ebo);
|
||||
if (ebo)
|
||||
{
|
||||
glDrawElements(_mode, size(), GL_UNSIGNED_INT, getElementBufferObjectOffset());
|
||||
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, getElementBufferObjectOffset(), _numInstances);
|
||||
else glDrawElements(_mode, size(), GL_UNSIGNED_INT, getElementBufferObjectOffset());
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements(_mode, size(), GL_UNSIGNED_INT, &front());
|
||||
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
|
||||
else glDrawElements(_mode, size(), GL_UNSIGNED_INT, &front());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements(_mode, size(), GL_UNSIGNED_INT, &front());
|
||||
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
|
||||
else glDrawElements(_mode, size(), GL_UNSIGNED_INT, &front());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,8 @@ State::State():
|
||||
_glVertexAttribPointer = 0;
|
||||
_glEnableVertexAttribArray = 0;
|
||||
_glDisableVertexAttribArray = 0;
|
||||
_glDrawArraysInstanced = 0;
|
||||
_glDrawElementsInstanced = 0;
|
||||
|
||||
_dynamicObjectCount = 0;
|
||||
|
||||
@@ -754,6 +756,9 @@ void State::initializeExtensionProcs()
|
||||
setGLExtensionFuncPtr(_glDisableVertexAttribArray, "glDisableVertexAttribArray","glDisableVertexAttribArrayARB");
|
||||
setGLExtensionFuncPtr(_glBindBuffer, "glBindBuffer","glBindBufferARB");
|
||||
|
||||
setGLExtensionFuncPtr(_glDrawArraysInstanced, "glDrawArraysInstanced","glDrawArraysInstancedEXT");
|
||||
setGLExtensionFuncPtr(_glDrawElementsInstanced, "glDrawElementsInstanced","glDrawElementsInstancedEXT");
|
||||
|
||||
if ( osg::getGLVersionNumber() >= 2.0 || osg::isGLExtensionSupported(_contextID,"GL_ARB_vertex_shader") )
|
||||
{
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,&_glMaxTextureUnits);
|
||||
|
||||
@@ -46,8 +46,9 @@
|
||||
#define VERSION_0035 35
|
||||
#define VERSION_0036 36
|
||||
#define VERSION_0037 37
|
||||
#define VERSION_0038 38
|
||||
|
||||
#define VERSION VERSION_0037
|
||||
#define VERSION VERSION_0038
|
||||
|
||||
/* The BYTE_SEX tag is used to check the endian
|
||||
of the IVE file being read in. The IVE format
|
||||
|
||||
@@ -30,6 +30,11 @@ void PrimitiveSet::write(DataOutputStream* out){
|
||||
throw Exception("PrimitiveSet::write(): Could not cast this osg::PrimitiveSet to an osg::Object.");
|
||||
|
||||
|
||||
if ( out->getVersion() >= VERSION_0038 )
|
||||
{
|
||||
out->writeInt(getNumInstances());
|
||||
}
|
||||
|
||||
// Write PrimitiveSet's properties.
|
||||
out->writeInt(getMode());
|
||||
}
|
||||
@@ -49,6 +54,11 @@ void PrimitiveSet::read(DataInputStream* in){
|
||||
throw Exception("PrimitiveSet::read(): Could not cast this osg::PrimitiveSet to an osg::Object.");
|
||||
|
||||
|
||||
if ( in->getVersion() >= VERSION_0038 )
|
||||
{
|
||||
setNumInstances(in->readInt());
|
||||
}
|
||||
|
||||
// Read in primitiveset properties.
|
||||
setMode(in->readInt());
|
||||
}
|
||||
|
||||
@@ -1003,7 +1003,9 @@ bool Array_writeLocalData(const Array& array,Output& fw)
|
||||
bool Primitive_readLocalData(Input& fr,osg::Geometry& geom)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
if (fr.matchSequence("DrawArrays %w %i %i"))
|
||||
bool firstMatched = false;
|
||||
if ((firstMatched = fr.matchSequence("DrawArrays %w %i %i %i")) ||
|
||||
fr.matchSequence("DrawArrays %w %i %i") )
|
||||
{
|
||||
|
||||
GLenum mode;
|
||||
@@ -1015,14 +1017,25 @@ bool Primitive_readLocalData(Input& fr,osg::Geometry& geom)
|
||||
int count;
|
||||
fr[3].getInt(count);
|
||||
|
||||
geom.addPrimitiveSet(new DrawArrays(mode,first,count));
|
||||
int numInstances = 0;
|
||||
if (firstMatched)
|
||||
{
|
||||
fr[4].getInt(numInstances);
|
||||
fr += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
fr += 4;
|
||||
}
|
||||
|
||||
geom.addPrimitiveSet(new DrawArrays(mode, first, count, numInstances));
|
||||
|
||||
fr += 4;
|
||||
|
||||
iteratorAdvanced = true;
|
||||
|
||||
}
|
||||
else if (fr.matchSequence("DrawArrayLengths %w %i %i {"))
|
||||
else if ((firstMatched = fr.matchSequence("DrawArrayLengths %w %i %i %i {")) ||
|
||||
fr.matchSequence("DrawArrayLengths %w %i %i {") )
|
||||
{
|
||||
int entry = fr[1].getNoNestedBrackets();
|
||||
|
||||
@@ -1035,10 +1048,20 @@ bool Primitive_readLocalData(Input& fr,osg::Geometry& geom)
|
||||
int capacity;
|
||||
fr[3].getInt(capacity);
|
||||
|
||||
fr += 5;
|
||||
|
||||
int numInstances = 0;
|
||||
if (firstMatched)
|
||||
{
|
||||
fr[4].getInt(numInstances);
|
||||
fr += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
fr += 5;
|
||||
}
|
||||
|
||||
DrawArrayLengths* prim = new DrawArrayLengths;
|
||||
prim->setMode(mode);
|
||||
prim->setNumInstances(numInstances);
|
||||
prim->setFirst(first);
|
||||
prim->reserve(capacity);
|
||||
|
||||
@@ -1057,7 +1080,8 @@ bool Primitive_readLocalData(Input& fr,osg::Geometry& geom)
|
||||
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr.matchSequence("DrawElementsUByte %w %i {"))
|
||||
else if ((firstMatched = fr.matchSequence("DrawElementsUByte %w %i %i {")) ||
|
||||
fr.matchSequence("DrawElementsUByte %w %i {"))
|
||||
{
|
||||
int entry = fr[1].getNoNestedBrackets();
|
||||
|
||||
@@ -1067,10 +1091,20 @@ bool Primitive_readLocalData(Input& fr,osg::Geometry& geom)
|
||||
int capacity;
|
||||
fr[2].getInt(capacity);
|
||||
|
||||
fr += 4;
|
||||
|
||||
int numInstances = 0;
|
||||
if (firstMatched)
|
||||
{
|
||||
fr[3].getInt(numInstances);
|
||||
fr += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
fr += 4;
|
||||
}
|
||||
|
||||
DrawElementsUByte* prim = new DrawElementsUByte;
|
||||
prim->setMode(mode);
|
||||
prim->setNumInstances(numInstances);
|
||||
prim->reserve(capacity);
|
||||
|
||||
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
@@ -1088,7 +1122,8 @@ bool Primitive_readLocalData(Input& fr,osg::Geometry& geom)
|
||||
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr.matchSequence("DrawElementsUShort %w %i {"))
|
||||
else if ((firstMatched = fr.matchSequence("DrawElementsUShort %w %i %i {")) ||
|
||||
fr.matchSequence("DrawElementsUShort %w %i {"))
|
||||
{
|
||||
int entry = fr[1].getNoNestedBrackets();
|
||||
|
||||
@@ -1098,10 +1133,20 @@ bool Primitive_readLocalData(Input& fr,osg::Geometry& geom)
|
||||
int capacity;
|
||||
fr[2].getInt(capacity);
|
||||
|
||||
fr += 4;
|
||||
int numInstances = 0;
|
||||
if (firstMatched)
|
||||
{
|
||||
fr[3].getInt(numInstances);
|
||||
fr += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
fr += 4;
|
||||
}
|
||||
|
||||
DrawElementsUShort* prim = new DrawElementsUShort;
|
||||
prim->setMode(mode);
|
||||
prim->setNumInstances(numInstances);
|
||||
prim->reserve(capacity);
|
||||
|
||||
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
@@ -1119,7 +1164,8 @@ bool Primitive_readLocalData(Input& fr,osg::Geometry& geom)
|
||||
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr.matchSequence("DrawElementsUInt %w %i {"))
|
||||
else if ((firstMatched = fr.matchSequence("DrawElementsUInt %w %i %i {")) ||
|
||||
fr.matchSequence("DrawElementsUInt %w %i {"))
|
||||
{
|
||||
int entry = fr[1].getNoNestedBrackets();
|
||||
|
||||
@@ -1129,10 +1175,20 @@ bool Primitive_readLocalData(Input& fr,osg::Geometry& geom)
|
||||
int capacity;
|
||||
fr[2].getInt(capacity);
|
||||
|
||||
fr += 4;
|
||||
int numInstances = 0;
|
||||
if (firstMatched)
|
||||
{
|
||||
fr[3].getInt(numInstances);
|
||||
fr += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
fr += 4;
|
||||
}
|
||||
|
||||
DrawElementsUInt* prim = new DrawElementsUInt;
|
||||
prim->setMode(mode);
|
||||
prim->setNumInstances(numInstances);
|
||||
prim->reserve(capacity);
|
||||
|
||||
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
@@ -1162,14 +1218,18 @@ bool Primitive_writeLocalData(const PrimitiveSet& prim,Output& fw)
|
||||
case(PrimitiveSet::DrawArraysPrimitiveType):
|
||||
{
|
||||
const DrawArrays& cprim = static_cast<const DrawArrays&>(prim);
|
||||
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.getFirst()<<" "<<cprim.getCount()<<std::endl;
|
||||
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.getFirst()<<" "<<cprim.getCount();
|
||||
if (prim.getNumInstances()>0) fw<<" "<<prim.getNumInstances();
|
||||
fw<<std::endl;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case(PrimitiveSet::DrawArrayLengthsPrimitiveType):
|
||||
{
|
||||
const DrawArrayLengths& cprim = static_cast<const DrawArrayLengths&>(prim);
|
||||
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.getFirst()<<" "<<cprim.size()<<std::endl;
|
||||
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.getFirst()<<" "<<cprim.size();
|
||||
if (prim.getNumInstances()>0) fw<<" "<<prim.getNumInstances();
|
||||
fw<<std::endl;
|
||||
writeArray(fw,cprim.begin(),cprim.end());
|
||||
return true;
|
||||
}
|
||||
@@ -1177,7 +1237,9 @@ bool Primitive_writeLocalData(const PrimitiveSet& prim,Output& fw)
|
||||
case(PrimitiveSet::DrawElementsUBytePrimitiveType):
|
||||
{
|
||||
const DrawElementsUByte& cprim = static_cast<const DrawElementsUByte&>(prim);
|
||||
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size()<<std::endl;
|
||||
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size();
|
||||
if (prim.getNumInstances()>0) fw<<" "<<prim.getNumInstances();
|
||||
fw<<std::endl;
|
||||
writeArrayAsInts(fw,cprim.begin(),cprim.end());
|
||||
return true;
|
||||
}
|
||||
@@ -1185,7 +1247,9 @@ bool Primitive_writeLocalData(const PrimitiveSet& prim,Output& fw)
|
||||
case(PrimitiveSet::DrawElementsUShortPrimitiveType):
|
||||
{
|
||||
const DrawElementsUShort& cprim = static_cast<const DrawElementsUShort&>(prim);
|
||||
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size()<<std::endl;
|
||||
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size();
|
||||
if (prim.getNumInstances()>0) fw<<" "<<prim.getNumInstances();
|
||||
fw<<std::endl;
|
||||
writeArray(fw,cprim.begin(),cprim.end());
|
||||
return true;
|
||||
}
|
||||
@@ -1193,7 +1257,9 @@ bool Primitive_writeLocalData(const PrimitiveSet& prim,Output& fw)
|
||||
case(PrimitiveSet::DrawElementsUIntPrimitiveType):
|
||||
{
|
||||
const DrawElementsUInt& cprim = static_cast<const DrawElementsUInt&>(prim);
|
||||
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size()<<std::endl;
|
||||
fw<<cprim.className()<<" "<<Geometry_getPrimitiveModeStr(cprim.getMode())<<" "<<cprim.size();
|
||||
if (prim.getNumInstances()>0) fw<<" "<<prim.getNumInstances();
|
||||
fw<<std::endl;
|
||||
writeArray(fw,cprim.begin(),cprim.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user