b839d7ac36
- aggiunta gestione primitiva delle textures.
248 lines
8.4 KiB
C++
248 lines
8.4 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2015
|
|
//----------------------------------------------------------------------------
|
|
// File : TextureMgr.cpp Data : 27.09.15 Versione : 1.6i8
|
|
// Contenuto : Implementazione della classe gestione textures.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 27.09.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "Scene.h"
|
|
#include "TextureMgr.h"
|
|
#include "\EgtDev\Include\EGnStringUtils.h"
|
|
#include "\EgtDev\Include\EgtStringConverter.h"
|
|
#include "\EgtDev\Extern\FreeImage\Include\FreeImage.h"
|
|
|
|
using namespace std ;
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
TextureMgr::TextureMgr( void)
|
|
{
|
|
// inserisco le texture standard calcolate : Chessboard e Lines
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
TextureMgr::~TextureMgr( void)
|
|
{
|
|
// scarico le texture da OpenGL
|
|
for ( auto iIter = m_umTextData.begin() ; iIter != m_umTextData.end() ; ++ iIter) {
|
|
GLuint nTextId = iIter->second.nTexId ;
|
|
glDeleteTextures( 1, &nTextId) ;
|
|
}
|
|
m_umTextData.clear() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
TextureMgr::LoadTexture( const string& sName, const string& sFile, double dDimX, double dDimY, bool bRepeat)
|
|
{
|
|
// verifico se immagine già caricata
|
|
auto iIter = m_umTextData.find( sName) ;
|
|
if ( iIter != m_umTextData.end())
|
|
return ( EqualNoCase( iIter->second.sFile, sFile) && iIter->second.bRepeat == bRepeat) ;
|
|
|
|
// leggo l'immagine dal file
|
|
FIBITMAP* pDib = nullptr ;
|
|
if ( ! ReadImage( sFile, pDib))
|
|
return false ;
|
|
|
|
// se necessario, converto l'immagine a 32 bit per pixel (BGRA)
|
|
int bitsPerPixel = FreeImage_GetBPP( pDib) ;
|
|
if ( bitsPerPixel != 32) {
|
|
FIBITMAP* pTmpDib = pDib ;
|
|
pDib = FreeImage_ConvertTo32Bits( pTmpDib) ;
|
|
FreeImage_Unload( pTmpDib) ;
|
|
}
|
|
|
|
// se necessario e possibile, la riduco alle dimensioni caricabili da OpenGL corrente
|
|
if ( ! TestImageWithOpenGL( pDib))
|
|
return false ;
|
|
|
|
// recupero le dimensioni in pixel dell'immagine
|
|
int nWidth = FreeImage_GetWidth( pDib) ;
|
|
int nHeight = FreeImage_GetHeight( pDib) ;
|
|
|
|
// carico l'immagine in OpenGL come texture
|
|
GLuint nTexName ;
|
|
glPixelStorei( GL_UNPACK_ALIGNMENT, 4) ;
|
|
glGenTextures( 1, &nTexName) ;
|
|
glBindTexture( GL_TEXTURE_2D, nTexName) ;
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ( bRepeat ? GL_REPEAT : GL_CLAMP_TO_BORDER)) ;
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ( bRepeat ? GL_REPEAT : GL_CLAMP_TO_BORDER)) ;
|
|
float color[] = { 0.9f, 0.9f, 0.9f, 1.0f} ;
|
|
glTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color) ;
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) ;
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) ;
|
|
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nWidth, nHeight,
|
|
0, GL_BGRA, GL_UNSIGNED_BYTE, FreeImage_GetBits( pDib)) ;
|
|
// libero l'immagine originaria
|
|
FreeImage_Unload( pDib) ;
|
|
|
|
// verifico che la texture sia stata veramente caricata
|
|
if ( ! glIsTexture( nTexName))
|
|
return false ;
|
|
|
|
// rendo non corrente questa texture
|
|
glBindTexture( GL_TEXTURE_2D, 0) ;
|
|
|
|
// salvo i dati
|
|
TextureData textData( sFile, dDimX, dDimY, nWidth, nHeight, nTexName, bRepeat) ;
|
|
m_umTextData.emplace( sName, textData) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
TextureMgr::UnloadTexture( const std::string& sName)
|
|
{
|
|
// cerco la texture, se non la trovo già ok
|
|
auto iIter = m_umTextData.find( sName) ;
|
|
if ( iIter == m_umTextData.end())
|
|
return true ;
|
|
// scarico la texture da OpenGL
|
|
GLuint nTextId = iIter->second.nTexId ;
|
|
glDeleteTextures( 1, &nTextId) ;
|
|
// tolgo la texture dall'elenco
|
|
m_umTextData.erase( iIter) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
TextureMgr::ChangeDimensions( const std::string& sName, double dDimX, double dDimY)
|
|
{
|
|
// ricerca della texture di nome dato
|
|
auto iIter = m_umTextData.find( sName) ;
|
|
if ( iIter == m_umTextData.end())
|
|
return false ;
|
|
// assegno le nuove dimensioni
|
|
iIter->second.dDimX = dDimX ;
|
|
iIter->second.dDimY = dDimY ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
TextureMgr::GetTextureData( const string& sName, unsigned int& nId, double& dDimX, double& dDimY)
|
|
{
|
|
// ricerca della texture di nome dato
|
|
auto iIter = m_umTextData.find( sName) ;
|
|
if ( iIter == m_umTextData.end())
|
|
return false ;
|
|
// restituzione dei parametri
|
|
nId = iIter->second.nTexId ;
|
|
dDimX = iIter->second.dDimX ;
|
|
dDimY = iIter->second.dDimY ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
TextureMgr::ReadImage( const string& sFile, FIBITMAP*& pDib)
|
|
{
|
|
// deduco il formato dell'immagine dalla sua segnatura o dalla estensione del file
|
|
FREE_IMAGE_FORMAT nFif = FreeImage_GetFileTypeU( stringtoW( sFile), 0) ;
|
|
if ( nFif == FIF_UNKNOWN)
|
|
nFif = FreeImage_GetFIFFromFilenameU( stringtoW( sFile)) ;
|
|
// se non determinata, esco con errore
|
|
if ( nFif == FIF_UNKNOWN)
|
|
return false ;
|
|
|
|
// carico l'immagine
|
|
pDib = nullptr ;
|
|
if ( FreeImage_FIFSupportsReading( nFif))
|
|
pDib = FreeImage_LoadU( nFif, stringtoW( sFile)) ;
|
|
if ( pDib == nullptr)
|
|
return false ;
|
|
|
|
// recupero alcuni dati dell'immagine e li verifico
|
|
if ( FreeImage_GetBits( pDib) == nullptr ||
|
|
FreeImage_GetWidth( pDib) == 0 || FreeImage_GetHeight( pDib) == 0) {
|
|
FreeImage_Unload( pDib) ;
|
|
pDib = nullptr ;
|
|
return false ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
TextureMgr::TestImageWithOpenGL( FIBITMAP*& pDib)
|
|
{
|
|
// recupero le dimensioni in pixel dell'immagine
|
|
int nWidth = FreeImage_GetWidth( pDib) ;
|
|
int nHeight = FreeImage_GetHeight( pDib) ;
|
|
|
|
// verifico sia caricabile da OpenGL corrente
|
|
glTexImage2D( GL_PROXY_TEXTURE_2D, 0, GL_RGBA, nWidth, nHeight,
|
|
0, GL_BGRA, GL_UNSIGNED_BYTE, FreeImage_GetBits( pDib)) ;
|
|
int nW ;
|
|
glGetTexLevelParameteriv( GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &nW) ;
|
|
if ( nW == 0) {
|
|
// recupero la massima dimensione di una texture per OpenGL corrente
|
|
int nMaxTextDim ;
|
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &nMaxTextDim) ;
|
|
// cerco le dimensioni POT (power of two) appena minori delle due dimensioni
|
|
int nNewW = nMaxTextDim ;
|
|
while ( nNewW > nWidth)
|
|
nNewW /= 2 ;
|
|
int nNewH = nMaxTextDim ;
|
|
while ( nNewH > nHeight)
|
|
nNewH /= 2 ;
|
|
// deformo la texture per avere queste dimensioni
|
|
FIBITMAP* pTmpDib = pDib ;
|
|
pDib = FreeImage_Rescale( pTmpDib, nNewW, nNewH, FILTER_BILINEAR) ;
|
|
FreeImage_Unload( pTmpDib) ;
|
|
nWidth = nNewW ;
|
|
nHeight = nNewH ;
|
|
// verifico che la nuova immagine sia valida
|
|
if ( pDib == nullptr)
|
|
return false ;
|
|
if ( FreeImage_GetBits( pDib) == nullptr ||
|
|
FreeImage_GetWidth( pDib) != nWidth || FreeImage_GetHeight( pDib) != nHeight) {
|
|
FreeImage_Unload( pDib) ;
|
|
pDib = nullptr ;
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
//// !!! PROVVISORIO Textures
|
|
//#define checkImageWidth 64
|
|
//#define checkImageHeight 64
|
|
//static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
|
|
//static GLuint texName;
|
|
//
|
|
//void makeCheckImage(void)
|
|
//{
|
|
// int i, j, c;
|
|
//
|
|
// for (i = 0; i < checkImageHeight; i++) {
|
|
// for (j = 0; j < checkImageWidth; j++) {
|
|
// c = (((i&0x8)==0)^((j&0x8)==0))*255;
|
|
// checkImage[i][j][0] = (GLubyte) c;
|
|
// checkImage[i][j][1] = (GLubyte) c;
|
|
// checkImage[i][j][2] = (GLubyte) c;
|
|
// checkImage[i][j][3] = (GLubyte) 255;
|
|
// }
|
|
// }
|
|
//}
|
|
//
|
|
//#include "\EgtDev\Extern\FreeImage\Include\FreeImage.h"
|
|
//#include "\EgtDev\Include\EgtStringConverter.h"
|
|
//#include <string>
|