diff options
author | Martin Smith <msmith@trolltech.com> | 2010-02-11 10:33:15 (GMT) |
---|---|---|
committer | Martin Smith <msmith@trolltech.com> | 2010-02-11 10:33:15 (GMT) |
commit | fe7f5f8a183099b8503bb25d69fe5939014e0009 (patch) | |
tree | 7a6edfd7b0ce36387ca5d969654a2c92c53061ce /src/opengl | |
parent | 802051dd1eb8dd63e84ac0c241f560d8cdf350c5 (diff) | |
parent | f7c910a9d44eb7f775f93fd8ccf94c3e8fd38201 (diff) | |
download | Qt-fe7f5f8a183099b8503bb25d69fe5939014e0009.zip Qt-fe7f5f8a183099b8503bb25d69fe5939014e0009.tar.gz Qt-fe7f5f8a183099b8503bb25d69fe5939014e0009.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/oslo-staging-1
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/qglextensions.cpp | 6 | ||||
-rw-r--r-- | src/opengl/qglextensions_p.h | 46 | ||||
-rw-r--r-- | src/opengl/qglshaderprogram.cpp | 162 | ||||
-rw-r--r-- | src/opengl/qglshaderprogram.h | 24 |
4 files changed, 233 insertions, 5 deletions
diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp index 03fca39..02d5501 100644 --- a/src/opengl/qglextensions.cpp +++ b/src/opengl/qglextensions.cpp @@ -224,6 +224,12 @@ bool qt_resolve_buffer_extensions(QGLContext *ctx) bool qt_resolve_glsl_extensions(QGLContext *ctx) { + // Geometry shaders are optional... + glProgramParameteriEXT = (_glProgramParameteriEXT) ctx->getProcAddress(QLatin1String("glProgramParameteriEXT")); + glFramebufferTextureEXT = (_glFramebufferTextureEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureEXT")); + glFramebufferTextureLayerEXT = (_glFramebufferTextureLayerEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureLayerEXT")); + glFramebufferTextureFaceEXT = (_glFramebufferTextureFaceEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureFaceEXT")); + #if defined(QT_OPENGL_ES_2) // The GLSL shader functions are always present in OpenGL/ES 2.0. // The only exceptions are glGetProgramBinaryOES and glProgramBinaryOES. diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index 116dfa6..f6613fd 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -197,6 +197,15 @@ typedef void (APIENTRY *_glBlitFramebufferEXT) (int srcX0, int srcY0, int srcX1, typedef void (APIENTRY *_glRenderbufferStorageMultisampleEXT) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +// GL_EXT_geometry_shader4 +typedef void (APIENTRY *_glProgramParameteriEXT)(GLuint program, GLenum pname, GLint value); +typedef void (APIENTRY *_glFramebufferTextureEXT)(GLenum target, GLenum attachment, + GLuint texture, GLint level); +typedef void (APIENTRY *_glFramebufferTextureLayerEXT)(GLenum target, GLenum attachment, + GLuint texture, GLint level, GLint layer); +typedef void (APIENTRY *_glFramebufferTextureFaceEXT)(GLenum target, GLenum attachment, + GLuint texture, GLint level, GLenum face); + // ARB_texture_compression typedef void (APIENTRY *_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); @@ -310,6 +319,10 @@ struct QGLExtensionFuncs qt_glMapBufferARB = 0; qt_glUnmapBufferARB = 0; + qt_glProgramParameteriEXT = 0; + qt_glFramebufferTextureEXT = 0; + qt_glFramebufferTextureLayerEXT = 0; + qt_glFramebufferTextureFaceEXT = 0; #if !defined(QT_OPENGL_ES) // Texture compression qt_glCompressedTexImage2DARB = 0; @@ -425,6 +438,11 @@ struct QGLExtensionFuncs _glMapBufferARB qt_glMapBufferARB; _glUnmapBufferARB qt_glUnmapBufferARB; + // Geometry shaders... + _glProgramParameteriEXT qt_glProgramParameteriEXT; + _glFramebufferTextureEXT qt_glFramebufferTextureEXT; + _glFramebufferTextureLayerEXT qt_glFramebufferTextureLayerEXT; + _glFramebufferTextureFaceEXT qt_glFramebufferTextureFaceEXT; #if !defined(QT_OPENGL_ES) // Texture compression _glCompressedTexImage2DARB qt_glCompressedTexImage2DARB; @@ -661,6 +679,29 @@ struct QGLExtensionFuncs #define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A #endif +// Geometry shader defines +#ifndef GL_GEOMETRY_SHADER_EXT +# define GL_GEOMETRY_SHADER_EXT 0x8DD9 +# define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +# define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +# define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +# define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +# define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +# define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +# define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +# define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +# define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +# define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +# define GL_LINES_ADJACENCY_EXT 0xA +# define GL_LINE_STRIP_ADJACENCY_EXT 0xB +# define GL_TRIANGLES_ADJACENCY_EXT 0xC +# define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +# define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +# define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +# define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +# define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +# define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#endif #if !defined(QT_OPENGL_ES_2) #define glProgramStringARB QGLContextPrivate::extensionFuncs(ctx).qt_glProgramStringARB @@ -781,6 +822,11 @@ struct QGLExtensionFuncs #define glClearDepth glClearDepthf #endif +#define glProgramParameteriEXT QGLContextPrivate::extensionFuncs(ctx).qt_glProgramParameteriEXT +#define glFramebufferTextureEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureEXT +#define glFramebufferTextureLayerEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureLayerEXT +#define glFramebufferTextureFaceEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureFaceEXT + #if !defined(QT_OPENGL_ES) #define glCompressedTexImage2D QGLContextPrivate::extensionFuncs(ctx).qt_glCompressedTexImage2DARB #endif diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 8fd4acf..170b650 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -143,6 +143,8 @@ QT_BEGIN_NAMESPACE \value Vertex Vertex 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 GL_EXT_geometry_shader4 extension. */ #ifndef GL_FRAGMENT_SHADER @@ -226,6 +228,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) { @@ -509,6 +513,10 @@ GLuint QGLShader::shaderId() const return d->shaderGuard.id(); } + + + + #undef ctx #define ctx programGuard.context() @@ -521,8 +529,9 @@ public: , linked(false) , inited(false) , removingShaders(false) - , vertexShader(0) - , fragmentShader(0) + , geometryVertexCount(64) + , geometryInputType(0) + , geometryOutputType(0) { } ~QGLShaderProgramPrivate(); @@ -531,11 +540,14 @@ 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; bool hasShader(QGLShader::ShaderType type) const; }; @@ -604,6 +616,7 @@ bool QGLShaderProgram::init() context = QGLContext::currentContext(); d->programGuard.setContext(context); } + if (!context) return false; if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) { @@ -831,6 +844,7 @@ bool QGLShaderProgram::link() GLuint program = d->programGuard.id(); if (!program) return false; + GLint value; if (d->shaders.isEmpty()) { // If there are no explicit shaders, then it is possible that the @@ -843,6 +857,22 @@ bool QGLShaderProgram::link() if (d->linked) return true; } + + // 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); value = 0; glGetProgramiv(program, GL_LINK_STATUS, &value); @@ -3047,6 +3077,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. @@ -3078,6 +3199,39 @@ 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::hasOpenGLShaders(ShaderType type, const QGLContext *context) +{ + if (!context) + context = QGLContext::currentContext(); + if (!context) + return false; + + if ((type & ~(Geometry | Vertex | Fragment)) || type == 0) + return false; + + bool resolved = qt_resolve_glsl_extensions(const_cast<QGLContext *>(context)); + if (!resolved) + return false; + + if ((type & Geometry) && !QByteArray((const char *) glGetString(GL_EXTENSIONS)).contains("GL_EXT_geometry_shader4")) + return false; + + return true; +} + + + #ifdef Q_MAC_COMPAT_GL_FUNCTIONS /*! \internal */ void QGLShaderProgram::setAttributeArray diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h index 19ce9f2..d612b05 100644 --- a/src/opengl/qglshaderprogram.h +++ b/src/opengl/qglshaderprogram.h @@ -66,7 +66,8 @@ public: enum ShaderTypeBit { Vertex = 0x0001, - Fragment = 0x0002 + Fragment = 0x0002, + Geometry = 0x0004 }; Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit) @@ -88,6 +89,8 @@ public: GLuint shaderId() const; + static bool hasOpenGLShaders(ShaderType type, const QGLContext *context = 0); + private: friend class QGLShaderProgram; @@ -100,6 +103,14 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QGLShader::ShaderType) class QGLShaderProgramPrivate; +#ifndef GL_EXT_geometry_shader4 +# define GL_LINES_ADJACENCY_EXT 0xA +# define GL_LINE_STRIP_ADJACENCY_EXT 0xB +# define GL_TRIANGLES_ADJACENCY_EXT 0xC +# define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#endif + + class Q_OPENGL_EXPORT QGLShaderProgram : public QObject { Q_OBJECT @@ -128,6 +139,17 @@ public: GLuint programId() const; + int maxGeometryOutputVertices() const; + + void setGeometryOutputVertexCount(int count); + int geometryOutputVertexCount() const; + + void setGeometryInputType(GLenum inputType); + GLenum geometryInputType() const; + + void setGeometryOutputType(GLenum outputType); + GLenum geometryOutputType() const; + void bindAttributeLocation(const char *name, int location); void bindAttributeLocation(const QByteArray& name, int location); void bindAttributeLocation(const QString& name, int location); |