fix cr/lfs and remove trailing whitespaces...
[supertux.git] / src / video / texture.cpp
1 //  $Id$
2 //
3 //  SuperTux
4 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
20 #include <config.h>
21
22 #include "texture.hpp"
23
24 #include <GL/gl.h>
25 #include <assert.h>
26 #include "glutil.hpp"
27
28 static inline bool is_power_of_2(int v)
29 {
30   return (v & (v-1)) == 0;
31 }
32
33 Texture::Texture(unsigned int w, unsigned int h, GLenum glformat)
34 {
35   assert(is_power_of_2(w));
36   assert(is_power_of_2(h));
37
38   this->width = w;
39   this->height = h;
40
41   assert_gl("before creating texture");
42   glGenTextures(1, &handle);
43
44   try {
45     glBindTexture(GL_TEXTURE_2D, handle);
46
47     glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA,
48                  GL_UNSIGNED_BYTE, 0);
49
50     set_texture_params();
51   } catch(...) {
52     glDeleteTextures(1, &handle);
53     throw;
54   }
55 }
56
57 Texture::Texture(SDL_Surface* image, GLenum glformat)
58 {
59   const SDL_PixelFormat* format = image->format;
60   if(!is_power_of_2(image->w) || !is_power_of_2(image->h))
61     throw std::runtime_error("image has no power of 2 size");
62   if(format->BitsPerPixel != 24 && format->BitsPerPixel != 32)
63     throw std::runtime_error("image has no 24 or 32 bit color depth");
64
65   this->width = image->w;
66   this->height = image->h;
67
68   assert_gl("before creating texture");
69   glGenTextures(1, &handle);
70
71   try {
72     GLenum sdl_format;
73     if(format->BytesPerPixel == 3)
74       sdl_format = GL_RGB;
75     else if(format->BytesPerPixel == 4)
76       sdl_format = GL_RGBA;
77     else
78       assert(false);
79
80     glBindTexture(GL_TEXTURE_2D, handle);
81     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
82     glPixelStorei(GL_UNPACK_ROW_LENGTH, image->pitch/format->BytesPerPixel);
83     glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, sdl_format,
84             GL_UNSIGNED_BYTE, image->pixels);
85
86     assert_gl("creating texture");
87
88     set_texture_params();
89   } catch(...) {
90     glDeleteTextures(1, &handle);
91     throw;
92   }
93 }
94
95 Texture::~Texture()
96 {
97   glDeleteTextures(1, &handle);
98 }
99
100 void
101 Texture::set_texture_params()
102 {
103   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
104   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
105   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
106   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
107
108   assert_gl("set texture params");
109 }