Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
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

You're reading from   OpenGL 4 Shading Language Cookbook Build high-quality, real-time 3D graphics with OpenGL 4.6, GLSL 4.6 and C++17

Arrow left icon
Product type Paperback
Published in Sep 2018
Publisher Packt
ISBN-13 9781789342253
Length 472 pages
Edition 3rd Edition
Languages
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 (13) Chapters Close

Preface 1. Getting Started with GLSL FREE CHAPTER 2. Working with GLSL Programs 3. The Basics of GLSL Shaders 4. Lighting and Shading 5. Using Textures 6. Image Processing and Screen Space Techniques 7. Using Geometry and Tessellation Shaders 8. Shadows 9. Using Noise in Shaders 10. Particle Systems and Animation 11. Using Compute Shaders 12. Other Books You May Enjoy

Loading a SPIR-V shader program

Standard, Portable Intermediate Representation - V (SPIR-V) is an intermediate language designed and standardized by the Khronos Group for shaders. It is intended to be a compiler target for a number of different languages. In the Vulkan API, shaders are required to be compiled to SPIR-V before they can be loaded. SPIR-V is intended to provide developers with the freedom to develop their shaders in any language they want (as long as it can be compiled to SPIR-V), and avoid the need for an OpenGL (or Vulkan) implementation to provide compilers for multiple languages. 

Support for SPIR-V shader binaries was added to OpenGL core with version 4.6, but is also available via the ARB_gl_spirv extension for earlier OpenGL versions.

Currently, the Khronos Group provides a reference compiler for compiling GLSL to SPIR-V. It is available on GitHub at https://github.com/KhronosGroup/glslang.

In this recipe, we'll go through the steps involved in precompiling a GLSL shader pair to SPIR-V, and then load it into an OpenGL program.

Getting ready

Download and compile the OpenGL shader validator from https://github.com/KhronosGroup/glslang. Make sure that the glslangValidator binary is available in your PATH command line. In this example, we'll use the shader pair located in the basic.vert.glsl and basic.frag.glsl files.

Note that you'll need to use explicit locations for all of your input/output variables in the shaders. For details, see the Linking a shader program recipe.

All variables used for input/output interfaces (in/out variables) must have a location assigned.

How to do it...

Start by compiling the shader pair into SPIR-V using the glslangValidator tool:

glslangValidator -G -o basic.vert.spv basic.vert.glsl
glslangValidator -G -o basic.frag.spv basic.frag.glsl

If successful, this produces the basic.vert.spv and basic.frag.spv SPIR-V output files.

To load your SPIR-V shaders into an OpenGL program, use glShaderBinary and glSpecializeShader. With glShaderBinary, use GL_SHADER_BINARY_FORMAT_SPIR_V as the binary format:

GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);

// Load the shader into a std::vector
std::ifstream inStream("basic.vert.spv", std::ios::binary);
std::istreambuf_iterator<char> startIt(inStream), endIt;
std::vector<char> buffer(startIt, endIt);
inStream.close();

// Load using glShaderBinary
glShaderBinary(1, &vertShader, GL_SHADER_BINARY_FORMAT_SPIR_V, buffer.data(), buffer.size());

// Specialize the shader (specify the entry point)
glSpecializeShader( vertShader, "main", 0, 0, 0);

// Check for success/failure
GLint status;
glGetShaderiv(vertShader, GL_COMPILE_STATUS, &status);
if( GL_FALSE == status ) {
// Loading failed...
}

The process is nearly exactly the same for the fragment shader; just use GL_FRAGMENT_SHADER instead of GL_VERTEX_SHADER on the first line.

Finally, we create the program object, attach the shaders, and link. This process is identical to that shown in the Linking a shader program recipe, so we won't reproduce it here.

How it works...

The glShaderBinary function provides us with the ability to load shaders that have been compiled to the SPIR-V format. This part is fairly straightforward.

The function that might be a bit more confusing is glSpecializeShader. We are required to call this function before the shader stage can be linked. This call is needed because a single SPIR-V file can have multiple entry points, and SPIR-V files can have specialization constants, which are parameters that the user can provide before it is compiled into native code. 

At a minimum, we need to define the entry point for our shader. Since the source language is GLSL, the entry point is main. We specify the entry point(s) via the second argument. For GLSL, we simply use the main constant string. The last three parameters can be used to define the specialization constants. The first of the three is the number of constants, the next is a pointer to an array of constant indices, and the last is a pointer to an array of constant values.

The process of specializing an SPIR-V shader is similar to compiling a GLSL shader. Before calling glSpecializeShader, or if specialization fails, the compile status will be GL_FALSE. If specialization succeeds, the compile status will be GL_TRUE. As with GLSL shaders, we can query the shader info log to get detailed error messages (see the Compiling a shader recipe).

There's more...

SPIR-V appears to be the future of shader programming in the Vulkan/OpenGL space. However, GLSL is not going away anytime soon. GLSL compilers still ship with OpenGL and there's currently no sign that they will be removed or deprecated. The OpenGL specification still considers GLSL to be the primary shading language. 

However, if you're interested in getting on board with SPIR-V early, or you have an interest in moving toward Vulkan, it might be valuable to you to start working with SPIR-V now in OpenGL. Fortunately, that's possible, at least in recent versions of OpenGL.

The future of SPIR-V is very bright. There is already a (mostly complete) compiler for HLSL that targets SPIR-V, and it is likely that other languages will be developed soon. It's an exciting time for shader programming!

See also

  • The chapter01/scenebasic.cpp file in the example code
  • The Compiling a shader recipe
  • The Linking a shader program recipe
You have been reading a chapter from
OpenGL 4 Shading Language Cookbook - Third Edition
Published in: Sep 2018
Publisher: Packt
ISBN-13: 9781789342253
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