16 std::string read(
const char *filename )
18 std::stringbuf source;
19 std::ifstream in(filename);
20 if(in.good() ==
false)
21 printf(
"[error] loading program '%s'...\n", filename);
23 printf(
"loading program '%s'...\n", filename);
31 std::string prepare_source( std::string file,
const std::string& definitions )
41 size_t b= file.find(
"#version");
42 if(b != std::string::npos)
44 size_t e = file.find(
'\n', b );
45 if(e != std::string::npos)
47 version= file.substr(0, e +1);
50 if(file.find(
"#version") != std::string::npos)
52 printf(
"[error] found several #version directives. failed.\n");
59 printf(
"[error] no #version directive found. failed.\n");
64 if(definitions.empty() ==
false)
66 source.append(version);
67 source.append(definitions).append(
"\n");
72 source.append(version);
80 GLuint compile_shader(
const GLuint program,
const GLenum shader_type,
const std::string& source )
82 if(source.size() == 0)
85 GLuint shader= glCreateShader(shader_type);
86 glAttachShader(program, shader);
88 const char *sources= source.c_str();
89 glShaderSource(shader, 1, &sources, NULL);
90 glCompileShader(shader);
93 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
94 return (status == GL_TRUE) ? shader : 0;
98 int reload_program( GLuint program,
const char *filename,
const char *definitions )
105 glGetProgramiv(program, GL_ATTACHED_SHADERS, &shaders_max);
108 std::vector<GLuint> shaders(shaders_max, 0);
109 glGetAttachedShaders(program, shaders_max, NULL, &shaders.front());
110 for (
int i = 0; i < shaders_max; i++)
112 glDetachShader(program, shaders[i]);
113 glDeleteShader(shaders[i]);
117 #ifdef GL_VERSION_4_3
118 glObjectLabel(GL_PROGRAM, program, -1, filename);
122 std::string common_source= read(filename);
123 std::string vertex_source= prepare_source(common_source, std::string(definitions).append(
"#define VERTEX_SHADER\n"));
124 std::string fragment_source= prepare_source(common_source, std::string(definitions).append(
"#define FRAGMENT_SHADER\n"));
127 GLuint vertex_shader= compile_shader(program, GL_VERTEX_SHADER, vertex_source);
128 GLuint fragment_shader= compile_shader(program, GL_FRAGMENT_SHADER, fragment_source);
130 glLinkProgram(program);
134 glGetProgramiv(program, GL_LINK_STATUS, &status);
135 if(status == GL_FALSE)
137 if(vertex_shader == 0)
138 printf(
"[error] compiling vertex shader...\n%s\n", definitions);
139 if(fragment_shader == 0)
140 printf(
"[error] compiling fragment shader...\n%s\n", definitions);
141 printf(
"[error] linking program %u '%s'...\n", program, filename);
146 glUseProgram(program);
152 GLuint program= glCreateProgram();
164 glGetProgramiv(program, GL_ATTACHED_SHADERS, &shaders_max);
166 std::vector<GLuint> shaders(shaders_max, 0);
167 glGetAttachedShaders(program, shaders_max, NULL, &shaders.front());
168 for(
int i= 0; i < shaders_max; i++)
170 glDetachShader(program, shaders[i]);
171 glDeleteShader(shaders[i]);
174 glDeleteProgram(program);
182 void print_line( std::string& errors,
const char *source,
const int begin_id,
const int line_id )
186 for(
unsigned int i= 0; source[i] != 0; i++)
194 if(line >= begin_id && line <= line_id)
197 errors.push_back(
'0' + (line / 1000) % 10);
198 errors.push_back(
'0' + (line / 100) % 10);
199 errors.push_back(
'0' + (line / 10) % 10);
200 errors.push_back(
'0' + (line / 1) % 10);
205 if(line >= begin_id && line <= line_id)
207 if(source[i] ==
'\t')
210 errors.push_back(source[i]);
217 int print_errors( std::string& errors,
const char *log,
const char *source )
219 printf(
"[error log]\n%s\n", log);
221 int first_error= INT_MAX;
224 for(
int i= 0; log[i] != 0; i++)
227 int string_id= 0, line_id= 0, position= 0;
228 if(sscanf(&log[i],
"%d ( %d ) : %n", &string_id, &line_id, &position) == 2
229 || sscanf(&log[i],
"%d : %d (%*d) : %n", &string_id, &line_id, &position) == 2
230 || sscanf(&log[i],
"ERROR : %d : %d : %n", &string_id, &line_id, &position) == 2
231 || sscanf(&log[i],
"WARNING : %d : %d : %n", &string_id, &line_id, &position) == 2)
233 if(string_id != last_string || line_id != last_line)
236 first_error= std::min(first_error, line_id);
240 print_line(errors, source, last_line +1, line_id);
245 for(i+= position; log[i] != 0; i++)
247 errors.push_back(log[i]);
252 last_string= string_id;
256 print_line(errors, source, last_line +1, 1000);
268 errors.append(
"[error] no program...\n");
273 glGetProgramiv(program, GL_LINK_STATUS, &status);
274 if(status == GL_TRUE)
277 int first_error= INT_MAX;
281 glGetProgramiv(program, GL_ATTACHED_SHADERS, &shaders_max);
283 std::vector<GLuint> shaders(shaders_max, 0);
284 glGetAttachedShaders(program, shaders_max, NULL, &shaders.front());
285 for(
int i= 0; i < shaders_max; i++)
288 glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &value);
289 if(value == GL_FALSE)
292 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &value);
293 std::vector<char>log(value+1, 0);
294 glGetShaderInfoLog(shaders[i], (GLsizei) log.size(), NULL, &log.front());
297 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &value);
298 std::vector<char> source(value+1, 0);
299 glGetShaderSource(shaders[i], source.size(), NULL, &source.front());
301 glGetShaderiv(shaders[i], GL_SHADER_TYPE, &value);
302 errors.append(
"[error] compiling ");
303 if(value == GL_VERTEX_SHADER)
304 errors.append(
"vertex shader...\n");
305 else if(value == GL_FRAGMENT_SHADER)
306 errors.append(
"fragment shader...\n");
308 errors.append(
"shader...\n");
311 int last_error= print_errors(errors, &log.front(), &source.front());
312 first_error= std::min(first_error, last_error);
319 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value);
321 std::vector<char>log(value+1, 0);
322 glGetProgramInfoLog(program, (GLsizei) log.size(), NULL, &log.front());
324 errors.append(
"[error] linking program...\n").append(log.begin(), log.end());
334 if(errors.size() > 0)
335 printf(
"%s\n", errors.c_str());
int program_print_errors(const GLuint program)
affiche les erreurs de compilation.
GLuint read_program(const char *filename, const char *definitions)
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.
int program_format_errors(const GLuint program, std::string &errors)
renvoie les erreurs de compilation.
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().
int release_program(const GLuint program)
detruit les shaders et le program.
int reload_program(GLuint program, const char *filename, const char *definitions)
recharge les sources et recompile un shader program.