shader.c (4738B)
1 bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source, struct Shader *compiled_shader) 2 { 3 GLint success; 4 GLchar info_log[512]; 5 6 if (!(vertex_shader_source && fragment_shader_source)) 7 { 8 print("Error: One or more shader source files weren't loaded.\n"); 9 return false; 10 } 11 else 12 { 13 GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); 14 glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL); 15 glCompileShader(vertex_shader); 16 glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success); 17 if (!success) 18 { 19 glGetShaderInfoLog(vertex_shader, 512, NULL, info_log); 20 print("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n %s\n", info_log); 21 // TODO: handle errors here in a better way 22 return false; 23 } 24 25 GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); 26 glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL); 27 glCompileShader(fragment_shader); 28 glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success); 29 if (!success) 30 { 31 glGetShaderInfoLog(fragment_shader, 512, NULL, info_log); 32 print("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n %s\n", info_log); 33 // TODO: handle errors here in a better way 34 return false; 35 } 36 37 compiled_shader->program = glCreateProgram(); 38 glAttachShader(compiled_shader->program, vertex_shader); 39 glAttachShader(compiled_shader->program, fragment_shader); 40 glLinkProgram(compiled_shader->program); 41 glGetProgramiv(compiled_shader->program, GL_LINK_STATUS, &success); 42 if (!success) 43 { 44 glGetShaderInfoLog(compiled_shader->program, 512, NULL, info_log); 45 print("ERROR::SHADER::LINKING_FAILED\n %s\n", info_log); 46 // TODO: handle errors here in a better way 47 return false; 48 } 49 50 glDeleteShader(fragment_shader); 51 glDeleteShader(vertex_shader); 52 53 for (u32 uniform = 0; uniform < NUM_SHADER_UNIFORMS; uniform++) 54 { 55 char *name = shader_uniform_get_name(uniform); 56 assert(name); 57 i32 location = glGetUniformLocation(compiled_shader->program, name); 58 if (location == -1) 59 { 60 print("Uniform name not found in shader: %s\n", name); 61 } 62 compiled_shader->uniform_locations[uniform] = location; 63 } 64 return true; 65 } 66 } 67 68 bool shader_check_pointer(struct Shader *s) 69 { 70 if (s) 71 { 72 return true; 73 } 74 else 75 { 76 print("Error: invalid Shader pointer\n"); 77 return false; 78 } 79 } 80 81 void shader_use(struct Shader *s) 82 { 83 if (shader_check_pointer(s)) 84 { 85 glUseProgram(s->program); 86 } 87 } 88 89 90 void shader_setb(struct Shader *s, enum ShaderUniform u, bool value) 91 { 92 if (shader_check_pointer(s)) 93 { 94 glUniform1i(s->uniform_locations[u], (int)value); 95 } 96 } 97 98 99 void shader_seti(struct Shader *s, enum ShaderUniform u, int value) 100 { 101 if (shader_check_pointer(s)) 102 { 103 glUniform1i(s->uniform_locations[u], value); 104 } 105 } 106 107 108 void shader_setf(struct Shader *s, enum ShaderUniform u, f32 value) 109 { 110 if (shader_check_pointer(s)) 111 { 112 glUniform1f(s->uniform_locations[u], value); 113 } 114 } 115 116 117 void shader_setm4(struct Shader *s, enum ShaderUniform u, m4 *mat) 118 { 119 if (shader_check_pointer(s)) 120 { 121 f32 valueptr[sizeof(m4)]; 122 glmth_m4_valueptr(*mat, valueptr); 123 glUniformMatrix4fv(s->uniform_locations[u], 1, GL_TRUE, valueptr); 124 } 125 } 126 127 128 void shader_setf3(struct Shader *s, enum ShaderUniform u, f32 x, f32 y, f32 z) 129 { 130 if (shader_check_pointer(s)) 131 { 132 glUniform3f(s->uniform_locations[u], x, y, z); 133 } 134 } 135 136 137 void shader_setf3_1(struct Shader *s, enum ShaderUniform u, f32 f) 138 { 139 if (shader_check_pointer(s)) 140 { 141 shader_setf3(s, u, f, f, f); 142 } 143 } 144 145 146 void shader_setv3(struct Shader *s, enum ShaderUniform u, v3 *v) 147 { 148 if (shader_check_pointer(s)) 149 { 150 shader_setf3(s, u, v->x, v->y, v->z); 151 } 152 } 153 154 char *shader_uniform_get_name(enum ShaderUniform u) 155 { 156 char *name = NULL; 157 switch(u) 158 { 159 case SHADER_UNIFORM_MODEL: 160 name = "model"; 161 break; 162 case SHADER_UNIFORM_VIEW: 163 name = "view"; 164 break; 165 case SHADER_UNIFORM_PROJECTION: 166 name = "projection"; 167 break; 168 case SHADER_UNIFORM_ALPHA: 169 name = "alpha"; 170 break; 171 case NUM_SHADER_UNIFORMS: 172 // fallthrough 173 default: 174 // do nothing 175 break; 176 } 177 return name; 178 }