- Reworked Surface class and drawing stuff:
[supertux.git] / src / video / texture.cpp
1 //  $Id$
2 //
3 //  SuperTux -  A Jump'n Run
4 //  Copyright (C) 2004 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 #include <config.h>
20
21 #include "texture.hpp"
22
23 #include <GL/gl.h>
24 #include <assert.h>
25 #include "glutil.hpp"
26
27 static inline bool is_power_of_2(int v)
28 {
29   return (v & (v-1)) == 0;
30 }
31
32 Texture::Texture(unsigned int w, unsigned int h, GLenum glformat)
33 {
34   assert(is_power_of_2(w));
35   assert(is_power_of_2(h));
36
37   this->width = w;
38   this->height = h;
39   
40   assert_gl("before creating texture");
41   glGenTextures(1, &handle);
42   
43   try {
44     glBindTexture(GL_TEXTURE_2D, handle);
45
46     glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA,
47                  GL_UNSIGNED_BYTE, 0);
48
49     set_texture_params();
50   } catch(...) {
51     glDeleteTextures(1, &handle);
52     throw;
53   }
54 }
55
56 Texture::Texture(SDL_Surface* image, GLenum glformat)
57 {
58   const SDL_PixelFormat* format = image->format;
59   if(!is_power_of_2(image->w) || !is_power_of_2(image->h))
60     throw std::runtime_error("image has no power of 2 size");
61   if(format->BitsPerPixel != 24 && format->BitsPerPixel != 32)
62     throw std::runtime_error("image has no 24 or 32 bit color depth");
63   
64   this->width = image->w;
65   this->height = image->h;
66
67   assert_gl("before creating texture");
68   glGenTextures(1, &handle);
69   
70   try {
71     GLenum sdl_format;
72     if(format->BytesPerPixel == 3)
73       sdl_format = GL_RGB;
74     else if(format->BytesPerPixel == 4)
75       sdl_format = GL_RGBA;
76     else
77       assert(false);
78
79     glBindTexture(GL_TEXTURE_2D, handle);
80     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
81     glPixelStorei(GL_UNPACK_ROW_LENGTH, image->pitch/format->BytesPerPixel);
82     glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, sdl_format,
83             GL_UNSIGNED_BYTE, image->pixels);
84
85     assert_gl("creating texture");
86
87     set_texture_params();    
88   } catch(...) {
89     glDeleteTextures(1, &handle);
90     throw;
91   }
92 }
93
94 Texture::~Texture()
95 {
96   glDeleteTextures(1, &handle);
97 }
98
99 void
100 Texture::set_texture_params()
101 {
102   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
103   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
104   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
105   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
106
107   assert_gl("set texture params");
108 }
109