|
|
@ -24,6 +24,8 @@ |
|
|
|
#include "openglsurfacepainter.h" |
|
|
|
#include "openglsurfacepainter.h" |
|
|
|
#include <QtCore/qmath.h> |
|
|
|
#include <QtCore/qmath.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "glutils.h" |
|
|
|
|
|
|
|
|
|
|
|
#ifndef GL_TEXTURE0 |
|
|
|
#ifndef GL_TEXTURE0 |
|
|
|
# define GL_TEXTURE0 0x84C0 |
|
|
|
# define GL_TEXTURE0 0x84C0 |
|
|
|
# define GL_TEXTURE1 0x84C1 |
|
|
|
# define GL_TEXTURE1 0x84C1 |
|
|
@ -58,8 +60,7 @@ OpenGLSurfacePainter::OpenGLSurfacePainter() |
|
|
|
, m_videoColorMatrix(GST_VIDEO_COLOR_MATRIX_UNKNOWN) |
|
|
|
, m_videoColorMatrix(GST_VIDEO_COLOR_MATRIX_UNKNOWN) |
|
|
|
{ |
|
|
|
{ |
|
|
|
#ifndef QT_OPENGL_ES |
|
|
|
#ifndef QT_OPENGL_ES |
|
|
|
glActiveTexture = (_glActiveTexture) QGLContext::currentContext()->getProcAddress( |
|
|
|
glActiveTexture = (_glActiveTexture) QGLContext::currentContext()->getProcAddress(QLatin1String("glActiveTexture")); |
|
|
|
QLatin1String("glActiveTexture")); |
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -178,24 +179,28 @@ void OpenGLSurfacePainter::paint(quint8 *data, |
|
|
|
QPainter *painter, |
|
|
|
QPainter *painter, |
|
|
|
const PaintAreas & areas) |
|
|
|
const PaintAreas & areas) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); |
|
|
|
|
|
|
|
if (!funcs) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
// if these are enabled, we need to reenable them after beginNativePainting()
|
|
|
|
// if these are enabled, we need to reenable them after beginNativePainting()
|
|
|
|
// has been called, as they may get disabled
|
|
|
|
// has been called, as they may get disabled
|
|
|
|
bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST); |
|
|
|
bool stencilTestEnabled = funcs->glIsEnabled(GL_STENCIL_TEST); |
|
|
|
bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST); |
|
|
|
bool scissorTestEnabled = funcs->glIsEnabled(GL_SCISSOR_TEST); |
|
|
|
|
|
|
|
|
|
|
|
painter->beginNativePainting(); |
|
|
|
painter->beginNativePainting(); |
|
|
|
|
|
|
|
|
|
|
|
if (stencilTestEnabled) |
|
|
|
if (stencilTestEnabled) |
|
|
|
glEnable(GL_STENCIL_TEST); |
|
|
|
funcs->glEnable(GL_STENCIL_TEST); |
|
|
|
if (scissorTestEnabled) |
|
|
|
if (scissorTestEnabled) |
|
|
|
glEnable(GL_SCISSOR_TEST); |
|
|
|
funcs->glEnable(GL_SCISSOR_TEST); |
|
|
|
|
|
|
|
|
|
|
|
const GLfloat vertexCoordArray[] = QRECT_TO_GLMATRIX(areas.videoArea); |
|
|
|
const GLfloat vertexCoordArray[] = QRECT_TO_GLMATRIX(areas.videoArea); |
|
|
|
|
|
|
|
|
|
|
|
const GLfloat txLeft = areas.sourceRect.left(); |
|
|
|
const GLfloat txLeft = areas.sourceRect.left(); |
|
|
|
const GLfloat txRight = areas.sourceRect.right(); |
|
|
|
const GLfloat txRight = areas.sourceRect.right(); |
|
|
|
const GLfloat txTop = areas.sourceRect.top(); |
|
|
|
const GLfloat txTop = areas.sourceRect.top(); |
|
|
|
const GLfloat txBottom = areas.sourceRect.bottom(); |
|
|
|
const GLfloat txBottom = areas.sourceRect.bottom(); |
|
|
|
|
|
|
|
|
|
|
|
const GLfloat textureCoordArray[] = |
|
|
|
const GLfloat textureCoordArray[] = |
|
|
|
{ |
|
|
|
{ |
|
|
@ -206,8 +211,8 @@ void OpenGLSurfacePainter::paint(quint8 *data, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < m_textureCount; ++i) { |
|
|
|
for (int i = 0; i < m_textureCount; ++i) { |
|
|
|
glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); |
|
|
|
funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); |
|
|
|
glTexImage2D( |
|
|
|
funcs->glTexImage2D( |
|
|
|
GL_TEXTURE_2D, |
|
|
|
GL_TEXTURE_2D, |
|
|
|
0, |
|
|
|
0, |
|
|
|
m_textureInternalFormat, |
|
|
|
m_textureInternalFormat, |
|
|
@ -217,10 +222,10 @@ void OpenGLSurfacePainter::paint(quint8 *data, |
|
|
|
m_textureFormat, |
|
|
|
m_textureFormat, |
|
|
|
m_textureType, |
|
|
|
m_textureType, |
|
|
|
data + m_textureOffsets[i]); |
|
|
|
data + m_textureOffsets[i]); |
|
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
|
|
|
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
|
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
|
|
|
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
|
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
|
|
|
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
|
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
|
|
|
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
paintImpl(painter, vertexCoordArray, textureCoordArray); |
|
|
|
paintImpl(painter, vertexCoordArray, textureCoordArray); |
|
|
@ -392,22 +397,19 @@ ArbFpSurfacePainter::ArbFpSurfacePainter() |
|
|
|
, m_programId(0) |
|
|
|
, m_programId(0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const QGLContext *context = QGLContext::currentContext(); |
|
|
|
const QGLContext *context = QGLContext::currentContext(); |
|
|
|
|
|
|
|
glProgramStringARB = (_glProgramStringARB) context->getProcAddress(QLatin1String("glProgramStringARB")); |
|
|
|
glProgramStringARB = (_glProgramStringARB) context->getProcAddress( |
|
|
|
glBindProgramARB = (_glBindProgramARB) context->getProcAddress(QLatin1String("glBindProgramARB")); |
|
|
|
QLatin1String("glProgramStringARB")); |
|
|
|
glDeleteProgramsARB = (_glDeleteProgramsARB) context->getProcAddress(QLatin1String("glDeleteProgramsARB")); |
|
|
|
glBindProgramARB = (_glBindProgramARB) context->getProcAddress( |
|
|
|
glGenProgramsARB = (_glGenProgramsARB) context->getProcAddress(QLatin1String("glGenProgramsARB")); |
|
|
|
QLatin1String("glBindProgramARB")); |
|
|
|
glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) context->getProcAddress(QLatin1String("glProgramLocalParameter4fARB")); |
|
|
|
glDeleteProgramsARB = (_glDeleteProgramsARB) context->getProcAddress( |
|
|
|
|
|
|
|
QLatin1String("glDeleteProgramsARB")); |
|
|
|
|
|
|
|
glGenProgramsARB = (_glGenProgramsARB) context->getProcAddress( |
|
|
|
|
|
|
|
QLatin1String("glGenProgramsARB")); |
|
|
|
|
|
|
|
glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) context->getProcAddress( |
|
|
|
|
|
|
|
QLatin1String("glProgramLocalParameter4fARB")); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ArbFpSurfacePainter::init(const BufferFormat &format) |
|
|
|
void ArbFpSurfacePainter::init(const BufferFormat &format) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Q_ASSERT(m_textureCount == 0); |
|
|
|
Q_ASSERT(m_textureCount == 0); |
|
|
|
|
|
|
|
QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); |
|
|
|
|
|
|
|
if (!funcs) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
const char *program = 0; |
|
|
|
const char *program = 0; |
|
|
|
|
|
|
|
|
|
|
@ -467,7 +469,7 @@ void ArbFpSurfacePainter::init(const BufferFormat &format) |
|
|
|
|
|
|
|
|
|
|
|
glGenProgramsARB(1, &m_programId); |
|
|
|
glGenProgramsARB(1, &m_programId); |
|
|
|
|
|
|
|
|
|
|
|
GLenum glError = glGetError(); |
|
|
|
GLenum glError = funcs->glGetError(); |
|
|
|
if (glError != GL_NO_ERROR) { |
|
|
|
if (glError != GL_NO_ERROR) { |
|
|
|
throw QString("ARBfb Shader allocation error ") + |
|
|
|
throw QString("ARBfb Shader allocation error ") + |
|
|
|
QString::number(static_cast<int>(glError), 16); |
|
|
|
QString::number(static_cast<int>(glError), 16); |
|
|
@ -479,27 +481,28 @@ void ArbFpSurfacePainter::init(const BufferFormat &format) |
|
|
|
qstrlen(program), |
|
|
|
qstrlen(program), |
|
|
|
reinterpret_cast<const GLvoid *>(program)); |
|
|
|
reinterpret_cast<const GLvoid *>(program)); |
|
|
|
|
|
|
|
|
|
|
|
if ((glError = glGetError()) != GL_NO_ERROR) { |
|
|
|
if ((glError = funcs->glGetError()) != GL_NO_ERROR) { |
|
|
|
const GLubyte* errorString = glGetString(GL_PROGRAM_ERROR_STRING_ARB); |
|
|
|
const GLubyte* errorString = funcs->glGetString(GL_PROGRAM_ERROR_STRING_ARB); |
|
|
|
|
|
|
|
|
|
|
|
glDeleteProgramsARB(1, &m_programId); |
|
|
|
glDeleteProgramsARB(1, &m_programId); |
|
|
|
m_textureCount = 0; |
|
|
|
m_textureCount = 0; |
|
|
|
m_programId = 0; |
|
|
|
m_programId = 0; |
|
|
|
|
|
|
|
|
|
|
|
throw QString("ARBfp Shader compile error ") + |
|
|
|
throw QString("ARBfp Shader compile error ") + |
|
|
|
QString::number(static_cast<int>(glError), 16) + |
|
|
|
QString::number(static_cast<int>(glError), 16) + |
|
|
|
reinterpret_cast<const char *>(errorString); |
|
|
|
reinterpret_cast<const char *>(errorString); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
glGenTextures(m_textureCount, m_textureIds); |
|
|
|
funcs->glGenTextures(m_textureCount, m_textureIds); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ArbFpSurfacePainter::cleanup() |
|
|
|
void ArbFpSurfacePainter::cleanup() |
|
|
|
{ |
|
|
|
{ |
|
|
|
glDeleteTextures(m_textureCount, m_textureIds); |
|
|
|
QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); |
|
|
|
glDeleteProgramsARB(1, &m_programId); |
|
|
|
if (funcs) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
funcs->glDeleteTextures(m_textureCount, m_textureIds); |
|
|
|
|
|
|
|
glDeleteProgramsARB(1, &m_programId); |
|
|
|
|
|
|
|
} |
|
|
|
m_textureCount = 0; |
|
|
|
m_textureCount = 0; |
|
|
|
m_programId = 0; |
|
|
|
m_programId = 0; |
|
|
|
} |
|
|
|
} |
|
|
@ -509,8 +512,11 @@ void ArbFpSurfacePainter::paintImpl(const QPainter *painter, |
|
|
|
const GLfloat *textureCoordArray) |
|
|
|
const GLfloat *textureCoordArray) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Q_UNUSED(painter); |
|
|
|
Q_UNUSED(painter); |
|
|
|
|
|
|
|
QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); |
|
|
|
|
|
|
|
if (!funcs) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
glEnable(GL_FRAGMENT_PROGRAM_ARB); |
|
|
|
funcs->glEnable(GL_FRAGMENT_PROGRAM_ARB); |
|
|
|
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId); |
|
|
|
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId); |
|
|
|
|
|
|
|
|
|
|
|
glProgramLocalParameter4fARB( |
|
|
|
glProgramLocalParameter4fARB( |
|
|
@ -535,28 +541,28 @@ void ArbFpSurfacePainter::paintImpl(const QPainter *painter, |
|
|
|
m_colorMatrix(2, 2), |
|
|
|
m_colorMatrix(2, 2), |
|
|
|
m_colorMatrix(2, 3)); |
|
|
|
m_colorMatrix(2, 3)); |
|
|
|
|
|
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE0); |
|
|
|
funcs->glActiveTexture(GL_TEXTURE0); |
|
|
|
glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); |
|
|
|
funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); |
|
|
|
|
|
|
|
|
|
|
|
if (m_textureCount == 3) { |
|
|
|
if (m_textureCount == 3) { |
|
|
|
glActiveTexture(GL_TEXTURE1); |
|
|
|
funcs->glActiveTexture(GL_TEXTURE1); |
|
|
|
glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); |
|
|
|
funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); |
|
|
|
glActiveTexture(GL_TEXTURE2); |
|
|
|
funcs->glActiveTexture(GL_TEXTURE2); |
|
|
|
glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); |
|
|
|
funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); |
|
|
|
glActiveTexture(GL_TEXTURE0); |
|
|
|
funcs->glActiveTexture(GL_TEXTURE0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
glVertexPointer(2, GL_FLOAT, 0, vertexCoordArray); |
|
|
|
funcs->glVertexPointer(2, GL_FLOAT, 0, vertexCoordArray); |
|
|
|
glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray); |
|
|
|
funcs->glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray); |
|
|
|
|
|
|
|
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY); |
|
|
|
funcs->glEnableClientState(GL_VERTEX_ARRAY); |
|
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
|
|
funcs->glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
|
|
|
|
|
|
|
|
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
|
|
|
funcs->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
|
|
|
|
|
|
|
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY); |
|
|
|
funcs->glDisableClientState(GL_VERTEX_ARRAY); |
|
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
|
|
|
funcs->glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
|
|
|
glDisable(GL_FRAGMENT_PROGRAM_ARB); |
|
|
|
funcs->glDisable(GL_FRAGMENT_PROGRAM_ARB); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
@ -724,14 +730,19 @@ void GlslSurfacePainter::init(const BufferFormat &format) |
|
|
|
throw QString("Shader link error ") + m_program.log(); |
|
|
|
throw QString("Shader link error ") + m_program.log(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
glGenTextures(m_textureCount, m_textureIds); |
|
|
|
QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); |
|
|
|
|
|
|
|
if (funcs) |
|
|
|
|
|
|
|
funcs->glGenTextures(m_textureCount, m_textureIds); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void GlslSurfacePainter::cleanup() |
|
|
|
void GlslSurfacePainter::cleanup() |
|
|
|
{ |
|
|
|
{ |
|
|
|
glDeleteTextures(m_textureCount, m_textureIds); |
|
|
|
QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); |
|
|
|
m_program.removeAllShaders(); |
|
|
|
if (funcs) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
funcs->glDeleteTextures(m_textureCount, m_textureIds); |
|
|
|
|
|
|
|
m_program.removeAllShaders(); |
|
|
|
|
|
|
|
} |
|
|
|
m_textureCount = 0; |
|
|
|
m_textureCount = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -739,8 +750,8 @@ void GlslSurfacePainter::paintImpl(const QPainter *painter, |
|
|
|
const GLfloat *vertexCoordArray, |
|
|
|
const GLfloat *vertexCoordArray, |
|
|
|
const GLfloat *textureCoordArray) |
|
|
|
const GLfloat *textureCoordArray) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const int deviceWidth = painter->device()->width(); |
|
|
|
const int deviceWidth = painter->device()->width(); |
|
|
|
const int deviceHeight = painter->device()->height(); |
|
|
|
const int deviceHeight = painter->device()->height(); |
|
|
|
|
|
|
|
|
|
|
|
const QTransform transform = painter->deviceTransform(); |
|
|
|
const QTransform transform = painter->deviceTransform(); |
|
|
|
|
|
|
|
|
|
|
@ -780,27 +791,31 @@ void GlslSurfacePainter::paintImpl(const QPainter *painter, |
|
|
|
m_program.setAttributeArray("textureCoordArray", textureCoordArray, 2); |
|
|
|
m_program.setAttributeArray("textureCoordArray", textureCoordArray, 2); |
|
|
|
m_program.setUniformValue("positionMatrix", positionMatrix); |
|
|
|
m_program.setUniformValue("positionMatrix", positionMatrix); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); |
|
|
|
|
|
|
|
if (!funcs) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
if (m_textureCount == 3) { |
|
|
|
if (m_textureCount == 3) { |
|
|
|
glActiveTexture(GL_TEXTURE0); |
|
|
|
funcs->glActiveTexture(GL_TEXTURE0); |
|
|
|
glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); |
|
|
|
funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); |
|
|
|
glActiveTexture(GL_TEXTURE1); |
|
|
|
funcs->glActiveTexture(GL_TEXTURE1); |
|
|
|
glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); |
|
|
|
funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); |
|
|
|
glActiveTexture(GL_TEXTURE2); |
|
|
|
funcs->glActiveTexture(GL_TEXTURE2); |
|
|
|
glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); |
|
|
|
funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); |
|
|
|
glActiveTexture(GL_TEXTURE0); |
|
|
|
funcs->glActiveTexture(GL_TEXTURE0); |
|
|
|
|
|
|
|
|
|
|
|
m_program.setUniformValue("texY", 0); |
|
|
|
m_program.setUniformValue("texY", 0); |
|
|
|
m_program.setUniformValue("texU", 1); |
|
|
|
m_program.setUniformValue("texU", 1); |
|
|
|
m_program.setUniformValue("texV", 2); |
|
|
|
m_program.setUniformValue("texV", 2); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
glActiveTexture(GL_TEXTURE0); |
|
|
|
funcs->glActiveTexture(GL_TEXTURE0); |
|
|
|
glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); |
|
|
|
funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); |
|
|
|
|
|
|
|
|
|
|
|
m_program.setUniformValue("texRgb", 0); |
|
|
|
m_program.setUniformValue("texRgb", 0); |
|
|
|
} |
|
|
|
} |
|
|
|
m_program.setUniformValue("colorMatrix", m_colorMatrix); |
|
|
|
m_program.setUniformValue("colorMatrix", m_colorMatrix); |
|
|
|
|
|
|
|
|
|
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
|
|
|
funcs->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
|
|
|
|
|
|
|
|
|
|
|
m_program.release(); |
|
|
|
m_program.release(); |
|
|
|
} |
|
|
|
} |
|
|
|