Reputation: 16148
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.
Upvotes: 4
Views: 2558
Reputation: 54602
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);
Upvotes: 9
Reputation: 14730
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).
Upvotes: 3
Reputation: 749
I don't think it's possible to create multiple shaders at once. glCreateShaderProgram
just does everything needed to create a shader for you (create, compile, link).
If you look at the documentation at opengl.org, you will see that you can only create one shader at a time. You can only specify one of the following GLenum
s: GL_COMPUTE_SHADER
, GL_VERTEX_SHADER
, GL_TESS_CONTROL_SHADER
, GL_TESS_EVALUATION_SHADER
, GL_GEOMETRY_SHADER
, or GL_FRAGMENT_SHADER
.
I think you are right about what you are thinking. OpenGL is probably interpreting two shaders as one and that is not possible.
You can do this:
glCreateShader(GL_VERTEX_SHADER);
glCreateShader(GL_FRAGMENT_SHADER);
Look at the Description field of the source I have provided. It will explain what further to do with the shader objects.
I am not sure why you can pass an array of strings. It could be if you had multiple small snippets of shader code in different source code files.
Source: https://www.opengl.org/sdk/docs/man/html/glCreateShader.xhtml
Upvotes: 1