Adapted GLBeginEndAdapter to use state.drawQuad(..) rather than use it's local GL_QUADS emulation.

Fixed to osg::Texture for GLES support.

Added automatic GLenum mode mappings in osg::PrimitiveSet to provide a fallback for non support glDrawArray/glDrawElement modes.

Added finer gained error checking during StateSet::compile().
This commit is contained in:
Robert Osfield
2009-11-12 14:35:44 +00:00
parent efb9908644
commit 8b141567b9
5 changed files with 94 additions and 48 deletions

View File

@@ -157,9 +157,6 @@ class OSG_EXPORT GLBeginEndAdapter
osg::ref_ptr<osg::Vec4Array> _colors;
VertexArrayList _texCoordsList;
VertexArrayList _vertexAttribsList;
typedef std::vector<unsigned short> UShortArray;
UShortArray _indexArray;
};
}

View File

@@ -282,27 +282,7 @@ void GLBeginEndAdapter::End()
if (_primitiveMode==GL_QUADS)
{
unsigned int numQuads = _vertices->size()/4;
unsigned int numIndices = numQuads * 6;
if (numIndices > _indexArray.size())
{
// we need to expand the _indexArray to be big enough to cope with all the quads required.
unsigned int numExistingQuads = _indexArray.size()/6;
_indexArray.reserve(numIndices);
for(unsigned int i=numExistingQuads; i<numQuads; ++i)
{
unsigned int base = i*4;
_indexArray.push_back(base);
_indexArray.push_back(base+1);
_indexArray.push_back(base+3);
_indexArray.push_back(base+1);
_indexArray.push_back(base+2);
_indexArray.push_back(base+3);
}
}
glDrawElements(GL_TRIANGLES, numQuads*6, GL_UNSIGNED_SHORT, &(_indexArray.front()));
_state->drawQuads(0, _vertices->size());
}
else if (_primitiveMode==GL_QUAD_STRIP)
{

View File

@@ -37,8 +37,28 @@ unsigned int PrimitiveSet::getNumPrimitives() const
void DrawArrays::draw(State& state, bool) const
{
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
GLenum mode = _mode;
if (_mode==GL_QUADS)
{
state.drawQuads(_first, _count, _numInstances);
return;
}
else if (mode==GL_POLYGON)
{
mode = GL_TRIANGLE_FAN;
}
else if (mode==GL_QUAD_STRIP)
{
mode = GL_TRIANGLE_STRIP;
}
if (_numInstances>=1) state.glDrawArraysInstanced(mode,_first,_count, _numInstances);
else glDrawArrays(mode,_first,_count);
#else
if (_numInstances>=1) state.glDrawArraysInstanced(_mode,_first,_count, _numInstances);
else glDrawArrays(_mode,_first,_count);
#endif
}
void DrawArrays::accept(PrimitiveFunctor& functor) const
@@ -69,16 +89,36 @@ unsigned int DrawArrayLengths::getNumPrimitives() const
return 0;
}
void DrawArrayLengths::draw(State&, bool) const
void DrawArrayLengths::draw(State& state, bool) const
{
GLenum mode = _mode;
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
if (_mode==GL_QUADS)
{
GLint first = _first;
for(vector_type::const_iterator itr=begin();
itr!=end();
++itr)
{
state.drawQuads(first, *itr, _numInstances);
first += *itr;
}
return;
}
if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
#endif
GLint first = _first;
for(vector_type::const_iterator itr=begin();
itr!=end();
++itr)
{
glDrawArrays(_mode,first,*itr);
glDrawArrays(mode,first,*itr);
first += *itr;
}
}
void DrawArrayLengths::accept(PrimitiveFunctor& functor) const
@@ -124,25 +164,31 @@ DrawElementsUByte::~DrawElementsUByte()
void DrawElementsUByte::draw(State& state, bool useVertexBufferObjects) const
{
GLenum mode = _mode;
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
#endif
if (useVertexBufferObjects)
{
GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
state.bindElementBufferObject(ebo);
if (ebo)
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
else glDrawElements(mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
}
else
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
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
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
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());
}
}
@@ -174,25 +220,31 @@ DrawElementsUShort::~DrawElementsUShort()
void DrawElementsUShort::draw(State& state, bool useVertexBufferObjects) const
{
GLenum mode = _mode;
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
#endif
if (useVertexBufferObjects)
{
GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
state.bindElementBufferObject(ebo);
if (ebo)
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
}
else
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_SHORT, &front(), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, &front());
if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, &front(), _numInstances);
else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, &front());
}
}
else
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_SHORT, &front(), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, &front());
if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, &front(), _numInstances);
else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, &front());
}
}
@@ -224,25 +276,31 @@ DrawElementsUInt::~DrawElementsUInt()
void DrawElementsUInt::draw(State& state, bool useVertexBufferObjects) const
{
GLenum mode = _mode;
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
#endif
if (useVertexBufferObjects)
{
GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
state.bindElementBufferObject(ebo);
if (ebo)
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
else glDrawElements(mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
}
else
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_INT, &front(), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_INT, &front());
if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, &front(), _numInstances);
else glDrawElements(mode, size(), GL_UNSIGNED_INT, &front());
}
}
else
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_INT, &front(), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_INT, &front());
if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, &front(), _numInstances);
else glDrawElements(mode, size(), GL_UNSIGNED_INT, &front());
}
}

View File

@@ -1326,11 +1326,16 @@ void StateSet::setThreadSafeRefUnref(bool threadSafe)
void StateSet::compileGLObjects(State& state) const
{
bool checkForGLErrors = state.getCheckForGLErrors()==osg::State::ONCE_PER_ATTRIBUTE;
for(AttributeList::const_iterator itr = _attributeList.begin();
itr!=_attributeList.end();
++itr)
{
itr->second.first->compileGLObjects(state);
if (checkForGLErrors && state.checkGLErrors("StateSet::compileGLObejcts() compiling attribute"))
{
osg::notify(osg::NOTICE)<<" GL Error when compiling "<<itr->second.first->className()<<std::endl;
}
}
for(TextureAttributeList::const_iterator taitr=_textureAttributeList.begin();
@@ -1342,6 +1347,10 @@ void StateSet::compileGLObjects(State& state) const
++itr)
{
itr->second.first->compileGLObjects(state);
if (checkForGLErrors && state.checkGLErrors("StateSet::compileGLObejcts() compiling texture attribute"))
{
osg::notify(osg::NOTICE)<<" GL Error when compiling "<<itr->second.first->className()<<std::endl;
}
}
}
}

View File

@@ -1135,7 +1135,7 @@ Texture::Texture():
_useHardwareMipMapGeneration(true),
_unrefImageDataAfterApply(false),
_clientStorageHint(false),
_resizeNonPowerOfTwoHint(true),
_resizeNonPowerOfTwoHint(!OSG_GLES2_FEATURES && !OSG_GL3_FEATURES),
_borderColor(0.0, 0.0, 0.0, 0.0),
_borderWidth(0),
_internalFormatMode(USE_IMAGE_DATA_FORMAT),
@@ -1569,8 +1569,8 @@ void Texture::applyTexParameters(GLenum target, State& state) const
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
if (ws == CLAMP) ws = CLAMP_TO_EDGE;
if (wt == CLAMP) wr = CLAMP_TO_EDGE;
if (wr == CLAMP) wt = CLAMP_TO_EDGE;
if (wt == CLAMP) wt = CLAMP_TO_EDGE;
if (wr == CLAMP) wr = CLAMP_TO_EDGE;
#endif
const Image * image = getImage(0);
@@ -2455,12 +2455,14 @@ void Texture::Extensions::setupGLExtensions(unsigned int contextID)
_isTextureIntegerEXTSupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_EXT_texture_integer");
#if 0
if (rendererString.find("Radeon")!=std::string::npos || rendererString.find("RADEON")!=std::string::npos)
{
_isNonPowerOfTwoTextureMipMappedSupported = false;
osg::notify(osg::INFO)<<"Disabling _isNonPowerOfTwoTextureMipMappedSupported for ATI hardware."<<std::endl;
}
#endif
if (rendererString.find("GeForce FX")!=std::string::npos)
{
_isNonPowerOfTwoTextureMipMappedSupported = false;