glShaderSource
expects two related sequences (C-style arrays) of values.
The first sequence is an array of C-strings, either zero-terminated or not.
The second sequence is an array of integers, indicating the length of each of the strings in the first sequence. This sequence is optional if the strings are zero-terminated, as the library will find the lengths by itself.
The GL-prefixed types are because the OpenGL specification needs to talk about types without tying itself into a particular language, so it introduces aliases of common C types.
GLchar
is a type similiar to the C char
, which serves to represent a narrow character.
GLint
is a signed integer type, commonly used to represent object handles and offsets.
There's also others like GLenum
and GLvoid
.
GLchar const*
is the OpenGL spelling of the char const*
type. Apart from being used to point to a single character, it's commonly used to represent a string of characters. When used in that meaning, it shall point to a sequence of characters, ending with a sentinel value ''
to know that the string ends.
The reason for making glShaderSource
take more than one string is because OpenGL's shader compiler has exposed the concept of a file. Each of these strings represents the contents of one file, and it will compile as if these files are concatenated together. Note that this file is largely unrelated to the filesystem thing of the same name. glShaderSource
only deals with strings containing text.
This is beneficial when you've got some fragments you want to assemble together into the full shader source, like if you want to prepend a #version
statement or some common preamble, or have implemented some sort of include directive yourself.
As for an example of how to use it:
std::string v = "#version 150
";
std::string c = ReadTextFile("common.glsl"); // read a string with the file contents
std::string s = ReadTextFile("mesh.vert"); // same here
GLchar const* files[] = { v.c_str(), c.c_str(), s.c_str() };
GLint lengths[] = { v.size(), c.size(), s.size() };
glShaderSource(id, 3, files, lengths);
Here we're combining three strings for OpenGL to consider as one large chunk of source text. Note that my convenience function ReadTextFile
reads the content of a filesystem file into a string, no part of OpenGL ever touches the filesystem. If you want to get the contents of a text file, image file or mesh file into OpenGL structures, you need to read it in for yourself ahead of time.