SBSPSS/Utils/MapEdit/TexCache.cpp

194 lines
4.9 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"
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
2001-02-06 23:25:39 +01:00
/*
int CTexCache::GetTexIdx(const char *Filename,int Flags)
2000-10-27 20:18:30 +02:00
{
2000-11-30 23:17:55 +01:00
sTex Tex;
2001-02-06 23:25:39 +01:00
Tex.Filename=Filename;
2000-11-30 23:17:55 +01:00
Tex.Flags=Flags;
return(TexList.Find(Tex));
2000-11-22 23:08:47 +01:00
}
2001-02-06 23:25:39 +01:00
*/
2000-11-22 23:08:47 +01:00
/*****************************************************************************/
2000-11-30 23:17:55 +01:00
// Checks loaded files for dups, assumes all passed RGB is unique
2001-02-07 19:46:59 +01:00
int CTexCache::ProcessTexture(const char *Filename,int Flags,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-10-27 22:21:39 +02:00
NewTex.Flags=Flags;
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-02-10 21:21:20 +01: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);
2000-11-30 23:17:55 +01: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
/**************************************************************************************/
const int TexAlignTable[]={1,2,4,8,16,32,64,128,256};
const int TexAlignTableSize=sizeof(TexAlignTable)/sizeof(int);
int CTexCache::AlignSize(int Size)
{
for (int i=0;i<TexAlignTableSize-1; i++)
{
if (Size>TexAlignTable[i] && Size<TexAlignTable[i+1]) return(TexAlignTable[i+1]);
}
return(Size);
}
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-01-03 23:11:13 +01:00
2000-12-11 23:42:19 +01:00
RGBData.Width=ThisFrame.GetWidth();
RGBData.Height=ThisFrame.GetHeight();
RGBData.RGB=(u8*)malloc(RGBData.Width*RGBData.Height*3);
ThisFrame.FlipY();
ThisFrame.MakeRGB(RGBData.RGB);
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)
{
2000-12-11 23:42:19 +01:00
free(RGBData.RGB);
2000-11-22 23:08:47 +01:00
}
}
/**************************************************************************************/
2000-11-30 23:17:55 +01:00
void CTexCache::LoadTex(sTex &ThisTex,sRGBData *TexData)
{
2000-12-11 23:42:19 +01:00
u8 *Buffer;
2000-11-30 23:17:55 +01:00
int TexWidth=TexData->Width;
int TexHeight=TexData->Height;
int GLWidth=AlignSize(TexWidth);
int GLHeight=AlignSize(TexHeight);
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
2000-12-11 23:42:19 +01:00
Buffer=(u8*)malloc(GLWidth*GLHeight*4);
2000-12-01 22:08:54 +01:00
Src=TexData->RGB;
2000-11-30 23:17:55 +01:00
Dst=&Buffer[0];
2001-02-10 21:21:20 +01:00
2000-12-01 22:08:54 +01:00
for (int Y=0; Y<TexHeight; Y++)
2000-11-30 23:17:55 +01:00
{
2000-12-01 22:08:54 +01:00
for (int X=0; X<TexWidth; 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;
}
2000-12-01 22:08:54 +01:00
Dst+=(GLWidth-TexWidth)*4;
2000-11-30 23:17:55 +01:00
}
ThisTex.TexWidth=TexWidth;
ThisTex.TexHeight=TexHeight;
2000-11-22 23:08:47 +01:00
2000-12-01 22:08:54 +01:00
ThisTex.dW=(1.0f)/(float)(GLWidth/16.0f);
ThisTex.dH=(1.0f)/(float)(GLHeight/16.0f);
glGenTextures(1, &ThisTex.TexID);
2000-11-22 23:08:47 +01:00
glBindTexture(GL_TEXTURE_2D, ThisTex.TexID);
2000-11-30 23:17:55 +01:00
glTexImage2D(GL_TEXTURE_2D, 0, 4, GLWidth, GLHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, &Buffer[0]);
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);
2000-12-11 23:42:19 +01:00
free(Buffer);
2000-11-22 23:08:47 +01:00
}
/**************************************************************************************/
/**************************************************************************************/
/**************************************************************************************/
2000-11-14 16:03:04 +01:00
void CTexCache::Purge()
{
int ListSize=TexList.size();
TRACE1("Purging %i textures\n",ListSize);
for (int i=0; i<ListSize; i++)
{
glDeleteTextures(1,&TexList[i].TexID);
}
TexList.clear();
2000-11-30 23:17:55 +01:00
}
/**************************************************************************************/