diff --git a/EgtGraphics.vcxproj b/EgtGraphics.vcxproj index a544015..8f40d7c 100644 --- a/EgtGraphics.vcxproj +++ b/EgtGraphics.vcxproj @@ -234,7 +234,11 @@ copy $(TargetPath) \EgtProg\Dll64 + + CppHeader + + @@ -255,6 +259,7 @@ copy $(TargetPath) \EgtProg\Dll64 Create Create + diff --git a/EgtGraphics.vcxproj.filters b/EgtGraphics.vcxproj.filters index 3c0e414..0d7ccf9 100644 --- a/EgtGraphics.vcxproj.filters +++ b/EgtGraphics.vcxproj.filters @@ -78,6 +78,9 @@ File di intestazione + + File di intestazione + @@ -119,6 +122,12 @@ File di origine + + File di origine + + + File di origine + diff --git a/Scene.h b/Scene.h index b022d04..fcb3bcb 100644 --- a/Scene.h +++ b/Scene.h @@ -14,6 +14,7 @@ #pragma once //---------------------------------------------------------------------------- +#include "TextureMgr.h" #include "/EgtDev/Include/EGrScene.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "OpenGL.h" @@ -160,6 +161,9 @@ class Scene : public IEGrScene return false ; vtDir = m_vtLastSnapDir ; return true ; } + // Texture + virtual bool LoadTexture( const std::string& sName, const std::string& sFile, + double dDimX, double dDimY, bool bRepeat) ; public : // Basic @@ -238,6 +242,8 @@ class Scene : public IEGrScene bool m_bUpOk ; // flag per stato aggiornamento di Up int m_nViewportW ; // larghezza della finestra int m_nViewportH ; // altezza della finestra + // Textures + TextureMgr m_TextMgr ; // gestore di textures // Background Color m_colBackTop ; // colore di sfondo in alto Color m_colBackBottom ; // colore di sfondo in basso diff --git a/SceneGeom.cpp b/SceneGeom.cpp index d431be7..63abd60 100644 --- a/SceneGeom.cpp +++ b/SceneGeom.cpp @@ -414,8 +414,61 @@ Scene::DrawGeoObj( const IGdbIterator& iIter, int nPass, const MdStMkCol& siObj) glLoadName( iIter.GetId()) ; } + // eventuale texture + string sTxtName ; + if ( iIter.GetInfo( "!TXT", sTxtName)) { + + Frame3d frRef ; + iIter.GetGlobFrame( frRef) ; + + GLuint texName ; + double dTextDimS = 400 ; + double dTextDimT = 200 ; + m_TextMgr.GetTextureData( sTxtName, texName, dTextDimS, dTextDimT) ; + + glEnable( GL_TEXTURE_2D) ; + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ; + glBindTexture( GL_TEXTURE_2D, texName) ; + + GLfloat PlaneS[4] ; + GLfloat PlaneT[4] ; + Point3d ptOri(-4009.4378,-2415.5604,0) ; + ptOri.ToLoc( frRef) ; + Vector3d vtX = X_AX ; + vtX.ToLoc( frRef) ; + //vtX.Rotate( Z_AX, 30) ; + Vector3d vtY = Y_AX ; + vtY.ToLoc( frRef) ; + //vtY.Rotate( Z_AX, 30) ; + // creo piano per la S + PlaneS[0] = GLfloat( vtX.x / dTextDimS) ; + PlaneS[1] = GLfloat( vtX.y / dTextDimS) ; + PlaneS[2] = GLfloat( vtX.z / dTextDimS) ; + PlaneS[3] = GLfloat( - vtX * ( ptOri - ORIG) / dTextDimS) ; + // creo piano per la T + PlaneT[0] = GLfloat( vtY.x / dTextDimT) ; + PlaneT[1] = GLfloat( vtY.y / dTextDimT) ; + PlaneT[2] = GLfloat( vtY.z / dTextDimT) ; + PlaneT[3] = GLfloat( - vtY * ( ptOri - ORIG) / dTextDimT) ; + // setto generazione texture automatica + glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR) ; + glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR) ; + glTexGenfv( GL_S, GL_OBJECT_PLANE, PlaneS) ; + glTexGenfv( GL_T, GL_OBJECT_PLANE, PlaneT) ; + + glEnable( GL_TEXTURE_GEN_S) ; + glEnable( GL_TEXTURE_GEN_T) ; + } + // eseguo visualizzazione - return pGraphics->Draw( siObj.nStat, siObj.nMark, bSurfSha, nAlpha, bShowAux) ; + bool bOk = pGraphics->Draw( siObj.nStat, siObj.nMark, bSurfSha, nAlpha, bShowAux) ; + + // !!! per textures !!! + glDisable( GL_TEXTURE_GEN_S) ; + glDisable( GL_TEXTURE_GEN_T) ; + glDisable( GL_TEXTURE_2D) ; + + return bOk ; } //---------------------------------------------------------------------------- diff --git a/SceneTexture.cpp b/SceneTexture.cpp new file mode 100644 index 0000000..6a4dbe3 --- /dev/null +++ b/SceneTexture.cpp @@ -0,0 +1,25 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2015 +//---------------------------------------------------------------------------- +// File : SceneTexture.cpp Data : 27.09.15 Versione : 1.6i8 +// Contenuto : Implementazione della gestione texturesa della classe scena. +// +// +// +// Modifiche : 27.09.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "Scene.h" + +//---------------------------------------------------------------------------- +bool +Scene::LoadTexture( const std::string& sName, const std::string& sFile, + double dDimX, double dDimY, bool bRepeat) +{ + return m_TextMgr.LoadTexture( sName, sFile, dDimX, dDimY, bRepeat) ; +} + diff --git a/TextureMgr.cpp b/TextureMgr.cpp new file mode 100644 index 0000000..3ac4abe --- /dev/null +++ b/TextureMgr.cpp @@ -0,0 +1,247 @@ +//---------------------------------------------------------------------------- +// 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 diff --git a/TextureMgr.h b/TextureMgr.h new file mode 100644 index 0000000..87b48be --- /dev/null +++ b/TextureMgr.h @@ -0,0 +1,58 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2015 +//---------------------------------------------------------------------------- +// File : Scene.h Data : 27.09.15 Versione : 1.6i8 +// Contenuto : Dichiarazione della classe gestione textures. +// +// +// +// Modifiche : 27.09.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#pragma once + +#include +#include + +//---------------------------------------------------------------------------- +struct TextureData { + std::string sFile ; + double dDimX ; + double dDimY ; + int nWidth ; + int nHeight ; + unsigned int nTexId ; + bool bRepeat ; + + TextureData( void) + : dDimX( 0), dDimY( 0), nWidth( 0), nHeight( 0), nTexId( 0), bRepeat( false) {} + TextureData( std::string sF, double dX, double dY, int nW, int nH, unsigned int nT, bool bR) + : sFile( sF), dDimX( dX), dDimY( dY), nWidth( nW), nHeight( nH), nTexId( nT), bRepeat( bR) {} +} ; +typedef std::unordered_map STRTEXTD_UMAP ; + +struct FIBITMAP ; + +//---------------------------------------------------------------------------- +class TextureMgr +{ + public : + TextureMgr( void) ; + ~TextureMgr( void) ; + + public : + bool LoadTexture( const std::string& sName, const std::string& sPath, + double dDimX, double dDimY, bool bRepeat) ; + bool ChangeDimensions( const std::string& sName, double dDimX, double dDimY) ; + bool UnloadTexture( const std::string& sName) ; + bool GetTextureData( const std::string& sName, unsigned int& nId, double& dDimX, double& dDimY) ; + + private : + bool ReadImage( const std::string& sFile, FIBITMAP*& pDib) ; + bool TestImageWithOpenGL( FIBITMAP*& pDib) ; + + private : + STRTEXTD_UMAP m_umTextData ; +} ; \ No newline at end of file diff --git a/stdafx.h b/stdafx.h index 17703b9..082ddd6 100644 --- a/stdafx.h +++ b/stdafx.h @@ -32,8 +32,10 @@ #pragma comment(lib, "glu32.lib") #if defined( _WIN64) #pragma comment(lib, EGTEXTDIR "GLEW/lib/x64/glew32mx.lib") +#pragma comment(lib, EGTEXTDIR "FreeImage/lib/x64/FreeImage.lib") #elif defined( _WIN32) #pragma comment(lib, EGTEXTDIR "GLEW/lib/x32/glew32mx.lib") +#pragma comment(lib, EGTEXTDIR "FreeImage/lib/x32/FreeImage.lib") #endif #pragma comment(lib, EGTLIBDIR "EgtGeneral" EGTLIBVER ".lib")