You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
6.7 KiB
240 lines
6.7 KiB
// 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));
|
|
}
|
|
|