EgtGraphics :

- miglioramenti a GetImage con risoluzioni elevate.
This commit is contained in:
Dario Sassi
2017-02-15 08:12:59 +00:00
parent 5be1bf8dc7
commit eb510f2cbb
2 changed files with 65 additions and 30 deletions
+62 -27
View File
@@ -21,7 +21,7 @@ using namespace std ;
//----------------------------------------------------------------------------
bool
Scene::GetImage( int nShowMode, bool bShowGrid, bool bShowFrame, Color colBackTop, Color colBackBottom,
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
@@ -41,32 +41,73 @@ Scene::GetImage( int nShowMode, bool bShowGrid, bool bShowFrame, Color colBackTo
double dCoeffW = double( nDestWidth) / nWidth ;
double dCoeffH = double( nDestHeight) / nHeight ;
// Alloco il buffer di lettura dei pixel della vista OpenGL ( fattore 4 perché RGBA)
// 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 ;
// Imposto attributi di visualizzazione
// Salvo stato di visualizzazione
int nCurrShowMode = m_nShowMode ;
m_nShowMode = nShowMode ;
bool bCurrShowGrid = m_bShowGrid ;
m_bShowGrid = bShowGrid ;
bool bCurrShowFrame = m_bShowFrame ;
m_bShowFrame = 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 ;
// Imposto zoom
// Salvo stato di zoom
Point3d ptCurrCenter = m_ptCenter ;
double dCurrHalfWidth = m_dHalfWidth ;
double dCurrHalfHeight = m_dHalfHeight ;
double dCoeff = max( dCoeffW, dCoeffH) / min( dCoeffW, dCoeffH) ;
m_dHalfWidth *= dCoeff ;
m_dHalfHeight *= dCoeff ;
// Imposto zoom globale
double dZoom = max( dCoeffW / nN, dCoeffH / nM) / min( dCoeffW / nN, dCoeffH / nM) ;
m_dHalfWidth *= dZoom ;
m_dHalfHeight *= dZoom ;
// Eseguo disegno sul back buffer
if ( ! MyDraw( false))
return false ;
// 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))
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 ;
@@ -75,16 +116,10 @@ Scene::GetImage( int nShowMode, bool bShowGrid, bool bShowFrame, Color colBackTo
m_colBackBottom = colCurrBackBottom ;
m_colBackTop = colCurrBackTop ;
// Ripristino zoom
m_ptCenter = ptCurrCenter ;
m_dHalfWidth = dCurrHalfWidth ;
m_dHalfHeight = dCurrHalfHeight ;
// 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* pDib = FreeImage_ConvertFromRawBits( pBuffer, nWidth, nHeight, 4 * nWidth, 32,
0x0000FF00, 0xFF000000, 0x00FF0000, false) ;
// converto l'immagine a 24 bit per pixel
FIBITMAP* pTmpDib = pDib ;
pDib = FreeImage_ConvertTo24Bits( pTmpDib) ;
@@ -93,19 +128,19 @@ Scene::GetImage( int nShowMode, bool bShowGrid, bool bShowFrame, Color colBackTo
// Eseguo scalatura della bitmap
int nLeft ; int nTop ;
int nRight ; int nBottom ;
if ( dCoeffW >= dCoeffH) {
if ( dCoeffW / nN >= dCoeffH / nM) {
nLeft = 0 ;
nRight = nWidth - 1 ;
int nDeltaH = nHeight - int( nDestHeight / dCoeffW) ;
nRight = nN * nWidth - 1 ;
int nDeltaH = nM * nHeight - nN * int( nDestHeight / dCoeffW) ;
nTop = nDeltaH / 2 ;
nBottom = nHeight - nTop ;
nBottom = nM * nHeight - nTop - 1 ;
}
else {
nTop = 0 ;
nBottom = nHeight ;
int nDeltaW = nWidth - int( nDestWidth / dCoeffH) ;
nBottom = nM * nHeight - 1 ;
int nDeltaW = nN * nWidth - nM * int( nDestWidth / dCoeffH) ;
nLeft = nDeltaW / 2 ;
nRight = nWidth - nLeft ;
nRight = nN * nWidth - nLeft - 1 ;
}
FIBITMAP* pTmp2Dib = pDib ;
pDib = FreeImage_RescaleRect( pTmp2Dib, nDestWidth, nDestHeight, nLeft, nTop, nRight, nBottom, FILTER_BSPLINE) ;