rev |
line source |
nuclear@9
|
1 #include <math.h>
|
nuclear@0
|
2 #include "texture.h"
|
nuclear@0
|
3 #include "image.h"
|
nuclear@0
|
4 #include "opengl.h"
|
nuclear@0
|
5 #include "imago2.h"
|
nuclear@0
|
6 #include "logger.h"
|
nuclear@0
|
7 #include "datapath.h"
|
nuclear@0
|
8
|
nuclear@15
|
9 using namespace goatgfx;
|
nuclear@15
|
10
|
nuclear@0
|
11 static int glifmt_from_ifmt(unsigned int ifmt);
|
nuclear@0
|
12 static int glfmt_from_ifmt(unsigned int ifmt);
|
nuclear@0
|
13 static int gltype_from_ifmt(unsigned int ifmt);
|
nuclear@0
|
14
|
nuclear@0
|
15 static int glifmt_from_imgfmt(Image::Format fmt);
|
nuclear@0
|
16
|
nuclear@0
|
17 static unsigned int cur_target[8] = {
|
nuclear@0
|
18 GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D,
|
nuclear@0
|
19 GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D
|
nuclear@0
|
20 };
|
nuclear@0
|
21
|
nuclear@15
|
22 namespace goatgfx {
|
nuclear@15
|
23
|
nuclear@0
|
24 void set_texture(Texture *tex, int tunit)
|
nuclear@0
|
25 {
|
nuclear@0
|
26 if(tex) {
|
nuclear@0
|
27 tex->bind(tunit);
|
nuclear@0
|
28 } else {
|
nuclear@0
|
29 glActiveTexture(GL_TEXTURE0 + tunit);
|
nuclear@0
|
30 glBindTexture(cur_target[tunit], 0);
|
nuclear@0
|
31 glActiveTexture(GL_TEXTURE0);
|
nuclear@0
|
32 }
|
nuclear@0
|
33 }
|
nuclear@0
|
34
|
nuclear@0
|
35 Texture *load_texture(const char *fname)
|
nuclear@0
|
36 {
|
nuclear@0
|
37 TextureCube *texcube = new TextureCube;
|
nuclear@0
|
38 if(texcube->load(fname)) {
|
nuclear@0
|
39 return texcube;
|
nuclear@0
|
40 }
|
nuclear@0
|
41 delete texcube;
|
nuclear@0
|
42
|
nuclear@0
|
43 Texture2D *tex = new Texture2D;
|
nuclear@0
|
44 if(tex->load(fname)) {
|
nuclear@0
|
45 return tex;
|
nuclear@0
|
46 }
|
nuclear@0
|
47 delete tex;
|
nuclear@0
|
48 return 0;
|
nuclear@0
|
49 }
|
nuclear@0
|
50
|
nuclear@15
|
51 } // namespace goatgfx
|
nuclear@0
|
52
|
nuclear@0
|
53 Texture::Texture()
|
nuclear@0
|
54 {
|
nuclear@0
|
55 target = 0;
|
nuclear@0
|
56 sz[0] = sz[1] = sz[2] = 0;
|
nuclear@0
|
57 texfmt = 0;
|
nuclear@0
|
58
|
nuclear@0
|
59 glGenTextures(1, &id);
|
nuclear@0
|
60 }
|
nuclear@0
|
61
|
nuclear@0
|
62 Texture::~Texture()
|
nuclear@0
|
63 {
|
nuclear@0
|
64 if(id) {
|
nuclear@0
|
65 glDeleteTextures(1, &id);
|
nuclear@0
|
66 }
|
nuclear@0
|
67 }
|
nuclear@0
|
68
|
nuclear@0
|
69 void Texture::set_wrapping(unsigned int wrap)
|
nuclear@0
|
70 {
|
nuclear@0
|
71 if(!target) {
|
nuclear@0
|
72 return;
|
nuclear@0
|
73 }
|
nuclear@0
|
74
|
nuclear@0
|
75 glBindTexture(target, id);
|
nuclear@0
|
76 glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
|
nuclear@0
|
77 glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);
|
nuclear@0
|
78 }
|
nuclear@0
|
79
|
nuclear@0
|
80 void Texture::set_filtering(unsigned int filt)
|
nuclear@0
|
81 {
|
nuclear@0
|
82 unsigned int mag_filter;
|
nuclear@0
|
83
|
nuclear@0
|
84 if(!target) {
|
nuclear@0
|
85 return;
|
nuclear@0
|
86 }
|
nuclear@0
|
87
|
nuclear@0
|
88 switch(filt) {
|
nuclear@0
|
89 case GL_LINEAR_MIPMAP_NEAREST:
|
nuclear@0
|
90 case GL_LINEAR_MIPMAP_LINEAR:
|
nuclear@0
|
91 mag_filter = GL_LINEAR;
|
nuclear@0
|
92 break;
|
nuclear@0
|
93
|
nuclear@0
|
94 case GL_NEAREST_MIPMAP_NEAREST:
|
nuclear@0
|
95 case GL_NEAREST_MIPMAP_LINEAR:
|
nuclear@0
|
96 mag_filter = GL_NEAREST;
|
nuclear@0
|
97 break;
|
nuclear@0
|
98
|
nuclear@0
|
99 default:
|
nuclear@0
|
100 mag_filter = filt;
|
nuclear@0
|
101 }
|
nuclear@0
|
102
|
nuclear@0
|
103 set_filtering(filt, mag_filter);
|
nuclear@0
|
104 }
|
nuclear@0
|
105
|
nuclear@0
|
106 void Texture::set_filtering(unsigned int min_filt, unsigned int mag_filt)
|
nuclear@0
|
107 {
|
nuclear@0
|
108 glBindTexture(target, id);
|
nuclear@0
|
109 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, min_filt);
|
nuclear@0
|
110 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, mag_filt);
|
nuclear@0
|
111 }
|
nuclear@0
|
112
|
nuclear@0
|
113 unsigned int Texture::get_format() const
|
nuclear@0
|
114 {
|
nuclear@0
|
115 return texfmt;
|
nuclear@0
|
116 }
|
nuclear@0
|
117
|
nuclear@0
|
118 int Texture::get_size(int dim) const
|
nuclear@0
|
119 {
|
nuclear@0
|
120 if(dim < 0 || dim >= 3) {
|
nuclear@0
|
121 return 0;
|
nuclear@0
|
122 }
|
nuclear@0
|
123 return sz[dim];
|
nuclear@0
|
124 }
|
nuclear@0
|
125
|
nuclear@0
|
126 unsigned int Texture::get_id() const
|
nuclear@0
|
127 {
|
nuclear@0
|
128 return id;
|
nuclear@0
|
129 }
|
nuclear@0
|
130
|
nuclear@0
|
131 void Texture::bind(int tex_unit) const
|
nuclear@0
|
132 {
|
nuclear@0
|
133 glActiveTexture(GL_TEXTURE0 + tex_unit);
|
nuclear@0
|
134 glBindTexture(target, id);
|
nuclear@0
|
135 glActiveTexture(GL_TEXTURE0);
|
nuclear@0
|
136
|
nuclear@0
|
137 cur_target[tex_unit] = target;
|
nuclear@0
|
138 }
|
nuclear@0
|
139
|
nuclear@0
|
140
|
nuclear@0
|
141 // ---- Texture2D ----
|
nuclear@0
|
142
|
nuclear@0
|
143 Texture2D::Texture2D()
|
nuclear@0
|
144 {
|
nuclear@0
|
145 target = GL_TEXTURE_2D;
|
nuclear@0
|
146 }
|
nuclear@0
|
147
|
nuclear@0
|
148 void Texture2D::create(int xsz, int ysz, unsigned int ifmt)
|
nuclear@0
|
149 {
|
nuclear@0
|
150 int fmt = glfmt_from_ifmt(ifmt);
|
nuclear@0
|
151 int type = gltype_from_ifmt(ifmt);
|
nuclear@0
|
152
|
nuclear@0
|
153 glBindTexture(GL_TEXTURE_2D, id);
|
nuclear@0
|
154 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@0
|
155 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@0
|
156 glTexImage2D(GL_TEXTURE_2D, 0, glifmt_from_ifmt(ifmt), xsz, ysz, 0, fmt, type, 0);
|
nuclear@0
|
157 CHECKGLERR;
|
nuclear@0
|
158 sz[0] = xsz;
|
nuclear@0
|
159 sz[1] = ysz;
|
nuclear@0
|
160 texfmt = ifmt;
|
nuclear@0
|
161 }
|
nuclear@0
|
162
|
nuclear@0
|
163 void Texture2D::set_image(const Image &img, int idx)
|
nuclear@0
|
164 {
|
nuclear@0
|
165 texfmt = glifmt_from_imgfmt(img.get_format());
|
nuclear@0
|
166 unsigned int fmt = glfmt_from_ifmt(texfmt);
|
nuclear@0
|
167 unsigned int type = gltype_from_ifmt(texfmt);
|
nuclear@0
|
168
|
nuclear@0
|
169 sz[0] = img.get_width();
|
nuclear@0
|
170 sz[1] = img.get_height();
|
nuclear@0
|
171
|
nuclear@0
|
172 glBindTexture(GL_TEXTURE_2D, id);
|
nuclear@0
|
173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
nuclear@0
|
174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@0
|
175 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
nuclear@0
|
176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
nuclear@0
|
177
|
nuclear@0
|
178 #ifdef __GLEW_H__
|
nuclear@0
|
179 if(GLEW_SGIS_generate_mipmap) {
|
nuclear@0
|
180 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
nuclear@0
|
181 #endif
|
nuclear@0
|
182 glTexImage2D(GL_TEXTURE_2D, 0, texfmt, sz[0], sz[1], 0, fmt, type, img.get_pixels());
|
nuclear@0
|
183 #ifdef __GLEW_H__
|
nuclear@0
|
184 } else {
|
nuclear@0
|
185 gluBuild2DMipmaps(GL_TEXTURE_2D, texfmt, sz[0], sz[1], fmt, type, img.get_pixels());
|
nuclear@0
|
186 }
|
nuclear@0
|
187 #endif
|
nuclear@0
|
188
|
nuclear@0
|
189 #ifdef GL_ES_VERSION_2_0
|
nuclear@0
|
190 glGenerateMipmap(GL_TEXTURE_2D);
|
nuclear@0
|
191 #endif
|
nuclear@0
|
192 }
|
nuclear@0
|
193
|
nuclear@0
|
194 bool Texture2D::load(const char *fname)
|
nuclear@0
|
195 {
|
nuclear@0
|
196 Image img;
|
nuclear@2
|
197 if(!img.load(fname)) {
|
nuclear@0
|
198 error_log("failed to load 2D texture: %s\n", fname);
|
nuclear@0
|
199 return false;
|
nuclear@0
|
200 }
|
nuclear@0
|
201 set_image(img);
|
nuclear@0
|
202
|
nuclear@0
|
203 info_log("loaded 2D texture: %s\n", fname);
|
nuclear@0
|
204 return true;
|
nuclear@0
|
205 }
|
nuclear@0
|
206
|
nuclear@0
|
207 bool Texture2D::save(const char *fname) const
|
nuclear@0
|
208 {
|
nuclear@0
|
209 #ifndef GL_ES_VERSION_2_0
|
nuclear@0
|
210 unsigned char *pixels = new unsigned char[sz[0] * sz[1] * 4];
|
nuclear@0
|
211
|
nuclear@0
|
212 glBindTexture(GL_TEXTURE_2D, id);
|
nuclear@0
|
213 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
nuclear@0
|
214
|
nuclear@0
|
215 if(img_save_pixels(fname, pixels, sz[0], sz[1]) == -1) {
|
nuclear@0
|
216 error_log("failed to save 2D texture: %s\n", fname);
|
nuclear@0
|
217 delete [] pixels;
|
nuclear@0
|
218 return false;
|
nuclear@0
|
219 }
|
nuclear@0
|
220
|
nuclear@0
|
221 info_log("saved 2D texture: %s\n", fname);
|
nuclear@0
|
222 delete [] pixels;
|
nuclear@0
|
223 return true;
|
nuclear@0
|
224 #else
|
nuclear@0
|
225 return false; // TODO
|
nuclear@0
|
226 #endif
|
nuclear@0
|
227 }
|
nuclear@0
|
228
|
nuclear@0
|
229 // ---- TextureCube ----
|
nuclear@0
|
230 static unsigned int cube_faces[] = {
|
nuclear@0
|
231 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
nuclear@0
|
232 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
nuclear@0
|
233 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
|
nuclear@0
|
234 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
nuclear@0
|
235 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
|
nuclear@0
|
236 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
|
nuclear@0
|
237 };
|
nuclear@0
|
238
|
nuclear@0
|
239 TextureCube::TextureCube()
|
nuclear@0
|
240 {
|
nuclear@0
|
241 target = GL_TEXTURE_CUBE_MAP;
|
nuclear@0
|
242 }
|
nuclear@0
|
243
|
nuclear@0
|
244 void TextureCube::create(int xsz, int ysz, unsigned int ifmt)
|
nuclear@0
|
245 {
|
nuclear@0
|
246 if(xsz != ysz) {
|
nuclear@0
|
247 error_log("trying to create cubemap with different width and height (%dx%d)\n", xsz, ysz);
|
nuclear@0
|
248 return;
|
nuclear@0
|
249 }
|
nuclear@0
|
250
|
nuclear@0
|
251 texfmt = ifmt;
|
nuclear@0
|
252
|
nuclear@0
|
253 glBindTexture(GL_TEXTURE_CUBE_MAP, id);
|
nuclear@6
|
254 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@6
|
255 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@6
|
256 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
nuclear@6
|
257 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
nuclear@9
|
258 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
nuclear@0
|
259
|
nuclear@0
|
260 for(int i=0; i<6; i++) {
|
nuclear@0
|
261 glTexImage2D(cube_faces[i], 0, ifmt, xsz, ysz, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
nuclear@0
|
262 }
|
nuclear@0
|
263 }
|
nuclear@0
|
264
|
nuclear@0
|
265 void TextureCube::set_image(const Image &img, int idx)
|
nuclear@0
|
266 {
|
nuclear@6
|
267 texfmt = glifmt_from_imgfmt(img.get_format());
|
nuclear@6
|
268 unsigned int fmt = glfmt_from_ifmt(texfmt);
|
nuclear@6
|
269 unsigned int type = gltype_from_ifmt(texfmt);
|
nuclear@6
|
270
|
nuclear@6
|
271 sz[0] = img.get_width();
|
nuclear@6
|
272 sz[1] = img.get_height();
|
nuclear@6
|
273
|
nuclear@6
|
274 glBindTexture(GL_TEXTURE_CUBE_MAP, id);
|
nuclear@6
|
275 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@6
|
276 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@6
|
277 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
nuclear@6
|
278 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
nuclear@9
|
279 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
nuclear@6
|
280
|
nuclear@6
|
281 glTexImage2D(cube_faces[idx], 0, texfmt, sz[0], sz[1], 0, fmt, type, img.get_pixels());
|
nuclear@0
|
282 }
|
nuclear@0
|
283
|
nuclear@0
|
284 bool TextureCube::load(const char *fname)
|
nuclear@0
|
285 {
|
nuclear@6
|
286 static const float one_third = 1.0 / 3.0;
|
nuclear@6
|
287 static const float two_thirds = 2.0 / 3.0;
|
nuclear@6
|
288 static const float hcross[2][6] = {
|
nuclear@6
|
289 {0.5, 0.0, 0.25, 0.25, 0.25, 0.75}, {one_third, one_third, 0.0, two_thirds, one_third, one_third} };
|
nuclear@6
|
290 static const float vcross[2][6] = {
|
nuclear@6
|
291 {two_thirds, 0.0, one_third, one_third, one_third, one_third}, {0.25, 0.25, 0.0, 0.5, 0.25, 0.75} };
|
nuclear@6
|
292 static const float hsix[2][6] = {
|
nuclear@6
|
293 {0.0, 0.0, one_third, one_third, two_thirds, two_thirds}, {0.0, 0.5, 0.0, 0.5, 0.0, 0.5} };
|
nuclear@6
|
294
|
nuclear@6
|
295 Image img;
|
nuclear@6
|
296 if(!img.load(fname)) {
|
nuclear@6
|
297 return false;
|
nuclear@6
|
298 }
|
nuclear@6
|
299
|
nuclear@6
|
300 int xsz = img.get_width();
|
nuclear@6
|
301 int ysz = img.get_height();
|
nuclear@6
|
302
|
nuclear@6
|
303 if(xsz / 4 == ysz / 3) {
|
nuclear@6
|
304 // horizontal cross, assume the vertical bit is center-left
|
nuclear@6
|
305 return load_multi(img, hcross[0], hcross[1], xsz / 4);
|
nuclear@6
|
306 }
|
nuclear@6
|
307 if(xsz / 3 == ysz / 4) {
|
nuclear@6
|
308 // vertical cross, assume the horizontal bit is center-top (180-rotated image 5)
|
nuclear@6
|
309 return load_multi(img, vcross[0], vcross[1], ysz / 4, (1 << 5));
|
nuclear@6
|
310 }
|
nuclear@6
|
311 if(xsz / 3 == ysz / 2) {
|
nuclear@6
|
312 // horizontal sixpack
|
nuclear@6
|
313 return load_multi(img, hsix[0], hsix[1], ysz / 2);
|
nuclear@6
|
314 }
|
nuclear@6
|
315
|
nuclear@6
|
316 error_log("failed to load %s: unknown cubemap configuration\n", fname);
|
nuclear@6
|
317 return false;
|
nuclear@0
|
318 }
|
nuclear@0
|
319
|
nuclear@0
|
320 bool TextureCube::save(const char *fname) const
|
nuclear@0
|
321 {
|
nuclear@0
|
322 return false; // TODO
|
nuclear@0
|
323 }
|
nuclear@0
|
324
|
nuclear@6
|
325 bool TextureCube::load_multi(const Image &img, const float *xoffsets, const float *yoffsets, float sz,
|
nuclear@6
|
326 unsigned int rotmask)
|
nuclear@6
|
327 {
|
nuclear@6
|
328 for(int i=0; i<6; i++) {
|
nuclear@6
|
329 Image face;
|
nuclear@6
|
330
|
nuclear@6
|
331 int xoffs = xoffsets[i] * img.get_width();
|
nuclear@6
|
332 int yoffs = yoffsets[i] * img.get_height();
|
nuclear@6
|
333
|
nuclear@6
|
334 if(!face.set_pixels(sz, sz, img.get_pixels(), xoffs, yoffs, img.get_width(), img.get_format())) {
|
nuclear@6
|
335 return false;
|
nuclear@6
|
336 }
|
nuclear@6
|
337
|
nuclear@6
|
338 if(rotmask & (1 << i)) {
|
nuclear@6
|
339 face.rotate_180();
|
nuclear@6
|
340 }
|
nuclear@6
|
341 set_image(face, i);
|
nuclear@6
|
342 }
|
nuclear@6
|
343 return true;
|
nuclear@6
|
344 }
|
nuclear@6
|
345
|
nuclear@0
|
346 static int glifmt_from_ifmt(unsigned int ifmt)
|
nuclear@0
|
347 {
|
nuclear@0
|
348 #ifdef GL_ES_VERSION_2_0
|
nuclear@0
|
349 switch(ifmt) {
|
nuclear@0
|
350 case GL_LUMINANCE16F:
|
nuclear@0
|
351 case GL_LUMINANCE32F:
|
nuclear@0
|
352 ifmt = GL_LUMINANCE;
|
nuclear@0
|
353 break;
|
nuclear@0
|
354
|
nuclear@0
|
355 case GL_RGB16F:
|
nuclear@0
|
356 case GL_RGB32F:
|
nuclear@0
|
357 ifmt = GL_RGB;
|
nuclear@0
|
358 break;
|
nuclear@0
|
359
|
nuclear@0
|
360 case GL_RGBA16F:
|
nuclear@0
|
361 case GL_RGBA32F:
|
nuclear@0
|
362 ifmt = GL_RGBA;
|
nuclear@0
|
363 break;
|
nuclear@0
|
364
|
nuclear@0
|
365 default:
|
nuclear@0
|
366 break;
|
nuclear@0
|
367 }
|
nuclear@0
|
368 #endif
|
nuclear@0
|
369 return ifmt; // by default just pass it through...
|
nuclear@0
|
370 }
|
nuclear@0
|
371
|
nuclear@0
|
372 static int glfmt_from_ifmt(unsigned int ifmt)
|
nuclear@0
|
373 {
|
nuclear@0
|
374 switch(ifmt) {
|
nuclear@0
|
375 case GL_LUMINANCE16F:
|
nuclear@0
|
376 case GL_LUMINANCE32F:
|
nuclear@0
|
377 return GL_LUMINANCE;
|
nuclear@0
|
378
|
nuclear@0
|
379 case GL_RGB16F:
|
nuclear@0
|
380 case GL_RGB32F:
|
nuclear@0
|
381 return GL_RGB;
|
nuclear@0
|
382
|
nuclear@0
|
383 case GL_RGBA16F:
|
nuclear@0
|
384 case GL_RGBA32F:
|
nuclear@0
|
385 return GL_RGBA;
|
nuclear@0
|
386
|
nuclear@0
|
387 default:
|
nuclear@0
|
388 break;
|
nuclear@0
|
389 }
|
nuclear@0
|
390 return ifmt;
|
nuclear@0
|
391 }
|
nuclear@0
|
392
|
nuclear@0
|
393 static int gltype_from_ifmt(unsigned int ifmt)
|
nuclear@0
|
394 {
|
nuclear@0
|
395 switch(ifmt) {
|
nuclear@0
|
396 case GL_RGB16F:
|
nuclear@0
|
397 case GL_RGBA16F:
|
nuclear@0
|
398 case GL_LUMINANCE16F:
|
nuclear@0
|
399 #ifdef GL_ES_VERSION_2_0
|
nuclear@0
|
400 return GL_HALF_FLOAT_OES;
|
nuclear@0
|
401 #endif
|
nuclear@0
|
402 case GL_RGB32F:
|
nuclear@0
|
403 case GL_RGBA32F:
|
nuclear@0
|
404 case GL_LUMINANCE32F:
|
nuclear@0
|
405 return GL_FLOAT;
|
nuclear@0
|
406
|
nuclear@0
|
407 default:
|
nuclear@0
|
408 break;
|
nuclear@0
|
409 }
|
nuclear@0
|
410 return GL_UNSIGNED_BYTE;
|
nuclear@0
|
411 }
|
nuclear@0
|
412
|
nuclear@0
|
413 static int glifmt_from_imgfmt(Image::Format fmt)
|
nuclear@0
|
414 {
|
nuclear@0
|
415 switch(fmt) {
|
nuclear@0
|
416 case Image::FMT_GREY:
|
nuclear@0
|
417 return GL_LUMINANCE;
|
nuclear@0
|
418 case Image::FMT_GREY_FLOAT:
|
nuclear@0
|
419 return GL_LUMINANCE16F;
|
nuclear@0
|
420 case Image::FMT_RGB:
|
nuclear@0
|
421 return GL_RGB;
|
nuclear@0
|
422 case Image::FMT_RGB_FLOAT:
|
nuclear@0
|
423 return GL_RGB16F;
|
nuclear@0
|
424 case Image::FMT_RGBA:
|
nuclear@0
|
425 return GL_RGBA;
|
nuclear@0
|
426 case Image::FMT_RGBA_FLOAT:
|
nuclear@0
|
427 return GL_RGBA16F;
|
nuclear@0
|
428 default:
|
nuclear@0
|
429 break;
|
nuclear@0
|
430 }
|
nuclear@0
|
431 return 0;
|
nuclear@0
|
432 }
|
nuclear@0
|
433
|
nuclear@0
|
434 // ---- TextureSet ----
|
nuclear@0
|
435 static void destroy_texture(Texture *tex)
|
nuclear@0
|
436 {
|
nuclear@0
|
437 delete tex;
|
nuclear@0
|
438 }
|
nuclear@0
|
439
|
nuclear@0
|
440 TextureSet::TextureSet()
|
nuclear@0
|
441 : DataSet<Texture*>(load_texture, destroy_texture)
|
nuclear@0
|
442 {
|
nuclear@0
|
443 }
|