2000-10-27 20:18:30 +02:00
|
|
|
/*********************/
|
|
|
|
/*** Texture Cache ***/
|
|
|
|
/*********************/
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "gl3d.h"
|
|
|
|
#include <gl\gl.h>
|
|
|
|
#include <gl\glu.h>
|
|
|
|
#include <gl\glut.h>
|
2000-11-22 23:08:47 +01:00
|
|
|
#include <gl\glaux.h> // Header File For The Glaux Library
|
2000-10-27 20:18:30 +02:00
|
|
|
#include <Vector>
|
|
|
|
|
|
|
|
#include "TexCache.h"
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*****************************************************************************/
|
2000-11-30 23:17:55 +01:00
|
|
|
int CTexCache::GetTexIdx(char *Filename,int Flags)
|
2000-10-27 20:18:30 +02:00
|
|
|
{
|
2000-11-30 23:17:55 +01:00
|
|
|
sTex Tex;
|
|
|
|
strcpy(Tex.Filename,Filename);
|
|
|
|
Tex.Flags=Flags;
|
|
|
|
return(TexList.Find(Tex));
|
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
|
|
|
|
int CTexCache::ProcessTexture(char *Filename,int Flags,sRGBData *RGBData)
|
2000-11-22 23:08:47 +01:00
|
|
|
{
|
|
|
|
int ListSize=TexList.size();
|
|
|
|
|
|
|
|
sTex NewTex;
|
|
|
|
sRGBData ThisRGB;
|
|
|
|
|
2000-11-30 23:17:55 +01:00
|
|
|
strcpy(NewTex.Filename,Filename);
|
|
|
|
NewTex.Flags=Flags;
|
|
|
|
|
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
|
|
|
|
2000-11-30 23:17:55 +01:00
|
|
|
TRACE1("Loading Texture %s\n",NewTex.Filename);
|
|
|
|
LoadBMP(NewTex.Filename,ThisRGB);
|
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
|
|
|
/**************************************************************************************/
|
|
|
|
void CTexCache::LoadBMP(char *Filename,sRGBData &RGBData)
|
|
|
|
{
|
|
|
|
FILE *File=NULL;
|
|
|
|
AUX_RGBImageRec *Aux;
|
|
|
|
|
|
|
|
Aux=auxDIBImageLoad(Filename);
|
|
|
|
RGBData.Width=Aux->sizeX;
|
|
|
|
RGBData.Height=Aux->sizeY;
|
2000-11-24 23:34:20 +01:00
|
|
|
RGBData.RGB=Aux->data;
|
2000-11-22 23:08:47 +01:00
|
|
|
free(Aux); // Safe to free aux now, contents copied (I HATE AUX)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************************/
|
|
|
|
void CTexCache::FreeBMP(sRGBData &RGBData)
|
|
|
|
{
|
|
|
|
if (RGBData.RGB)
|
|
|
|
{
|
|
|
|
free((unsigned char*)RGBData.RGB);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************************/
|
2000-11-30 23:17:55 +01:00
|
|
|
void CTexCache::LoadTex(sTex &ThisTex,sRGBData *TexData)
|
|
|
|
{
|
|
|
|
std::vector<u8> Buffer;
|
|
|
|
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
|
|
|
|
|
|
|
|
Buffer.resize(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];
|
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);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************************/
|
|
|
|
/**************************************************************************************/
|
|
|
|
/**************************************************************************************/
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************************/
|