Book Image

OpenGL 4.0 Shading Language Cookbook

Book Image

OpenGL 4.0 Shading Language Cookbook

Overview of this book

The OpenGL Shading Language (GLSL) is a programming language used for customizing parts of the OpenGL graphics pipeline that were formerly fixed-function, and are executed directly on the GPU. It provides programmers with unprecedented flexibility for implementing effects and optimizations utilizing the power of modern GPUs. With version 4.0, the language has been further refined to provide programmers with greater flexibility, and additional features have been added such as an entirely new stage called the tessellation shader. The OpenGL Shading Language 4.0 Cookbook provides easy-to-follow examples that first walk you through the theory and background behind each technique then go on to provide and explain the GLSL and OpenGL code needed to implement it. Beginning level through to advanced techniques are presented including topics such as texturing, screen-space techniques, lighting, shading, tessellation shaders, geometry shaders, and shadows. The OpenGL Shading Language 4.0 Cookbook is a practical guide that takes you from the basics of programming with GLSL 4.0 and OpenGL 4.0, through basic lighting and shading techniques, to more advanced techniques and effects. It presents techniques for producing basic lighting and shading effects; examples that demonstrate how to make use of textures for a wide variety of effects and as part of other techniques; examples of screen-space techniques, shadowing, tessellation and geometry shaders, noise, and animation. The OpenGL Shading Language 4.0 Cookbook provides examples of modern shading techniques that can be used as a starting point for programmers to expand upon to produce modern, interactive, 3D computer graphics applications.
Table of Contents (16 chapters)
OpenGL 4.0 Shading Language Cookbook
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Getting a list of active uniform variables


While it is a simple process to query for the location of an individual uniform variable, there may be instances where it can be useful to generate a list of all active uniform variables. For example, one might choose to create a set of variables to store the location of each uniform and assign their values after the program is linked. This would avoid the need to query for uniform locations when setting the value of the uniform variables, creating slightly more efficient code.

Getting ready

We'll start with a basic OpenGL program that compiles and links a shader program. You could use the shaders from the recipe Sending data to a shader using per-vertex attributes and vertex buffer objects. In the following example, we'll assume that the handle to the program is in a variable named programHandle.

How to do it...

After linking the shader program, use the following steps to print information about the active uniform variables:

  1. Retrieve the maximum length of the names of all of the active uniforms and the number of active uniforms using glGetProgramiv.

    GLint nUniforms, maxLen;
    
    glGetProgramiv( programHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, 
                  &maxLen);
    glGetProgramiv( programHandle, GL_ACTIVE_UNIFORMS,
                  &nUniforms);
  2. Allocate space to store each uniform variable's name.

    GLchar * name = (GLchar *) malloc( maxLen );
  3. Retrieve and print information about each active uniform using glGetActiveUniform and glGetUniformLocation.

    GLint size, location;
    GLsizei written;
    GLenum type;
    printf(" Location | Name\n");
    printf("------------------------------------------------\n");
    for( int i = 0; i < nUniforms; ++i ) {
        glGetActiveUniform( programHandle, i, maxLen, &written, 
                          &size, &type, name );
        location = glGetUniformLocation(programHandle, name);
        printf(" %-8d | %s\n", location, name);
    }
    
    free(name);

How it works...

In step one above, we call the function glGetProgramiv to query for the maximum length of the uniform variable names (GL_ACTIVE_UNIFORM_MAX_LENGTH), and the number of active uniforms (GL_ACTIVE_UNIFORMS). The maximum length value includes the null terminating character, so in step 2 we allocate enough space to store a name of that length.

Next, we loop from zero to the number of uniforms minus one, and call glGetActiveUniform to retrieve information about each variable. Similar to glGetActiveAttrib, this function provides several pieces of information about the variable including its size, type, and name. We then query for the location of that uniform variable by calling glGetUniformLocation. It is quite often the case that the index used in the call to glGetActiveUniform is the same as the uniform's location, but we make the call just to be sure.

Finally, we print the name and location of the variable to standard out.

There's more...

As with vertex attributes, a uniform variable is not considered active unless it is determined by the GLSL linker that it will be used within the shader.

Note that one could also use the function glGetActiveUniformName instead of glGetActiveUniform. The former only provides the name, while the latter also provides the size and type.

See also

  • Sending data to a shader using uniform variables