]> git.jsancho.org Git - lugaru.git/blob - Source/Texture.cpp
Add copyright notice and AUTHORS file for open source contributors
[lugaru.git] / Source / Texture.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
4
5 This file is part of Lugaru.
6
7 Lugaru is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 Lugaru is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "gamegl.h"
22 #include "Texture.h"
23 #include "ImageIO.h"
24
25 using namespace std;
26
27 extern ImageRec texture;
28 extern bool trilinear;
29
30
31 class TextureRes
32 {
33 private:
34     static vector<TextureRes*> list;
35
36     GLuint id;
37     string filename;
38     bool hasMipmap;
39     bool hasAlpha;
40     bool isSkin;
41     int skinsize;
42     GLubyte* data;
43     int datalen;
44     GLubyte* skindata;
45
46     void load();
47
48 public:
49     TextureRes(const string& filename, bool hasMipmap, bool hasAlpha);
50     TextureRes(const string& filename, bool hasMipmap, GLubyte* array, int* skinsize);
51     ~TextureRes();
52     void bind();
53
54     static void reloadAll();
55 };
56
57
58 vector<TextureRes*> TextureRes::list;
59
60 void TextureRes::load()
61 {
62     //load image into 'texture' global var
63     if (!skindata) {
64         upload_image(ConvertFileName(filename.c_str()));
65     }
66
67     skinsize = texture.sizeX;
68     GLuint type = GL_RGBA;
69     if (texture.bpp == 24)
70         type = GL_RGB;
71
72     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
73
74     glDeleteTextures(1, &id);
75     glGenTextures(1, &id);
76     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
77
78     glBindTexture(GL_TEXTURE_2D, id);
79     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
80     if (hasMipmap) {
81         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (trilinear ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST));
82         glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
83     } else {
84         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
85     }
86
87     if (isSkin) {
88         if (skindata) {
89             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, skinsize, skinsize, 0, GL_RGB, GL_UNSIGNED_BYTE, skindata);
90         } else {
91             free(data);
92             const int nb = texture.sizeY * texture.sizeX * (texture.bpp / 8);
93             data = (GLubyte*)malloc(nb * sizeof(GLubyte));
94             datalen = 0;
95             for (int i = 0; i < nb; i++)
96                 if ((i + 1) % 4 || type == GL_RGB)
97                     data[datalen++] = texture.data[i];
98             glTexImage2D(GL_TEXTURE_2D, 0, type, texture.sizeX, texture.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
99         }
100     } else {
101         glTexImage2D(GL_TEXTURE_2D, 0, type, texture.sizeX, texture.sizeY, 0, type, GL_UNSIGNED_BYTE, texture.data);
102     }
103 }
104
105 void TextureRes::bind()
106 {
107     glBindTexture(GL_TEXTURE_2D, id);
108 }
109
110 TextureRes::TextureRes(const string& _filename, bool _hasMipmap, bool _hasAlpha):
111     id(0), filename(_filename), hasMipmap(_hasMipmap), hasAlpha(_hasAlpha), isSkin(false),
112     skinsize(0), data(NULL), datalen(0), skindata(NULL)
113 {
114     load();
115     list.push_back(this);
116 }
117
118 TextureRes::TextureRes(const string& _filename, bool _hasMipmap, GLubyte* array, int* skinsizep):
119     id(0), filename(_filename), hasMipmap(_hasMipmap), hasAlpha(false), isSkin(true),
120     skinsize(0), data(NULL), datalen(0), skindata(NULL)
121 {
122     load();
123     *skinsizep = skinsize;
124     for (int i = 0; i < datalen; i++)
125         array[i] = data[i];
126     skindata = array;
127     list.push_back(this);
128 }
129
130 TextureRes::~TextureRes()
131 {
132     free(data);
133     glDeleteTextures(1, &id);
134     for (vector<TextureRes*>::iterator it = list.begin(); it != list.end(); it++)
135         if (*it == this) {
136             list.erase(it);
137             break;
138         }
139 }
140
141 void TextureRes::reloadAll()
142 {
143     for (vector<TextureRes*>::iterator it = list.begin(); it != list.end(); it++) {
144         (*it)->id = 0;
145         (*it)->load();
146     }
147 }
148
149
150 void Texture::load(const string& filename, bool hasMipmap, bool hasAlpha)
151 {
152     destroy();
153     tex = new TextureRes(filename, hasMipmap, hasAlpha);
154 }
155
156 void Texture::load(const string& filename, bool hasMipmap, GLubyte* array, int* skinsizep)
157 {
158     destroy();
159     tex = new TextureRes(filename, hasMipmap, array, skinsizep);
160 }
161
162 void Texture::destroy()
163 {
164     if (tex) {
165         delete tex;
166         tex = NULL;
167     }
168 }
169
170 void Texture::bind()
171 {
172     if (tex)
173         tex->bind();
174     else
175         glBindTexture(GL_TEXTURE_2D, 0);
176 }
177
178 void Texture::reloadAll()
179 {
180     TextureRes::reloadAll();
181 }
182