OpenGL: Reinstate support for OpenGL geometry shaders
Unlike QGLShader, this requires the OpenGL 3.2 core implementation of geometry shaders to keep the API simple. Change-Id: Icb07f430c4c5b5d950bcf6f7119becec4cfaad8a Reviewed-by: James Turner <james.turner@kdab.com> Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
This commit is contained in:
parent
05a61de622
commit
2c8c0cb33a
@ -103,6 +103,7 @@ typedef GLfloat GLdouble;
|
|||||||
#if !defined(QT_OPENGL_ES_2)
|
#if !defined(QT_OPENGL_ES_2)
|
||||||
# if !defined(Q_OS_MAC) || (defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
# if !defined(Q_OS_MAC) || (defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
||||||
# define QT_OPENGL_3
|
# define QT_OPENGL_3
|
||||||
|
# define QT_OPENGL_3_2
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -145,6 +145,8 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
\value Vertex Vertex shader written in the OpenGL Shading Language (GLSL).
|
\value Vertex Vertex shader written in the OpenGL Shading Language (GLSL).
|
||||||
\value Fragment Fragment shader written in the OpenGL Shading Language (GLSL).
|
\value Fragment Fragment shader written in the OpenGL Shading Language (GLSL).
|
||||||
|
\value Geometry Geometry shaders written in the OpenGL Shading Language (GLSL)
|
||||||
|
based on the OpenGL core feature (requires OpenGL >= 3.2).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class QOpenGLShaderPrivate : public QObjectPrivate
|
class QOpenGLShaderPrivate : public QObjectPrivate
|
||||||
@ -156,7 +158,17 @@ public:
|
|||||||
, shaderType(type)
|
, shaderType(type)
|
||||||
, compiled(false)
|
, compiled(false)
|
||||||
, glfuncs(new QOpenGLFunctions(ctx))
|
, glfuncs(new QOpenGLFunctions(ctx))
|
||||||
|
#ifndef QT_OPENGL_ES_2
|
||||||
|
, supportsGeometryShaders(false)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifndef QT_OPENGL_ES_2
|
||||||
|
// Geometry shaders require OpenGL >= 3.2
|
||||||
|
if (shaderType & QOpenGLShader::Geometry) {
|
||||||
|
QSurfaceFormat f = ctx->format();
|
||||||
|
supportsGeometryShaders = (f.version() >= qMakePair<int, int>(3, 2));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
~QOpenGLShaderPrivate();
|
~QOpenGLShaderPrivate();
|
||||||
|
|
||||||
@ -167,6 +179,11 @@ public:
|
|||||||
|
|
||||||
QOpenGLFunctions *glfuncs;
|
QOpenGLFunctions *glfuncs;
|
||||||
|
|
||||||
|
#ifndef QT_OPENGL_ES_2
|
||||||
|
// Support for geometry shaders
|
||||||
|
bool supportsGeometryShaders;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool create();
|
bool create();
|
||||||
bool compile(QOpenGLShader *q);
|
bool compile(QOpenGLShader *q);
|
||||||
void deleteShader();
|
void deleteShader();
|
||||||
@ -192,10 +209,15 @@ bool QOpenGLShaderPrivate::create()
|
|||||||
if (!context)
|
if (!context)
|
||||||
return false;
|
return false;
|
||||||
GLuint shader;
|
GLuint shader;
|
||||||
if (shaderType == QOpenGLShader::Vertex)
|
if (shaderType == QOpenGLShader::Vertex) {
|
||||||
shader = glfuncs->glCreateShader(GL_VERTEX_SHADER);
|
shader = glfuncs->glCreateShader(GL_VERTEX_SHADER);
|
||||||
else
|
#if defined(QT_OPENGL_3_2)
|
||||||
|
} else if (shaderType == QOpenGLShader::Geometry && supportsGeometryShaders) {
|
||||||
|
shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
shader = glfuncs->glCreateShader(GL_FRAGMENT_SHADER);
|
shader = glfuncs->glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
}
|
||||||
if (!shader) {
|
if (!shader) {
|
||||||
qWarning() << "QOpenGLShader: could not create shader";
|
qWarning() << "QOpenGLShader: could not create shader";
|
||||||
return false;
|
return false;
|
||||||
@ -234,6 +256,8 @@ bool QOpenGLShaderPrivate::compile(QOpenGLShader *q)
|
|||||||
type = types[0];
|
type = types[0];
|
||||||
else if (shaderType == QOpenGLShader::Vertex)
|
else if (shaderType == QOpenGLShader::Vertex)
|
||||||
type = types[1];
|
type = types[1];
|
||||||
|
else if (shaderType == QOpenGLShader::Geometry)
|
||||||
|
type = types[2];
|
||||||
|
|
||||||
// Get info and source code lengths
|
// Get info and source code lengths
|
||||||
GLint infoLogLength = 0;
|
GLint infoLogLength = 0;
|
||||||
@ -2926,6 +2950,19 @@ void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4
|
|||||||
setUniformValueArray(uniformLocation(name), values, count);
|
setUniformValueArray(uniformLocation(name), values, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the hardware limit for how many vertices a geometry shader
|
||||||
|
can output.
|
||||||
|
*/
|
||||||
|
int QOpenGLShaderProgram::maxGeometryOutputVertices() const
|
||||||
|
{
|
||||||
|
GLint n = 0;
|
||||||
|
#if defined(QT_OPENGL_3_2)
|
||||||
|
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &n);
|
||||||
|
#endif
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns true if shader programs written in the OpenGL Shading
|
Returns true if shader programs written in the OpenGL Shading
|
||||||
Language (GLSL) are supported on this system; false otherwise.
|
Language (GLSL) are supported on this system; false otherwise.
|
||||||
@ -2972,9 +3009,22 @@ bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context)
|
|||||||
if (!context)
|
if (!context)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((type & ~(Vertex | Fragment)) || type == 0)
|
if ((type & ~(Geometry | Vertex | Fragment)) || type == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (type == Geometry) {
|
||||||
|
#ifndef QT_OPENGL_ES_2
|
||||||
|
// Geometry shaders require OpenGL 3.2 or newer
|
||||||
|
QSurfaceFormat format = context->format();
|
||||||
|
return (format.version() >= qMakePair<int, int>(3, 2));
|
||||||
|
#else
|
||||||
|
// No geometry shader support in OpenGL ES2
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unconditional support of vertex and fragment shaders implicitly assumes
|
||||||
|
// a minimum OpenGL version of 2.0
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,8 @@ public:
|
|||||||
enum ShaderTypeBit
|
enum ShaderTypeBit
|
||||||
{
|
{
|
||||||
Vertex = 0x0001,
|
Vertex = 0x0001,
|
||||||
Fragment = 0x0002
|
Fragment = 0x0002,
|
||||||
|
Geometry = 0x0004
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit)
|
Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit)
|
||||||
|
|
||||||
@ -126,6 +127,8 @@ public:
|
|||||||
|
|
||||||
GLuint programId() const;
|
GLuint programId() const;
|
||||||
|
|
||||||
|
int maxGeometryOutputVertices() const;
|
||||||
|
|
||||||
void bindAttributeLocation(const char *name, int location);
|
void bindAttributeLocation(const char *name, int location);
|
||||||
void bindAttributeLocation(const QByteArray& name, int location);
|
void bindAttributeLocation(const QByteArray& name, int location);
|
||||||
void bindAttributeLocation(const QString& name, int location);
|
void bindAttributeLocation(const QString& name, int location);
|
||||||
|
Loading…
Reference in New Issue
Block a user