kopia lustrzana https://github.com/f4exb/sdrangel
OpenGL modernization: draw the waterfall the new way
rodzic
3aabeb4399
commit
c5a45e57ee
|
@ -36,6 +36,7 @@ public:
|
||||||
|
|
||||||
void initializeGL();
|
void initializeGL();
|
||||||
void initTexture(const QImage& image);
|
void initTexture(const QImage& image);
|
||||||
|
void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels);
|
||||||
void drawSurface(const QMatrix4x4& transformMatrix, GLfloat* textureCoords, GLfloat *vertices, int nbVertices);
|
void drawSurface(const QMatrix4x4& transformMatrix, GLfloat* textureCoords, GLfloat *vertices, int nbVertices);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
|
|
|
@ -180,9 +180,12 @@ private:
|
||||||
GLShaderSimple m_glShaderSimple;
|
GLShaderSimple m_glShaderSimple;
|
||||||
GLShaderTextured m_glShaderLeftScale;
|
GLShaderTextured m_glShaderLeftScale;
|
||||||
GLShaderTextured m_glShaderFrequencyScale;
|
GLShaderTextured m_glShaderFrequencyScale;
|
||||||
|
GLShaderTextured m_glShaderWaterfall;
|
||||||
int m_matrixLoc;
|
int m_matrixLoc;
|
||||||
int m_colorLoc;
|
int m_colorLoc;
|
||||||
|
|
||||||
|
static const int m_waterfallBufferHeight = 256;
|
||||||
|
|
||||||
void updateWaterfall(const std::vector<Real>& spectrum);
|
void updateWaterfall(const std::vector<Real>& spectrum);
|
||||||
void updateHistogram(const std::vector<Real>& spectrum);
|
void updateHistogram(const std::vector<Real>& spectrum);
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,18 @@ void GLShaderTextured::initTexture(const QImage& image)
|
||||||
m_texture->setWrapMode(QOpenGLTexture::Repeat);
|
m_texture->setWrapMode(QOpenGLTexture::Repeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLShaderTextured::subTexture(int xOffset, int yOffset, int width, int height, const void *pixels)
|
||||||
|
{
|
||||||
|
if (!m_texture) {
|
||||||
|
qDebug("GLShaderTextured::subTexture: no texture defined. Doing nothing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||||
|
m_texture->bind();
|
||||||
|
f->glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
}
|
||||||
|
|
||||||
void GLShaderTextured::drawSurface(const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices)
|
void GLShaderTextured::drawSurface(const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices)
|
||||||
{
|
{
|
||||||
draw(GL_TRIANGLE_FAN, transformMatrix, textureCoords, vertices, nbVertices);
|
draw(GL_TRIANGLE_FAN, transformMatrix, textureCoords, vertices, nbVertices);
|
||||||
|
|
|
@ -512,6 +512,7 @@ void GLSpectrum::initializeGL()
|
||||||
m_glShaderSimple.initializeGL();
|
m_glShaderSimple.initializeGL();
|
||||||
m_glShaderLeftScale.initializeGL();
|
m_glShaderLeftScale.initializeGL();
|
||||||
m_glShaderFrequencyScale.initializeGL();
|
m_glShaderFrequencyScale.initializeGL();
|
||||||
|
m_glShaderWaterfall.initializeGL();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLSpectrum::resizeGL(int width, int height)
|
void GLSpectrum::resizeGL(int width, int height)
|
||||||
|
@ -556,10 +557,7 @@ void GLSpectrum::paintGL()
|
||||||
// paint waterfall
|
// paint waterfall
|
||||||
if (m_displayWaterfall)
|
if (m_displayWaterfall)
|
||||||
{
|
{
|
||||||
glPushMatrix();
|
#ifdef GL_DEPRECATED
|
||||||
glTranslatef(m_glWaterfallRect.x(), m_glWaterfallRect.y(), 0);
|
|
||||||
glScalef(m_glWaterfallRect.width(), m_glWaterfallRect.height(), 1);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_waterfallTexture);
|
glBindTexture(GL_TEXTURE_2D, m_waterfallTexture);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
@ -575,9 +573,13 @@ void GLSpectrum::paintGL()
|
||||||
|
|
||||||
float prop_y = m_waterfallTexturePos / (m_waterfallTextureHeight - 1.0);
|
float prop_y = m_waterfallTexturePos / (m_waterfallTextureHeight - 1.0);
|
||||||
float off = 1.0 / (m_waterfallTextureHeight - 1.0);
|
float off = 1.0 / (m_waterfallTextureHeight - 1.0);
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(m_glWaterfallRect.x(), m_glWaterfallRect.y(), 0);
|
||||||
|
glScalef(m_glWaterfallRect.width(), m_glWaterfallRect.height(), 1);
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
#ifdef GL_DEPRECATED
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f(0, prop_y + 1 - off);
|
glTexCoord2f(0, prop_y + 1 - off);
|
||||||
glVertex2f(0, m_invertedWaterfall ? 0 : 1);
|
glVertex2f(0, m_invertedWaterfall ? 0 : 1);
|
||||||
|
@ -588,6 +590,9 @@ void GLSpectrum::paintGL()
|
||||||
glTexCoord2f(0, prop_y);
|
glTexCoord2f(0, prop_y);
|
||||||
glVertex2f(0, m_invertedWaterfall ? 1 : 0);
|
glVertex2f(0, m_invertedWaterfall ? 1 : 0);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glPopMatrix();
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
GLfloat vtx1[] = {
|
GLfloat vtx1[] = {
|
||||||
|
@ -596,6 +601,19 @@ void GLSpectrum::paintGL()
|
||||||
1, m_invertedWaterfall ? 1.0f : 0.0f,
|
1, m_invertedWaterfall ? 1.0f : 0.0f,
|
||||||
0, m_invertedWaterfall ? 1.0f : 0.0f
|
0, m_invertedWaterfall ? 1.0f : 0.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < m_waterfallBufferPos; i++)
|
||||||
|
{
|
||||||
|
m_glShaderWaterfall.subTexture(0, m_waterfallTexturePos, m_fftSize, 1, m_waterfallBuffer->scanLine(i));
|
||||||
|
m_waterfallTexturePos = (m_waterfallTexturePos + 1) % m_waterfallTextureHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_waterfallBufferPos = 0;
|
||||||
|
|
||||||
|
float prop_y = m_waterfallTexturePos / (m_waterfallTextureHeight - 1.0);
|
||||||
|
float off = 1.0 / (m_waterfallTextureHeight - 1.0);
|
||||||
|
|
||||||
GLfloat tex1[] = {
|
GLfloat tex1[] = {
|
||||||
0, prop_y + 1 - off,
|
0, prop_y + 1 - off,
|
||||||
1, prop_y + 1 - off,
|
1, prop_y + 1 - off,
|
||||||
|
@ -603,27 +621,9 @@ void GLSpectrum::paintGL()
|
||||||
0, prop_y
|
0, prop_y
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef GL_ANDROID
|
m_glShaderWaterfall.drawSurface(m_glWaterfallBoxMatrix, tex1, vtx1, 4);
|
||||||
glEnableVertexAttribArray(GL_VERTEX_ARRAY);
|
|
||||||
glEnableVertexAttribArray(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glVertexAttribPointer(GL_VERTEX_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, vtx1);
|
|
||||||
glVertexAttribPointer(GL_TEXTURE_COORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, tex1);
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
||||||
glDisableVertexAttribArray(GL_VERTEX_ARRAY);
|
|
||||||
glDisableVertexAttribArray(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
#else
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glVertexPointer(2, GL_FLOAT, 0, vtx1);
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, tex1);
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glPopMatrix();
|
|
||||||
|
|
||||||
// paint channels
|
// paint channels
|
||||||
if (m_mouseInside)
|
if (m_mouseInside)
|
||||||
|
@ -1998,25 +1998,52 @@ void GLSpectrum::applyChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fftSizeChanged = true;
|
bool fftSizeChanged = true;
|
||||||
if(m_waterfallBuffer != NULL)
|
|
||||||
|
if(m_waterfallBuffer != NULL) {
|
||||||
fftSizeChanged = m_waterfallBuffer->width() != m_fftSize;
|
fftSizeChanged = m_waterfallBuffer->width() != m_fftSize;
|
||||||
|
}
|
||||||
|
|
||||||
bool windowSizeChanged = m_waterfallTextureHeight != waterfallHeight;
|
bool windowSizeChanged = m_waterfallTextureHeight != waterfallHeight;
|
||||||
|
|
||||||
|
if (fftSizeChanged || windowSizeChanged)
|
||||||
|
{
|
||||||
|
if(m_waterfallBuffer != 0) {
|
||||||
|
delete m_waterfallBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_waterfallBuffer = new QImage(m_fftSize, waterfallHeight, QImage::Format_ARGB32);
|
||||||
|
|
||||||
|
if(m_waterfallBuffer != 0)
|
||||||
|
{
|
||||||
|
m_waterfallBuffer->fill(qRgb(0x00, 0x00, 0x00));
|
||||||
|
m_glShaderWaterfall.initTexture(*m_waterfallBuffer);
|
||||||
|
m_waterfallBufferPos = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_fftSize = 0;
|
||||||
|
m_changesPending = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(fftSizeChanged) {
|
if(fftSizeChanged) {
|
||||||
|
#ifdef GL_DEPRECATED
|
||||||
if(m_waterfallBuffer != NULL) {
|
if(m_waterfallBuffer != NULL) {
|
||||||
delete m_waterfallBuffer;
|
delete m_waterfallBuffer;
|
||||||
m_waterfallBuffer = NULL;
|
m_waterfallBuffer = NULL;
|
||||||
}
|
}
|
||||||
m_waterfallBuffer = new QImage(m_fftSize, 256, QImage::Format_ARGB32);
|
m_waterfallBuffer = new QImage(m_fftSize, m_waterfallBufferHeight, QImage::Format_ARGB32);
|
||||||
if(m_waterfallBuffer != NULL) {
|
if(m_waterfallBuffer != NULL) {
|
||||||
m_waterfallBuffer->fill(qRgb(0x00, 0x00, 0x00));
|
m_waterfallBuffer->fill(qRgb(0x00, 0x00, 0x00));
|
||||||
|
m_glShaderWaterfall.initTexture(*m_waterfallBuffer);
|
||||||
m_waterfallBufferPos = 0;
|
m_waterfallBufferPos = 0;
|
||||||
} else {
|
} else {
|
||||||
m_fftSize = 0;
|
m_fftSize = 0;
|
||||||
m_changesPending = true;
|
m_changesPending = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if(m_histogramBuffer != NULL) {
|
if(m_histogramBuffer != NULL) {
|
||||||
delete m_histogramBuffer;
|
delete m_histogramBuffer;
|
||||||
m_histogramBuffer = NULL;
|
m_histogramBuffer = NULL;
|
||||||
|
|
Ładowanie…
Reference in New Issue