Skip to content

Commit

Permalink
gl: optimize VAO binding
Browse files Browse the repository at this point in the history
  • Loading branch information
wang-bin committed Jul 24, 2016
1 parent b3d08c0 commit 116b90d
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 16 deletions.
27 changes: 19 additions & 8 deletions src/opengl/Geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,17 @@ void Geometry::setIndexValue(int index, int value)
{
switch (indexType()) {
case TypeU8: {
quint8* d = (quint8*)m_idata.data();
quint8* d = (quint8*)m_idata.constData();
*(d+index) = value;
}
break;
case TypeU16: {
quint16* d = (quint16*)m_idata.data();
quint16* d = (quint16*)m_idata.constData();
*(d+index) = value;
}
break;
case TypeU32: {
quint32* d = (quint32*)m_idata.data();
quint32* d = (quint32*)m_idata.constData();
*(d+index) = value;
}
break;
Expand All @@ -93,21 +93,21 @@ void Geometry::setIndexValue(int index, int v1, int v2, int v3)
{
switch (indexType()) {
case TypeU8: {
quint8* d = (quint8*)m_idata.data();
quint8* d = (quint8*)m_idata.constData();
*(d+index++) = v1;
*(d+index++) = v2;
*(d+index++) = v2;
}
break;
case TypeU16: {
quint16* d = (quint16*)m_idata.data();
quint16* d = (quint16*)m_idata.constData();
*(d+index++) = v1;
*(d+index++) = v2;
*(d+index++) = v3;
}
break;
case TypeU32: {
quint32* d = (quint32*)m_idata.data();
quint32* d = (quint32*)m_idata.constData();
*(d+index++) = v1;
*(d+index++) = v2;
*(d+index++) = v3;
Expand Down Expand Up @@ -142,6 +142,17 @@ void Geometry::allocate(int nbVertex, int nbIndex)
}
}

bool Geometry::compare(const Geometry *other) const
{
if (this == other)
return true;
if (!other)
return false;
if (stride() != other->stride())
return false;
return attributes() == other->attributes();
}

TexturedGeometry::TexturedGeometry()
: Geometry()
, nb_tex(0)
Expand Down Expand Up @@ -183,14 +194,14 @@ void TexturedGeometry::setPoint(int index, const QPointF &p, const QPointF &tp,

void TexturedGeometry::setGeometryPoint(int index, const QPointF &p)
{
float *v = (float*)(m_vdata.data() + index*stride());
float *v = (float*)(m_vdata.constData() + index*stride());
*v = p.x();
*(v+1) = p.y();
}

void TexturedGeometry::setTexturePoint(int index, const QPointF &tp, int texIndex)
{
float *v = (float*)(m_vdata.data() + index*stride() + (texIndex+1)*2*sizeof(float));
float *v = (float*)(m_vdata.constData() + index*stride() + (texIndex+1)*2*sizeof(float));
*v = tp.x();
*(v+1) = tp.y();
}
Expand Down
15 changes: 14 additions & 1 deletion src/opengl/Geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,15 @@ class Attribute {
int tupleSize() const {return m_tupleSize;}
int offset() const {return m_offset;}
bool normalize() const {return m_normalize;}
bool operator==(const Attribute& other) const {
return tupleSize() == other.tupleSize()
&& offset() == other.offset()
&& type() == other.type()
&& normalize() == other.normalize();
}
};
#ifndef QT_NO_DEBUG_STREAM
Q_AV_EXPORT QDebug operator<<(QDebug debug, const Attribute &a);
QDebug operator<<(QDebug debug, const Attribute &a);
#endif

/*!
Expand Down Expand Up @@ -83,6 +89,7 @@ class Geometry {
virtual const QVector<Attribute>& attributes() const = 0;
void* vertexData() { return m_vdata.data();}
const void* vertexData() const { return m_vdata.constData();}
const void* constVertexData() const { return m_vdata.constData();}
void* indexData() { return m_icount > 0 ? m_idata.data() : NULL;}
const void* indexData() const { return m_icount > 0 ? m_idata.constData() : NULL;}
int indexCount() const { return m_icount;}
Expand All @@ -97,6 +104,12 @@ class Geometry {
* Call allocate() when all parameters are set. vertexData() may change
*/
void allocate(int nbVertex, int nbIndex = 0);
/*!
* \brief compare
* Compare each attribute and stride that used in glVertexAttribPointer
* \return true if equal
*/
bool compare(const Geometry *other) const;
protected:
Primitive m_primitive;
DataType m_itype;
Expand Down
16 changes: 11 additions & 5 deletions src/opengl/GeometryRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ GeometryRenderer::GeometryRenderer()
, features_(kVBO|kIBO|kVAO)
, ibo(QOpenGLBuffer::IndexBuffer)
{
static bool disable_ibo = qgetenv("QTAV_NO_IBO").toInt() > 0;
setFeature(kIBO, !disable_ibo);
static bool disable_vbo = qgetenv("QTAV_NO_VBO").toInt() > 0;
setFeature(kVBO, !disable_vbo);
static bool disable_vao = qgetenv("QTAV_NO_VAO").toInt() > 0;
Expand Down Expand Up @@ -72,6 +74,7 @@ bool GeometryRenderer::testFeatures(int value) const

void GeometryRenderer::updateGeometry(Geometry *geo)
{
const Geometry* old = g; // old geometry will be compared later, so make sure destroy old after updateGeometry
g = geo;
if (!g) {
ibo.destroy();
Expand Down Expand Up @@ -117,14 +120,17 @@ void GeometryRenderer::updateGeometry(Geometry *geo)
#if QT_VAO
if (!vao.isCreated())
return;
if (g->compare(old))
return;
//qDebug("geometry attributes changed, rebind vao...");
// TODO: call once is enough if no feature and no geometry attribute is changed
if (vbo.isCreated()) {
vbo.bind();
for (int an = 0; an < g->attributes().size(); ++an) {
// FIXME: assume bind order is 0,1,2...
const Attribute& a = g->attributes().at(an);
DYGL(glVertexAttribPointer(an, a.tupleSize(), a.type(), a.normalize(), g->stride(), reinterpret_cast<const void *>(qptrdiff(a.offset())))); //TODO: in setActiveShader
DYGL(glEnableVertexAttribArray(an));
QOpenGLContext::currentContext()->functions()->glVertexAttribPointer(an, a.tupleSize(), a.type(), a.normalize(), g->stride(), reinterpret_cast<const void *>(qptrdiff(a.offset()))); //TODO: in setActiveShader
QOpenGLContext::currentContext()->functions()->glEnableVertexAttribArray(an);
}
vbo.release(); // unbind after vao unbind?
}
Expand Down Expand Up @@ -167,8 +173,8 @@ void GeometryRenderer::bindBuffers()
}
for (int an = 0; an < g->attributes().size(); ++an) {
const Attribute& a = g->attributes().at(an);
DYGL(glVertexAttribPointer(an, a.tupleSize(), a.type(), a.normalize(), g->stride(), vdata + a.offset()));
DYGL(glEnableVertexAttribArray(an)); //TODO: in setActiveShader
QOpenGLContext::currentContext()->functions()->glVertexAttribPointer(an, a.tupleSize(), a.type(), a.normalize(), g->stride(), vdata + a.offset());
QOpenGLContext::currentContext()->functions()->glEnableVertexAttribArray(an); //TODO: in setActiveShader
}
}

Expand Down Expand Up @@ -199,7 +205,7 @@ void GeometryRenderer::unbindBuffers()
if (!g)
return;
for (int an = 0; an < g->attributes().size(); ++an) {
DYGL(glDisableVertexAttribArray(an));
QOpenGLContext::currentContext()->functions()->glDisableVertexAttribArray(an);
}
}

Expand Down
13 changes: 11 additions & 2 deletions src/opengl/GeometryRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ class QOpenGLShaderProgram;
QT_END_NAMESPACE

namespace QtAV {
/*!
* \brief The GeometryRenderer class
* TODO: support multiple geometry with same primitive (glPrimitiveRestartIndex, glDrawArraysInstanced, glDrawArraysInstanced, glMultiDrawArrays...)
*/
class GeometryRenderer
{
public:
Expand All @@ -47,8 +51,13 @@ class GeometryRenderer
int features() const;
int actualFeatures() const;
bool testFeatures(int value) const;
/// assume attributes are bound in the order 0, 1, 2,....
/// null geometry: release vao/vbo
/*!
* \brief updateGeometry
* Update geometry buffer. Rebind VBO, IBO to VAO if geometry attributes is changed.
* Assume attributes are bound in the order 0, 1, 2,....
* Make sure the old geometry is not destroyed before this call because it will be used to compare with the new \l geo
* \param geo null: release vao/vbo
*/
void updateGeometry(Geometry* geo = NULL);
void render();
protected:
Expand Down

0 comments on commit 116b90d

Please sign in to comment.