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 vertex input attributes and indices


As covered in the previous recipe, the input variables within a vertex shader are linked to generic vertex attribute indices at the time the program is linked. If we need to specify the relationship, we can either call glBindAttribLocation before linking, or we can use layout qualifiers within the shader itself.

However, it may be preferable to let the linker create the mappings automatically and query for them after program linking is complete. In this recipe, we'll see a simple example that prints all the active attributes and their indices.

Getting ready

Start with an OpenGL program that compiles and links a shader pair. You could use the shaders from the previous recipe.

As in previous recipes, we'll assume that the handle to the shader program is stored in a variable named programHandle.

How to do it...

After linking the shader program, use the following steps to print information about the active attributes in your shader program:

  1. Retrieve the number of active attributes and the maximum length of their names using glGetProgramiv.

    GLint maxLength, nAttribs;
    glGetProgramiv(programHandle, GL_ACTIVE_ATTRIBUTES, 
                   &nAttribs);
    glGetProgramiv(programHandle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, 
                   &maxLength);
  2. Allocate a buffer to hold each attribute name.

    GLchar * name = (GLchar *) malloc( maxLength );
  3. Get and print information about each active attribute using glGetActiveAttrib and glGetAttribLocation.

    GLint written, size, location; 
    GLenum type;
    printf(" Index | Name\n");
    printf("------------------------------------------------\n");
    for( int i = 0; i < nAttribs; i++ ) {
        glGetActiveAttrib( programHandle, i, maxLength, &written, &size, &type, name );
        location = glGetAttribLocation(programHandle, name);
        printf(" %-5d | %s\n",location, name);
    }
    
    free(name);

How it works...

We start by querying for the number of active attributes by calling glGetProgramiv with the argument GL_ACTIVE_ATTRIBUTES. The result is stored in nAttribs. Next, we query for the length of the longest attribute name (GL_ACTIVE_ATTRIBUTE_MAX_LENGTH) and store the result in maxLength. This includes the null terminating character, so we use that value to allocate space to store each variable name.

Next, we loop over each index (0 to nAttrib - 1), and retrieve information about each attribute by calling glGetActiveAttrib and glGetAttribLocation. The function glGetActiveAttrib returns a bunch of information about the attribute at the index provided as the second argument. Note that this index is not necessarily the same as the generic vertex attribute index (location) for the variable. The function provides the attribute name, size, and type, which are stored in the variables name, size, and type. Once we have the variable name, we can query for its location (the generic attribute index), by calling glGetAttribLocation , and passing in the program handle and the variable name. We then print the variable's location and name to standard out.

There's more...

It should be noted that, in order for a vertex shader input variable to be considered active, it must be used within the vertex shader. In other words, a variable is considered active if it is determined by the GLSL linker that it may be accessed during program execution. If a variable is declared within a shader, but not used, the above code will not display the variable because it is not considered active and will be effectively ignored by OpenGL.

See also

  • Compiling a shader

  • Linking a shader program

  • Sending data to a shader using per-vertex attributes and vertex buffer objects