http://docs.gl/gl4/glCreateShaderProgram
Pseudo code:
const GLuint shader = glCreateShader(type);
if (shader) {
glShaderSource(shader, count, strings, NULL);
glCompileShader(shader);
const GLuint program = glCreateProgram();
if (program) {
GLint compiled = GL_FALSE;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE);
if (compiled) {
glAttachShader(program, shader);
glLinkProgram(program);
glDetachShader(program, shader);
}
/* append-shader-info-log-to-program-info-log */
}
glDeleteShader(shader);
return program;
}
else {
return 0;
}
I didn't know that it is possible to compile several shaders at once. The problem that I have is that the documentation doesn't tell me how to call this.
What type should I specify if I want to compile a vertex + fragment shader? Initially I tried glCreateShader(GL_VERTEX_SHADER | GL_FRAGMENT_SHADER); but then it complained about two main functions. OpenGL probably interpreted two shaders as one shader.
glCreateShaderProgram() only compiles and links a single shader. The last argument is an array of strings just like the corresponding argument for glShaderSource(), which is also used for specifying the source of one shader. Being able to pass multiple strings is just a convenience for both of those calls. For example, if you have your shader code as an array of strings (say one per line), you can directly pass them in, without a need to concatenate them first.
glCreateShaderProgram() is intended to be used in conjunction with program pipeline objects. This mechanism allows you to combine shaders from several programs, without a need to link them. A typical call sequence would look like this:
GLuint vertProgId = glCreateShaderProgram(GL_VERTEX_SHADER, 1, &vertSrc);
GLuint fragProgId = glCreateShaderProgram(GL_FRAGMENT_SHADER, 1, &fragSrc);
GLuint pipelineId = 0;
glGenProgramPipelines(1, &pipelineId);
glUseProgramStages(pipelineId, GL_VERTEX_SHADER_BIT, vertProgId);
glUseProgramStages(pipelineId, GL_FRAGMENT_SHADER_BIT, fragProgId);
glBindProgramPipeline(pipelineId);
From the linked documentation:
glCreateShaderProgram creates a program object containing compiled and linked shaders for a single stage specified by
type.
[emphasis mine]
What it means is that you cannot use it with a list of shaders targeting different parts of the rendering pipeline.
However, you could perhaps modify the sample implementation to cover that need for you. It would require to change the function signature by replacing the first parameter by an array of GLenum of count elements, then turn the implementation into a loop on each pair shader[i], strings[i] to add them to the generated program, where shader is an array of shader ids associated with each source string separately.
Once each shader has been compiled, the code would then link the whole into a program, release all the shader ids, and return the program id (actual implementation left as an exercise).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With