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