15 std::string read(
const char *filename )
17 std::stringbuf source;
18 std::ifstream in(filename);
19 if(in.good() ==
false)
20 printf(
"[error] loading program '%s'...\n", filename);
22 printf(
"loading program '%s'...\n", filename);
30 std::string prepare_source( std::string file,
const std::string& definitions )
40 size_t b= file.find(
"#version");
41 if(b != std::string::npos)
43 size_t e = file.find(
'\n', b );
44 if(e != std::string::npos)
46 version= file.substr(0, e +1);
49 if(file.find(
"#version") != std::string::npos)
51 printf(
"[error] found several #version directives. failed.\n");
58 printf(
"[error] no #version directive found. failed.\n");
63 if(definitions.empty() ==
false)
65 source.append(version);
66 source.append(definitions).append(
"\n");
71 source.append(version);
80 const char *shader_string(
const GLenum type )
84 case GL_VERTEX_SHADER:
return "vertex shader";
85 case GL_FRAGMENT_SHADER:
return "fragment shader";
86 case GL_GEOMETRY_SHADER:
return "geometry shader";
88 case GL_TESS_CONTROL_SHADER:
return "control shader";
89 case GL_TESS_EVALUATION_SHADER:
return "evaluation shader";
92 case GL_COMPUTE_SHADER:
return "compute shader";
94 default:
return "shader";
99 const char *shader_keys[] =
104 "TESSELATION_CONTROL",
105 "EVALUATION_CONTROL",
108 const int shader_keys_max= 6;
111 GLenum shader_types[] =
116 #ifdef GL_VERSION_4_0
117 GL_TESS_CONTROL_SHADER,
118 GL_TESS_EVALUATION_SHADER,
123 #ifdef GL_VERSION_4_3
131 GLuint compile_shader(
const GLuint program,
const GLenum shader_type,
const std::string& source )
133 if(source.size() == 0 || shader_type == 0)
136 GLuint shader= glCreateShader(shader_type);
137 glAttachShader(program, shader);
139 const char *sources= source.c_str();
140 glShaderSource(shader, 1, &sources, NULL);
141 glCompileShader(shader);
144 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
145 return (status == GL_TRUE) ? shader : 0;
149 int reload_program(
const GLuint program,
const char *filename,
const char *definitions )
156 glGetProgramiv(program, GL_ATTACHED_SHADERS, &shaders_max);
159 std::vector<GLuint> shaders(shaders_max, 0);
160 glGetAttachedShaders(program, shaders_max, NULL, &shaders.front());
161 for (
int i = 0; i < shaders_max; i++)
163 glDetachShader(program, shaders[i]);
164 glDeleteShader(shaders[i]);
168 #ifdef GL_VERSION_4_3
169 glObjectLabel(GL_PROGRAM, program, -1, filename);
173 std::string common_source= read(filename);
174 for(
int i = 0; i < shader_keys_max; i++)
176 if(common_source.find(shader_keys[i]) != std::string::npos)
179 std::string source= prepare_source(common_source, std::string(definitions).append(
"#define ").append(shader_keys[i]).append(
"\n"));
180 GLuint shader= compile_shader(program, shader_types[i], source);
183 printf(
"[error] compiling %s...\n%s\n", shader_string(shader_types[i]), definitions);
188 glLinkProgram(program);
192 glGetProgramiv(program, GL_LINK_STATUS, &status);
193 if(status == GL_FALSE)
195 printf(
"[error] linking program %u '%s'...\n", program, filename);
200 glUseProgram(program);
206 GLuint program= glCreateProgram();
218 glGetProgramiv(program, GL_ATTACHED_SHADERS, &shaders_max);
222 std::vector<GLuint> shaders(shaders_max, 0);
223 glGetAttachedShaders(program, shaders_max, NULL, &shaders.front());
224 for(
int i= 0; i < shaders_max; i++)
226 glDetachShader(program, shaders[i]);
227 glDeleteShader(shaders[i]);
231 glDeleteProgram(program);
241 GLint status= GL_FALSE;
242 glGetProgramiv(program, GL_LINK_STATUS, &status);
245 #ifdef GL_VERSION_4_3
247 glGetObjectLabel(GL_PROGRAM, program,
sizeof(
label),
nullptr,
label);
249 if(status == GL_FALSE)
250 printf(
"program %u '%s' %s...\n", program,
label, (status == GL_TRUE) ?
"ready" :
"not ready");
252 printf(
"program %u %s...\n", program, (status == GL_TRUE) ?
"ready" :
"not ready");
256 return (status == GL_TRUE);
265 glGetProgramiv(program, GL_LINK_STATUS, &status);
268 #ifdef GL_VERSION_4_3
270 glGetObjectLabel(GL_PROGRAM, program,
sizeof(
label),
nullptr,
label);
272 if(status == GL_FALSE)
273 printf(
"program %u '%s' %s...\n", program,
label, (status == GL_TRUE) ?
"ready" :
"not ready");
275 printf(
"program %u %s...\n", program, (status == GL_TRUE) ?
"ready" :
"not ready");
279 return (status == GL_FALSE);
286 void print_line( std::string& errors,
const char *source,
const int begin_id,
const int line_id )
290 for(
unsigned int i= 0; source[i] != 0; i++)
298 if(line >= begin_id && line <= line_id)
301 errors.push_back(
'0' + (line / 1000) % 10);
302 errors.push_back(
'0' + (line / 100) % 10);
303 errors.push_back(
'0' + (line / 10) % 10);
304 errors.push_back(
'0' + (line / 1) % 10);
309 if(line >= begin_id && line <= line_id)
311 if(source[i] ==
'\t')
314 errors.push_back(source[i]);
321 int print_errors( std::string& errors,
const char *log,
const char *source )
323 printf(
"[error log]\n%s\n", log);
325 int first_error= INT_MAX;
328 for(
int i= 0; log[i] != 0; i++)
331 int string_id= 0, line_id= 0, position= 0;
332 if(sscanf(&log[i],
"%d ( %d ) : %n", &string_id, &line_id, &position) == 2
333 || sscanf(&log[i],
"%d : %d (%*d) : %n", &string_id, &line_id, &position) == 2
334 || sscanf(&log[i],
"ERROR : %d : %d : %n", &string_id, &line_id, &position) == 2
335 || sscanf(&log[i],
"WARNING : %d : %d : %n", &string_id, &line_id, &position) == 2)
337 if(string_id != last_string || line_id != last_line)
340 first_error=
std::min(first_error, line_id);
344 print_line(errors, source, last_line +1, line_id);
349 for(i+= position; log[i] != 0; i++)
351 errors.push_back(log[i]);
356 last_string= string_id;
360 print_line(errors, source, last_line +1, 1000);
372 errors.append(
"[error] no program...\n");
377 glGetProgramiv(program, GL_LINK_STATUS, &status);
378 if(status == GL_TRUE)
381 int first_error= INT_MAX;
384 glGetProgramiv(program, GL_ATTACHED_SHADERS, &shaders_max);
387 errors.append(
"[error] no shaders...\n");
391 std::vector<GLuint> shaders(shaders_max, 0);
392 glGetAttachedShaders(program, shaders_max, NULL, &shaders.front());
393 for(
int i= 0; i < shaders_max; i++)
396 glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &
value);
397 if(
value == GL_FALSE)
400 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &
value);
401 std::vector<char>log(
value+1, 0);
402 glGetShaderInfoLog(shaders[i], (GLsizei) log.size(), NULL, &log.front());
405 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &
value);
406 std::vector<char> source(
value+1, 0);
407 glGetShaderSource(shaders[i], (GLsizei) source.size(), NULL, &source.front());
409 glGetShaderiv(shaders[i], GL_SHADER_TYPE, &
value);
410 errors.append(
"[error] compiling ").append(shader_string(
value)).append(
"...\n");
413 int last_error= print_errors(errors, &log.front(), &source.front());
414 first_error=
std::min(first_error, last_error);
421 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &
value);
423 std::vector<char>log(
value+1, 0);
424 glGetProgramInfoLog(program, (GLsizei) log.size(), NULL, &log.front());
426 errors.append(
"[error] linking program...\n").append(log.begin(), log.end());
436 if(errors.size() > 0)
437 printf(
"%s\n", errors.c_str());
void label(Widgets &w, const char *format,...)
cree un texte. meme fonctionnement que printf().
bool value(Widgets &w, const char *label, int &value, const int value_min, const int value_max, const int value_step)
valeur editable par increment.
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
Point min(const Point &a, const Point &b)
renvoie la plus petite composante de chaque point. x, y, z= min(a.x, b.x), min(a.y,...
GLuint read_program(const char *filename, const char *definitions)
int program_print_errors(const GLuint program)
affiche les erreurs de compilation.
int release_program(const GLuint program)
detruit les shaders et le program.
bool program_errors(const GLuint program)
renvoie vrai si le programme n'est pas pret.
int reload_program(const GLuint program, const char *filename, const char *definitions)
bool program_ready(const GLuint program)
renvoie vrai si le programme est pret. (pas d'erreurs de compilation des shaders, pas d'erreur de lin...
int program_format_errors(const GLuint program, std::string &errors)
renvoie les erreurs de compilation.