I am using glib for dynamic arrays and just standard C99. I have written some function:
GArray* shaders2array(int num,...);
In the above function, num=number of Shaders and it takes a number of const GLchar* shaders as its arguments.
GLuint loadShaders(GArray* vertexShaders,GArray* fragmentShaders);
The above function returns a GLuint program.
Here are my code:
GArray* shaders2array(GLuint num,...)
{
GArray* shadersArray = g_array_new(GL_FALSE,GL_FALSE,sizeof(const GLchar*));
va_list list;
va_start(list,num);
for(GLuint i=0;i<num;i++)
{
const GLchar* x = va_arg(list,GLchar*);
g_array_append_val(shadersArray,x);
}
va_end(list);
return shadersArray;
}
GLuint loadShaders(GArray* vertexShaders,GArray* fragmentShaders)
{
//Allocate Space for Shaders
GLuint* vShaders = malloc(sizeof(GLuint)*vertexShaders->len);
GLuint* fShaders = malloc(sizeof(GLuint)*fragmentShaders->len);
//Compile Shaders
for(guint i=0;i<vertexShaders->len;i++)
{
vShaders[i] = compileShader(g_array_index(vertexShaders,const GLchar*,i),GL_VERTEX_SHADER);
}
for(guint i=0;i<fragmentShaders->len;i++)
{
fShaders[i] = compileShader(g_array_index(fragmentShaders,const GLchar*,i),GL_FRAGMENT_SHADER);
}
GLuint shaderProgram = glCreateProgram();
//Attach Shaders
for(guint i=0;i<vertexShaders->len;i++)
{
glAttachShader(shaderProgram,vShaders[i]);
}
for(guint i=0;i<fragmentShaders->len;i++)
{
glAttachShader(shaderProgram,fShaders[i]);
}
//Check For Linking Errors
checkShader(&shaderProgram,GL_LINK_STATUS);
//Delete the Shaders
for(guint i=0;i<vertexShaders->len;i++)
{
glDeleteShader(vShaders[i]);
}
for(guint i=0;i<fragmentShaders->len;i++)
{
glDeleteShader(fShaders[i]);
}
free(vShaders);
free(fShaders);
return shaderProgram;
}
When I do something like:
const GLchar* vertexSrc = readFile("vertexShader.vert");
const GLchar* fragmentSrc = readFile("fragmentShader.frag");
GArray* vShaders = shaders2array(1,vertexSrc);
GArray* fShaders = shaders2array(1,fragmentSrc);
GLuint shaderProgram = loadShaders(vShaders,fShaders);
I get an Error:
Error: Program linking failed. Error:
My Error checking program is:
void checkShader(GLuint* shader, GLenum statusType)
{
GLint success; GLchar infoLog[512];
switch(statusType)
{
case GL_COMPILE_STATUS:
{
glGetShaderiv(*shader,statusType,&success);
if (!success)
{
glGetShaderInfoLog(*shader, 512, NULL, infoLog);
printf("Error: Shader compilation failed! Error: %s
",infoLog);
}
break;
}
case GL_LINK_STATUS:
{
glGetProgramiv(*shader,statusType,&success);
if (!success) {
glGetProgramInfoLog(*shader, 512, NULL, infoLog);
printf("Error: Program linking failed! Error: %s
",infoLog);
}
break;
}
}
}
As you can see from above, if there was any GLSL based error then I could have get the
infoLog
but I am not able to get it. But when I was doing something like:
GArray* list = shaders2array(2,vertexSrc,fragmentSrc);
for (guint k = 0; k < list->len; k++)
{
printf("Array val: %s
",g_array_index(list,GLchar*,k));
}
GLuint vertexShader = compileShader(vertexSrc,GL_VERTEX_SHADER);
GLuint fragmentShader = compileShader(fragmentSrc,GL_FRAGMENT_SHADER);
shaderProgram=linkShaders(&vertexShader,&fragmentShader);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
the program worked perfectly. I tried very hard to detect the bug, but I wasn’t able to identify it. I know its a lot of code but if anyone is able to help me out then I will be grateful to him/her. If you need anymore data then feel free to ask.