Hello. This is a question about the C language more than OGL. I am a novice in both.
I use C11 and GL33C on GNU/Linux x64. The goal is to load shader source file contents and pass them to glShaderSource
, etc. I did write a working program using calloc
.
For educational purposes, I would like to write a different version, that only uses static allocation. I may be misunderstanding how the process works.
Here is the relevant function. It does not compile.
bool shader_source_file_load(const GLuint shader_name, const char* source_file_pathname)
{
if (0 == shader_name) {
return false;
}
bool success_flag = true;
char sane_pathname[8192] = {0};
realpath(source_file_pathname, sane_pathname);
FILE* f = fopen(sane_pathname, "r");
if (NULL == f) {
perror("shader source: could not open source file");
goto fail;
}
enum {
BUF_SIZE = 8192,
MAX_LINE_QUANTITY = 1024,
};
GLsizei count = 0;
GLchar content[MAX_LINE_QUANTITY][BUF_SIZE] = {{0}, {0}};
GLint length[MAX_LINE_QUANTITY] = {0};
char buf_p[BUF_SIZE] = {0};
setvbuf(f, buf_p, _IOLBF, BUF_SIZE);
while (!feof(f)) {
if (ferror(f)) {
perror("shader source: could not read source file");
goto fail;
}
char* t = fgets(buf_p, BUF_SIZE, f);
if (NULL == t) {
break;
}
int32_t line_len = 0;
for (uint32_t k = 0; k < BUF_SIZE; ++k) {
if ('\0' == buf_p[k]) {
/* Line length excluding the null termination character. */
line_len = k - 1;
break;
}
content[count][k] = buf_p[k];
}
length[count] = line_len;
++count;
if (count >= MAX_LINE_QUANTITY) {
fputs("shader source: too many lines\n", stderr);
goto fail;
}
}
fclose(f);
if (success_flag) {
glShaderSource(shader_name, count, content, length);
const GLenum e = glGetError();
switch (e) {
case GL_NO_ERROR: {
success_flag = true || success_flag ;
break;
}
case GL_INVALID_OPERATION: {
fputs("shader source: require valid shader object\n", stderr);
}
case GL_INVALID_VALUE: {
fputs("malformed shader source\n", stderr);
}
default: {
goto fail;
}
}
}
return success_flag;
fail: {
clearerr(f);
fclose(f);
gl_error_print(stderr);
success_flag = false;
return success_flag;
}
}
The compiler complains the type is incompatible. How do I make it compatible? I understand that arrays and pointers are distinct concepts. I also believed that arrays can be accessed via pointers. glShaderSource
expects an array of char
pointers. Isn’t it what I am trying to pass here? What’s the difference?
I understand that fgets
buffer is effectively cleared on each call. Hence why I copy the contents. Am I doing it correctly here?
src/gl/base.c: In function ‘shader_source_file_load’:
src/gl/base.c:130:52: error: passing argument 3 of ‘epoxy_glShaderSource’ from incompatible pointer type [-Werror=incompatible-pointer-types]
130 | glShaderSource(shader_name, count, content, length);
| ^~~~~~~
| |
| GLchar (*)[8192] {aka char (*)[8192]}
src/gl/base.c:130:52: note: expected ‘const GLchar * const*’ {aka ‘const char * const*’} but argument is of type ‘GLchar (*)[8192]’ {aka ‘char (*)[8192]’}
cc1: all warnings being treated as errors