2 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "supertux/gameconfig.hpp"
18 #include "video/gl/gl_texture.hpp"
22 inline bool is_power_of_2(int v)
24 return (v & (v-1)) == 0;
27 inline int next_power_of_two(int val)
37 GLTexture::GLTexture(unsigned int width, unsigned int height) :
44 #ifdef GL_VERSION_ES_CM_1_0
45 assert(is_power_of_2(width));
46 assert(is_power_of_2(height));
48 texture_width = width;
49 texture_height = height;
51 image_height = height;
53 assert_gl("before creating texture");
54 glGenTextures(1, &handle);
57 glBindTexture(GL_TEXTURE_2D, handle);
59 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width,
60 texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
64 glDeleteTextures(1, &handle);
69 GLTexture::GLTexture(SDL_Surface* image) :
76 #ifdef GL_VERSION_ES_CM_1_0
77 texture_width = next_power_of_two(image->w);
78 texture_height = next_power_of_two(image->h);
80 if (GLEW_ARB_texture_non_power_of_two)
82 texture_width = image->w;
83 texture_height = image->h;
87 texture_width = next_power_of_two(image->w);
88 texture_height = next_power_of_two(image->h);
92 image_width = image->w;
93 image_height = image->h;
95 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
96 SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
97 texture_width, texture_height, 32,
98 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
100 SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
101 texture_width, texture_height, 32,
102 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
106 throw std::runtime_error("Couldn't create texture: out of memory");
109 SDL_SetAlpha(image, 0, 0);
110 SDL_BlitSurface(image, 0, convert, 0);
112 assert_gl("before creating texture");
113 glGenTextures(1, &handle);
117 if(convert->format->BytesPerPixel == 3)
119 else if(convert->format->BytesPerPixel == 4)
120 sdl_format = GL_RGBA;
122 sdl_format = GL_RGBA;
126 glBindTexture(GL_TEXTURE_2D, handle);
127 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
128 #ifdef GL_UNPACK_ROW_LENGTH
129 glPixelStorei(GL_UNPACK_ROW_LENGTH, convert->pitch/convert->format->BytesPerPixel);
131 /* OpenGL ES doesn't support UNPACK_ROW_LENGTH, let's hope SDL didn't add
132 * padding bytes, otherwise we need some extra code here... */
133 assert(convert->pitch == texture_width * convert->format->BytesPerPixel);
136 if(SDL_MUSTLOCK(convert))
138 SDL_LockSurface(convert);
142 { // no not use mipmaps
143 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width,
144 texture_height, 0, sdl_format,
145 GL_UNSIGNED_BYTE, convert->pixels);
149 gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, texture_width,
150 texture_height, sdl_format,
151 GL_UNSIGNED_BYTE, convert->pixels);
154 if(SDL_MUSTLOCK(convert))
156 SDL_UnlockSurface(convert);
159 assert_gl("creating texture");
161 set_texture_params();
163 glDeleteTextures(1, &handle);
164 SDL_FreeSurface(convert);
167 SDL_FreeSurface(convert);
170 GLTexture::~GLTexture()
172 glDeleteTextures(1, &handle);
176 GLTexture::set_texture_params()
178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
184 assert_gl("set texture params");