7 #if defined(GL_ES_VERSION_2_0) || defined(GL_VERSION_3_0)
8 #define USE_GL_GENERATE_MIPMAP
9 #elif defined(__GLEW_H__)
10 #define USE_SGIS_GENERATE_MIPMAP
13 static int glifmt_from_ifmt(unsigned int ifmt);
14 static int glfmt_from_ifmt(unsigned int ifmt);
15 static int gltype_from_ifmt(unsigned int ifmt);
17 static int glifmt_from_imgfmt(Image::Format fmt);
18 static Image::Format imgfmt_from_glifmt(unsigned int ifmt);
20 static unsigned int cur_target[8] = {
21 GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D,
22 GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D
25 void bind_texture(Texture *tex, int tunit)
30 glActiveTexture(GL_TEXTURE0 + tunit);
31 glBindTexture(cur_target[tunit], 0);
32 glActiveTexture(GL_TEXTURE0);
36 Texture *load_texture(const char *fname)
38 TextureCube *texcube = new TextureCube;
39 if(texcube->load(fname)) {
44 Texture2D *tex = new Texture2D;
45 if(tex->load(fname)) {
56 sz[0] = sz[1] = sz[2] = 0;
59 glGenTextures(1, &id);
65 glDeleteTextures(1, &id);
69 void Texture::set_wrapping(unsigned int wrap)
75 glBindTexture(target, id);
76 glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
77 glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);
80 void Texture::set_filtering(unsigned int filt)
82 unsigned int mag_filter;
89 case GL_LINEAR_MIPMAP_NEAREST:
90 case GL_LINEAR_MIPMAP_LINEAR:
91 mag_filter = GL_LINEAR;
94 case GL_NEAREST_MIPMAP_NEAREST:
95 case GL_NEAREST_MIPMAP_LINEAR:
96 mag_filter = GL_NEAREST;
103 set_filtering(filt, mag_filter);
106 void Texture::set_filtering(unsigned int min_filt, unsigned int mag_filt)
108 glBindTexture(target, id);
109 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, min_filt);
110 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, mag_filt);
113 unsigned int Texture::get_format() const
118 int Texture::get_size(int dim) const
120 if(dim < 0 || dim >= 3) {
126 unsigned int Texture::get_id() const
131 void Texture::bind(int tex_unit) const
133 glActiveTexture(GL_TEXTURE0 + tex_unit);
134 glBindTexture(target, id);
135 glActiveTexture(GL_TEXTURE0);
137 cur_target[tex_unit] = target;
141 // ---- Texture2D ----
143 Texture2D::Texture2D()
145 target = GL_TEXTURE_2D;
148 TextureType Texture2D::get_type() const
153 void Texture2D::create(int xsz, int ysz, unsigned int ifmt)
155 int fmt = glfmt_from_ifmt(ifmt);
156 int type = gltype_from_ifmt(ifmt);
158 glBindTexture(GL_TEXTURE_2D, id);
159 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
160 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
161 glTexImage2D(GL_TEXTURE_2D, 0, glifmt_from_ifmt(ifmt), xsz, ysz, 0, fmt, type, 0);
167 void Texture2D::set_image(const Image &img, int idx)
169 texfmt = glifmt_from_imgfmt(img.get_format());
170 unsigned int fmt = glfmt_from_ifmt(texfmt);
171 unsigned int type = gltype_from_ifmt(texfmt);
173 sz[0] = img.get_width();
174 sz[1] = img.get_height();
176 glBindTexture(GL_TEXTURE_2D, id);
177 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
180 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
182 #ifdef USE_SGIS_GENERATE_MIPMAP
183 if(GLEW_SGIS_generate_mipmap) {
184 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
186 glTexImage2D(GL_TEXTURE_2D, 0, texfmt, sz[0], sz[1], 0, fmt, type, img.get_pixels());
187 #ifdef USE_SGIS_GENERATE_MIPMAP
189 gluBuild2DMipmaps(GL_TEXTURE_2D, texfmt, sz[0], sz[1], fmt, type, img.get_pixels());
193 #ifdef USE_GL_GENERATE_MIPMAP
194 glGenerateMipmap(GL_TEXTURE_2D);
198 void Texture2D::get_image(Image *img, int idx) const
200 #ifndef GL_ES_VERSION_2_0
201 glBindTexture(GL_TEXTURE_2D, id);
203 Image::Format img_fmt = imgfmt_from_glifmt(texfmt);
204 img->create(sz[0], sz[1], img_fmt);
206 unsigned int fmt = glfmt_from_ifmt(texfmt);
207 unsigned int type = gltype_from_ifmt(texfmt);
208 glGetTexImage(GL_TEXTURE_2D, 0, fmt, type, img->get_pixels());
209 #endif // GL_ES_VERSION_2_0
212 void Texture2D::set_subimage(const Image &img, int xoffs, int yoffs)
214 unsigned int ifmt = glifmt_from_imgfmt(img.get_format());
216 glBindTexture(GL_TEXTURE_2D, id);
217 glTexSubImage2D(GL_TEXTURE_2D, 0, xoffs, yoffs, img.get_width(), img.get_height(),
218 glfmt_from_ifmt(ifmt), gltype_from_ifmt(ifmt), img.get_pixels());
221 bool Texture2D::load(const char *fname)
224 if(!img.load(fname)) {
225 fprintf(stderr, "failed to load 2D texture: %s\n", fname);
230 printf("loaded 2D texture: %s\n", fname);
234 bool Texture2D::save(const char *fname) const
236 #ifndef GL_ES_VERSION_2_0
237 unsigned char *pixels = new unsigned char[sz[0] * sz[1] * 4];
239 glBindTexture(GL_TEXTURE_2D, id);
240 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
242 if(img_save_pixels(fname, pixels, sz[0], sz[1]) == -1) {
243 fprintf(stderr, "failed to save 2D texture: %s\n", fname);
248 printf("saved 2D texture: %s\n", fname);
252 return false; // TODO
256 // ---- TextureCube ----
257 static unsigned int cube_faces[] = {
258 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
259 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
260 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
261 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
262 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
263 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
266 TextureCube::TextureCube()
268 target = GL_TEXTURE_CUBE_MAP;
271 TextureType TextureCube::get_type() const
277 void TextureCube::create(int xsz, int ysz, unsigned int ifmt)
280 fprintf(stderr, "trying to create cubemap with different width and height (%dx%d)\n", xsz, ysz);
286 glBindTexture(GL_TEXTURE_CUBE_MAP, id);
287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
288 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
289 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
290 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
292 for(int i=0; i<6; i++) {
293 glTexImage2D(cube_faces[i], 0, ifmt, xsz, ysz, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
297 void TextureCube::set_image(const Image &img, int idx)
302 void TextureCube::get_image(Image *img, int idx) const
307 bool TextureCube::load(const char *fname)
309 return false; // TODO
312 bool TextureCube::save(const char *fname) const
314 return false; // TODO
317 static int glifmt_from_ifmt(unsigned int ifmt)
319 #ifdef GL_ES_VERSION_2_0
321 case GL_LUMINANCE16F:
322 case GL_LUMINANCE32F:
340 return ifmt; // by default just pass it through...
343 static int glfmt_from_ifmt(unsigned int ifmt)
346 case GL_LUMINANCE16F:
347 case GL_LUMINANCE32F:
364 static int gltype_from_ifmt(unsigned int ifmt)
369 case GL_LUMINANCE16F:
370 #ifdef GL_ES_VERSION_2_0
371 return GL_HALF_FLOAT_OES;
375 case GL_LUMINANCE32F:
381 return GL_UNSIGNED_BYTE;
384 static int glifmt_from_imgfmt(Image::Format fmt)
387 case Image::FMT_GREY:
389 case Image::FMT_GREY_FLOAT:
390 return GL_LUMINANCE16F;
393 case Image::FMT_RGB_FLOAT:
395 case Image::FMT_RGBA:
397 case Image::FMT_RGBA_FLOAT:
405 static Image::Format imgfmt_from_glifmt(unsigned int ifmt)
409 return Image::FMT_GREY;
410 case GL_LUMINANCE16F:
411 return Image::FMT_GREY_FLOAT;
413 return Image::FMT_RGB;
415 return Image::FMT_RGB_FLOAT;
417 return Image::FMT_RGBA;
419 return Image::FMT_RGBA_FLOAT;
424 fprintf(stderr, "imgfmt_from_glifmt: unknown internal format: %x\n", ifmt);
428 return Image::FMT_RGBA; // ... whatever