dbd0c9a739
- migliorie nella funzione GetImage di Scene.
164 lines
6.0 KiB
C++
164 lines
6.0 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2017-2017
|
|
//----------------------------------------------------------------------------
|
|
// File : SceneImage.cpp Data : 11.02.17 Versione : 1.8b2
|
|
// Contenuto : Implementazione della gestione immagini della classe scena.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 11.02.17 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "Scene.h"
|
|
#include "\EgtDev\Include\EgtStringConverter.h"
|
|
#include "\EgtDev\Extern\FreeImage\Include\FreeImage.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Scene::GetImage( int nShowMode, Color colBackTop, Color colBackBottom,
|
|
int nDestWidth, int nDestHeight, const string& sFile)
|
|
{
|
|
// Cerco e verifico il formato del file da scrivere a partire dall'estensione
|
|
FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilenameU( stringtoW( sFile)) ;
|
|
if ( fif == FIF_UNKNOWN || ! FreeImage_FIFSupportsWriting( fif))
|
|
return false ;
|
|
|
|
// Dimensioni della vista
|
|
int nWidth = m_nViewportW ;
|
|
int nHeight = m_nViewportH ;
|
|
if ( nWidth == 0 || nHeight == 0)
|
|
return false ;
|
|
|
|
// Coefficienti di scalatura
|
|
if ( nDestWidth == 0 || nDestHeight == 0)
|
|
return false ;
|
|
double dCoeffW = double( nDestWidth) / nWidth ;
|
|
double dCoeffH = double( nDestHeight) / nHeight ;
|
|
|
|
// Costanti per mask colori (BGRA)
|
|
const unsigned int BLUE_MASK = 0xFF000000 ;
|
|
const unsigned int GREEN_MASK = 0x00FF0000 ;
|
|
const unsigned int RED_MASK = 0x0000FF00 ;
|
|
|
|
// Alloco immagine complessiva
|
|
int nN = max( int( dCoeffW + 0.5), 1) ;
|
|
int nM = max( int( dCoeffH + 0.5), 1) ;
|
|
FIBITMAP* pDib = FreeImage_Allocate( nN * nWidth, nM * nHeight, 32, RED_MASK, GREEN_MASK, BLUE_MASK) ;
|
|
if ( pDib == nullptr)
|
|
return false ;
|
|
|
|
// Alloco il buffer di lettura dei pixel della vista OpenGL ( fattore 4 perché BGRA)
|
|
BYTE* pBuffer = new BYTE[ 4 * nWidth * nHeight] ;
|
|
if ( pBuffer == nullptr)
|
|
return false ;
|
|
|
|
// Salvo stato di visualizzazione
|
|
int nCurrShowMode = m_nShowMode ;
|
|
bool bCurrShowGrid = m_bShowGrid ;
|
|
bool bCurrShowFrame = m_bShowFrame ;
|
|
bool bCurrShowGlobFrame = m_bShowGlobFrame ;
|
|
Color colCurrBackTop = m_colBackTop ;
|
|
Color colCurrBackBottom = m_colBackBottom ;
|
|
// Imposto attributi di visualizzazione
|
|
m_nShowMode = nShowMode ;
|
|
m_bShowGrid = false ;
|
|
m_bShowFrame = false ;
|
|
m_bShowGlobFrame = false ;
|
|
m_colBackTop = colBackTop ;
|
|
m_colBackBottom = colBackBottom ;
|
|
// Salvo stato di zoom
|
|
Point3d ptCurrCenter = m_ptCenter ;
|
|
double dCurrHalfWidth = m_dHalfWidth ;
|
|
double dCurrHalfHeight = m_dHalfHeight ;
|
|
// Imposto zoom globale
|
|
double dZoom = max( dCoeffW / nN, dCoeffH / nM) / min( dCoeffW / nN, dCoeffH / nM) ;
|
|
m_dHalfWidth *= dZoom ;
|
|
m_dHalfHeight *= dZoom ;
|
|
|
|
// Eseguo N x M disegni
|
|
double dCoeff = max( 1.0 / nN, 1.0 / nM) ;
|
|
double dWs = m_dHalfWidth * dCoeff ;
|
|
double dHs = m_dHalfHeight * dCoeff ;
|
|
Vector3d vtX = m_vtUp ^ m_vtDirCamera ;
|
|
Vector3d vtY = m_vtUp ;
|
|
Point3d ptOrig = m_ptCenter - vtX * dWs * nN - vtY * dHs * nM ;
|
|
for ( int i = 0 ; i < nN ; ++ i) {
|
|
for ( int j = 0 ; j < nM ; ++ j) {
|
|
// Aggiusto scalature
|
|
m_ptCenter = ptOrig + vtX * (( 2 * i + 1) * dWs) + vtY * (( 2 * j + 1) * dHs) ;
|
|
m_dHalfWidth = dWs ;
|
|
m_dHalfHeight = dHs ;
|
|
// Eseguo disegno sul back buffer
|
|
if ( ! MyDraw( false)) {
|
|
delete [] pBuffer ;
|
|
return false ;
|
|
}
|
|
// Leggo l'immagine nel buffer
|
|
glReadBuffer( GL_BACK) ;
|
|
glReadPixels( 0, 0, nWidth, nHeight, GL_BGRA, GL_UNSIGNED_BYTE, pBuffer) ;
|
|
// Converto al formato di FreeImage
|
|
FIBITMAP* pTmpDib = FreeImage_ConvertFromRawBits( pBuffer, nWidth, nHeight, 4 * nWidth, 32,
|
|
RED_MASK, GREEN_MASK, BLUE_MASK, false) ;
|
|
// Inserisco nell'immagine complessiva
|
|
FreeImage_Paste( pDib, pTmpDib, i * nWidth, ( nM - 1 - j) * nHeight, 255) ;
|
|
FreeImage_Unload( pTmpDib) ;
|
|
}
|
|
}
|
|
|
|
// Ripristino attributi di visualizzazione originali
|
|
m_nShowMode = nCurrShowMode ;
|
|
m_bShowGrid = bCurrShowGrid ;
|
|
m_bShowFrame = bCurrShowFrame ;
|
|
m_bShowGlobFrame = bCurrShowGlobFrame ;
|
|
m_colBackBottom = colCurrBackBottom ;
|
|
m_colBackTop = colCurrBackTop ;
|
|
// Ripristino zoom
|
|
m_ptCenter = ptCurrCenter ;
|
|
m_dHalfWidth = dCurrHalfWidth ;
|
|
m_dHalfHeight = dCurrHalfHeight ;
|
|
|
|
// converto l'immagine a 24 bit per pixel
|
|
FIBITMAP* pTmpDib = pDib ;
|
|
pDib = FreeImage_ConvertTo24Bits( pTmpDib) ;
|
|
FreeImage_Unload( pTmpDib) ;
|
|
|
|
// Se necessario, eseguo scalatura della bitmap
|
|
if ( nDestWidth != nN * nWidth || nDestHeight != nM * nHeight) {
|
|
int nLeft ; int nTop ;
|
|
int nRight ; int nBottom ;
|
|
if ( dCoeffW / nN >= dCoeffH / nM) {
|
|
nLeft = 0 ;
|
|
nRight = nN * nWidth - 1 ;
|
|
int nDeltaH = nM * nHeight - nN * int( nDestHeight / dCoeffW) ;
|
|
nTop = nDeltaH / 2 ;
|
|
nBottom = nM * nHeight - nTop - 1 ;
|
|
}
|
|
else {
|
|
nTop = 0 ;
|
|
nBottom = nM * nHeight - 1 ;
|
|
int nDeltaW = nN * nWidth - nM * int( nDestWidth / dCoeffH) ;
|
|
nLeft = nDeltaW / 2 ;
|
|
nRight = nN * nWidth - nLeft - 1 ;
|
|
}
|
|
FIBITMAP* pTmp2Dib = pDib ;
|
|
pDib = FreeImage_RescaleRect( pTmp2Dib, nDestWidth, nDestHeight, nLeft, nTop, nRight, nBottom, FILTER_CATMULLROM) ;
|
|
FreeImage_Unload( pTmp2Dib) ;
|
|
}
|
|
|
|
// Salvataggio
|
|
int nFlag = 0 ;
|
|
bool bOk = ( FreeImage_SaveU( fif, pDib, stringtoW( sFile), nFlag) != FALSE) ;
|
|
|
|
// Libero le risorse
|
|
FreeImage_Unload( pDib) ;
|
|
delete [] pBuffer ;
|
|
|
|
return bOk ;
|
|
}
|