/*********************/ /*** Texture Cache ***/ /*********************/ #include "stdafx.h" #include #include #include #include #include #include "TexCache.h" #include "utils.h" /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ // Checks loaded files for dups, assumes all passed RGB is unique int CTexCache::ProcessTexture(const char *Filename,sRGBData *RGBData) { int ListSize=TexList.size(); sTex NewTex; sRGBData ThisRGB; GFName FName=Filename; NewTex.Name=FName.File(); NewTex.Filename=Filename; if (!RGBData) // Need to load file { int Idx=GetTexIdx(NewTex); // Is already loaded? if (Idx!=-1) return(Idx); TRACE1("Loading Texture %s\n",NewTex.Filename); if (!LoadBMP(NewTex.Filename,ThisRGB)) { exit(-1); return(ListSize); } RGBData=&ThisRGB; LoadTex(NewTex,RGBData); FreeBMP(ThisRGB); NewTex.Loaded=true; } else { LoadTex(NewTex,RGBData); NewTex.Loaded=FALSE; } TexList.push_back(NewTex); return(ListSize); } /**************************************************************************************/ /**************************************************************************************/ /**************************************************************************************/ void CTexCache::CreateAlignTex(Frame &ThisFrame,sRGBData &RGBData) { int FrameW=ThisFrame.GetWidth(); int FrameH=ThisFrame.GetHeight(); int AlignW=AlignSize(FrameW); int AlignH=AlignSize(FrameH); RGBData.RGB=(u8*)MemAlloc(AlignW*AlignH*3); ThisFrame.FlipY(); RGBData.OldW=FrameW; RGBData.OldH=FrameH; RGBData.TexW=AlignW; RGBData.TexH=AlignH; RGBData.ScaleU=(float)FrameW/(float)AlignW; RGBData.ScaleV=(float)FrameH/(float)AlignH; if (FrameW==AlignW && FrameH==AlignH) { ThisFrame.MakeRGB(RGBData.RGB); return; } // Tex is mis aligned, so align and fill borders with pure pink u8 *Buffer=(u8*)MemAlloc(FrameW*FrameH*3); u8 *Src,*Dst; int X,Y; ThisFrame.MakeRGB(Buffer); Dst=RGBData.RGB; Src=Buffer; Dst=RGBData.RGB; for (Y=0; YTexW*RGBData->TexH*4); ASSERT(Buffer); Src=RGBData->RGB; Dst=Buffer; for (int Y=0; YTexH; Y++) { for (int X=0; XTexW; X++) { u8 R,G,B,A; R=*Src++; G=*Src++; B=*Src++; A=255; if ((R==BlankRGB.rgbRed && G==BlankRGB.rgbGreen && B==BlankRGB.rgbBlue)) // Create alpha for transparent pixels (flagged with PINK!!) { A=0; } *Dst++=R; *Dst++=G; *Dst++=B; *Dst++=A; } } ThisTex.OldW=RGBData->OldW; ThisTex.OldH=RGBData->OldH; ThisTex.TexW=RGBData->TexW; ThisTex.TexH=RGBData->TexH; ThisTex.ScaleU=RGBData->ScaleU; ThisTex.ScaleV=RGBData->ScaleV; int Err; glGenTextures(1, &ThisTex.TexID); Err=glGetError();ASSERT(Err==0); glBindTexture(GL_TEXTURE_2D, ThisTex.TexID); Err=glGetError();ASSERT(Err==0); glTexImage2D(GL_TEXTURE_2D, 0, 4, RGBData->TexW, RGBData->TexH, 0, GL_RGBA, GL_UNSIGNED_BYTE, Buffer); Err=glGetError();ASSERT(Err==0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); Err=glGetError();ASSERT(Err==0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); Err=glGetError();ASSERT(Err==0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); Err=glGetError();ASSERT(Err==0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); Err=glGetError();ASSERT(Err==0); glBindTexture(GL_TEXTURE_2D, 0); Err=glGetError();ASSERT(Err==0); MemFree(Buffer); } /**************************************************************************************/ /**************************************************************************************/ /**************************************************************************************/ void CTexCache::Purge() { int ListSize=TexList.size(); TRACE1("Purging %i textures\n",ListSize); for (int i=0; i