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
00065 if (params.Type==GL_TEXTURE_CUBE_MAP_POSITIVE_X || params.Type==GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
00066 params.Type==GL_TEXTURE_CUBE_MAP_POSITIVE_Y || params.Type==GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
00067 params.Type==GL_TEXTURE_CUBE_MAP_POSITIVE_Z || params.Type==GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
00068 {
00069 return LoadCubeMap(Fullpath, params);
00070 }
00071
00072
00073 map<string,int>::iterator i=m_LoadedMap.find(Fullpath);
00074 if (i!=m_LoadedMap.end())
00075 {
00076 return i->second;
00077 }
00078
00079 unsigned char *ImageData;
00080 TextureDesc desc;
00081 ImageData=PNGLoader::Load(Fullpath,desc.Width,desc.Height,desc.Format);
00082
00083 if (ImageData!=NULL)
00084 {
00085
00086
00087
00088 glEnable(params.Type);
00089
00090 if (params.ID==-1)
00091 {
00092 GLuint id;
00093 glGenTextures(1,&id);
00094 params.ID=id;
00095
00096 m_TextureMap[params.ID]=desc;
00097 m_LoadedMap[Fullpath]=params.ID;
00098 }
00099
00100 UploadTexture(desc,params,ImageData);
00101 delete[] ImageData;
00102 return params.ID;
00103 }
00104 m_LoadedMap[Fullpath]=0;
00105 return 0;
00106 }
00107
00108 unsigned int TexturePainter::LoadCubeMap(const string &Fullpath, CreateParams ¶ms)
00109 {
00110
00111 map<string,int>::iterator i=m_LoadedCubeMap.find(Fullpath);
00112 if (i!=m_LoadedCubeMap.end())
00113 {
00114 return i->second;
00115 }
00116
00117 unsigned char *ImageData;
00118 TextureDesc desc;
00119 ImageData=PNGLoader::Load(Fullpath,desc.Width,desc.Height,desc.Format);
00120
00121 if (ImageData!=NULL)
00122 {
00123
00124
00125
00126 glEnable(params.Type);
00127
00128 if (params.ID==-1)
00129 {
00130 GLuint id;
00131 glGenTextures(1,&id);
00132 params.ID=id;
00133
00134 m_TextureMap[params.ID]=desc;
00135 m_LoadedCubeMap[Fullpath]=params.ID;
00136
00137 CubeMapDesc newcubemap;
00138 m_CubeMapMap[params.ID] = newcubemap;
00139
00140 switch (params.Type)
00141 {
00142 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: m_CubeMapMap[params.ID].Positive[0]=params.ID; break;
00143 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: m_CubeMapMap[params.ID].Negative[0]=params.ID; break;
00144 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: m_CubeMapMap[params.ID].Positive[1]=params.ID; break;
00145 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: m_CubeMapMap[params.ID].Negative[1]=params.ID; break;
00146 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: m_CubeMapMap[params.ID].Positive[2]=params.ID; break;
00147 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: m_CubeMapMap[params.ID].Negative[2]=params.ID; break;
00148 default: assert(0); break;
00149 }
00150 }
00151 else
00152 {
00153
00154
00155 unsigned int primary = params.ID;
00156 GLuint id;
00157 glGenTextures(1,&id);
00158 params.ID=id;
00159 m_TextureMap[params.ID]=desc;
00160 m_LoadedCubeMap[Fullpath]=params.ID;
00161
00162 switch (params.Type)
00163 {
00164 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: m_CubeMapMap[primary].Positive[0]=params.ID; break;
00165 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: m_CubeMapMap[primary].Negative[0]=params.ID; break;
00166 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: m_CubeMapMap[primary].Positive[1]=params.ID; break;
00167 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: m_CubeMapMap[primary].Negative[1]=params.ID; break;
00168 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: m_CubeMapMap[primary].Positive[2]=params.ID; break;
00169 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: m_CubeMapMap[primary].Negative[2]=params.ID; break;
00170 default: assert(0); break;
00171 }
00172 }
00173
00174 UploadTexture(desc,params,ImageData);
00175 delete[] ImageData;
00176 return params.ID;
00177 }
00178 m_LoadedMap[Fullpath]=0;
00179 return 0;
00180 }
00181
00182 void TexturePainter::UploadTexture(TextureDesc desc, CreateParams params, const unsigned char *ImageData)
00183 {
00184 glBindTexture(params.Type,params.ID);
00185
00186 if (params.GenerateMipmaps)
00187 {
00188 if (desc.Format==RGB)
00189 {
00190 gluBuild2DMipmaps(params.Type,3,desc.Width,desc.Height,GL_RGB,GL_UNSIGNED_BYTE,ImageData);
00191 }
00192 else
00193 {
00194 gluBuild2DMipmaps(params.Type,4,desc.Width,desc.Height,GL_RGBA,GL_UNSIGNED_BYTE,ImageData);
00195 }
00196 }
00197 else
00198 {
00199
00200
00201
00202 if (desc.Format==RGB)
00203 {
00204 glTexImage2D(params.Type,params.MipLevel,3,desc.Width,desc.Height,params.Border,
00205 GL_RGB,GL_UNSIGNED_BYTE,ImageData);
00206 }
00207 else
00208 {
00209 glTexImage2D(params.Type,params.MipLevel,4,desc.Width,desc.Height,params.Border,
00210 GL_RGBA,GL_UNSIGNED_BYTE,ImageData);
00211 }
00212 }
00213 }
00214
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 (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 (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 return false;
00253 }
00254
00255 return true;
00256 }
00257
00258 return false;
00259 }
00260
00261 unsigned int TexturePainter::MakeTexture(unsigned int w, unsigned int h, PData *data)
00262 {
00263 GLuint ID=0;
00264 TypedPData<dColour> *pixels = dynamic_cast<TypedPData<dColour>*>(data);
00265 if (pixels)
00266 {
00267
00268 glGenTextures(1,&ID);
00269 glBindTexture(GL_TEXTURE_2D,ID);
00270 gluBuild2DMipmaps(GL_TEXTURE_2D,4,w,h,GL_RGBA,GL_FLOAT,&pixels->m_Data[0]);
00271 return ID;
00272 }
00273 return 0;
00274 }
00275
00276 bool TexturePainter::SetCurrent(unsigned int *ids, TextureState *states)
00277 {
00278 bool ret=false;
00279
00280 for (int c=0; c<MAX_TEXTURES; c++)
00281 {
00282 #ifdef ENABLE_MULTITEXTURE
00283 glActiveTexture(GL_TEXTURE0+c);
00284 #endif
00285
00286 if (ids[c]!=0)
00287 {
00288 map<unsigned int,CubeMapDesc>::iterator i=m_CubeMapMap.find(ids[c]);
00289
00290 if (i!=m_CubeMapMap.end())
00291 {
00292 glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_X,i->second.Positive[0]);
00293 glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,i->second.Negative[0]);
00294 glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,i->second.Positive[1]);
00295 glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,i->second.Negative[1]);
00296 glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,i->second.Positive[2]);
00297 glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,i->second.Negative[2]);
00298
00299 glEnable(GL_TEXTURE_CUBE_MAP);
00300 ApplyState(GL_TEXTURE_CUBE_MAP,states[c],true);
00301 }
00302 else
00303 {
00304 glEnable(GL_TEXTURE_2D);
00305 glBindTexture(GL_TEXTURE_2D,ids[c]);
00306 ApplyState(GL_TEXTURE_2D,states[c],false);
00307 }
00308
00309 ret=true;
00310 }
00311 else
00312 {
00313 glDisable(GL_TEXTURE_2D);
00314 glDisable(GL_TEXTURE_CUBE_MAP);
00315 }
00316 }
00317
00318 #ifdef ENABLE_MULTITEXTURE
00319 glActiveTexture(GL_TEXTURE0);
00320 #endif
00321
00322 return ret;
00323 }
00324
00325 void TexturePainter::ApplyState(int type, TextureState &state, bool cubemap)
00326 {
00327 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, state.TexEnv);
00328 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, state.EnvColour.arr());
00329 glTexParameteri(type, GL_TEXTURE_MIN_FILTER, state.Min);
00330 glTexParameteri(type, GL_TEXTURE_MAG_FILTER, state.Mag);
00331 glTexParameteri(type, GL_TEXTURE_WRAP_S, state.WrapS);
00332 glTexParameteri(type, GL_TEXTURE_WRAP_T, state.WrapT);
00333 if (cubemap) glTexParameteri(type, GL_TEXTURE_WRAP_R, state.WrapT);
00334 glTexParameterfv(type, GL_TEXTURE_BORDER_COLOR, state.BorderColour.arr());
00335 glTexParameterf(type, GL_TEXTURE_PRIORITY, state.Priority);
00336 glTexParameterf(type, GL_TEXTURE_MIN_LOD, state.MinLOD);
00337 glTexParameterf(type, GL_TEXTURE_MAX_LOD, state.MaxLOD);
00338 }
00339
00340 void TexturePainter::DisableAll()
00341 {
00342 #ifdef ENABLE_MULTITEXTURE
00343 for (int c=0; c<MAX_TEXTURES; c++)
00344 {
00345 glActiveTexture(GL_TEXTURE0+c);
00346 glDisable(GL_TEXTURE_2D);
00347 }
00348 glClientActiveTexture(GL_TEXTURE0);
00349 #else
00350 glDisable(GL_TEXTURE_2D);
00351 #endif
00352 }
00353
00354
00355
00356
00357
00358
00359