…aaand add PREFIX to the freebsd makefile too
[voxelands-alt.git] / src / graphics / material.c
blobd360a770710b8abeb7abf4f96dceea3c44e9f93d
1 /************************************************************************
2 * material.c
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 ************************************************************************/
20 #include "common.h"
21 #include "graphics.h"
22 #include "list.h"
24 #include <string.h>
26 static struct {
27 material_t *materials;
28 int ids;
29 GLuint current_texture;
30 } mat_data ={
31 NULL,
36 /* create a new blank material */
37 material_t *mat_create()
39 material_t *mat = malloc(sizeof(material_t));
40 mat->id = mat_data.ids++;
41 mat->name[0] = 0;
42 mat->options = MATOPT_BFCULL;
43 mat->tex = NULL;
44 mat->next = NULL;
45 mat->shininess = 1.0;
46 mat->reflectivity = 0.0;
47 mat->bumpiness = 0.0;
49 mat_data.materials = list_push(&mat_data.materials,mat);
51 return mat;
54 /* free a material */
55 void mat_free(material_t *mat)
57 if (!mat)
58 return;
60 mat_data.materials = list_remove(&mat_data.materials,mat);
62 if (mat->tex)
63 tex_free(mat->tex);
65 free(mat);
68 /* create a material from a texture */
69 material_t *mat_from_tex(texture_t *tex)
71 material_t *mat = mat_create();
72 mat->tex = tex;
73 strcpy(mat->name,tex->name);
75 return mat;
78 /* create a material from pixel data */
79 material_t *mat_from_pixels(image_t *p)
81 material_t *mat = mat_create();
82 mat->tex = tex_from_pixels(p);
83 strcpy(mat->name,mat->tex->name);
85 return mat;
88 /* update a material from pixel data */
89 material_t *mat_update_pixels(material_t *mat, image_t *p)
91 if (!mat)
92 return mat_from_pixels(p);
94 mat->tex = tex_update_pixels(mat->tex,p);
96 return mat;
99 /* create a material from an image */
100 material_t *mat_from_image(char* type, char* file)
102 material_t *mat = mat_create();
104 mat->tex = tex_from_image(type,file);
105 if (!mat->tex) {
106 mat_free(mat);
107 return NULL;
110 strcpy(mat->name,mat->tex->name);
112 return mat;
115 /* create a material from a colour */
116 material_t *mat_from_colour(colour_t *c)
118 char buff[100];
119 material_t *mat;
120 snprintf(buff,100,"rgba-%d-%d-%d-%d",c->r,c->g,c->b,c->a);
122 mat = mat_create();
124 mat->tex = tex_from_rgba(1,1,c->r,c->g,c->b,c->a);
125 if (!mat->tex) {
126 mat_free(mat);
127 return NULL;
130 strcpy(mat->name,buff);
132 return mat;
135 /* use a material */
136 void mat_use(material_t *mat, shader_t *shader)
138 if (mat->tex) {
139 GLenum e;
140 if (mat->tex->state != 1)
141 tex_generate(mat->tex);
142 if (mat_data.current_texture != mat->tex->glid)
143 glBindTexture(GL_TEXTURE_2D,mat->tex->glid);
144 mat_data.current_texture = mat->tex->glid;
145 e = glGetError();
146 if (e != GL_NO_ERROR) {
147 char* es = opengl_error_string(e);
148 vlprintf(CN_ERROR "%s",es);
149 mat->tex->state = 0;
150 return;
154 /* specular values */
155 if (shader) {
156 shader_uniform_float(shader,"shininess",mat->shininess);
157 shader_uniform_float(shader,"reflectivity",mat->reflectivity);
158 shader_uniform_float(shader,"bumpiness",mat->bumpiness);
161 /* options */
162 if ((mat->options&MATOPT_BFCULL)) {
163 glEnable(GL_CULL_FACE);
164 glCullFace(GL_BACK);
165 }else{
166 glDisable(GL_CULL_FACE);
170 /* set the shininess and reflectivity of a material */
171 void mat_shininess(material_t *mat, float shininess, float reflectivity)
173 mat->shininess = shininess;
174 mat->reflectivity = reflectivity;
177 /* set the bumpiness (for bump mapping) of a material */
178 void mat_bumpiness(material_t *mat, float bumpiness)
180 mat->bumpiness = bumpiness;
183 /* set the name of a material */
184 void mat_name(material_t *mat, char* name)
186 strncpy(mat->name,name,100);
189 /* set the texture of a material */
190 void mat_tex(material_t *mat, texture_t *tex)
192 mat->tex = tex;
195 /* set the texture of a material from an image file */
196 void mat_tex_file(material_t *mat, char* type, char* file)
198 mat->tex = tex_from_image(type,file);
199 strcpy(mat->name,mat->tex->name);
202 /* set the options for a material, return the previous options */
203 uint32_t mat_options(material_t *mat, uint32_t opt)
205 uint32_t o = mat->options;
206 if (opt != MATOPT_GET)
207 mat->options = opt;
208 return o;