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.0 Shading Language Cookbook

You're reading from   OpenGL 4.0 Shading Language Cookbook With over 60 recipes, this Cookbook will teach you both the elementary and finer points of the OpenGL Shading Language, and get you familiar with the specific features of GLSL 4.0. A totally practical, hands-on guide.

Arrow left icon
Product type Paperback
Published in Jul 2011
Publisher Packt
ISBN-13 9781849514767
Length 340 pages
Edition 1st Edition
Tools
Arrow right icon
Toc

Table of Contents (16) Chapters Close

OpenGL 4.0 Shading Language Cookbook
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
1. Getting Started with GLSL 4.0 FREE CHAPTER 2. The Basics of GLSL Shaders 3. Lighting, Shading Effects, and Optimizations 4. Using Textures 5. Image Processing and Screen Space Techniques 6. Using Geometry and Tessellation Shaders 7. Shadows 8. Using Noise in Shaders 9. Animation and Particles Index

Linking a shader program


Once we have compiled our shaders and before we can actually install them into the OpenGL pipeline, we need to link them together into a shader program. Among other things, the linking step involves making the connections between the input variables from one shader to the output variables of another, and making the connections between the other input/output variables of a shader to appropriate locations in the OpenGL environment.

Linking involves steps that are similar to those involved in compiling a shader. We attach each shader object to a new shader program object and then tell the shader program object to link (making sure that the shader objects are compiled before linking).

Getting ready

For this recipe we'll assume that you've already compiled two shader objects whose handles are stored in the variables vertShader and fragShader.

For this and a few other recipes in this chapter, we'll use the following source code for the fragment shader:

#version 400

in vec3 Color;

out vec4 FragColor;

void main() {
    FragColor = vec4(Color, 1.0);
}

For the vertex shader, we'll use the source code from the previous recipe.

How to do it...

In our OpenGL initialization function, and after the compilation of the shader objects referred to by vertShader and fragShader, use the following steps.

  1. Create the program object.

    GLuint programHandle = glCreateProgram();
    if( 0 == programHandle )
    {
        fprintf(stderr, "Error creating program object.\n");
        exit(1);
    }
  2. Attach the shaders to the program object.

    glAttachShader( programHandle, vertShader );
    glAttachShader( programHandle, fragShader );
  3. Link the program.

    glLinkProgram( programHandle );
  4. Verify the link status.

    GLint status;
    glGetProgramiv( programHandle, GL_LINK_STATUS, &status );
    if( GL_FALSE == status ) {
    
        fprintf( stderr, "Failed to link shader program!\n" );
    
        GLint logLen;
        glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, 
                       &logLen);
        if( logLen > 0 )
        {
            char * log = (char *)malloc(logLen);
            GLsizei written;
            glGetProgramInfoLog(programHandle, logLen, 
                               &written, log);
            fprintf(stderr, "Program log: \n%s", log);
            free(log);
        }
    }
  5. If linking is successful, install the program into the OpenGL pipeline.

    else 
    {
      glUseProgram( programHandle );
    }

How it works...

We start by calling glCreateProgram to create an empty program object. This function returns a handle to the program object, which we store in a variable named programHandle. If an error occurs with program creation, the function will return 0. We check for that, and if it occurs, we print an error message and exit.

Next, we attach each shader to the program object using glAttachShader. The first argument is the handle to the program object, and the second is the handle to the shader object to be attached.

Then, we link the program by calling glLinkProgram, providing the handle to the program object as the only argument. As with compilation, we check for the success or failure of the link with the subsequent query.

We check the status of the link by calling glGetProgramiv . Similar to glGetShaderiv, glGetProgramiv allows us to query various attributes of the shader program. In this case, we ask for the status of the link by providing GL_LINK_STATUS as the second argument. The status is returned in the location pointed to by the third argument, in this case named status.

The link status is either GL_TRUE or GL_FALSE indicating the success or failure of the link. If the value of the status is GL_FALSE, we retrieve and display the program information log, which should contain additional information and error messages. The program log is retrieved by the call to glGetProgramInfoLog . The first argument is the handle to the program object, the second is the size of the buffer to contain the log, the third is a pointer to a GLsizei variable where the number of bytes written to the buffer will be stored (excluding the null terminator), and the fourth is a pointer to the buffer that will store the log. The buffer can be allocated based on the size returned by the call to glGetProgramiv with the parameter GL_INFO_LOG_LENGTH. The string that is provided in log will be properly null terminated.

Finally, if the link is successful, we install the program into the OpenGL pipeline by calling glUseProgram , providing the handle to the program as the argument.

With the simple fragment shader from this recipe and the vertex shader from the preceding recipe compiled, linked, and installed into the OpenGL pipeline, we have a complete OpenGL pipeline and are ready to begin rendering. Drawing a triangle and supplying different values (red, green, and blue) for the Color attribute yields an image of a multi-colored triangle where the vertices are red, green, and blue, and inside the triangle, the three colors are interpolated, causing a blending of colors throughout.

There's more...

You can compile and link multiple shader programs within a single OpenGL program. They can be swapped in and out of the OpenGL pipeline by calling glUseProgram to select the desired program.

Deleting a shader program

If a program is no longer needed, it can be deleted from the OpenGL memory by calling glDeleteProgram, providing the program handle as the only argument. This invalidates the handle and frees the memory used by the program. Note that if the program object is currently in use, it will not be immediately deleted, but will be flagged for deletion when it is no longer in use.

The deletion of a shader program detaches the shader objects that were attached to the program but does not delete them unless those shader objects have already been flagged for deletion by a previous call to glDeleteShader.

See also

  • Compiling a shader

You have been reading a chapter from
OpenGL 4.0 Shading Language Cookbook
Published in: Jul 2011
Publisher: Packt
ISBN-13: 9781849514767
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 €18.99/month. Cancel anytime