1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-22 16:08:39 -05:00

Update TVScreen to OpenGL 3.3

This commit is contained in:
Jon Beniston 2022-06-19 23:22:43 +01:00
parent 34ce5ae398
commit 94f93ee9ad
5 changed files with 321 additions and 92 deletions

View File

@ -20,7 +20,7 @@
#include "gui/glshadertvarray.h" #include "gui/glshadertvarray.h"
const QString GLShaderTVArray::m_strVertexShaderSourceArray = QString( const QString GLShaderTVArray::m_strVertexShaderSourceArray2 = QString(
"uniform highp mat4 uMatrix;\n" "uniform highp mat4 uMatrix;\n"
"attribute highp vec4 vertex;\n" "attribute highp vec4 vertex;\n"
"attribute highp vec2 texCoord;\n" "attribute highp vec2 texCoord;\n"
@ -30,15 +30,38 @@ const QString GLShaderTVArray::m_strVertexShaderSourceArray = QString(
" texCoordVar = texCoord;\n" " texCoordVar = texCoord;\n"
"}\n"); "}\n");
const QString GLShaderTVArray::m_strFragmentShaderSourceColored = QString( const QString GLShaderTVArray::m_strVertexShaderSourceArray = QString(
"#version 330\n"
"uniform highp mat4 uMatrix;\n"
"in highp vec4 vertex;\n"
"in highp vec2 texCoord;\n"
"out mediump vec2 texCoordVar;\n"
"void main() {\n"
" gl_Position = uMatrix * vertex;\n"
" texCoordVar = texCoord;\n"
"}\n");
const QString GLShaderTVArray::m_strFragmentShaderSourceColored2 = QString(
"uniform lowp sampler2D uTexture;\n" "uniform lowp sampler2D uTexture;\n"
"varying mediump vec2 texCoordVar;\n" "varying mediump vec2 texCoordVar;\n"
"void main() {\n" "void main() {\n"
" gl_FragColor = texture2D(uTexture, texCoordVar);\n" " gl_FragColor = texture2D(uTexture, texCoordVar);\n"
"}\n"); "}\n");
const QString GLShaderTVArray::m_strFragmentShaderSourceColored = QString(
"#version 330\n"
"uniform lowp sampler2D uTexture;\n"
"in mediump vec2 texCoordVar;\n"
"out vec4 fragColor;\n"
"void main() {\n"
" fragColor = texture(uTexture, texCoordVar);\n"
"}\n");
GLShaderTVArray::GLShaderTVArray(bool blnColor) : GLShaderTVArray::GLShaderTVArray(bool blnColor) :
m_objProgram(nullptr), m_objProgram(nullptr),
m_vao(nullptr),
m_verticesBuf(nullptr),
m_textureCoordsBuf(nullptr),
m_matrixLoc(0), m_matrixLoc(0),
m_textureLoc(0), m_textureLoc(0),
m_objImage(nullptr), m_objImage(nullptr),
@ -59,7 +82,7 @@ GLShaderTVArray::~GLShaderTVArray()
cleanup(); cleanup();
} }
void GLShaderTVArray::initializeGL(int intCols, int intRows) void GLShaderTVArray::initializeGL(int majorVersion, int minorVersion, int intCols, int intRows)
{ {
QMatrix4x4 objQMatrix; QMatrix4x4 objQMatrix;
@ -73,7 +96,8 @@ void GLShaderTVArray::initializeGL(int intCols, int intRows)
if (!m_objProgram) if (!m_objProgram)
{ {
m_objProgram = new QOpenGLShaderProgram(); m_objProgram = new QOpenGLShaderProgram();
if ((majorVersion > 3) || ((majorVersion == 3) && (minorVersion >= 3)))
{
if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Vertex,
m_strVertexShaderSourceArray)) m_strVertexShaderSourceArray))
{ {
@ -89,6 +113,28 @@ void GLShaderTVArray::initializeGL(int intCols, int intRows)
<< m_objProgram->log(); << m_objProgram->log();
} }
m_vao = new QOpenGLVertexArrayObject();
m_vao->create();
m_vao->bind();
}
else
{
if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Vertex,
m_strVertexShaderSourceArray2))
{
qDebug() << "GLShaderArray::initializeGL: error in vertex shader: "
<< m_objProgram->log();
}
if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Fragment,
m_strFragmentShaderSourceColored2))
{
qDebug()
<< "GLShaderArray::initializeGL: error in fragment shader: "
<< m_objProgram->log();
}
}
m_objProgram->bindAttributeLocation("vertex", 0); m_objProgram->bindAttributeLocation("vertex", 0);
if (!m_objProgram->link()) if (!m_objProgram->link())
@ -100,6 +146,16 @@ void GLShaderTVArray::initializeGL(int intCols, int intRows)
m_objProgram->bind(); m_objProgram->bind();
m_objProgram->setUniformValue(m_matrixLoc, objQMatrix); m_objProgram->setUniformValue(m_matrixLoc, objQMatrix);
m_objProgram->setUniformValue(m_textureLoc, 0); m_objProgram->setUniformValue(m_textureLoc, 0);
if (m_vao)
{
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_objProgram->release(); m_objProgram->release();
} }
@ -232,17 +288,41 @@ void GLShaderTVArray::RenderPixels(unsigned char *chrData)
ptrF->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_intCols, m_intRows, GL_RGBA, ptrF->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_intCols, m_intRows, GL_RGBA,
GL_UNSIGNED_BYTE, m_objImage->bits()); GL_UNSIGNED_BYTE, m_objImage->bits());
if (m_vao)
{
m_vao->bind();
m_verticesBuf->bind();
m_verticesBuf->allocate(arrVertices, intNbVertices * 2 * sizeof(GL_FLOAT));
m_objProgram->enableAttributeArray(0);
m_objProgram->setAttributeBuffer(0, GL_FLOAT, 0, 2);
m_textureCoordsBuf->bind();
m_textureCoordsBuf->allocate(arrTextureCoords, intNbVertices * 2 * sizeof(GL_FLOAT));
m_objProgram->enableAttributeArray(1);
m_objProgram->setAttributeBuffer(1, GL_FLOAT, 0, 2);
}
else
{
ptrF->glEnableVertexAttribArray(0); // vertex ptrF->glEnableVertexAttribArray(0); // vertex
ptrF->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, arrVertices); ptrF->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, arrVertices);
ptrF->glEnableVertexAttribArray(1); // texture coordinates ptrF->glEnableVertexAttribArray(1); // texture coordinates
ptrF->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, arrTextureCoords); ptrF->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, arrTextureCoords);
}
ptrF->glDrawArrays(GL_TRIANGLES, 0, intNbVertices); ptrF->glDrawArrays(GL_TRIANGLES, 0, intNbVertices);
//cleanup //cleanup
if (m_vao)
{
m_vao->release();
}
else
{
ptrF->glDisableVertexAttribArray(0); ptrF->glDisableVertexAttribArray(0);
ptrF->glDisableVertexAttribArray(1); ptrF->glDisableVertexAttribArray(1);
}
//*********************// //*********************//
@ -294,6 +374,13 @@ void GLShaderTVArray::cleanup()
delete m_objImage; delete m_objImage;
m_objImage = nullptr; m_objImage = nullptr;
} }
delete m_verticesBuf;
m_verticesBuf = nullptr;
delete m_textureCoordsBuf;
m_textureCoordsBuf = nullptr;
delete m_vao;
m_vao = nullptr;
} }
bool GLShaderTVArray::SelectRow(int intLine) bool GLShaderTVArray::SelectRow(int intLine)

View File

@ -26,6 +26,8 @@
#include <QOpenGLFunctions_3_0> #include <QOpenGLFunctions_3_0>
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QMatrix4x4> #include <QMatrix4x4>
#include <QVector4D> #include <QVector4D>
#include <QDebug> #include <QDebug>
@ -45,7 +47,7 @@ public:
void setColor(bool blnColor) { m_blnColor = blnColor; } void setColor(bool blnColor) { m_blnColor = blnColor; }
void setAlphaBlend(bool blnAlphaBlend) { m_blnAlphaBlend = blnAlphaBlend; } void setAlphaBlend(bool blnAlphaBlend) { m_blnAlphaBlend = blnAlphaBlend; }
void setAlphaReset() { m_blnAlphaReset = true; } void setAlphaReset() { m_blnAlphaReset = true; }
void initializeGL(int intCols, int intRows); void initializeGL(int majorVersion, int minorVersion, int intCols, int intRows);
void cleanup(); void cleanup();
QRgb *GetRowBuffer(int intRow); QRgb *GetRowBuffer(int intRow);
void RenderPixels(unsigned char *chrData); void RenderPixels(unsigned char *chrData);
@ -57,10 +59,15 @@ public:
protected: protected:
QOpenGLShaderProgram *m_objProgram; QOpenGLShaderProgram *m_objProgram;
QOpenGLVertexArrayObject *m_vao;
QOpenGLBuffer *m_verticesBuf;
QOpenGLBuffer *m_textureCoordsBuf;
int m_matrixLoc; int m_matrixLoc;
int m_textureLoc; int m_textureLoc;
//int m_objColorLoc; //int m_objColorLoc;
static const QString m_strVertexShaderSourceArray2;
static const QString m_strVertexShaderSourceArray; static const QString m_strVertexShaderSourceArray;
static const QString m_strFragmentShaderSourceColored2;
static const QString m_strFragmentShaderSourceColored; static const QString m_strFragmentShaderSourceColored;
QImage *m_objImage; QImage *m_objImage;

View File

@ -178,7 +178,13 @@ void TVScreen::paintGL()
if ((m_askedCols != 0) && (m_askedRows != 0)) if ((m_askedCols != 0) && (m_askedRows != 0))
{ {
m_glShaderArray.initializeGL(m_askedCols, m_askedRows); int major = 0, minor = 0;
if (QOpenGLContext::currentContext())
{
major = QOpenGLContext::currentContext()->format().majorVersion();
minor = QOpenGLContext::currentContext()->format().minorVersion();
}
m_glShaderArray.initializeGL(major, minor, m_askedCols, m_askedRows);
m_askedCols = 0; m_askedCols = 0;
m_askedRows = 0; m_askedRows = 0;
} }

View File

@ -21,7 +21,7 @@
#include "tvscreenanalog.h" #include "tvscreenanalog.h"
static const char* vertexShaderSource = static const char* vertexShaderSource2 =
"attribute highp vec4 vertex;\n" "attribute highp vec4 vertex;\n"
"attribute highp vec2 texCoord;\n" "attribute highp vec2 texCoord;\n"
"varying highp vec2 texCoordVar;\n" "varying highp vec2 texCoordVar;\n"
@ -30,7 +30,17 @@ static const char* vertexShaderSource =
" texCoordVar = texCoord;\n" " texCoordVar = texCoord;\n"
"}\n"; "}\n";
static const char* fragmentShaderSource = static const char* vertexShaderSource =
"#version 330\n"
"in highp vec4 vertex;\n"
"in highp vec2 texCoord;\n"
"out highp vec2 texCoordVar;\n"
"void main() {\n"
" gl_Position = vertex;\n"
" texCoordVar = texCoord;\n"
"}\n";
static const char* fragmentShaderSource2 =
"uniform highp sampler2D tex1;\n" "uniform highp sampler2D tex1;\n"
"uniform highp sampler2D tex2;\n" "uniform highp sampler2D tex2;\n"
"uniform highp float imw;\n" "uniform highp float imw;\n"
@ -64,9 +74,48 @@ static const char* fragmentShaderSource =
" gl_FragColor = vec4(p);\n" " gl_FragColor = vec4(p);\n"
"}\n"; "}\n";
static const char* fragmentShaderSource =
"#version 330\n"
"uniform highp sampler2D tex1;\n"
"uniform highp sampler2D tex2;\n"
"uniform highp float imw;\n"
"uniform highp float imh;\n"
"uniform highp float tlw;\n"
"uniform highp float tlh;\n"
"in highp vec2 texCoordVar;\n"
"out vec4 fragColor;\n"
"void main() {\n"
" float tlhw = 0.5 * tlw;"
" float tlhh = 0.5 * tlh;"
" float tys = (texCoordVar.y + tlhh) * imh;\n"
" float p1y = floor(tys) * tlh - tlhh;\n"
" float p3y = p1y + tlh;\n"
" float tshift1 = texture2D(tex2, vec2(0.0, p1y)).r;\n"
" float tshift3 = texture2D(tex2, vec2(0.0, p3y)).r;\n"
" float shift1 = (1.0 - tshift1 * 2.0) * tlw;\n"
" float shift3 = (1.0 - tshift3 * 2.0) * tlw;\n"
" float txs1 = (texCoordVar.x + shift1 + tlhw) * imw;\n"
" float txs3 = (texCoordVar.x + shift3 + tlhw) * imw;\n"
" float p1x = floor(txs1) * tlw - tlhw;\n"
" float p3x = floor(txs3) * tlw - tlhw;\n"
" float p2x = p1x + tlw;\n"
" float p4x = p3x + tlw;\n"
" float p1 = texture(tex1, vec2(p1x, p1y)).r;\n"
" float p2 = texture(tex1, vec2(p2x, p1y)).r;\n"
" float p3 = texture(tex1, vec2(p3x, p3y)).r;\n"
" float p4 = texture(tex1, vec2(p4x, p3y)).r;\n"
" float p12 = mix(p1, p2, fract(txs1));\n"
" float p34 = mix(p3, p4, fract(txs3));\n"
" float p = mix(p12, p34, fract(tys));\n"
" fragColor = vec4(p);\n"
"}\n";
TVScreenAnalog::TVScreenAnalog(QWidget *parent) : TVScreenAnalog::TVScreenAnalog(QWidget *parent) :
QOpenGLWidget(parent), QOpenGLWidget(parent),
m_shader(nullptr), m_shader(nullptr),
m_vao(nullptr),
m_verticesBuf(nullptr),
m_textureCoordsBuf(nullptr),
m_imageTexture(nullptr), m_imageTexture(nullptr),
m_lineShiftsTexture(nullptr) m_lineShiftsTexture(nullptr)
{ {
@ -107,6 +156,13 @@ void TVScreenAnalog::cleanup()
delete m_lineShiftsTexture; delete m_lineShiftsTexture;
m_lineShiftsTexture = nullptr; m_lineShiftsTexture = nullptr;
} }
delete m_verticesBuf;
m_verticesBuf = nullptr;
delete m_textureCoordsBuf;
m_textureCoordsBuf = nullptr;
delete m_vao;
m_vao = nullptr;
} }
TVScreenAnalogBuffer *TVScreenAnalog::getBackBuffer() TVScreenAnalogBuffer *TVScreenAnalog::getBackBuffer()
@ -147,6 +203,14 @@ void TVScreenAnalog::initializeGL()
m_shader = new QOpenGLShaderProgram(this); m_shader = new QOpenGLShaderProgram(this);
int majorVersion = 0, minorVersion = 0;
if (QOpenGLContext::currentContext())
{
majorVersion = QOpenGLContext::currentContext()->format().majorVersion();
minorVersion = QOpenGLContext::currentContext()->format().minorVersion();
}
if ((majorVersion > 3) || ((majorVersion == 3) && (minorVersion >= 3)))
{
if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource)) if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource))
{ {
qWarning() qWarning()
@ -163,6 +227,29 @@ void TVScreenAnalog::initializeGL()
return; return;
} }
m_vao = new QOpenGLVertexArrayObject();
m_vao->create();
m_vao->bind();
}
else
{
if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource2))
{
qWarning()
<< "TVScreenAnalog::initializeGL: error in vertex shader:"
<< m_shader->log();
return;
}
if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource2))
{
qWarning()
<< "TVScreenAnalog::initializeGL: error in fragment shader:"
<< m_shader->log();
return;
}
}
if (!m_shader->link()) if (!m_shader->link())
{ {
qWarning() qWarning()
@ -179,6 +266,16 @@ void TVScreenAnalog::initializeGL()
m_imageHeightLoc = m_shader->uniformLocation("imh"); m_imageHeightLoc = m_shader->uniformLocation("imh");
m_texelWidthLoc = m_shader->uniformLocation("tlw"); m_texelWidthLoc = m_shader->uniformLocation("tlw");
m_texelHeightLoc = m_shader->uniformLocation("tlh"); m_texelHeightLoc = m_shader->uniformLocation("tlh");
if (m_vao)
{
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();
}
} }
void TVScreenAnalog::initializeTextures(TVScreenAnalogBuffer *buffer) void TVScreenAnalog::initializeTextures(TVScreenAnalogBuffer *buffer)
@ -280,13 +377,40 @@ void TVScreenAnalog::paintGL()
1.0f, 1.0f 1.0f, 1.0f
}; };
if (m_vao)
{
m_vao->bind();
m_verticesBuf->bind();
m_verticesBuf->allocate(vertices, 4 * 2 * sizeof(GL_FLOAT));
m_shader->enableAttributeArray(m_vertexAttribIndex);
m_shader->setAttributeBuffer(m_vertexAttribIndex, GL_FLOAT, 0, 2);
// As these coords are constant, this could be moved into the init method
m_textureCoordsBuf->bind();
m_textureCoordsBuf->allocate(arrTextureCoords, 4 * 2 * sizeof(GL_FLOAT));
m_shader->enableAttributeArray(m_texCoordAttribIndex);
m_shader->setAttributeBuffer(m_texCoordAttribIndex, GL_FLOAT, 0, 2);
}
else
{
glVertexAttribPointer(m_vertexAttribIndex, 2, GL_FLOAT, GL_FALSE, 0, vertices); glVertexAttribPointer(m_vertexAttribIndex, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(m_vertexAttribIndex); glEnableVertexAttribArray(m_vertexAttribIndex);
glVertexAttribPointer(m_texCoordAttribIndex, 2, GL_FLOAT, GL_FALSE, 0, arrTextureCoords); glVertexAttribPointer(m_texCoordAttribIndex, 2, GL_FLOAT, GL_FALSE, 0, arrTextureCoords);
glEnableVertexAttribArray(m_texCoordAttribIndex); glEnableVertexAttribArray(m_texCoordAttribIndex);
}
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if (m_vao)
{
m_vao->release();
}
else
{
glDisableVertexAttribArray(m_vertexAttribIndex); glDisableVertexAttribArray(m_vertexAttribIndex);
glDisableVertexAttribArray(m_texCoordAttribIndex); glDisableVertexAttribArray(m_texCoordAttribIndex);
}
m_shader->release(); m_shader->release();
} }

View File

@ -31,6 +31,8 @@
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <QOpenGLFunctions> #include <QOpenGLFunctions>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
class TVScreenAnalogBuffer class TVScreenAnalogBuffer
{ {
@ -130,6 +132,9 @@ class SDRGUI_API TVScreenAnalog : public QOpenGLWidget, protected QOpenGLFunctio
TVScreenAnalogBuffer *m_backBuffer; TVScreenAnalogBuffer *m_backBuffer;
QOpenGLShaderProgram *m_shader; QOpenGLShaderProgram *m_shader;
QOpenGLVertexArrayObject *m_vao;
QOpenGLBuffer *m_verticesBuf;
QOpenGLBuffer *m_textureCoordsBuf;
QOpenGLTexture *m_imageTexture; QOpenGLTexture *m_imageTexture;
QOpenGLTexture *m_lineShiftsTexture; QOpenGLTexture *m_lineShiftsTexture;