To save the shader binary, first verify that the driver supports at least one shader binary format:
GLint formats = 0;
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
if( formats < 1 ) {
std::cerr << "Driver does not support any binary formats." << std::endl;
exit(EXIT_FAILURE);
}
Then, assuming at least one binary format is available, use glGetProgramBinary to retrieve the compiled shader code and write it to a file:
// Get the binary length
GLint length = 0;
glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &length);
// Retrieve the binary code
std::vector<GLubyte> buffer(length);
GLenum format = 0;
glGetProgramBinary(program, length, NULL, &format, buffer.data());
// Write the binary to a file.
std::string fName("shader.bin");
std::cout << "Writing to " << fName << ", binary format = " << format << std::endl;
std::ofstream out(fName.c_str(), std::ios::binary);
out.write( reinterpret_cast<char *>(buffer.data()), length );
out.close();
To load and use a shader binary, retrieve the compiled program from storage, and use glProgramBinary to load it into the OpenGL context:
GLuint program = glCreateProgram();
// Load binary from file
std::ifstream inputStream("shader.bin", std::ios::binary);
std::istreambuf_iterator<char> startIt(inputStream), endIt;
std::vector<char> buffer(startIt, endIt); // Load file
inputStream.close();
// Install shader binary
glProgramBinary(program, format, buffer.data(), buffer.size() );
// Check for success/failure
GLint status;
glGetprogramiv(program, GL_LINK_STATUS, &status);
if( GL_FALSE == status ) {
// Handle failure ...
}