1 /************************************************************************
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
27 static shader_t
*shaders
= NULL
;
28 static shader_t
*active
= NULL
;
30 static GLuint
shader_load(file_t
*f
, GLenum type
)
38 s
= glCreateShader(type
);
39 glShaderSource(s
, 1, (const GLchar
**)&f
->data
,NULL
);
41 glGetShaderiv(s
,GL_COMPILE_STATUS
,&i
);
44 glGetShaderInfoLog(s
,512,&i
,buff
);
45 vlprintf("Shader %s failed to compile: %s",f
->name
,buff
);
53 shader_t
*shader_create(char* name
)
62 if (snprintf(buff
,512,"%s_vertex.glsl",name
) < 512)
63 vert
= file_load("shader",buff
);
64 if (snprintf(buff
,512,"%s_geometry.glsl",name
) < 512)
65 geom
= file_load("shader",buff
);
66 if (snprintf(buff
,512,"%s_fragment.glsl",name
) < 512)
67 frag
= file_load("shader",buff
);
69 if (!vert
&& !geom
&& !frag
)
72 s
= malloc(sizeof(shader_t
));
83 strncpy(s
->name
,name
,256);
91 s
->vert
= shader_load(vert
,GL_VERTEX_SHADER
);
93 s
->geom
= shader_load(geom
,GL_GEOMETRY_SHADER
);
95 s
->frag
= shader_load(frag
,GL_FRAGMENT_SHADER
);
97 if (!s
->vert
&& !s
->geom
&& !s
->frag
) {
108 s
->program
= glCreateProgram();
110 glAttachShader(s
->program
,s
->vert
);
112 glAttachShader(s
->program
,s
->geom
);
114 glAttachShader(s
->program
,s
->frag
);
115 glLinkProgram(s
->program
);
116 glGetProgramiv(s
->program
, GL_LINK_STATUS
, &i
);
118 glGetProgramInfoLog(s
->program
, 512, &i
, buff
);
119 vlprintf("Shader failed to link: %s",buff
);
122 glValidateProgram(s
->program
);
131 shaders
= list_push(&shaders
,s
);
137 void shader_free(shader_t
*s
)
145 glDetachShader(s
->program
,s
->vert
);
146 glDetachShader(s
->program
,s
->frag
);
147 glDeleteShader(s
->vert
);
148 glDeleteShader(s
->frag
);
149 glDeleteProgram(s
->program
);
154 /* bind an attribute to a shader */
155 int shader_attribute(shader_t
*s
, int att
, char* name
)
160 glBindAttribLocation(s
->program
,att
,name
);
161 glLinkProgram(s
->program
);
162 glValidateProgram(s
->program
);
167 /* set a shader uniform value */
168 int shader_uniform_int(shader_t
*s
, char* name
, int value
)
176 var
= glGetUniformLocation(s
->program
,name
);
177 glUniform1i(var
,value
);
182 /* set a shader uniform value */
183 int shader_uniform_float(shader_t
*s
, char* name
, float value
)
191 var
= glGetUniformLocation(s
->program
,name
);
192 glUniform1f(var
,value
);
197 /* set a shader uniform value */
198 int shader_uniform_v2(shader_t
*s
, char* name
, v2_t
*value
)
206 var
= glGetUniformLocation(s
->program
,name
);
207 glUniform2f(var
,value
->x
,value
->y
);
212 /* set a shader uniform value */
213 int shader_uniform_v3(shader_t
*s
, char* name
, v3_t
*value
)
221 var
= glGetUniformLocation(s
->program
,name
);
222 glUniform3f(var
,value
->x
,value
->y
,value
->z
);
227 /* set a shader uniform value */
228 int shader_uniform_matrix(shader_t
*s
, char* name
, matrix_t
*value
)
236 var
= glGetUniformLocation(s
->program
,name
);
237 glUniformMatrix4fv(var
,1,GL_FALSE
,value
->data
);
243 int shader_enable(shader_t
*s
)
249 shader_disable(active
);
251 glUseProgram(s
->program
);
259 /* stop using a shader */
260 int shader_disable(shader_t
*s
)
262 if (!s
|| !s
->active
)