diff options
Diffstat (limited to 'minilibx/mlx_shaders.c')
-rw-r--r-- | minilibx/mlx_shaders.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/minilibx/mlx_shaders.c b/minilibx/mlx_shaders.c new file mode 100644 index 0000000..4a58955 --- /dev/null +++ b/minilibx/mlx_shaders.c @@ -0,0 +1,240 @@ +// mlx_shaders.c + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <OpenGL/gl3.h> +#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)); +} |