SBSPSS/Utils/MapEdit/TexCache.cpp

224 lines
5.3 KiB
C++
Raw Normal View History

2000-10-27 20:18:30 +02:00
/*********************/
/*** Texture Cache ***/
/*********************/
#include "stdafx.h"
#include <gl\gl.h>
#include <gl\glu.h>
2000-12-11 23:42:19 +01:00
#include <frame.hpp>
2001-02-07 19:46:59 +01:00
#include <gfname.hpp>
2000-10-27 20:18:30 +02:00
#include <Vector>
#include "TexCache.h"
#include "utils.h"
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
2000-11-30 23:17:55 +01:00
// Checks loaded files for dups, assumes all passed RGB is unique
2001-03-22 21:49:58 +01:00
int CTexCache::ProcessTexture(const char *Filename,sRGBData *RGBData)
2000-11-22 23:08:47 +01:00
{
2001-02-07 19:46:59 +01:00
int ListSize=TexList.size();
2000-11-22 23:08:47 +01:00
sTex NewTex;
sRGBData ThisRGB;
2001-02-07 19:46:59 +01:00
GFName FName=Filename;
2000-11-22 23:08:47 +01:00
2001-02-07 19:46:59 +01:00
NewTex.Name=FName.File();
NewTex.Filename=Filename;
2000-11-22 23:08:47 +01:00
if (!RGBData) // Need to load file
{
2000-11-30 23:17:55 +01:00
int Idx=GetTexIdx(NewTex); // Is already loaded?
if (Idx!=-1) return(Idx);
2000-12-01 22:08:54 +01:00
2001-05-01 18:54:13 +02:00
// TRACE1("Loading Texture %s\n",NewTex.Filename);
2001-01-03 23:11:13 +01:00
2001-02-07 19:46:59 +01:00
if (!LoadBMP(NewTex.Filename,ThisRGB))
2001-01-03 23:11:13 +01:00
{
exit(-1);
return(ListSize);
}
2000-11-22 23:08:47 +01:00
RGBData=&ThisRGB;
LoadTex(NewTex,RGBData);
FreeBMP(ThisRGB);
2001-03-31 03:30:53 +02:00
NewTex.Loaded=true;
2000-11-22 23:08:47 +01:00
}
else
{
LoadTex(NewTex,RGBData);
2000-11-30 23:17:55 +01:00
NewTex.Loaded=FALSE;
2000-11-22 23:08:47 +01:00
}
2000-10-27 20:18:30 +02:00
TexList.push_back(NewTex);
2000-11-22 23:08:47 +01:00
return(ListSize);
2000-10-27 20:18:30 +02:00
}
2000-11-22 23:08:47 +01:00
/**************************************************************************************/
/**************************************************************************************/
2000-11-30 23:17:55 +01:00
/**************************************************************************************/
2001-03-31 03:30:53 +02:00
void CTexCache::CreateAlignTex(Frame &ThisFrame,sRGBData &RGBData)
2000-11-30 23:17:55 +01:00
{
2001-03-31 03:30:53 +02:00
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)
2000-11-30 23:17:55 +01:00
{
2001-03-31 03:30:53 +02:00
ThisFrame.MakeRGB(RGBData.RGB);
return;
2000-11-30 23:17:55 +01:00
}
2001-03-31 03:30:53 +02:00
// Tex is mis aligned, so align and fill borders with pure pink
2000-11-30 23:17:55 +01:00
2001-03-31 03:30:53 +02:00
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; Y<FrameH; Y++)
{
for (X=0; X<FrameW; X++)
{
*Dst++=*Src++;
*Dst++=*Src++;
*Dst++=*Src++;
}
for (X; X<AlignW; X++)
{
*Dst++=BlankRGB.rgbRed;
*Dst++=BlankRGB.rgbGreen;
*Dst++=BlankRGB.rgbBlue;
}
}
for (Y; Y<AlignH; Y++)
{
for (X=0; X<AlignW; X++)
{
*Dst++=BlankRGB.rgbRed;
*Dst++=BlankRGB.rgbGreen;
*Dst++=BlankRGB.rgbBlue;
}
}
2000-11-30 23:17:55 +01:00
2001-03-31 03:30:53 +02:00
MemFree(Buffer);
}
2000-11-30 23:17:55 +01:00
2000-11-22 23:08:47 +01:00
/**************************************************************************************/
2001-02-06 23:25:39 +01:00
bool CTexCache::LoadBMP(const char *Filename,sRGBData &RGBData)
2000-11-22 23:08:47 +01:00
{
2000-12-11 23:42:19 +01:00
Frame ThisFrame;
2001-01-03 23:11:13 +01:00
FILE *File;
// Check File exists
File=fopen(Filename,"r");
if (!File)
{
CString mexstr;
mexstr.Format("%s Not Found\n", Filename);
AfxMessageBox(mexstr,MB_OK | MB_ICONEXCLAMATION);
exit(EXIT_FAILURE );
return(false);
}
2000-12-11 23:42:19 +01:00
2001-01-03 23:11:13 +01:00
fclose(File);
2000-12-11 23:42:19 +01:00
ThisFrame.LoadBMP(Filename);
2001-03-31 03:30:53 +02:00
CreateAlignTex(ThisFrame,RGBData);
2001-01-03 23:11:13 +01:00
return(true);
2000-11-22 23:08:47 +01:00
}
/**************************************************************************************/
void CTexCache::FreeBMP(sRGBData &RGBData)
{
if (RGBData.RGB)
{
2001-03-31 03:30:53 +02:00
MemFree(RGBData.RGB);
RGBData.RGB=0;
2000-11-22 23:08:47 +01:00
}
}
/**************************************************************************************/
2001-03-31 03:30:53 +02:00
void CTexCache::LoadTex(sTex &ThisTex,sRGBData *RGBData)
2000-11-30 23:17:55 +01:00
{
2000-12-11 23:42:19 +01:00
u8 *Buffer;
2000-11-30 23:17:55 +01:00
u8 *Src,*Dst;
2000-12-01 22:08:54 +01:00
2000-11-30 23:17:55 +01:00
// create RGB & alpha texture & ensuse texture is correct size for GL
2001-03-31 03:30:53 +02:00
Buffer=(u8*)MemAlloc(RGBData->TexW*RGBData->TexH*4);
ASSERT(Buffer);
2000-11-30 23:17:55 +01:00
2001-03-31 03:30:53 +02:00
Src=RGBData->RGB;
Dst=Buffer;
2001-02-10 21:21:20 +01:00
2001-03-31 03:30:53 +02:00
for (int Y=0; Y<RGBData->TexH; Y++)
2000-11-30 23:17:55 +01:00
{
2001-03-31 03:30:53 +02:00
for (int X=0; X<RGBData->TexW; X++)
2000-11-30 23:17:55 +01:00
{
2000-12-01 22:08:54 +01:00
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!!)
2000-11-30 23:17:55 +01:00
{
A=0;
}
*Dst++=R;
*Dst++=G;
*Dst++=B;
*Dst++=A;
}
}
2001-03-31 03:30:53 +02:00
ThisTex.OldW=RGBData->OldW;
ThisTex.OldH=RGBData->OldH;
ThisTex.TexW=RGBData->TexW;
ThisTex.TexH=RGBData->TexH;
ThisTex.ScaleU=RGBData->ScaleU;
ThisTex.ScaleV=RGBData->ScaleV;
2001-04-07 23:05:33 +02:00
2000-12-01 22:08:54 +01:00
glGenTextures(1, &ThisTex.TexID);
2000-11-22 23:08:47 +01:00
glBindTexture(GL_TEXTURE_2D, ThisTex.TexID);
2001-03-31 03:30:53 +02:00
glTexImage2D(GL_TEXTURE_2D, 0, 4, RGBData->TexW, RGBData->TexH, 0, GL_RGBA, GL_UNSIGNED_BYTE, Buffer);
2000-11-22 23:08:47 +01:00
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
2000-12-29 23:20:38 +01:00
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
2000-11-22 23:08:47 +01:00
glBindTexture(GL_TEXTURE_2D, 0);
2001-03-31 03:30:53 +02:00
MemFree(Buffer);
2000-11-22 23:08:47 +01:00
}
/**************************************************************************************/
/**************************************************************************************/
/**************************************************************************************/
2000-11-14 16:03:04 +01:00
void CTexCache::Purge()
{
int ListSize=TexList.size();
2001-05-01 18:54:13 +02:00
// TRACE1("Purging %i textures\n",ListSize);
2000-11-14 16:03:04 +01:00
for (int i=0; i<ListSize; i++)
{
glDeleteTextures(1,&TexList[i].TexID);
}
TexList.clear();
2000-11-30 23:17:55 +01:00
}
/**************************************************************************************/