00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "State.h"
00018 #include "TexturePainter.h"
00019 #include "PNGLoader.h"
00020 #include "SearchPaths.h"
00021 #include <assert.h>
00022
00023 using namespace Fluxus;
00024
00025 TexturePainter *TexturePainter::m_Singleton=NULL;
00026
00027 TexturePainter::TexturePainter()
00028 {
00029 }
00030
00031 TexturePainter::~TexturePainter()
00032 {
00034 }
00035
00036 void TexturePainter::Initialise()
00037 {
00038 for (int c=0; c<MAX_TEXTURES; c++)
00039 {
00040 #ifdef ENABLE_MULTITEXTURE
00041 glActiveTexture(GL_TEXTURE0+c);
00042 glClientActiveTexture(GL_TEXTURE0+c);
00043 #endif
00044 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00045
00046 glMatrixMode(GL_TEXTURE);
00047 glLoadIdentity();
00048 }
00049 #ifdef ENABLE_MULTITEXTURE
00050 glClientActiveTexture(GL_TEXTURE0);
00051 #endif
00052 }
00053
00054 void TexturePainter::ClearCache()
00055 {
00056 m_TextureMap.clear();
00057 m_LoadedMap.clear();
00058 m_LoadedCubeMap.clear();
00059 }
00060
00061 unsigned int TexturePainter::LoadTexture(const string &Filename, CreateParams ¶ms)
00062 {
00063 string Fullpath = SearchPaths::Get()->GetFullPath(Filename);
00064 if (params.Type==GL_TEXTURE_CUBE_MAP_POSITIVE_X || params.Type==GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
00065 params.Type==GL_TEXTURE_CUBE_MAP_POSITIVE_Y || params.Type==GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
00066 params.Type==GL_TEXTURE_CUBE_MAP_POSITIVE_Z || params.Type==GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
00067 {
00068 return LoadCubeMap(Fullpath, params);
00069 }
00070
00071
00072 map<string,int>::iterator i=m_LoadedMap.find(Fullpath);
00073 if (i!=m_LoadedMap.end())
00074 {
00075 return i->second;
00076 }
00077
00078 unsigned char *ImageData;
00079 TextureDesc desc;
00080 ImageData=PNGLoader::Load(Fullpath,desc.Width,desc.Height,desc.Format);
00081
00082 if (ImageData!=NULL)
00083 {
00084
00085
00086
00087 glEnable(params.Type);
00088
00089 if (params.ID==-1)
00090 {
00091 GLuint id;
00092 glGenTextures(1,&id);
00093 params.ID=id;
00094
00095 m_TextureMap[params.ID]=desc;
00096 m_LoadedMap[Fullpath]=params.ID;
00097 }
00098
00099 UploadTexture(desc,params,ImageData);
00100 delete[] ImageData;
00101 return params.ID;
00102 }
00103 m_LoadedMap[Fullpath]=0;
00104 return 0;
00105 }
00106
00107 unsigned int TexturePainter::LoadCubeMap(const string &Fullpath, CreateParams ¶ms)
00108 {
00109
00110 map<string,int>::iterator i=m_LoadedCubeMap.find(Fullpath);
00111 if (i!=m_LoadedCubeMap.end())
00112 {
00113 return i->second;
00114 }
00115
00116 unsigned char *ImageData;
00117 TextureDesc desc;
00118 ImageData=PNGLoader::Load(Fullpath,desc.Width,desc.Height,desc.Format);
00119
00120 if (ImageData!=NULL)
00121 {
00122
00123
00124
00125 glEnable(params.Type);
00126
00127 if (params.ID==-1)
00128 {
00129 GLuint id;
00130 glGenTextures(1,&id);
00131 params.ID=id;
00132
00133 m_TextureMap[params.ID]=desc;
00134 m_LoadedCubeMap[Fullpath]=params.ID;
00135
00136 CubeMapDesc newcubemap;
00137 m_CubeMapMap[params.ID] = newcubemap;
00138
00139 switch (params.Type)
00140 {
00141 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: m_CubeMapMap[params.ID].Positive[0]=params.ID; break;
00142 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: m_CubeMapMap[params.ID].Negative[0]=params.ID; break;
00143 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: m_CubeMapMap[params.ID].Positive[1]=params.ID; break;
00144 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: m_CubeMapMap[params.ID].Negative[1]=params.ID; break;
00145 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: m_CubeMapMap[params.ID].Positive[2]=params.ID; break;
00146 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: m_CubeMapMap[params.ID].Negative[2]=params.ID; break;
00147 default: assert(0); break;
00148 }
00149 }
00150 else
00151 {
00152
00153
00154 unsigned int primary = params.ID;
00155 GLuint id;
00156 glGenTextures(1,&id);
00157 params.ID=id;
00158 m_TextureMap[params.ID]=desc;
00159 m_LoadedCubeMap[Fullpath]=params.ID;
00160
00161 switch (params.Type)
00162 {
00163 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: m_CubeMapMap[primary].Positive[0]=params.ID; break;
00164 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: m_CubeMapMap[primary].Negative[0]=params.ID; break;
00165 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: m_CubeMapMap[primary].Positive[1]=params.ID; break;
00166 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: m_CubeMapMap[primary].Negative[1]=params.ID; break;
00167 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: m_CubeMapMap[primary].Positive[2]=params.ID; break;
00168 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: m_CubeMapMap[primary].Negative[2]=params.ID; break;
00169 default: assert(0); break;
00170 }
00171 }
00172
00173 UploadTexture(desc,params,ImageData);
00174 delete[] ImageData;
00175 return params.ID;
00176 }
00177 m_LoadedMap[Fullpath]=0;
00178 return 0;
00179 }
00180
00181 void TexturePainter::UploadTexture(TextureDesc desc, CreateParams params, const unsigned char *ImageData)
00182 {
00183 glBindTexture(params.Type,params.ID);
00184
00185 if (params.GenerateMipmaps)
00186 {
00187 if (desc.Format==RGB)
00188 {
00189 gluBuild2DMipmaps(params.Type,3,desc.Width,desc.Height,GL_RGB,GL_UNSIGNED_BYTE,ImageData);
00190 }
00191 else
00192 {
00193 gluBuild2DMipmaps(params.Type,4,desc.Width,desc.Height,GL_RGBA,GL_UNSIGNED_BYTE,ImageData);
00194 }
00195 }
00196 else
00197 {
00198
00199
00200
00201 if (desc.Format==RGB)
00202 {
00203 glTexImage2D(params.Type,params.MipLevel,3,desc.Width,desc.Height,params.Border,
00204 GL_RGB,GL_UNSIGNED_BYTE,ImageData);
00205 }
00206 else
00207 {
00208 glTexImage2D(params.Type,params.MipLevel,4,desc.Width,desc.Height,params.Border,
00209 GL_RGBA,GL_UNSIGNED_BYTE,ImageData);
00210 }
00211 }
00212 }
00213
00215 bool TexturePainter::LoadPData(const string &Filename, unsigned int &w, unsigned int &h, TypedPData<dColour> &pixels)
00216 {
00217 string Fullpath = SearchPaths::Get()->GetFullPath(Filename);
00218
00219 unsigned char *ImageData;
00220 TextureDesc desc;
00221 ImageData=PNGLoader::Load(Fullpath,desc.Width,desc.Height,desc.Format);
00222
00223 if (ImageData!=NULL)
00224 {
00225 pixels.Resize(desc.Width*desc.Height);
00226 w=desc.Width;
00227 h=desc.Height;
00228
00229 if (desc.Format==RGB)
00230 {
00231 for (unsigned int n=0; n<desc.Width*desc.Height; n++)
00232 {
00233 pixels.m_Data[n]=dColour(ImageData[n*3]/255.0f,
00234 ImageData[n*3+1]/255.0f,
00235 ImageData[n*3+2]/255.0f,1.0f);
00236
00237 }
00238 }
00239 else if (desc.Format==RGBA)
00240 {
00241 for (unsigned int n=0; n<desc.Width*desc.Height; n++)
00242 {
00243 pixels.m_Data[n]=dColour(ImageData[n*4]/255.0f,
00244 ImageData[n*4+1]/255.0f,
00245 ImageData[n*4+2]/255.0f,
00246 ImageData[n*4+3]/255.0f);
00247
00248 }
00249 }
00250 else
00251 {
00252 delete[] ImageData;
00253 return false;
00254 }
00255
00256 delete[] ImageData;
00257 return true;
00258 }
00259
00260 return false;
00261 }
00262
00263 bool TexturePainter::SavePData(const string &Filename, unsigned int w, unsigned int h, const TypedPData<dColour> &pixels)
00264 {
00265
00266 unsigned char *ImageData=new unsigned char[w*h*4];
00267 for (unsigned int n=0; n<w*h; n++)
00268 {
00269 ImageData[n*4]=(unsigned char)(pixels.m_Data[n].r*255.0f);
00270 ImageData[n*4+1]=(unsigned char)(pixels.m_Data[n].g*255.0f);
00271 ImageData[n*4+2]=(unsigned char)(pixels.m_Data[n].b*255.0f);
00272 ImageData[n*4+3]=(unsigned char)(pixels.m_Data[n].a*255.0f);
00273 }
00274
00275 PNGLoader::Save(Filename, w, h, RGBA, ImageData);
00276
00277 delete[] ImageData;
00278 return true;
00279 }
00280
00281 unsigned int TexturePainter::MakeTexture(unsigned int w, unsigned int h, PData *data)
00282 {
00283 GLuint ID=0;
00284 TypedPData<dColour> *pixels = dynamic_cast<TypedPData<dColour>*>(data);
00285 if (pixels)
00286 {
00287
00288 glGenTextures(1,&ID);
00289 glBindTexture(GL_TEXTURE_2D,ID);
00290 gluBuild2DMipmaps(GL_TEXTURE_2D,4,w,h,GL_RGBA,GL_FLOAT,&pixels->m_Data[0]);
00291 return ID;
00292 }
00293 return 0;
00294 }
00295
00296 bool TexturePainter::SetCurrent(unsigned int *ids, TextureState *states)
00297 {
00298 bool ret=false;
00299
00300 for (int c=0; c<MAX_TEXTURES; c++)
00301 {
00302 #ifdef ENABLE_MULTITEXTURE
00303 glActiveTexture(GL_TEXTURE0+c);
00304 #endif
00305
00306 if (ids[c]!=0)
00307 {
00308 map<unsigned int,CubeMapDesc>::iterator i=m_CubeMapMap.find(ids[c]);
00309
00310 if (i!=m_CubeMapMap.end())
00311 {
00312 glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_X,i->second.Positive[0]);
00313 glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,i->second.Negative[0]);
00314 glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,i->second.Positive[1]);
00315 glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,i->second.Negative[1]);
00316 glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,i->second.Positive[2]);
00317 glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,i->second.Negative[2]);
00318
00319 glEnable(GL_TEXTURE_CUBE_MAP);
00320 ApplyState(GL_TEXTURE_CUBE_MAP,states[c],true);
00321 }
00322 else
00323 {
00324 glEnable(GL_TEXTURE_2D);
00325 glBindTexture(GL_TEXTURE_2D,ids[c]);
00326 ApplyState(GL_TEXTURE_2D,states[c],false);
00327 }
00328
00329 ret=true;
00330 }
00331 else
00332 {
00333 glDisable(GL_TEXTURE_2D);
00334 glDisable(GL_TEXTURE_CUBE_MAP);
00335 }
00336 }
00337
00338 #ifdef ENABLE_MULTITEXTURE
00339 glActiveTexture(GL_TEXTURE0);
00340 #endif
00341
00342 return ret;
00343 }
00344
00345 void TexturePainter::ApplyState(int type, TextureState &state, bool cubemap)
00346 {
00347 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, state.TexEnv);
00348 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, state.EnvColour.arr());
00349 glTexParameteri(type, GL_TEXTURE_MIN_FILTER, state.Min);
00350 glTexParameteri(type, GL_TEXTURE_MAG_FILTER, state.Mag);
00351 glTexParameteri(type, GL_TEXTURE_WRAP_S, state.WrapS);
00352 glTexParameteri(type, GL_TEXTURE_WRAP_T, state.WrapT);
00353 if (cubemap) glTexParameteri(type, GL_TEXTURE_WRAP_R, state.WrapT);
00354 glTexParameterfv(type, GL_TEXTURE_BORDER_COLOR, state.BorderColour.arr());
00355 glTexParameterf(type, GL_TEXTURE_PRIORITY, state.Priority);
00356 glTexParameterf(type, GL_TEXTURE_MIN_LOD, state.MinLOD);
00357 glTexParameterf(type, GL_TEXTURE_MAX_LOD, state.MaxLOD);
00358 }
00359
00360 void TexturePainter::DisableAll()
00361 {
00362 #ifdef ENABLE_MULTITEXTURE
00363 for (int c=0; c<MAX_TEXTURES; c++)
00364 {
00365 glActiveTexture(GL_TEXTURE0+c);
00366 glDisable(GL_TEXTURE_2D);
00367 }
00368 glClientActiveTexture(GL_TEXTURE0);
00369 #else
00370 glDisable(GL_TEXTURE_2D);
00371 #endif
00372 }
00373
00374 void TexturePainter::Dump()
00375 {
00376 for (map<string,int>::iterator i=m_LoadedMap.begin(); i!=m_LoadedMap.end(); ++i)
00377 {
00378 TextureDesc info = m_TextureMap[i->second];
00379 Trace::Stream<<i->first<<" "<<info.Width<<"X"<<info.Height<<" ";
00380 if (info.Format==RGB) Trace::Stream<<"RGB"<<endl;
00381 else if (info.Format==RGBA) Trace::Stream<<"RGBA"<<endl;
00382 }
00383 }
00384
00385
00386
00387
00388