ogl_program_build.c (2691B)
1 /* 2 2018 David DiPaola 3 licensed under CC0 (public domain, see https://creativecommons.org/publicdomain/zero/1.0/) 4 */ 5 6 #include <stdio.h> 7 8 #include <stdlib.h> 9 10 #include <GL/glew.h> 11 12 #include <GLFW/glfw3.h> 13 14 static int 15 _shader_compile( 16 GLenum shader_type, const char * shader_code, 17 GLuint * out_shader_ID 18 ) { 19 GLuint shader_ID; 20 const char * shader_type_str = (shader_type == GL_VERTEX_SHADER) ? "vertex" : "fragment"; 21 22 shader_ID = glCreateShader(shader_type); 23 24 glShaderSource(shader_ID, 1, &shader_code, NULL); 25 26 glCompileShader(shader_ID); 27 GLsizei log_length = 0; 28 glGetShaderiv(shader_ID, GL_INFO_LOG_LENGTH, &log_length); 29 if (log_length > 0) { 30 GLchar * log = calloc(log_length, sizeof(GLchar)); /* TODO handle error */ 31 glGetShaderInfoLog(shader_ID, log_length, NULL, log); 32 fprintf(stderr, "GL %s shader compiler: %s" "\n", shader_type_str, log); 33 free(log); 34 } 35 36 GLint status_compile = GL_FALSE; 37 glGetShaderiv(shader_ID, GL_COMPILE_STATUS, &status_compile); 38 if (status_compile != GL_TRUE) { 39 fprintf(stderr, "GL %s shader compiler: ERROR" "\n", shader_type_str); 40 fprintf(stderr, "\t" "at %s : %d" "\n", __FILE__, __LINE__); 41 return -1; 42 } 43 44 (*out_shader_ID) = shader_ID; 45 return 0; 46 } 47 48 GLuint 49 ogl_program_build(const char * program_vertex_source, const char * program_fragment_source) { 50 int status; 51 52 GLuint vertexshader_ID; 53 status = _shader_compile(GL_VERTEX_SHADER, program_vertex_source, &vertexshader_ID); 54 if (status < 0) { 55 fprintf(stderr, "\t" "at %s : %d" "\n", __FILE__, __LINE__); 56 exit(-1); 57 } 58 59 GLuint fragmentshader_ID; 60 status = _shader_compile(GL_FRAGMENT_SHADER, program_fragment_source, &fragmentshader_ID); 61 if (status < 0) { 62 fprintf(stderr, "\t" "at %s : %d" "\n", __FILE__, __LINE__); 63 exit(-1); 64 } 65 66 GLuint program_ID = glCreateProgram(); 67 glAttachShader(program_ID, vertexshader_ID); 68 glAttachShader(program_ID, fragmentshader_ID); 69 glLinkProgram(program_ID); 70 GLsizei log_length = 0; 71 glGetProgramiv(program_ID, GL_INFO_LOG_LENGTH, &log_length); 72 if ( log_length > 0 ){ 73 GLchar * log = calloc(log_length, sizeof(GLchar)); /* TODO handle error */ 74 glGetProgramInfoLog(program_ID, log_length, NULL, log); 75 fprintf(stderr, "GL shader program linker: %s" "\n", log); 76 free(log); 77 } 78 GLint status_compile = GL_FALSE; 79 glGetProgramiv(program_ID, GL_LINK_STATUS, &status_compile); 80 if (status_compile != GL_TRUE) { 81 fprintf(stderr, "GL shader program linker: ERROR" "\n"); 82 fprintf(stderr, "\t" "at %s : %d" "\n", __FILE__, __LINE__); 83 exit(-1); 84 } 85 86 glDetachShader(program_ID, vertexshader_ID); 87 glDetachShader(program_ID, fragmentshader_ID); 88 89 glDeleteShader(vertexshader_ID); 90 glDeleteShader(fragmentshader_ID); 91 92 return program_ID; 93 } 94