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.