Viadeo Twitter Google Bookmarks ! Facebook Digg del.icio.us MySpace Yahoo MyWeb Blinklist Netvouz Reddit Simpy StumbleUpon Bookmarks Windows Live Favorites 
Logo Documentation Qt ·  Page d'accueil  ·  Toutes les classes  ·  Classes principales  ·  Annotées  ·  Classes groupées  ·  Modules  ·  Fonctions  · 

QGLShaderProgramEffect Class

The QGLShaderProgramEffect class provides applications with the ability to use shader programs written in GLSL as effects for 3D rendering. More...

 #include <QGLShaderProgramEffect>

Inherits: QGLAbstractEffect.

This class was introduced in Qt 4.8.

Public Functions

QGLAbstractEffect()
QGLShaderProgramEffect()
virtual ~QGLAbstractEffect()
virtual ~QGLShaderProgramEffect()
QByteArray fragmentShader() const
GLenum geometryInputType()
GLenum geometryOutputType()
QByteArray geometryShader() const
int maximumLights() const
QOpenGLShaderProgram * program() const
virtual void setActive(QGLPainter * painter, bool flag) = 0
void setFragmentShader(const QByteArray & source)
void setFragmentShaderFromFile(const QString & fileName)
void setGeometryInputType(GLenum drawingMode)
void setGeometryOutputType(GLenum drawingMode)
void setGeometryShader(const QByteArray & source)
void setGeometryShaderFromFile(const QString & fileName)
void setMaximumLights(int value)
void setVertexShader(const QByteArray & source)
void setVertexShaderFromFile(const QString & fileName)
virtual bool supportsPicking() const
virtual void update(QGLPainter * painter, QGLPainter::Updates updates) = 0
QByteArray vertexShader() const

Reimplemented Public Functions

virtual void setActive(QGLPainter * painter, bool flag)
virtual void update(QGLPainter * painter, QGLPainter::Updates updates)

Protected Functions

virtual void afterLink()
virtual bool beforeLink()

Detailed Description

The QGLShaderProgramEffect class provides applications with the ability to use shader programs written in GLSL as effects for 3D rendering.

Writing portable shaders

Shader programs can be difficult to reuse across OpenGL implementations because of varying levels of support for standard vertex attributes and uniform variables. In particular, GLSL/ES lacks all of the standard variables that are present on desktop OpenGL systems: gl_Vertex, gl_Normal, gl_Color, and so on. Desktop OpenGL lacks the variable qualifiers highp, mediump, and lowp.

QGLShaderProgramEffect is built on top of QGLShaderProgram, which makes the process of writing portable shaders easier by prefixing all shader programs with the following lines on desktop OpenGL:

 #define highp
 #define mediump
 #define lowp

This makes it possible to run most GLSL/ES shader programs on desktop systems. The programmer should also restrict themselves to just features that are present in GLSL/ES, and avoid standard variable names that only work on the desktop.

QGLShaderProgramEffect also defines some standard attribute and uniform variable names that all shaders are expected to use. The following sections define these standard names.

Attributes

QGLShaderProgramEffect provides a standard set of 8 named vertex attributes that can be provided via QGLPainter::setVertexBundle():

Shader VariableMesh AttributePurpose
qt_VertexQGL::PositionThe primary position of the vertex.
qt_NormalQGL::NormalThe normal at each vertex, for lit material effects.
qt_ColorQGL::ColorThe color at each vertex, for per-vertex color effects.
qt_MultiTexCoord0QGL::TextureCoord0The texture co-ordinate at each vertex for texture unit 0.
qt_MultiTexCoord1QGL::TextureCoord1Secondary texture co-ordinate at each vertex.
qt_MultiTexCoord2QGL::TextureCoord2Tertiary texture co-ordinate at each vertex.
qt_Custom0QGL::CustomVertex0First custom vertex attribute that can be used for any user-defined purpose.
qt_Custom1QGL::CustomVertex1Second custom vertex attribute that can be used for any user-defined purpose.

These attributes may be used in the vertexShader(), as in the following example of a simple texture shader:

 attribute highp vec4 qt_Vertex;
 attribute highp vec4 qt_MultiTexCoord0;
 uniform mediump mat4 qt_ModelViewProjectionMatrix;
 varying highp vec4 qt_TexCoord0;

 void main(void)
 {
     gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex;
     qt_TexCoord0 = qt_MultiTexCoord0;
 }

Uniform variables

QGLShaderProgramEffect provides a standard set of uniform variables for common values from the QGLPainter environment:

Shader VariablePurpose
qt_ModelViewProjectionMatrixCombination of the modelview and projection matrices into a single 4x4 matrix.
qt_ModelViewMatrixModelview matrix without the projection. This is typically used for performing calculations in eye co-ordinates.
qt_ProjectionMatrixProjection matrix without the modelview.
qt_NormalMatrixNormal matrix, which is the transpose of the inverse of the top-left 3x3 part of the modelview matrix. This is typically used in lighting calcuations to transform qt_Normal.
qt_WorldMatrixModelview matrix without the eye position and orientation component. See QGLPainter::worldMatrix() for further information.
qt_Texture0Sampler corresponding to the texture on unit 0.
qt_Texture1Sampler corresponding to the texture on unit 1.
qt_Texture2Sampler corresponding to the texture on unit 2.
qt_ColorSet to the value of the QGLPainter::color() property. This is typically used for flat-color shaders that do not involve lighting. Note that this is different from the qt_Color attribute, which provides per-vertex colors.

The above variables are usually declared in the shaders as follows (where highp may be replaced with mediump or lowp depending upon the shader's precision requirements):

 uniform highp mat4 qt_ModelViewProjectionMatrix;
 uniform highp mat4 qt_ModelViewMatrix;
 uniform highp mat4 qt_ProjectionMatrix;
 uniform highp mat3 qt_NormalMatrix;
 uniform sampler2D qt_Texture0;
 uniform sampler2D qt_Texture1;
 uniform sampler2D qt_Texture2;
 uniform highp vec4 qt_Color;

Material parameters

QGLShaderProgramEffect will provide information about the front and back materials from QGLPainter::faceMaterial() if the qt_Materials array is present in the shader code. The array should be declared as follows:

 struct qt_MaterialParameters {
     mediump vec4 emission;
     mediump vec4 ambient;
     mediump vec4 diffuse;
     mediump vec4 specular;
     mediump float shininess;
 };
 uniform qt_MaterialParameters qt_Materials[2];

The front material will be provided as index 0 and the back material will be provided as index 1. If the shader only needs a single material, then the qt_Material variable can be declared instead:

 uniform qt_MaterialParameters qt_Material;

The front material will be provided as the value of qt_Material and the back material will be ignored.

Note: the emission parameter is actually QGLMaterial::emittedLight() combined with the QGLLightModel::ambientSceneColor() and QGLMaterial::ambientColor(). This helps simplify lighting shaders.

Lighting parameters

QGLShaderProgramEffect will provide information about the current lights specified on the QGLPainter if the qt_Lights array is present in the shader code. The array should be declared as follows:

 struct qt_LightParameters {
     mediump vec4 ambient;
     mediump vec4 diffuse;
     mediump vec4 specular;
     mediump vec4 position;
     mediump vec3 spotDirection;
     mediump float spotExponent;
     mediump float spotCutoff;
     mediump float spotCosCutoff;
     mediump float constantAttenuation;
     mediump float linearAttenuation;
     mediump float quadraticAttenuation;
 };
 const int qt_MaxLights = 8;
 uniform qt_LightParameters qt_Lights[qt_MaxLights];
 uniform int qt_NumLights;

As shown, up to 8 lights can be supported at once. Usually this is more lights than most shaders need, and so the user can change the qt_MaxLights constant to a smaller value if they wish. Be sure to also call setMaximumLights() to tell QGLShaderProgramEffect about the new light count limit.

The qt_NumLights uniform variable will be set to the actual number of lights that are active on the QGLPainter when update() is called.

Because most shaders will only need a single light, the shader can declare the qt_Light variable instead of the qt_Lights array:

 struct qt_SingleLightParameters {
     mediump vec4 position;
     mediump vec3 spotDirection;
     mediump float spotExponent;
     mediump float spotCutoff;
     mediump float spotCosCutoff;
     mediump float constantAttenuation;
     mediump float linearAttenuation;
     mediump float quadraticAttenuation;
 };
 uniform qt_SingleLightParameters qt_Light;

Note that we have omitted the ambient, diffuse, and specular colors for the single light. QGLShaderProgramEffect will combine the material and light colors ahead of time into qt_Material or qt_Materials. This makes lighting shaders more efficient because they do not have to compute material_color * light_color; just material_color is sufficient.

Varying variables

The name and purpose of the varying variables is up to the author of the vertex and fragment shaders, but the following names are recommended for texture co-ordinates:

Varying VariablePurpose
qt_TexCoord0Texture coordinate for unit 0, copied from the qt_MultiTexCoord0 attribute.
qt_TexCoord1Texture coordinate for unit 1, copied from the qt_MultiTexCoord1 attribute.
qt_TexCoord2Texture coordinate for unit 2, copied from the qt_MultiTexCoord2 attribute.

Lighting shader example

The following example demonstrates what a lighting shader that uses a single light, a single material, and a texture might look like. The shader is quite complex but demonstrates most of the features that can be found in the lighting implementation of a fixed-function OpenGL pipeline:

 attribute highp vec4 qt_Vertex;
 uniform highp mat4 qt_ModelViewProjectionMatrix;
 attribute highp vec3 qt_Normal;
 uniform highp mat4 qt_ModelViewMatrix;
 uniform highp mat3 qt_NormalMatrix;
 attribute highp vec4 qt_MultiTexCoord0;
 varying highp vec4 qt_TexCoord0;

 struct qt_MaterialParameters {
     mediump vec4 emission;
     mediump vec4 ambient;
     mediump vec4 diffuse;
     mediump vec4 specular;
     mediump float shininess;
 };
 uniform qt_MaterialParameters qt_Material;

 struct qt_SingleLightParameters {
     mediump vec4 position;
     mediump vec3 spotDirection;
     mediump float spotExponent;
     mediump float spotCutoff;
     mediump float spotCosCutoff;
     mediump float constantAttenuation;
     mediump float linearAttenuation;
     mediump float quadraticAttenuation;
 };
 uniform qt_SingleLightParameters qt_Light;

 varying mediump vec4 litColor;
 varying mediump vec4 litSecondaryColor;

 void main(void)
 {
     gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex;
     gTexCoord0 = qt_MultiTexCoord0;

     // Calculate the vertex and normal to use for lighting calculations.
     highp vec4 vertex = qt_ModelViewMatrix * qt_Vertex;
     highp vec3 normal = normalize(qt_NormalMatrix * qt_Normal);

     // Start with the material's emissive color and the ambient scene color,
     // which have been combined into the emission parameter.
     vec4 color = ggl_Material.emission;

     // Viewer is at infinity.
     vec3 toEye = vec3(0, 0, 1);

     // Determine the angle between the normal and the light direction.
     vec4 pli = qt_Light.position;
     vec3 toLight;
     if (pli.w == 0.0)
         toLight = normalize(pli.xyz);
     else
         toLight = normalize(pli.xyz - vertex.xyz);
     float angle = max(dot(normal, toLight), 0.0);

     // Calculate the ambient and diffuse light components.
     vec4 adcomponent = qt_Material.ambient + angle * qt_Material.diffuse;

     // Calculate the specular light components.
     vec4 scomponent;
     if (angle != 0.0) {
         vec3 h = normalize(toLight + toEye);
         angle = max(dot(normal, h), 0.0);
         float srm = qt_Material.shininess;
         vec4 scm = qt_Material.specular;
         if (srm != 0.0)
             scomponent = pow(angle, srm) * scm;
         else
             scomponent = scm;
     } else {
         scomponent = vec4(0, 0, 0, 0);
     }

     // Apply the spotlight angle and exponent.
     if (qt_Light.spotCutoff != 180.0) {
         float spot = max(dot(normalize(vertex.xyz - pli.xyz),
                              qt_Light.spotDirection), 0.0);
         if (spot < qt_Light.spotCosCutoff) {
             adcomponent = vec4(0, 0, 0, 0);
             scomponent = vec4(0, 0, 0, 0);
         } else {
             spot = pow(spot, qt_Light.spotExponent);
             adcomponent *= spot;
             scomponent *= spot;
         }
     }

     // Apply attenuation to the colors.
     if (pli.w != 0.0) {
         float attenuation = qt_Light.constantAttenuation;
         float k1 = qt_Light.linearAttenuation;
         float k2 = qt_Light.quadraticAttenuation;
         if (k1 != 0.0 || k2 != 0.0) {
             float len = length(pli.xyz - vertex.xyz);
             attenuation += k1 * len + k2 * len * len;
         }
         color += adcomponent / attenuation;
         scolor += scomponent / attenuation;
     } else {
         color += adcomponent;
         scolor += scomponent;
     }

     // Generate the final output colors to pass to the fragment shader.
     float alpha = qt_Material.diffuse.a;
     litColor = vec4(clamp(color.rgb, 0.0, 1.0), alpha);
     litSecondaryColor = vec4(clamp(scolor.rgb, 0.0, 1.0), 0.0);
 }

The corresponding fragment shader is as follows:

 varying mediump vec4 litColor;
 varying mediump vec4 litSecondaryColor;
 varying highp vec4 qt_TexCoord0;

 void main(void)
 {
     vec4 color = litColor * texture2D(qt_Texture0, qt_TexCoord0.st);
     gl_FragColor = clamp(color + litSecondaryColor, 0.0, 1.0);
 }

Fixed function operation

If the OpenGL implementation does not support shaders, then QGLShaderProgramEffect will fall back to a flat color effect based on QGLPainter::color(). It is recommended that the application consult QGLPainter::isFixedFunction() to determine if some other effect should be used instead.

Member Function Documentation

QGLShaderProgramEffect::QGLShaderProgramEffect()

Constructs a new shader program effect. This constructor is typically followed by calls to setVertexShader() and setFragmentShader().

Note that a shader program effect will be bound to the QOpenGLContext that is current when setActive() is called for the first time. After that, the effect can only be used with that context or any other QOpenGLContext that shares with it.

QGLShaderProgramEffect::~QGLShaderProgramEffect() [virtual]

Destroys this shader program effect.

void QGLShaderProgramEffect::afterLink() [virtual protected]

Called by setActive() just after the program() is linked. The default implementation does nothing.

This function can be overridden by subclasses to resolve uniform variable locations and cache them for later use in update().

See also beforeLink().

bool QGLShaderProgramEffect::beforeLink() [virtual protected]

Called by setActive() just before the program() is linked. Returns true if the standard vertex attributes should be bound by calls to QGLShaderProgram::bindAttributeLocation(). Returns false if the subclass has already bound the attributes.

This function can be overridden by subclasses to alter the vertex attribute bindings, or to add additional shader stages to program().

See also afterLink().

QByteArray QGLShaderProgramEffect::fragmentShader() const

Returns the source code for the fragment shader.

See also setFragmentShader(), vertexShader(), and geometryShader().

GLenum QGLShaderProgramEffect::geometryInputType()

Returns the type of primitives this program's geometry shader is expecting.

See also setGeometryInputType().

GLenum QGLShaderProgramEffect::geometryOutputType()

Returns the type of primitive this program's geometry shader will produce.

See also setGeometryOutputType().

QByteArray QGLShaderProgramEffect::geometryShader() const

Returns the source code for the geometry shader.

See also setGeometryShader(), fragmentShader(), and setGeometryShaderFromFile().

int QGLShaderProgramEffect::maximumLights() const

Returns the maximum number of lights that are supported by this shader program effect. The default value is 8.

The actual number of lights will be provided to the vertexShader() as the qt_NumLights uniform variable, which will always be less than or equal to maximumLights().

See also setMaximumLights().

QOpenGLShaderProgram * QGLShaderProgramEffect::program() const

Returns the shader program object that was created for this effect; null if setActive() has not been called yet.

This function can be used by the application to adjust custom uniform variables after the effect is activated on a QGLPainter:

 painter.setUserEffect(effect);
 effect->program()->setUniformValue("springiness", GLfloat(0.5f));

void QGLShaderProgramEffect::setActive(QGLPainter * painter, bool flag) [virtual]

Reimplemented from QGLAbstractEffect::setActive().

void QGLShaderProgramEffect::setFragmentShader(const QByteArray & source)

Sets the source code for the fragment shader.

See also fragmentShader(), setVertexShader(), and setGeometryShader().

void QGLShaderProgramEffect::setFragmentShaderFromFile(const QString & fileName)

Sets the source code for the fragment shader to the contents of fileName.

See also setFragmentShader(), setVertexShaderFromFile(), and setGeometryShaderFromFile().

void QGLShaderProgramEffect::setGeometryInputType(GLenum drawingMode)

Sets the type of primitive the program's geometry shader is expecting to recieve from the vertex shader to drawingMode. The default value is GL_TRIANGLE_STRIP.

If the program has no geometry shader, this has no effect.

See also geometryInputType().

void QGLShaderProgramEffect::setGeometryOutputType(GLenum drawingMode)

Sets what sort of primitives the program's geometry shader will produce to drawingMode. The default value is GL_TRIANGLE_STRIP.

If the program has no geometry shader, this has no effect.

See also geometryOutputType().

void QGLShaderProgramEffect::setGeometryShader(const QByteArray & source)

Sets the source code for the geometry shader.

See also geometryShader(), setFragmentShader(), and setGeometryShaderFromFile().

void QGLShaderProgramEffect::setGeometryShaderFromFile(const QString & fileName)

Sets the source code for the geometry shader to the contents of fileName.

See also setGeometryShader() and setFragmentShaderFromFile().

void QGLShaderProgramEffect::setMaximumLights(int value)

Sets the maximum number of lights that are supported by this shader program effect to value.

See also maximumLights().

void QGLShaderProgramEffect::setVertexShader(const QByteArray & source)

Sets the source code for the vertex shader.

See also vertexShader(), setGeometryShader(), setFragmentShader(), and setVertexShaderFromFile().

void QGLShaderProgramEffect::setVertexShaderFromFile(const QString & fileName)

Sets the source code for the vertex shader to the contents of fileName.

See also setVertexShader(), setGeometryShaderFromFile(), and setFragmentShaderFromFile().

void QGLShaderProgramEffect::update(QGLPainter * painter, QGLPainter::Updates updates) [virtual]

Reimplemented from QGLAbstractEffect::update().

QByteArray QGLShaderProgramEffect::vertexShader() const

Returns the source code for the vertex shader.

See also setVertexShader(), geometryShader(), fragmentShader(), and setVertexShaderFromFile().

Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. Qt 5.0-snapshot
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP !
 
 
 
 
Partenaires

Hébergement Web