]> git.jsancho.org Git - lugaru.git/blob - Source/Texture.cpp
fc5c06be6d626f8775cece3384aa289cd75d7fce
[lugaru.git] / Source / Texture.cpp
1 #include "gamegl.h"
2 #include "Texture.h"
3 #include "TGALoader.h"
4
5 using namespace std;
6
7 extern TGAImageRec texture;
8 extern bool trilinear;
9
10
11 class TextureRes
12 {
13 private:
14     static vector<TextureRes*> list;
15
16     GLuint id;
17     string filename;
18     bool hasMipmap;
19     bool hasAlpha;
20     bool isSkin;
21     int skinsize;
22     GLubyte* data;
23     int datalen;
24     GLubyte* skindata;
25
26     void load();
27
28 public:
29     TextureRes(const string& filename, bool hasMipmap, bool hasAlpha);
30     TextureRes(const string& filename, bool hasMipmap, GLubyte* array, int* skinsize);
31     ~TextureRes();
32     void bind();
33
34     static void reloadAll();
35 };
36
37
38 vector<TextureRes*> TextureRes::list;
39
40 void TextureRes::load()
41 {
42     //load image into 'texture' global var
43     if (!skindata) {
44         unsigned char filenamep[256];
45         CopyCStringToPascal(ConvertFileName(filename.c_str()), filenamep);
46         upload_image(filenamep, hasAlpha);
47     }
48
49     skinsize = texture.sizeX;
50     GLuint type = GL_RGBA;
51     if (texture.bpp == 24)
52         type = GL_RGB;
53
54     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
55
56     glDeleteTextures(1, &id);
57     glGenTextures(1, &id);
58     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
59
60     glBindTexture(GL_TEXTURE_2D, id);
61     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
62     if (hasMipmap) {
63         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (trilinear ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST));
64         glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
65     } else {
66         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
67     }
68
69     if (isSkin) {
70         if (skindata) {
71             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, skinsize, skinsize, 0, GL_RGB, GL_UNSIGNED_BYTE, skindata);
72         } else {
73             free(data);
74             const int nb = texture.sizeY * texture.sizeX * (texture.bpp / 8);
75             data = (GLubyte*)malloc(nb * sizeof(GLubyte));
76             datalen = 0;
77             for (int i = 0; i < nb; i++)
78                 if ((i + 1) % 4 || type == GL_RGB)
79                     data[datalen++] = texture.data[i];
80             glTexImage2D(GL_TEXTURE_2D, 0, type, texture.sizeX, texture.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
81         }
82     } else {
83         glTexImage2D(GL_TEXTURE_2D, 0, type, texture.sizeX, texture.sizeY, 0, type, GL_UNSIGNED_BYTE, texture.data);
84     }
85 }
86
87 void TextureRes::bind()
88 {
89     glBindTexture(GL_TEXTURE_2D, id);
90 }
91
92 TextureRes::TextureRes(const string& _filename, bool _hasMipmap, bool _hasAlpha):
93     id(0), filename(_filename), hasMipmap(_hasMipmap), hasAlpha(_hasAlpha), isSkin(false),
94     skinsize(0), data(NULL), datalen(0), skindata(NULL)
95 {
96     load();
97     list.push_back(this);
98 }
99
100 TextureRes::TextureRes(const string& _filename, bool _hasMipmap, GLubyte* array, int* skinsizep):
101     id(0), filename(_filename), hasMipmap(_hasMipmap), hasAlpha(false), isSkin(true),
102     skinsize(0), data(NULL), datalen(0), skindata(NULL)
103 {
104     load();
105     *skinsizep = skinsize;
106     for (int i = 0; i < datalen; i++)
107         array[i] = data[i];
108     skindata = array;
109     list.push_back(this);
110 }
111
112 TextureRes::~TextureRes()
113 {
114     free(data);
115     glDeleteTextures(1, &id);
116     for (vector<TextureRes*>::iterator it = list.begin(); it != list.end(); it++)
117         if (*it == this) {
118             list.erase(it);
119             break;
120         }
121 }
122
123 void TextureRes::reloadAll()
124 {
125     for (vector<TextureRes*>::iterator it = list.begin(); it != list.end(); it++) {
126         (*it)->id = 0;
127         (*it)->load();
128     }
129 }
130
131
132
133
134 void Texture::load(const string& filename, bool hasMipmap, bool hasAlpha)
135 {
136     destroy();
137     tex = new TextureRes(filename, hasMipmap, hasAlpha);
138 }
139
140 void Texture::load(const string& filename, bool hasMipmap, GLubyte* array, int* skinsizep)
141 {
142     destroy();
143     tex = new TextureRes(filename, hasMipmap, array, skinsizep);
144 }
145
146 void Texture::destroy()
147 {
148     if (tex) {
149         delete tex;
150         tex = NULL;
151     }
152 }
153
154 void Texture::bind()
155 {
156     if (tex)
157         tex->bind();
158     else
159         glBindTexture(GL_TEXTURE_2D, 0);
160 }
161
162 void Texture::reloadAll()
163 {
164     TextureRes::reloadAll();
165 }
166