summaryrefslogtreecommitdiffstats
path: root/src/opengl/qglshaderprogram.cpp
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar@trolltech.com>2010-02-01 13:30:01 (GMT)
committerGunnar Sletta <gunnar@trolltech.com>2010-02-01 13:30:01 (GMT)
commitfe849f50ca83f50f6068b7d494cb228fae1d6309 (patch)
tree64ae403632763d4e5d576cd600de2561872032f5 /src/opengl/qglshaderprogram.cpp
parentc06c254cf208840f14c9e562cae976f1a61f0879 (diff)
downloadQt-fe849f50ca83f50f6068b7d494cb228fae1d6309.zip
Qt-fe849f50ca83f50f6068b7d494cb228fae1d6309.tar.gz
Qt-fe849f50ca83f50f6068b7d494cb228fae1d6309.tar.bz2
Geometry Shader support in QGLShaderProgram
Diffstat (limited to 'src/opengl/qglshaderprogram.cpp')
-rw-r--r--src/opengl/qglshaderprogram.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index 5e2f1f5..43d1df8 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -213,6 +213,8 @@ bool QGLShaderPrivate::create()
GLuint shader;
if (shaderType == QGLShader::Vertex)
shader = glCreateShader(GL_VERTEX_SHADER);
+ else if (shaderType == QGLShader::Geometry)
+ shader = glCreateShader(GL_GEOMETRY_SHADER_EXT);
else
shader = glCreateShader(GL_FRAGMENT_SHADER);
if (!shader) {
@@ -496,6 +498,10 @@ GLuint QGLShader::shaderId() const
return d->shaderGuard.id();
}
+
+
+
+
#undef ctx
#define ctx programGuard.context()
@@ -508,8 +514,12 @@ public:
, linked(false)
, inited(false)
, removingShaders(false)
+ , geometryVertexCount(64)
+ , geometryInputType(0)
+ , geometryOutputType(0)
, vertexShader(0)
, fragmentShader(0)
+ , geometryShader(0)
{
}
~QGLShaderProgramPrivate();
@@ -518,11 +528,17 @@ public:
bool linked;
bool inited;
bool removingShaders;
+
+ int geometryVertexCount;
+ GLenum geometryInputType;
+ GLenum geometryOutputType;
+
QString log;
QList<QGLShader *> shaders;
QList<QGLShader *> anonShaders;
QGLShader *vertexShader;
QGLShader *fragmentShader;
+ QGLShader *geometryShader;
bool hasShader(QGLShader::ShaderType type) const;
};
@@ -820,6 +836,22 @@ bool QGLShaderProgram::link()
GLuint program = d->programGuard.id();
if (!program)
return false;
+
+ // Set up the geometry shader parameters
+ if (glProgramParameteriEXT) {
+ foreach (QGLShader *shader, d->shaders) {
+ if (shader->shaderType() & QGLShader::Geometry) {
+ glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT,
+ d->geometryInputType);
+ glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT,
+ d->geometryOutputType);
+ glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT,
+ d->geometryVertexCount);
+ break;
+ }
+ }
+ }
+
glLinkProgram(program);
GLint value = 0;
glGetProgramiv(program, GL_LINK_STATUS, &value);
@@ -2830,6 +2862,97 @@ void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x4 *
#undef ctx
/*!
+ Returns the hardware limit for how many vertices a geometry shader
+ can output.
+
+ \sa setGeometryShaderOutputVertexCount
+*/
+int QGLShaderProgram::maxGeometryOutputVertices() const
+{
+ int n;
+ glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
+ return n;
+}
+
+
+
+/*!
+ Sets the maximum number of vertices the current geometry shader
+ program will produce, if active.
+
+ This parameter takes effect the next time the program is linked.
+*/
+void QGLShaderProgram::setGeometryOutputVertexCount(int count)
+{
+#ifndef QT_NO_DEBUG
+ int max = maxGeometryOutputVertices();
+ if (count > max) {
+ qWarning("QGLShaderProgram::setGeometryOutputVertexCount: count: %d higher than maximum: %d",
+ count, max);
+ }
+#endif
+ d_func()->geometryVertexCount = count;
+}
+
+
+/*!
+ Returns the maximum number of vertices the current geometry shader
+ program will produce, if active.
+
+ This parameter takes effect the ntext time the program is linked.
+*/
+int QGLShaderProgram::geometryOutputVertexCount() const
+{
+ return d_func()->geometryVertexCount;
+}
+
+
+/*!
+ Sets the output type from the geometry shader, if active.
+
+ This parameter takes effect the next time the program is linked.
+*/
+void QGLShaderProgram::setGeometryInputType(GLenum inputType)
+{
+ d_func()->geometryInputType = inputType;
+}
+
+
+/*!
+ Returns the geometry shader input type, if active.
+
+ This parameter takes effect the next time the program is linked.
+ */
+
+GLenum QGLShaderProgram::geometryInputType() const
+{
+ return d_func()->geometryInputType;
+}
+
+
+/*!
+ Sets the output type from the geometry shader, if active.
+
+ This parameter takes effect the next time the program is linked.
+*/
+void QGLShaderProgram::setGeometryOutputType(GLenum outputType)
+{
+ d_func()->geometryOutputType = outputType;
+}
+
+
+/*!
+ Returns the geometry shader output type, if active.
+
+ This parameter takes effect the next time the program is linked.
+ */
+GLenum QGLShaderProgram::geometryOutputType() const
+{
+ return d_func()->geometryOutputType;
+}
+
+
+/*!
Returns true if shader programs written in the OpenGL Shading
Language (GLSL) are supported on this system; false otherwise.
@@ -2861,6 +2984,36 @@ void QGLShaderProgram::shaderDestroyed()
removeShader(shader);
}
+
+#undef ctx
+#undef context
+
+/*!
+ Returns true if shader programs of type \a type are supported on
+ this system; false otherwise.
+
+ The \a context is used to resolve the GLSL extensions.
+ If \a context is null, then QGLContext::currentContext() is used.
+*/
+bool QGLShader::hasShaders(ShaderType type, const QGLContext *context)
+{
+#if !defined(QT_OPENGL_ES_2)
+ if (!context)
+ context = QGLContext::currentContext();
+ if (!context)
+ return false;
+#endif
+ bool resolved = qt_resolve_glsl_extensions(const_cast<QGLContext *>(context));
+ if (!resolved)
+ return false;
+ const QGLContext *ctx = context;
+ if ((type & Geometry) && !glProgramParameteriEXT)
+ return false;
+ return true;
+}
+
+
+
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLShaderProgram::setUniformValue(int location, QMacCompatGLint value)