| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- #ifndef SHADER_H
- #define SHADER_H
- #include <GL/glew.h>
- enum shader_err {
- SHADER_ERR_OK,
- SHADER_ERR_FAIL_CREATE,
- SHADER_ERR_FAIL_CREATE_PROG,
- SHADER_ERR_FAIL_COMPILE,
- SHADER_ERR_FAIL_READ_FILE,
- SHADER_ERR_FAIL_LINK_PROG
- };
- struct ret_uint32_t_err {
- uint32_t f1;
- enum shader_err f2;
- };
- struct ret_uint32_t_err shader_compile_source(const char *src, GLenum type);
- struct ret_uint32_t_err shader_compile_file(const char *filepath, GLenum type);
- uint32_t shader_compile_file_or_exit(const char *filepath, GLenum type);
- struct ret_uint32_t_err program_link(uint32_t vert_shader,
- uint32_t frag_shader);
- uint32_t program_link_or_exit(uint32_t vert_shader, uint32_t frag_shader);
- const char *shader_type_to_cstr(GLenum type);
- #if defined(SHADER_IMP) || defined(IMP)
- #include <stdio.h>
- #include "unwrap.h"
- #include "file.h"
- struct ret_uint32_t_err
- shader_compile_source(const char *src, GLenum type)
- {
- enum shader_err err;
- uint32_t shdr = glCreateShader(type);
- if ( shdr == 0 ) {
- err = SHADER_ERR_FAIL_CREATE;
- goto err;
- }
- glShaderSource(shdr, 1, &src, NULL);
- glCompileShader(shdr);
- int32_t comp_status = GL_FALSE;
- glGetShaderiv(shdr, GL_COMPILE_STATUS, &comp_status);
- if ( comp_status == GL_FALSE ) {
- err = SHADER_ERR_FAIL_COMPILE;
- int32_t log_length = 1024;
- glGetShaderiv(shdr, GL_INFO_LOG_LENGTH, &log_length);
- log_length += 10;
- char *log = calloc(sizeof(char), (size_t)log_length);
- glGetShaderInfoLog(shdr, log_length, NULL, log);
- fprintf(stderr, "FAILED COMPILE %s : %s\n",
- shader_type_to_cstr(type), log);
- goto err;
- }
- return (struct ret_uint32_t_err) {
- .f1 = shdr,
- .f2 = SHADER_ERR_OK
- };
- err: ;
- return (struct ret_uint32_t_err) {
- .f1 = 0,
- .f2 = err
- };
- }
- struct ret_uint32_t_err
- shader_compile_file(const char *filepath, GLenum type)
- {
- char *src;
- enum file_err err;
- src = (char *) file_read_all(filepath, NULL, &err);
- if ( err != FILE_ERR_OK ) {
- return (struct ret_uint32_t_err) {
- .f1 = 0,
- .f2 = SHADER_ERR_FAIL_READ_FILE,
- };
- }
- struct ret_uint32_t_err ret = shader_compile_source(src, type);
- free(src);
- return ret;
- }
- uint32_t
- shader_compile_file_or_exit(const char *filepath, GLenum type)
- {
- enum shader_err err;
- uint32_t shader;
- RET_UNWRAP2(shader, err, struct ret_uint32_t_err,
- shader_compile_file(filepath, type));
- if ( err != SHADER_ERR_OK ) {
- fprintf(stderr, "Failed to compile shader %s\n", filepath);
- exit(EXIT_FAILURE);
- }
- return shader;
- }
- struct ret_uint32_t_err
- program_link(uint32_t vert_shader, uint32_t frag_shader)
- {
- enum shader_err err;
- uint32_t prog = glCreateProgram();
- if ( prog == 0 ) {
- err = SHADER_ERR_FAIL_CREATE_PROG;
- goto err;
- }
- glAttachShader(prog, vert_shader);
- glAttachShader(prog, frag_shader);
- glLinkProgram(prog);
- int32_t link_status = GL_FALSE;
- glGetProgramiv(prog, GL_LINK_STATUS, &link_status);
- if ( link_status != GL_TRUE ) {
- err = SHADER_ERR_FAIL_LINK_PROG;
- int32_t log_length = 1024;
- glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &log_length);
- log_length += 10;
- char *log = calloc(sizeof(char), (size_t)log_length);
- glGetProgramInfoLog(prog, log_length, NULL, log);
- fprintf(stderr, "FAILED LINK PROG: %s\n", log);
- goto err;
- }
- glDeleteShader(vert_shader);
- glDeleteShader(frag_shader);
- return (struct ret_uint32_t_err) {
- .f1 = prog,
- .f2 = SHADER_ERR_OK,
- };
- err: ;
- return (struct ret_uint32_t_err) {
- .f1 = 0,
- .f2 = err,
- };
- }
- uint32_t
- program_link_or_exit(uint32_t vert_shader, uint32_t frag_shader)
- {
- enum shader_err err;
- uint32_t prog;
- RET_UNWRAP2(prog, err, struct ret_uint32_t_err,
- program_link(vert_shader, frag_shader));
- if ( err != SHADER_ERR_OK ) {
- fprintf(stderr, "Failed to link program\n");
- exit(EXIT_FAILURE);
- }
- return prog;
- }
- const char *
- shader_type_to_cstr(GLenum type)
- {
- switch ( type ) {
- case GL_VERTEX_SHADER: return "GL_VERTEX_SHADER"; break;
- case GL_FRAGMENT_SHADER: return "GL_FRAGMENT_SHADER"; break;
- }
- return "(Unknown Shader)";
- }
- #endif /* defined(SHADER_IMP) || defined(IMP) */
- #endif
|