Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
OpenGL 4 Shading Language Cookbook, Second Edition

You're reading from   OpenGL 4 Shading Language Cookbook, Second Edition Acquiring the skills of OpenGL Shading Language is so much easier with this cookbook. You'll be creating graphics rather than learning theory, gaining a high level of capability in modern 3D programming along the way.

Arrow left icon
Product type Paperback
Published in Dec 2013
Publisher Packt
ISBN-13 9781782167020
Length 394 pages
Edition 2nd Edition
Tools
Arrow right icon
Authors (2):
Arrow left icon
David A Wolff David A Wolff
Author Profile Icon David A Wolff
David A Wolff
David Wolff David Wolff
Author Profile Icon David Wolff
David Wolff
Arrow right icon
View More author details
Toc

Table of Contents (12) Chapters Close

Preface 1. Getting Started with GLSL FREE CHAPTER 2. The Basics of GLSL Shaders 3. Lighting, Shading, and Optimization 4. Using Textures 5. Image Processing and Screen Space Techniques 6. Using Geometry and Tessellation Shaders 7. Shadows 8. Using Noise in Shaders 9. Particle Systems and Animation 10. Using Compute Shaders Index

Getting a list of active vertex input attributes and locations

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 use layout qualifiers within the shader, or we could call glBindAttribLocation before linking.

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 and enabling the shader program, use the following code to display the list of active attributes:

  1. Start by querying for the number of active attributes:
    GLint numAttribs;
    glGetProgramInterfaceiv(programHandle, GL_PROGRAM_INPUT,GL_ACTIVE_RESOURCES, &numAttribs);
  2. Loop through each attribute and query for the length of the name, the type and the attribute location, and print the results to standard out:
    GLenum properties[] = {GL_NAME_LENGTH, GL_TYPE, GL_LOCATION};
    
    printf("Active attributes:\n");
    for( int i = 0; i < numAttribs; ++i ) {
      GLint results[3];
      glGetProgramResourceiv(programHhandle, GL_PROGRAM_INPUT,i, 3, properties, 3, NULL, results);
    
      GLint nameBufSize = results[0] + 1;
      char * name = new char[nameBufSize];
      glGetProgramResourceName(programHandle, GL_PROGRAM_INPUT, i, nameBufSize, NULL, name);
      printf("%-5d %s (%s)\n", results[2], name, getTypeString(results[1]));
      delete [] name;
    }

How it works...

In step 1, we query for the number of active attributes, by calling glGetProgramInterfaceiv. The first argument is the handle to the program object, and the second (GL_PROGRAM_INPUT) indicates that we are querying for information about the program input variables (the vertex attributes). The third argument (GL_ACTIVE_RESOURCES) indicates that we want the number of active resources. The result is stored in the location pointed to by the last argument numAttribs.

Now that we have the number of attributes, we query for information about each one. The indices of the attributes run from 0 to numAttribs-1. We loop over those indices and for each we call glGetProgramResourceiv to get the length of the name, the type and the location. We specify what information we would like to receive by means of an array of GLenum values called properties. The first argument is the handle to the program object, the second is the resource that we are querying (GL_PROGRAM_INPUT). The third is the index of the attribute, the fourth is the number of values in the properties array, which is the fifth argument. The properties array contains GLenums, which specify the specific properties we would like to receive. In this example, the array contains: GL_NAME_LENGTH, GL_TYPE, and GL_LOCATION, which indicates that we want the length of the attribute's name, the data type of the attribute and its location. The sixth argument is the size of the buffer that will receive the results; the seventh argument is a pointer to an integer that would receive the number of results that were written. If that argument is NULL, then no information is provided. Finally, the last argument is a pointer to a GLint array that will receive the results. Each item in the properties array corresponds to the same index in the results array.

Next, we retrieve the name of the attribute by allocating a buffer to store the name and calling glGetProgramResourceName. The results array contains the length of the name in the first element, so we allocate an array of that size with an extra character just for good measure. The OpenGL documentation says that the size returned from glGetProgramResourceiv includes the null terminator, but it doesn't hurt to make sure by making a bit of additional space. In my tests, I've found this to be necessary on the latest NVIDIA drivers.

Finally, we get the name by calling glGetProgramResourceName, and then print the information to the screen. We print the attribute's location, name and type. The location is available in the third element of the results array, and the type is in the second. Note the use of the function getTypeString. This is a simple custom function that just returns a string representation of the data type. The data type is represented by one of the OpenGL defined constants GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, and so on. The getTypeString function consists of just one big switch statement returning a human-readable string corresponding to the value of the parameter (see the source code for glslprogram.cpp in the example code for this book).

The output of the previous code looks like this when it is run on the shaders from the previous recipes:

Active attributes:
1    VertexColor (vec3)
0    VertexPosition (vec3)

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 previous code will not display the variable because it is not considered active and effectively ignored by OpenGL.

The previous code is only valid for OpenGL 4.3 and later. Alternatively, you can achieve similar results with the functions glGetProgramiv, glGetActiveAttrib and glGetAttribLocation.

See also

  • The Compiling a shader recipe
  • The Linking a shader program recipe
  • The Sending data to a shader using vertex attributes and vertex buffer objects recipe
You have been reading a chapter from
OpenGL 4 Shading Language Cookbook, Second Edition - Second Edition
Published in: Dec 2013
Publisher: Packt
ISBN-13: 9781782167020
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime