]> git.jsancho.org Git - lugaru.git/blob - Source/Texture.cpp
Add copyright header to source files to match license for project
[lugaru.git] / Source / Texture.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3
4 This file is part of Lugaru.
5
6 Lugaru 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.
14
15 See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21
22 #include "gamegl.h"
23 #include "Texture.h"
24 #include "TGALoader.h"
25
26 using namespace std;
27
28 extern TGAImageRec texture;
29 extern bool trilinear;
30
31
32 class TextureRes
33 {
34 private:
35     static vector<TextureRes*> list;
36
37     GLuint id;
38     string filename;
39     bool hasMipmap;
40     bool hasAlpha;
41     bool isSkin;
42     int skinsize;
43     GLubyte* data;
44     int datalen;
45     GLubyte* skindata;
46
47     void load();
48
49 public:
50     TextureRes(const string& filename, bool hasMipmap, bool hasAlpha);
51     TextureRes(const string& filename, bool hasMipmap, GLubyte* array, int* skinsize);
52     ~TextureRes();
53     void bind();
54
55     static void reloadAll();
56 };
57
58
59 vector<TextureRes*> TextureRes::list;
60
61 void TextureRes::load()
62 {
63     //load image into 'texture' global var
64     if (!skindata) {
65         unsigned char filenamep[256];
66         CopyCStringToPascal(ConvertFileName(filename.c_str()), filenamep);
67         upload_image(filenamep, hasAlpha);
68     }
69
70     skinsize = texture.sizeX;
71     GLuint type = GL_RGBA;
72     if (texture.bpp == 24)
73         type = GL_RGB;
74
75     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
76
77     glDeleteTextures(1, &id);
78     glGenTextures(1, &id);
79     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
80
81     glBindTexture(GL_TEXTURE_2D, id);
82     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
83     if (hasMipmap) {
84         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (trilinear ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST));
85         glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
86     } else {
87         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
88     }
89
90     if (isSkin) {
91         if (skindata) {
92             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, skinsize, skinsize, 0, GL_RGB, GL_UNSIGNED_BYTE, skindata);
93         } else {
94             free(data);
95             const int nb = texture.sizeY * texture.sizeX * (texture.bpp / 8);
96             data = (GLubyte*)malloc(nb * sizeof(GLubyte));
97             datalen = 0;
98             for (int i = 0; i < nb; i++)
99                 if ((i + 1) % 4 || type == GL_RGB)
100                     data[datalen++] = texture.data[i];
101             glTexImage2D(GL_TEXTURE_2D, 0, type, texture.sizeX, texture.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
102         }
103     } else {
104         glTexImage2D(GL_TEXTURE_2D, 0, type, texture.sizeX, texture.sizeY, 0, type, GL_UNSIGNED_BYTE, texture.data);
105     }
106 }
107
108 void TextureRes::bind()
109 {
110     glBindTexture(GL_TEXTURE_2D, id);
111 }
112
113 TextureRes::TextureRes(const string& _filename, bool _hasMipmap, bool _hasAlpha):
114     id(0), filename(_filename), hasMipmap(_hasMipmap), hasAlpha(_hasAlpha), isSkin(false),
115     skinsize(0), data(NULL), datalen(0), skindata(NULL)
116 {
117     load();
118     list.push_back(this);
119 }
120
121 TextureRes::TextureRes(const string& _filename, bool _hasMipmap, GLubyte* array, int* skinsizep):
122     id(0), filename(_filename), hasMipmap(_hasMipmap), hasAlpha(false), isSkin(true),
123     skinsize(0), data(NULL), datalen(0), skindata(NULL)
124 {
125     load();
126     *skinsizep = skinsize;
127     for (int i = 0; i < datalen; i++)
128         array[i] = data[i];
129     skindata = array;
130     list.push_back(this);
131 }
132
133 TextureRes::~TextureRes()
134 {
135     free(data);
136     glDeleteTextures(1, &id);
137     for (vector<TextureRes*>::iterator it = list.begin(); it != list.end(); it++)
138         if (*it == this) {
139             list.erase(it);
140             break;
141         }
142 }
143
144 void TextureRes::reloadAll()
145 {
146     for (vector<TextureRes*>::iterator it = list.begin(); it != list.end(); it++) {
147         (*it)->id = 0;
148         (*it)->load();
149     }
150 }
151
152
153
154
155 void Texture::load(const string& filename, bool hasMipmap, bool hasAlpha)
156 {
157     destroy();
158     tex = new TextureRes(filename, hasMipmap, hasAlpha);
159 }
160
161 void Texture::load(const string& filename, bool hasMipmap, GLubyte* array, int* skinsizep)
162 {
163     destroy();
164     tex = new TextureRes(filename, hasMipmap, array, skinsizep);
165 }
166
167 void Texture::destroy()
168 {
169     if (tex) {
170         delete tex;
171         tex = NULL;
172     }
173 }
174
175 void Texture::bind()
176 {
177     if (tex)
178         tex->bind();
179     else
180         glBindTexture(GL_TEXTURE_2D, 0);
181 }
182
183 void Texture::reloadAll()
184 {
185     TextureRes::reloadAll();
186 }
187