Optimise VAO usage

pull/1291/head
Jon Beniston 2022-06-19 14:16:45 +01:00
rodzic 0a91c30038
commit 37622db678
3 zmienionych plików z 79 dodań i 39 usunięć

Wyświetl plik

@ -27,6 +27,9 @@
GLShaderColors::GLShaderColors() : GLShaderColors::GLShaderColors() :
m_program(nullptr), m_program(nullptr),
m_vao(nullptr),
m_verticesBuf(nullptr),
m_colorBuf(nullptr),
m_matrixLoc(0), m_matrixLoc(0),
m_alphaLoc(0) m_alphaLoc(0)
{ } { }
@ -48,6 +51,10 @@ void GLShaderColors::initializeGL(int majorVersion, int minorVersion)
if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored)) { if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored)) {
qDebug() << "GLShaderColors::initializeGL: error in fragment shader: " << m_program->log(); qDebug() << "GLShaderColors::initializeGL: error in fragment shader: " << m_program->log();
} }
m_vao = new QOpenGLVertexArrayObject();
m_vao->create();
m_vao->bind();
} }
else else
{ {
@ -69,6 +76,16 @@ void GLShaderColors::initializeGL(int majorVersion, int minorVersion)
m_program->bind(); m_program->bind();
m_matrixLoc = m_program->uniformLocation("uMatrix"); m_matrixLoc = m_program->uniformLocation("uMatrix");
m_alphaLoc = m_program->uniformLocation("uAlpha"); m_alphaLoc = m_program->uniformLocation("uAlpha");
if (m_vao)
{
m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
m_verticesBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw);
m_verticesBuf->create();
m_colorBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
m_colorBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw);
m_colorBuf->create();
m_vao->release();
}
m_program->release(); m_program->release();
} }
@ -106,27 +123,50 @@ void GLShaderColors::draw(unsigned int mode, const QMatrix4x4& transformMatrix,
f->glEnable(GL_BLEND); f->glEnable(GL_BLEND);
f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
f->glLineWidth(1.0f); f->glLineWidth(1.0f);
f->glEnableVertexAttribArray(0); // vertex if (m_vao)
f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices); {
f->glEnableVertexAttribArray(1); // colors m_vao->bind();
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, colors);
m_verticesBuf->bind();
m_verticesBuf->allocate(vertices, nbVertices * 2 * sizeof(GL_FLOAT));
m_program->enableAttributeArray(0);
m_program->setAttributeBuffer(0, GL_FLOAT, 0, 2);
m_colorBuf->bind();
m_colorBuf->allocate(colors, nbVertices * 3 * sizeof(GL_FLOAT));
m_program->enableAttributeArray(1);
m_program->setAttributeBuffer(1, GL_FLOAT, 0, 3);
}
else
{
f->glEnableVertexAttribArray(0); // vertex
f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
f->glEnableVertexAttribArray(1); // colors
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, colors);
}
f->glDrawArrays(mode, 0, nbVertices); f->glDrawArrays(mode, 0, nbVertices);
f->glDisableVertexAttribArray(0); if (m_vao)
f->glDisableVertexAttribArray(1); {
m_vao->release();
}
else
{
f->glDisableVertexAttribArray(0);
f->glDisableVertexAttribArray(1);
}
m_program->release(); m_program->release();
} }
void GLShaderColors::cleanup() void GLShaderColors::cleanup()
{ {
if (!QOpenGLContext::currentContext()) { delete m_program;
return; m_program = nullptr;
} delete m_vao;
m_vao = nullptr;
if (m_program) delete m_verticesBuf;
{ m_verticesBuf = nullptr;
delete m_program; delete m_colorBuf;
m_program = nullptr; m_colorBuf = nullptr;
}
} }
const QString GLShaderColors::m_vertexShaderSourceSimple2 = QString( const QString GLShaderColors::m_vertexShaderSourceSimple2 = QString(

Wyświetl plik

@ -24,6 +24,8 @@
#include <QString> #include <QString>
#include <QOpenGLFunctions> #include <QOpenGLFunctions>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include "export.h" #include "export.h"
@ -49,6 +51,9 @@ private:
void draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *vertices, GLfloat *colors, GLfloat alpha, int nbVertices); void draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *vertices, GLfloat *colors, GLfloat alpha, int nbVertices);
QOpenGLShaderProgram *m_program; QOpenGLShaderProgram *m_program;
QOpenGLVertexArrayObject *m_vao;
QOpenGLBuffer *m_verticesBuf;
QOpenGLBuffer *m_colorBuf;
int m_matrixLoc; int m_matrixLoc;
int m_alphaLoc; int m_alphaLoc;
static const QString m_vertexShaderSourceSimple2; static const QString m_vertexShaderSourceSimple2;

Wyświetl plik

@ -169,9 +169,20 @@ void GLShaderSpectrogram::initGrid(int elements)
m_vertexBuf->bind(); m_vertexBuf->bind();
m_vertexBuf->allocate(&vertices[0], vertices.size() * sizeof(QVector2D)); m_vertexBuf->allocate(&vertices[0], vertices.size() * sizeof(QVector2D));
// Create an array of indices into the vertex array that traces both horizontal and vertical lines if (m_vao)
{
m_programShaded->enableAttributeArray(m_coord2dLoc);
m_programShaded->setAttributeBuffer(m_coord2dLoc, GL_FLOAT, 0, 2);
m_programSimple->enableAttributeArray(m_coord2dLoc);
m_programSimple->setAttributeBuffer(m_coord2dLoc, GL_FLOAT, 0, 2);
m_vao->release();
}
std::vector<GLuint> indices(m_gridElements * m_gridElements * 6); std::vector<GLuint> indices(m_gridElements * m_gridElements * 6);
int i = 0; int i;
// Create an array of indices into the vertex array that traces both horizontal and vertical lines
i = 0;
for (int y = 0; y < e1; y++) { for (int y = 0; y < e1; y++) {
for (int x = 0; x < m_gridElements; x++) { for (int x = 0; x < m_gridElements; x++) {
@ -190,7 +201,7 @@ void GLShaderSpectrogram::initGrid(int elements)
m_index0Buf->bind(); m_index0Buf->bind();
m_index0Buf->allocate(&indices[0], m_gridElements * (e1) * 4 * sizeof(GLuint)); m_index0Buf->allocate(&indices[0], m_gridElements * (e1) * 4 * sizeof(GLuint));
// Create another array of indices that describes all the triangles needed to create a completely filled surface // Create an array of indices that describes all the triangles needed to create a completely filled surface
i = 0; i = 0;
for (int y = 0; y < m_gridElements; y++) { for (int y = 0; y < m_gridElements; y++) {
@ -208,11 +219,7 @@ void GLShaderSpectrogram::initGrid(int elements)
m_index1Buf->bind(); m_index1Buf->bind();
m_index1Buf->allocate(&indices[0], indices.size() * sizeof(GLuint)); m_index1Buf->allocate(&indices[0], indices.size() * sizeof(GLuint));
if (m_vao) if (!m_vao)
{
m_vao->release();
}
else
{ {
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glBindBuffer(GL_ARRAY_BUFFER, 0); f->glBindBuffer(GL_ARRAY_BUFFER, 0);
@ -438,28 +445,23 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style,
program->setUniformValueArray(m_lightPosLoc, lightPos, 1, 3); program->setUniformValueArray(m_lightPosLoc, lightPos, 1, 3);
} }
if (m_vao) {
m_vao->bind();
}
f->glEnable(GL_DEPTH_TEST); f->glEnable(GL_DEPTH_TEST);
f->glPolygonOffset(1, 0); f->glPolygonOffset(1, 0);
f->glEnable(GL_POLYGON_OFFSET_FILL); f->glEnable(GL_POLYGON_OFFSET_FILL);
m_vertexBuf->bind();
if (m_vao) if (m_vao)
{ {
program->enableAttributeArray(m_coord2dLoc); m_vao->bind();
program->setAttributeBuffer(m_coord2dLoc, GL_FLOAT, 0, 2);
} }
else else
{ {
m_vertexBuf->bind();
f->glEnableVertexAttribArray(m_coord2dLoc); f->glEnableVertexAttribArray(m_coord2dLoc);
f->glVertexAttribPointer(m_coord2dLoc, 2, GL_FLOAT, GL_FALSE, 0, 0); f->glVertexAttribPointer(m_coord2dLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
} }
m_index1Buf->bind(); m_index1Buf->bind();
switch (style) switch (style)
{ {
case SpectrumSettings::Points: case SpectrumSettings::Points:
@ -486,21 +488,14 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style,
f->glDrawElements(GL_LINES, m_gridElements * (m_gridElements+1) * 4, GL_UNSIGNED_INT, 0); f->glDrawElements(GL_LINES, m_gridElements * (m_gridElements+1) * 4, GL_UNSIGNED_INT, 0);
} }
if (m_vao) {
program->disableAttributeArray(m_coord2dLoc);
} else {
f->glDisableVertexAttribArray(m_coord2dLoc);
}
if (m_vao) if (m_vao)
{ {
m_vao->release(); m_vao->release();
m_vertexBuf->release();
m_index0Buf->release(); m_index0Buf->release();
m_index1Buf->release();
} }
else else
{ {
f->glDisableVertexAttribArray(m_coord2dLoc);
// Need to do this, otherwise nothing else is drawn by other shaders // Need to do this, otherwise nothing else is drawn by other shaders
f->glBindBuffer(GL_ARRAY_BUFFER, 0); f->glBindBuffer(GL_ARRAY_BUFFER, 0);
f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);