// mlx_shaders.c #include #include #include #include #include "mlx_int.h" void display_log(GLuint object, void (*param_func)(), void (*getlog_func)()) { GLint log_length; char *log; param_func(object, GL_INFO_LOG_LENGTH, &log_length); log = malloc(log_length); getlog_func(object, log_length, NULL, log); fprintf(stderr, "%s", log); free(log); } int mlx_shaders_pixel(glsl_info_t *glsl) { char *source; int length; GLint action_ok; glsl->pixel_vshader = glCreateShader(GL_VERTEX_SHADER); source = strdup("#version 110 \n" "attribute vec2 position;" "varying vec2 texcoord;" "void main()" "{" " gl_Position = vec4( position, 0.0, 1.0);" " texcoord = vec2(position[0]+1.0, 1.0 - position[1]) / 2.0;" "}"); length = strlen(source); glShaderSource(glsl->pixel_vshader, 1, (const GLchar**)&source, &length); glCompileShader(glsl->pixel_vshader); free(source); glGetShaderiv(glsl->pixel_vshader, GL_COMPILE_STATUS, &action_ok); if (!action_ok) { fprintf(stderr, "Failed to compile pixel vshader :\n"); display_log(glsl->pixel_vshader, glGetShaderiv, glGetShaderInfoLog); return (1); } glsl->pixel_fshader = glCreateShader(GL_FRAGMENT_SHADER); source = strdup("#version 110 \n" "uniform sampler2D texture;" "varying vec2 texcoord;" "void main()" "{" " gl_FragColor = texture2D(texture, texcoord);" "}"); length = strlen(source); glShaderSource(glsl->pixel_fshader, 1, (const GLchar**)&source, &length); glCompileShader(glsl->pixel_fshader); free(source); glGetShaderiv(glsl->pixel_fshader, GL_COMPILE_STATUS, &action_ok); if (!action_ok) { fprintf(stderr, "Failed to compile pixel fshader :\n"); display_log(glsl->pixel_fshader, glGetShaderiv, glGetShaderInfoLog); return (1); } glsl->pixel_program = glCreateProgram(); glAttachShader(glsl->pixel_program, glsl->pixel_vshader); glAttachShader(glsl->pixel_program, glsl->pixel_fshader); glLinkProgram(glsl->pixel_program); glGetProgramiv(glsl->pixel_program, GL_LINK_STATUS, &action_ok); if (!action_ok) { fprintf(stderr, "Failed to link pixel shader program:\n"); display_log(glsl->pixel_program, glGetProgramiv, glGetProgramInfoLog); return (1); } glFlush(); return (0); } int mlx_shaders_image(glsl_info_t *glsl) { char *source; int length; GLint action_ok; glsl->image_vshader = glCreateShader(GL_VERTEX_SHADER); source = strdup("#version 110 \n" "attribute vec2 position;" "uniform vec2 winhalfsize;" "uniform vec2 imagepos;" "uniform vec2 imagesize;" "varying vec2 texcoord;" "void main()" "{" " texcoord = position / imagesize;" " vec2 pos = position - winhalfsize + imagepos;" " pos = pos / winhalfsize;" " gl_Position = vec4( pos, 0.0, 1.0);" "}"); length = strlen(source); glShaderSource(glsl->image_vshader, 1, (const GLchar**)&source, &length); glCompileShader(glsl->image_vshader); free(source); glGetShaderiv(glsl->image_vshader, GL_COMPILE_STATUS, &action_ok); if (!action_ok) { fprintf(stderr, "Failed to compile image vshader :\n"); display_log(glsl->image_vshader, glGetShaderiv, glGetShaderInfoLog); return (1); } glsl->image_fshader = glCreateShader(GL_FRAGMENT_SHADER); source = strdup("#version 110 \n" "uniform sampler2D texture;" "varying vec2 texcoord;" "void main()" "{" " gl_FragColor = texture2D(texture, texcoord);" "}"); length = strlen(source); glShaderSource(glsl->image_fshader, 1, (const GLchar**)&source, &length); glCompileShader(glsl->image_fshader); free(source); glGetShaderiv(glsl->image_fshader, GL_COMPILE_STATUS, &action_ok); if (!action_ok) { fprintf(stderr, "Failed to compile image fshader :\n"); display_log(glsl->image_fshader, glGetShaderiv, glGetShaderInfoLog); return (1); } glsl->image_program = glCreateProgram(); glAttachShader(glsl->image_program, glsl->image_vshader); glAttachShader(glsl->image_program, glsl->image_fshader); glLinkProgram(glsl->image_program); glGetProgramiv(glsl->image_program, GL_LINK_STATUS, &action_ok); if (!action_ok) { fprintf(stderr, "Failed to link image shader program:\n"); display_log(glsl->image_program, glGetProgramiv, glGetProgramInfoLog); return (1); } glFlush(); return (0); } int mlx_shaders_font(glsl_info_t *glsl) { char *source; int length; GLint action_ok; glsl->font_vshader = glCreateShader(GL_VERTEX_SHADER); source = strdup("#version 110 \n" "attribute vec2 position;" "uniform vec2 winhalfsize;" "uniform vec2 fontposinwin;" "uniform vec2 fontposinatlas;" "uniform vec2 fontatlassize;" "varying vec2 texcoord;" "void main()" "{" #ifdef STRINGPUTX11 " texcoord = (position * vec2(1.4, -1.4) + fontposinatlas ) / fontatlassize;" #else " texcoord = (position * vec2(1.0, -1.0) + fontposinatlas ) / fontatlassize;" #endif " vec2 pos = position - winhalfsize + fontposinwin;" " pos = pos / winhalfsize;" " gl_Position = vec4( pos, 0.0, 1.0);" "}"); length = strlen(source); glShaderSource(glsl->font_vshader, 1, (const GLchar**)&source, &length); glCompileShader(glsl->font_vshader); free(source); glGetShaderiv(glsl->font_vshader, GL_COMPILE_STATUS, &action_ok); if (!action_ok) { fprintf(stderr, "Failed to compile font vshader :\n"); display_log(glsl->font_vshader, glGetShaderiv, glGetShaderInfoLog); return (1); } glsl->font_fshader = glCreateShader(GL_FRAGMENT_SHADER); source = strdup("#version 110 \n" "uniform sampler2D texture;" "uniform vec4 color;" "varying vec2 texcoord;" "void main()" "{" " gl_FragColor = color * texture2D(texture, texcoord);" "}"); length = strlen(source); glShaderSource(glsl->font_fshader, 1, (const GLchar**)&source, &length); glCompileShader(glsl->font_fshader); free(source); glGetShaderiv(glsl->font_fshader, GL_COMPILE_STATUS, &action_ok); if (!action_ok) { fprintf(stderr, "Failed to compile font fshader :\n"); display_log(glsl->font_fshader, glGetShaderiv, glGetShaderInfoLog); return (1); } glsl->font_program = glCreateProgram(); glAttachShader(glsl->font_program, glsl->font_vshader); glAttachShader(glsl->font_program, glsl->font_fshader); glLinkProgram(glsl->font_program); glGetProgramiv(glsl->font_program, GL_LINK_STATUS, &action_ok); if (!action_ok) { fprintf(stderr, "Failed to link font shader program:\n"); display_log(glsl->font_program, glGetProgramiv, glGetProgramInfoLog); return (1); } glFlush(); return (0); } int mlx_shaders(glsl_info_t *glsl) { return (mlx_shaders_pixel(glsl) + mlx_shaders_image(glsl) + mlx_shaders_font(glsl)); }