OpenGL 4.1 Goodness
OpenGL made some waves w/ their recent posting of the 4.1 specifications. Most notably the ability to save and load binary shader programs via GL_ARB_get_program_binary.
According to NVIDIA, via Ars Technica:
NVIDIA says that it will release OpenGL 4.1 drivers on or before Wednesday, with AMD (ATI) releasing them shortly. As is now traditional, Apple has given no indication of when, if ever, it will update Mac OS X’s OpenGL drivers to support the new standard; the company does not have full support for OpenGL 3.0. – ars technica
Additionally it appears that OpenGL 3.3 offers some support for this feature. OpenGL 4.1 doesn’t have any hardware specific requirements.
Usage, Ripped directly from the ARB specs.:
void retrieveProgramBinary(const GLchar* vsSource, const GLchar* fsSource, const char* myBinaryFileName, GLenum* binaryFormat) { GLuint newFS, newVS; GLuint newProgram; const GLchar* sources[1]; GLint success; GLint binaryLength; GLvoid* binary; FILE* outfile; // // Create new shader/program objects and attach them together. // newVS = glCreateShader(GL_VERTEX_SHADER); newFS = glCreateShader(GL_FRAGMENT_SHADER); newProgram = glCreateProgram(); glAttachShader(newProgram, newVS); glAttachShader(newProgram, newFS); // // Supply GLSL source shaders, compile, and link them // sources[0] = vsSource; glShaderSource(newVS, 1, sources, NULL); glCompileShader(newVS); sources[0] = fsSource; glShaderSource(newFS, 1, sources, NULL); glCompileShader(newFS); glProgramParameteri(newProgram, PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); glLinkProgram(newProgram); glGetProgramiv(newProgram, GL_LINK_STATUS, &success); if (!success) { // // Fallback to simpler source shaders? Take my toys and go home? // } glUseProgram(newProgram); // // Perform rendering and state changes likely to be encountered. // DoRendering(newProgram); // // Retrieve the binary from the program object // glGetProgramiv(newProgram, GL_PROGRAM_BINARY_LENGTH, &binaryLength); binary = (GLvoid*)malloc(binaryLength); glGetProgramBinary(newProgram, binaryLength, NULL, binaryFormat, binary); // // Cache the program binary for future runs // outfile = fopen(myBinaryFileName, "wb"); fwrite(binary, binaryLength, 1, outfile); fclose(outfile); free(binary); // // Clean up // glDeleteShader(newVS); glDeleteShader(newFS); glDeleteProgram(newProgram); } void loadProgramBinary(const char* myBinaryFileName, GLenum binaryFormat, GLuint progObj) { GLint binaryLength; GLvoid* binary; GLint success; FILE* infile; // // Read the program binary // infile = fopen(myBinaryFileName, "rb"); fseek(infile, 0, SEEK_END); binaryLength = (GLint)ftell(infile); binary = (GLvoid*)malloc(binaryLength); fseek(infile, 0, SEEK_SET); fread(binary, binaryLength, 1, infile); fclose(infile); // // Load the binary into the program object -- no need to link! // glProgramBinary(progObj, binaryFormat, binary, binaryLength); free(binary); glGetProgramiv(progObj, GL_LINK_STATUS, &success); if (!success) { // // Something must have changed since the program binaries // were cached away. Fallback to source shader loading path, // and then retrieve and cache new program binaries once again. // } }
Categories: Uncategorized