diff --git a/sdrgui/gui/glshadersimple.cpp b/sdrgui/gui/glshadersimple.cpp index 58dc1bdec..ef6b7244a 100644 --- a/sdrgui/gui/glshadersimple.cpp +++ b/sdrgui/gui/glshadersimple.cpp @@ -26,7 +26,10 @@ #include "gui/glshadersimple.h" GLShaderSimple::GLShaderSimple() : - m_program(0), + m_program(nullptr), + m_vao(nullptr), + m_verticesBuf(nullptr), + m_vertexLoc(0), m_matrixLoc(0), m_colorLoc(0) { } @@ -66,8 +69,19 @@ void GLShaderSimple::initializeGL(int majorVersion, int minorVersion) } m_program->bind(); + m_vertexLoc = m_program->attributeLocation("vertex"); m_matrixLoc = m_program->uniformLocation("uMatrix"); m_colorLoc = m_program->uniformLocation("uColour"); + if (m_vao) + { + m_vao = new QOpenGLVertexArrayObject(); + m_vao->create(); + m_vao->bind(); + m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_verticesBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_verticesBuf->create(); + m_vao->release(); + } m_program->release(); } @@ -102,23 +116,42 @@ void GLShaderSimple::draw(unsigned int mode, const QMatrix4x4& transformMatrix, m_program->bind(); m_program->setUniformValue(m_matrixLoc, transformMatrix); m_program->setUniformValue(m_colorLoc, color); + if (m_vao) + { + m_vao->bind(); + + m_verticesBuf->bind(); + m_verticesBuf->allocate(vertices, nbVertices * nbComponents * sizeof(GL_FLOAT)); + m_program->enableAttributeArray(m_vertexLoc); + m_program->setAttributeBuffer(m_vertexLoc, GL_FLOAT, 0, nbComponents); + } + else + { + f->glEnableVertexAttribArray(m_vertexLoc); // vertex + f->glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); + } + f->glEnable(GL_BLEND); f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); f->glLineWidth(1.0f); - f->glEnableVertexAttribArray(0); // vertex - f->glVertexAttribPointer(0, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); f->glDrawArrays(mode, 0, nbVertices); - f->glDisableVertexAttribArray(0); + + if (m_vao) { + m_vao->release(); + } else { + f->glDisableVertexAttribArray(m_vertexLoc); + } m_program->release(); } void GLShaderSimple::cleanup() { - if (QOpenGLContext::currentContext() && m_program) - { - delete m_program; - m_program = nullptr; - } + delete m_program; + m_program = nullptr; + delete m_vao; + m_vao = nullptr; + delete m_verticesBuf; + m_verticesBuf = nullptr; } const QString GLShaderSimple::m_vertexShaderSourceSimple2 = QString( diff --git a/sdrgui/gui/glshadersimple.h b/sdrgui/gui/glshadersimple.h index 9768129b3..5e261087d 100644 --- a/sdrgui/gui/glshadersimple.h +++ b/sdrgui/gui/glshadersimple.h @@ -21,6 +21,8 @@ #include #include +#include +#include #include "export.h" @@ -46,6 +48,9 @@ private: void draw(unsigned int mode, const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents); QOpenGLShaderProgram *m_program; + QOpenGLVertexArrayObject *m_vao; + QOpenGLBuffer *m_verticesBuf; + int m_vertexLoc; int m_matrixLoc; int m_colorLoc; static const QString m_vertexShaderSourceSimple2; diff --git a/sdrgui/gui/glshaderspectrogram.cpp b/sdrgui/gui/glshaderspectrogram.cpp index 7955c21f6..2b3a702f3 100644 --- a/sdrgui/gui/glshaderspectrogram.cpp +++ b/sdrgui/gui/glshaderspectrogram.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,7 @@ GLShaderSpectrogram::GLShaderSpectrogram() : m_colorMapTexture(nullptr), m_colorMapTextureId(0), m_programForLocs(nullptr), + m_coord2dLoc(0), m_textureTransformLoc(0), m_vertexTransformLoc(0), m_dataTextureLoc(0), @@ -45,9 +47,10 @@ GLShaderSpectrogram::GLShaderSpectrogram() : m_lightDirLoc(0), m_lightPosLoc(0), m_useImmutableStorage(true), - m_vertexBuf(QOpenGLBuffer::VertexBuffer), - m_index0Buf(QOpenGLBuffer::IndexBuffer), - m_index1Buf(QOpenGLBuffer::IndexBuffer), + m_vao(nullptr), + m_vertexBuf(nullptr), + m_index0Buf(nullptr), + m_index1Buf(nullptr), m_translateX(0.0), m_translateY(0.0), m_translateZ(0.0), @@ -107,6 +110,10 @@ void GLShaderSpectrogram::initializeGL(int majorVersion, int minorVersion) if (!m_programSimple->link()) { qDebug() << "GLShaderSpectrogram::initializeGL: error linking shader: " << m_programSimple->log(); } + + m_vao = new QOpenGLVertexArrayObject(); + m_vao->create(); + m_vao->bind(); } else { @@ -121,6 +128,20 @@ void GLShaderSpectrogram::initializeGL(int majorVersion, int minorVersion) qDebug() << "GLShaderSpectrogram::initializeGL: error linking shader: " << m_programSimple->log(); } } + + m_vertexBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_vertexBuf->setUsagePattern(QOpenGLBuffer::StaticDraw); + m_vertexBuf->create(); + m_index0Buf = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer); + m_index0Buf->setUsagePattern(QOpenGLBuffer::StaticDraw); + m_index0Buf->create(); + m_index1Buf = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer); + m_index1Buf->setUsagePattern(QOpenGLBuffer::StaticDraw); + m_index1Buf->create(); + + if (m_vao) { + m_vao->release(); + } } void GLShaderSpectrogram::initGrid(int elements) @@ -141,17 +162,12 @@ void GLShaderSpectrogram::initGrid(int elements) } } - m_vertexBuf.setUsagePattern(QOpenGLBuffer::StaticDraw); - m_vertexBuf.create(); + if (m_vao) { + m_vao->bind(); + } - m_index0Buf.setUsagePattern(QOpenGLBuffer::StaticDraw); - m_index0Buf.create(); - - m_index1Buf.setUsagePattern(QOpenGLBuffer::StaticDraw); - m_index1Buf.create(); - - m_vertexBuf.bind(); - m_vertexBuf.allocate(&vertices[0], vertices.size() * sizeof(QVector2D)); + m_vertexBuf->bind(); + 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 std::vector indices(m_gridElements * m_gridElements * 6); @@ -171,8 +187,8 @@ void GLShaderSpectrogram::initGrid(int elements) } } - m_index0Buf.bind(); - m_index0Buf.allocate(&indices[0], m_gridElements * (e1) * 4 * sizeof(GLuint)); + m_index0Buf->bind(); + 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 i = 0; @@ -189,12 +205,19 @@ void GLShaderSpectrogram::initGrid(int elements) } } - m_index1Buf.bind(); - m_index1Buf.allocate(&indices[0], indices.size() * sizeof(GLuint)); + m_index1Buf->bind(); + m_index1Buf->allocate(&indices[0], indices.size() * sizeof(GLuint)); - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); - f->glBindBuffer(GL_ARRAY_BUFFER, 0); - f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + if (m_vao) + { + m_vao->release(); + } + else + { + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + f->glBindBuffer(GL_ARRAY_BUFFER, 0); + f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } } void GLShaderSpectrogram::initColorMapTexture(const QString &colorMapName) @@ -356,6 +379,7 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, if (program != m_programForLocs) { + m_coord2dLoc = program->attributeLocation("coord2d"); m_textureTransformLoc = program->uniformLocation("textureTransform"); m_vertexTransformLoc = program->uniformLocation("vertexTransform"); m_dataTextureLoc = program->uniformLocation("dataTexture"); @@ -414,17 +438,28 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, program->setUniformValueArray(m_lightPosLoc, lightPos, 1, 3); } + if (m_vao) { + m_vao->bind(); + } + f->glEnable(GL_DEPTH_TEST); f->glPolygonOffset(1, 0); f->glEnable(GL_POLYGON_OFFSET_FILL); - int attribute_coord2d = program->attributeLocation("coord2d"); - f->glEnableVertexAttribArray(attribute_coord2d); - m_vertexBuf.bind(); - f->glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, 0); + m_vertexBuf->bind(); + if (m_vao) + { + program->enableAttributeArray(m_coord2dLoc); + program->setAttributeBuffer(m_coord2dLoc, GL_FLOAT, 0, 2); + } + else + { + f->glEnableVertexAttribArray(m_coord2dLoc); + f->glVertexAttribPointer(m_coord2dLoc, 2, GL_FLOAT, GL_FALSE, 0, 0); + } - m_index1Buf.bind(); + m_index1Buf->bind(); switch (style) { case SpectrumSettings::Points: @@ -447,14 +482,29 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, { // Draw the outline program->setUniformValue(m_brightnessLoc, 1.5f); - m_index0Buf.bind(); + m_index0Buf->bind(); f->glDrawElements(GL_LINES, m_gridElements * (m_gridElements+1) * 4, GL_UNSIGNED_INT, 0); } - f->glDisableVertexAttribArray(attribute_coord2d); - // Need to do this, otherwise nothing else is drawn... - f->glBindBuffer(GL_ARRAY_BUFFER, 0); - f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + if (m_vao) { + program->disableAttributeArray(m_coord2dLoc); + } else { + f->glDisableVertexAttribArray(m_coord2dLoc); + } + + if (m_vao) + { + m_vao->release(); + m_vertexBuf->release(); + m_index0Buf->release(); + m_index1Buf->release(); + } + else + { + // Need to do this, otherwise nothing else is drawn by other shaders + f->glBindBuffer(GL_ARRAY_BUFFER, 0); + f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } // If this is left enabled, channel markers aren't drawn properly f->glDisable(GL_DEPTH_TEST); @@ -464,30 +514,26 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, void GLShaderSpectrogram::cleanup() { + delete m_programShaded; + m_programShaded = nullptr; + delete m_programSimple; + m_programSimple = nullptr; + m_programForLocs = nullptr; + delete m_texture; + m_texture = nullptr; + delete m_colorMapTexture; + m_colorMapTexture = nullptr; + delete m_vertexBuf; + m_vertexBuf = nullptr; + delete m_index0Buf; + m_index0Buf = nullptr; + delete m_index1Buf; + m_index1Buf = nullptr; + if (!QOpenGLContext::currentContext()) { return; } - if (m_programShaded) - { - delete m_programShaded; - m_programShaded = nullptr; - } - - if (m_programSimple) - { - delete m_programSimple; - m_programSimple = nullptr; - } - - m_programForLocs = nullptr; - - if (m_texture) - { - delete m_texture; - m_texture = nullptr; - } - if (m_textureId) { glDeleteTextures(1, &m_textureId); @@ -499,12 +545,6 @@ void GLShaderSpectrogram::cleanup() glDeleteTextures(1, &m_colorMapTextureId); m_colorMapTextureId = 0; } - - if (m_colorMapTexture) - { - delete m_colorMapTexture; - m_colorMapTexture = nullptr; - } } bool GLShaderSpectrogram::useImmutableStorage() diff --git a/sdrgui/gui/glshaderspectrogram.h b/sdrgui/gui/glshaderspectrogram.h index b33eb963f..5b196b0c6 100644 --- a/sdrgui/gui/glshaderspectrogram.h +++ b/sdrgui/gui/glshaderspectrogram.h @@ -83,6 +83,7 @@ private: unsigned int m_colorMapTextureId; QOpenGLShaderProgram *m_programForLocs; // Which program the locations are for + int m_coord2dLoc; int m_textureTransformLoc; int m_vertexTransformLoc; int m_dataTextureLoc; @@ -100,9 +101,10 @@ private: static const QString m_fragmentShaderSimple2; static const QString m_fragmentShaderSimple; - QOpenGLBuffer m_vertexBuf; - QOpenGLBuffer m_index0Buf; - QOpenGLBuffer m_index1Buf; + QOpenGLVertexArrayObject *m_vao; + QOpenGLBuffer *m_vertexBuf; + QOpenGLBuffer *m_index0Buf; + QOpenGLBuffer *m_index1Buf; float m_translateX; float m_translateY; diff --git a/sdrgui/gui/glshadertextured.cpp b/sdrgui/gui/glshadertextured.cpp index 76168b4e4..e23f94884 100644 --- a/sdrgui/gui/glshadertextured.cpp +++ b/sdrgui/gui/glshadertextured.cpp @@ -28,7 +28,12 @@ GLShaderTextured::GLShaderTextured() : m_program(nullptr), + m_vao(nullptr), + m_verticesBuf(nullptr), + m_textureCoordsBuf(nullptr), m_texture(nullptr), + m_vertexLoc(0), + m_texCoordLoc(0), m_textureId(0), m_matrixLoc(0), m_textureLoc(0), @@ -74,8 +79,23 @@ void GLShaderTextured::initializeGL(int majorVersion, int minorVersion) } m_program->bind(); + m_vertexLoc = m_program->attributeLocation("vertex"); + m_texCoordLoc = m_program->attributeLocation("texCoord"); m_matrixLoc = m_program->uniformLocation("uMatrix"); m_textureLoc = m_program->uniformLocation("uTexture"); + if (m_vao) + { + m_vao = new QOpenGLVertexArrayObject(); + m_vao->create(); + m_vao->bind(); + m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_verticesBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_verticesBuf->create(); + m_textureCoordsBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_textureCoordsBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_textureCoordsBuf->create(); + m_vao->release(); + } m_program->release(); } @@ -176,12 +196,39 @@ void GLShaderTextured::draw(unsigned int mode, const QMatrix4x4& transformMatrix m_program->setUniformValue(m_matrixLoc, transformMatrix); m_texture->bind(); m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture - f->glEnableVertexAttribArray(0); // vertex - f->glVertexAttribPointer(0, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); - f->glEnableVertexAttribArray(1); // texture coordinates - f->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); + if (m_vao) + { + m_vao->bind(); + + m_verticesBuf->bind(); + m_verticesBuf->allocate(vertices, nbVertices * nbComponents * sizeof(GL_FLOAT)); + m_program->enableAttributeArray(m_vertexLoc); + m_program->setAttributeBuffer(m_vertexLoc, GL_FLOAT, 0, nbComponents); + + m_textureCoordsBuf->bind(); + m_textureCoordsBuf->allocate(textureCoords, nbVertices * 2 * sizeof(GL_FLOAT)); + m_program->enableAttributeArray(m_texCoordLoc); + m_program->setAttributeBuffer(m_texCoordLoc, GL_FLOAT, 0, 2); + } + else + { + f->glEnableVertexAttribArray(m_vertexLoc); // vertex + f->glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); + f->glEnableVertexAttribArray(m_texCoordLoc); // texture coordinates + f->glVertexAttribPointer(m_texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); + } + f->glDrawArrays(mode, 0, nbVertices); - f->glDisableVertexAttribArray(0); + + if (m_vao) + { + m_vao->release(); + } + else + { + f->glDisableVertexAttribArray(m_vertexLoc); + f->glDisableVertexAttribArray(m_texCoordLoc); + } m_program->release(); } @@ -197,33 +244,33 @@ void GLShaderTextured::drawMutable(unsigned int mode, const QMatrix4x4& transfor m_program->setUniformValue(m_matrixLoc, transformMatrix); glBindTexture(GL_TEXTURE_2D, m_textureId); m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture - glEnableVertexAttribArray(0); // vertex - glVertexAttribPointer(0, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); - glEnableVertexAttribArray(1); // texture coordinates - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); + glEnableVertexAttribArray(m_vertexLoc); // vertex + glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); + glEnableVertexAttribArray(m_texCoordLoc); // texture coordinates + glVertexAttribPointer(m_texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); glDrawArrays(mode, 0, nbVertices); - glDisableVertexAttribArray(0); + glDisableVertexAttribArray(m_vertexLoc); + glDisableVertexAttribArray(m_texCoordLoc); m_program->release(); } void GLShaderTextured::cleanup() { + delete m_program; + m_program = nullptr; + delete m_vao; + m_vao = nullptr; + delete m_verticesBuf; + m_verticesBuf = nullptr; + delete m_textureCoordsBuf; + m_textureCoordsBuf = nullptr; + delete m_texture; + m_texture = nullptr; + if (!QOpenGLContext::currentContext()) { return; } - if (m_program) - { - delete m_program; - m_program = nullptr; - } - - if (m_texture) - { - delete m_texture; - m_texture = nullptr; - } - if (m_textureId) { glDeleteTextures(1, &m_textureId); diff --git a/sdrgui/gui/glshadertextured.h b/sdrgui/gui/glshadertextured.h index 868a26f1d..a92b0d98e 100644 --- a/sdrgui/gui/glshadertextured.h +++ b/sdrgui/gui/glshadertextured.h @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "export.h" @@ -54,8 +56,13 @@ private: bool useImmutableStorage(); QOpenGLShaderProgram *m_program; + QOpenGLVertexArrayObject *m_vao; + QOpenGLBuffer *m_verticesBuf; + QOpenGLBuffer *m_textureCoordsBuf; QOpenGLTexture *m_texture; unsigned int m_textureId; + int m_vertexLoc; + int m_texCoordLoc; int m_matrixLoc; int m_textureLoc; bool m_useImmutableStorage;