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 ************************************************************************/
26 static texture_t
*textures
= NULL
;
27 static int tex_ids
= 0;
29 /* generate the hardware texture */
30 int tex_generate(texture_t
*tex
)
39 /* delete the old texture, if it exists */
41 glDeleteTextures(1, &tex
->glid
);
43 if (e
!= GL_NO_ERROR
) {
44 char* es
= opengl_error_string(e
);
45 vlprintf(CN_ERROR
"%s",es
);
50 /* create a new texture */
51 glGenTextures(1, &tex
->glid
);
53 if (e
!= GL_NO_ERROR
) {
54 char* es
= opengl_error_string(e
);
55 vlprintf(CN_ERROR
"%s",es
);
59 glBindTexture(GL_TEXTURE_2D
, tex
->glid
);
61 if (e
!= GL_NO_ERROR
) {
62 char* es
= opengl_error_string(e
);
63 vlprintf(CN_ERROR
"%s",es
);
67 b
= opengl_has_bilinear();
68 t
= opengl_has_trilinear();
69 m
= opengl_has_mipmap();
71 /* draw the pixels to the texture */
72 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA8
, tex
->px
->w
, tex
->px
->h
, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, tex
->px
->pixels
);
74 if (e
!= GL_NO_ERROR
) {
75 char* es
= opengl_error_string(e
);
76 vlprintf(CN_ERROR
"%s",es
);
81 /* shouldn't ever need this, but there's an ATI/AMD bug that this fixes */
82 glEnable(GL_TEXTURE_2D
);
83 glGenerateMipmap(GL_TEXTURE_2D
);
84 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
85 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
89 glTexParameteri(GL_TEXTURE_2D
,GL_TEXTURE_MAG_FILTER
,GL_LINEAR
);
91 glTexParameteri(GL_TEXTURE_2D
,GL_TEXTURE_MIN_FILTER
,GL_LINEAR_MIPMAP_LINEAR
);
93 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
96 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
97 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
99 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
100 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
103 if (opengl_has_anisotropic()) {
104 float ma
= opengl_max_anisotropic();
105 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MAX_ANISOTROPY_EXT
, ma
);
109 if (e
!= GL_NO_ERROR
) {
110 char* es
= opengl_error_string(e
);
111 vlprintf(CN_ERROR
"%s",es
);
120 /* add a new image to the cache */
121 texture_t
*tex_create()
123 texture_t
*tex
= malloc(sizeof(texture_t
));
137 textures
= list_push(&textures
,tex
);
143 void tex_free(texture_t
*tex
)
147 textures
= list_remove(&textures
,tex
);
149 glDeleteTextures(1, &tex
->glid
);
153 /* load an image to a texture */
154 texture_t
*tex_from_image(char* type
, char* file
)
162 if (!strcmp(t
->name
,file
))
170 p
= image_load(type
,file
);
174 /* and make a texture out of it */
175 t
= tex_from_pixels(p
);
177 strncpy(t
->name
,file
,100);
182 /* create a texture from pixel data */
183 texture_t
*tex_from_pixels(image_t
*px
)
196 tex
->xf
= 1.0/(GLfloat
)px
->w
;
197 tex
->yf
= 1.0/(GLfloat
)px
->h
;
199 if (!tex_generate(tex
))
207 /* update a texture from pixel data */
208 texture_t
*tex_update_pixels(texture_t
*tex
, image_t
*px
)
211 return tex_from_pixels(px
);
216 tex
->xf
= 1.0/(GLfloat
)px
->w
;
217 tex
->yf
= 1.0/(GLfloat
)px
->h
;
219 if (!tex_generate(tex
))
227 /* create a transparent texture */
228 texture_t
*tex_from_rgba(int x
, int y
, uint8_t r
, uint8_t g
, uint8_t b
, uint8_t a
)
236 snprintf(n
,100,"rgba-%u-%u-%u-%u-%d-%d",(uint32_t)r
,(uint32_t)g
,(uint32_t)b
,(uint32_t)a
,x
,y
);
239 if (!strcmp(t
->name
,n
))
247 p
= malloc(sizeof(image_t
));
256 p
->pixels
= malloc(sizeof(uint8_t)*size
);
270 t
= tex_from_pixels(p
);