transparent-cube

Minimal cross-platform native/wasm graphics example.
git clone git://git.amin.space/transparent-cube.git
Log | Files | Refs | README | LICENSE

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 }