eleni@19: #include eleni@19: #include eleni@19: eleni@19: #include eleni@19: #include eleni@19: #include eleni@19: #include eleni@19: eleni@19: #include "sdr.h" eleni@19: eleni@19: char* sdr_load(const char* fname) eleni@19: { eleni@19: if(!fname) { eleni@19: return 0; eleni@19: } eleni@19: eleni@19: FILE *fp; eleni@19: int ctr = 0; eleni@19: eleni@19: if(!(fp = fopen(fname, "rb"))) { eleni@19: fprintf(stderr, "Failed to open file %s: %s\n", fname, strerror(errno)); eleni@19: return 0; eleni@19: } eleni@19: fseek(fp, 0, SEEK_END); eleni@19: ctr = ftell(fp); eleni@19: rewind(fp); eleni@19: eleni@19: char *glsl = NULL; eleni@19: if(!(glsl = (char*) malloc(ctr + 1))) { eleni@19: perror("Failed to allocate memory"); eleni@19: return 0; eleni@19: } eleni@19: ctr = fread(glsl, 1, ctr, fp); eleni@19: fclose(fp); eleni@19: eleni@19: return glsl; eleni@19: } eleni@19: eleni@19: bool sdr_compile(unsigned int sdr) eleni@19: { eleni@19: int status, loglen; eleni@19: char infolog[512]; eleni@19: eleni@19: glCompileShader(sdr); eleni@19: glGetShaderiv(sdr, GL_COMPILE_STATUS, &status); eleni@19: glGetShaderInfoLog(sdr, sizeof infolog, &loglen, infolog); eleni@19: if(status == GL_FALSE) { eleni@19: fprintf(stderr, "Failed to compile shader: %s\n", infolog); eleni@19: return false; eleni@19: } else if(loglen) { eleni@19: fprintf(stderr, "%s\n", infolog); eleni@19: } eleni@19: return true; eleni@19: } eleni@19: eleni@19: unsigned int sdr_getprog(const char* vfname, const char* ffname) eleni@19: { eleni@19: char *vsdr_glsl = NULL; eleni@19: char *fsdr_glsl = NULL; eleni@19: eleni@19: GLuint vsdr; GLuint fsdr; eleni@19: vsdr = glCreateShader(GL_VERTEX_SHADER); eleni@19: fsdr = glCreateShader(GL_FRAGMENT_SHADER); eleni@19: eleni@19: if(!(vsdr_glsl = sdr_load(vfname))) eleni@19: return 0; eleni@19: if(!(fsdr_glsl = sdr_load(ffname))) eleni@19: return 0; eleni@19: eleni@19: glShaderSource(vsdr, 1, (const GLchar**)&vsdr_glsl, NULL); eleni@19: glShaderSource(fsdr, 1, (const GLchar**)&fsdr_glsl, NULL); eleni@19: eleni@19: free(vsdr_glsl); eleni@19: free(fsdr_glsl); eleni@19: eleni@19: if(!sdr_compile(vsdr)) { eleni@19: fprintf(stderr, "Shader %s failed to compile.\n", vfname); eleni@19: return 0; eleni@19: } eleni@19: if(!sdr_compile(fsdr)) { eleni@19: fprintf(stderr, "Shader %s failed to compile.\n", ffname); eleni@19: return 0; eleni@19: } eleni@19: eleni@19: unsigned int sprog; eleni@19: int status, loglen; eleni@19: char infolog[512]; eleni@19: eleni@19: sprog = glCreateProgram(); eleni@19: glAttachShader(sprog, vsdr); eleni@19: glAttachShader(sprog, fsdr); eleni@19: glLinkProgram(sprog); eleni@19: glGetProgramiv(sprog, GL_LINK_STATUS, &status); eleni@19: glGetProgramInfoLog(sprog, sizeof infolog, &loglen, infolog); eleni@19: if(status == GL_FALSE) { eleni@19: fprintf(stderr, "Error while linking shader program:\n%s\n", infolog); eleni@20: return 0; eleni@19: } else if(loglen) { eleni@19: fprintf(stderr, "%s\n", infolog); eleni@19: } eleni@19: return sprog; eleni@19: }