diff options
author | Gunnar Sletta <gunnar@trolltech.com> | 2010-02-01 13:30:01 (GMT) |
---|---|---|
committer | Gunnar Sletta <gunnar@trolltech.com> | 2010-02-01 13:30:01 (GMT) |
commit | fe849f50ca83f50f6068b7d494cb228fae1d6309 (patch) | |
tree | 64ae403632763d4e5d576cd600de2561872032f5 /src/opengl/qglshaderprogram.cpp | |
parent | c06c254cf208840f14c9e562cae976f1a61f0879 (diff) | |
download | Qt-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.cpp | 153 |
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) |