//---------------------------------------------------------------------------- // EgalTech 2014-2023 //---------------------------------------------------------------------------- // File : ObjOldGraphics.cpp Data : 08.07.23 Versione : 2.5g1 // Contenuto : Implementazione della classe grafica di un oggetto geometrico. // // // // Modifiche : 10.02.14 DS Creazione modulo. // 23.04.14 DS Agg. gestione materiali. // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ObjOldGraphics.h" #include "Scene.h" #include "/EgtDev/Include/EGkColor.h" #include "/EgtDev/Include/EGkPolyLine.h" #include "/EgtDev/Include/EGkGdbConst.h" #include "/EgtDev/Include/EGkTriangle3d.h" #include "/EgtDev/Include/EgtNumUtils.h" //--------------------------- Macro e Costanti ------------------------------- const int VECT_HEAP = 20 ; //---------------------------------------------------------------------------- ObjOldGraphics::~ObjOldGraphics( void) { Clear() ; } //---------------------------------------------------------------------------- void ObjOldGraphics::Reset( void) { m_bValid = false ; m_nCurrMode = GL_NONE ; } //---------------------------------------------------------------------------- void ObjOldGraphics::Clear( void) { m_ogaVect.clear() ; m_bValid = false ; m_nCurrMode = GL_NONE ; } //---------------------------------------------------------------------------- bool ObjOldGraphics::AddColor( const Color& colC) { return AddOgaColor( colC.GetRed(), colC.GetGreen(), colC.GetBlue(), colC.GetAlpha()) ; } //---------------------------------------------------------------------------- bool ObjOldGraphics::AddMaterial( const Color& colAmb, const Color& colDiff, const Color& colSpec, float fShin) { return AddOgaMaterial( OgAtom::MAT_A, colAmb.GetRed(), colAmb.GetGreen(), colAmb.GetBlue(), colDiff.GetAlpha()) && AddOgaMaterial( OgAtom::MAT_D, colDiff.GetRed(), colDiff.GetGreen(), colDiff.GetBlue(), colDiff.GetAlpha()) && AddOgaMaterial( OgAtom::MAT_S, colSpec.GetRed(), colSpec.GetGreen(), colSpec.GetBlue(), colDiff.GetAlpha()) && AddOgaMaterial( OgAtom::MAT_SH, fShin, 0, 0, 0) ; } //---------------------------------------------------------------------------- bool ObjOldGraphics::AddBackMaterial( const Color& colAmbDiff) { return AddOgaMaterial( OgAtom::MAT_B, colAmbDiff.GetRed(), colAmbDiff.GetGreen(), colAmbDiff.GetBlue(), colAmbDiff.GetAlpha()) ; } //---------------------------------------------------------------------------- bool ObjOldGraphics::AddLineStipple( int nFactor, int nPattern) { return AddOgaLineStipple( nFactor, nPattern) ; } //---------------------------------------------------------------------------- bool ObjOldGraphics::AddPoint( const Point3d& ptP, bool bAux) { // modo corrente deve essere nullo if ( m_nCurrMode != GL_NONE) return false ; // start AddOgaStart( GL_POINTS, bAux) ; // inserisco il nuovo vertice AddOgaVert3f( ptP) ; // aggiorno bbox m_b3Loc.Add( ptP) ; // fine AddOgaEnd() ; // dichiaro valida la grafica m_bValid = true ; return true ; } //---------------------------------------------------------------------------- bool ObjOldGraphics::AddPoints( const PNTVECTOR& vPnt, bool bAux) { // modo corrente deve essere nullo if ( m_nCurrMode != GL_NONE) return false ; // start AddOgaStart( GL_POINTS, bAux) ; // inserisco i vertici + aggiorno bbox for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) { AddOgaVert3f( vPnt[i]) ; m_b3Loc.Add( vPnt[i]) ; } // fine AddOgaEnd() ; // dichiaro valida la grafica m_bValid = true ; return true ; } //---------------------------------------------------------------------------- bool ObjOldGraphics::AddLines( const PNTVECTOR& vPnt, bool bAux) { // modo corrente deve essere nullo if ( m_nCurrMode != GL_NONE) return false ; // riservo memoria per vettore m_ogaVect.reserve( VECT_HEAP + vPnt.size()) ; // start AddOgaStart( GL_LINES, bAux) ; // inserisco i vertici + aggiorno bbox for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) { AddOgaVert3f( vPnt[i]) ; m_b3Loc.Add( vPnt[i]) ; } // fine AddOgaEnd() ; // dichiaro valida la grafica m_bValid = true ; return true ; } //---------------------------------------------------------------------------- bool ObjOldGraphics::AddPolyLine( const PolyLine& PL, bool bAux) { // modo corrente deve essere nullo if ( m_nCurrMode != GL_NONE) return false ; // riservo memoria per vettore m_ogaVect.reserve( VECT_HEAP + PL.GetPointNbr()) ; // start AddOgaStart( GL_LINE_STRIP, bAux) ; // inserisco i nuovi vertici + aggiorno bbox Point3d ptP ; for ( bool bFound = PL.GetFirstPoint( ptP) ; bFound ; bFound = PL.GetNextPoint( ptP)) { AddOgaVert3f( ptP) ; m_b3Loc.Add( ptP) ; } // fine AddOgaEnd() ; // dichiaro valida la grafica m_bValid = true ; return true ; } //---------------------------------------------------------------------------- bool ObjOldGraphics::StartTriangles( int nNum, bool bAux) { // modo corrente deve essere nullo if ( m_nCurrMode != GL_NONE) return false ; // riservo memoria per vettore m_ogaVect.reserve( VECT_HEAP + 3 * nNum) ; // inizio emissione triangoli AddOgaStart( GL_TRIANGLES, bAux) ; m_nCurrMode = GL_TRIANGLES ; return true ; } //---------------------------------------------------------------------------- bool ObjOldGraphics::AddTriangle( const Triangle3d& Tria, const TriFlags3d& TFlags, const TriNormals3d& TNrms) { // modo corrente deve essere triangoli if ( m_nCurrMode != GL_TRIANGLES) return false ; // emetto i flag, le normali e i vertici del triangolo + aggiorno bbox for ( int i = 0 ; i < 3 ; ++ i) { AddOgaBndFlag( TFlags.bFlag[i]) ; AddOgaNormal3f( TNrms.vtN[i]) ; AddOgaVert3f( Tria.GetP( i)) ; m_b3Loc.Add( Tria.GetP( i)) ; } return true ; } //---------------------------------------------------------------------------- bool ObjOldGraphics::EndTriangles( void) { // modo corrente deve essere triangoli if ( m_nCurrMode != GL_TRIANGLES) return false ; // termino il modo triangoli AddOgaEnd() ; m_nCurrMode = GL_NONE ; // dichiaro valida la grafica m_bValid = true ; return true ; } //---------------------------------------------------------------------------- static const float* AdjustColor( const float fCol[4], bool bDark) { if ( ! bDark) { return fCol ; } else { static float fDarkCol[4] = { fCol[0], fCol[1], fCol[2], fCol[3]} ; fDarkCol[0] = fCol[0] * 0.6f ; fDarkCol[1] = fCol[1] * 0.6f ; fDarkCol[2] = fCol[2] * 0.6f ; fDarkCol[3] = fCol[3] * 0.6f ; return fDarkCol ; } } //---------------------------------------------------------------------------- bool ObjOldGraphics::Draw( int nStat, int nMark, bool bSurfSha, bool bSurf, int nAlpha, bool bShowAux) { // se vuoto non faccio alcunché if ( m_ogaVect.size() == 0) return true ; // gestione stato di visualizzazione if ( nStat == GDB_ST_OFF) return true ; if ( nStat == GDB_ST_SEL) { glPointSize( (float) m_pScene->GetSelPointSize()) ; glLineWidth( (float) m_pScene->GetSelLineWidth()) ; } // colore speciale per superficie shading selezionata o marcata bool bStdCol = true ; float fSelMarkCol[4] = { 1, 1, 1, 1} ; float fSelMarkBackCol[4] = { 0.75, 0.75, 0.75, 1} ; if ( bSurfSha) { if ( nMark == GDB_MK_ON) { bStdCol = false ; Color colMark = ( ( GetScene() != nullptr) ? GetScene()->GetMark() : Color( 255, 255, 0)) ; colMark.SetAlpha( nAlpha) ; colMark.GetFloat( fSelMarkCol) ; Color colMarkBack = GetSurfBackColor( colMark) ; colMarkBack.SetAlpha( nAlpha) ; colMarkBack.GetFloat( fSelMarkBackCol) ; } else if ( nStat == GDB_ST_SEL) { bStdCol = false ; Color colSelSurf = ( ( GetScene() != nullptr) ? GetScene()->GetSelSurf() : Color( 255, 255, 192)) ; colSelSurf.SetAlpha( nAlpha) ; colSelSurf.GetFloat( fSelMarkCol) ; Color colSelSurfBack = GetSurfBackColor( colSelSurf) ; colSelSurfBack.SetAlpha( nAlpha) ; colSelSurfBack.GetFloat( fSelMarkBackCol) ; } } // determino se devo scurire il colore wireframe bool bDark = false ; if ( bStdCol && bSurf && ! bSurfSha) { Color colBT, colBB ; m_pScene->GetBackground( colBT, colBB) ; int nColMid = ( colBT.GetIntIntensity() + colBB.GetIntIntensity()) / 2 ; bDark = ( nColMid > 127) ; } // ciclo di disegno bool bStartA = false ; bool bLineStipple = false ; for ( const auto& Oga : m_ogaVect) { switch ( Oga.m_nType) { case OgAtom::START : glBegin( Oga.m_nMode) ; bStartA = false ; break ; case OgAtom::START_A : if ( bShowAux) glBegin( Oga.m_nMode) ; bStartA = true ; break ; case OgAtom::END : if ( ! bStartA || bShowAux) glEnd() ; bStartA = false ; break ; case OgAtom::VERT : if ( ! bStartA || bShowAux) glVertex3fv( Oga.m_fVal) ; break ; case OgAtom::BND_FLAG : if ( ! bStartA || bShowAux) glEdgeFlag( Oga.m_nFlag) ; break ; case OgAtom::NORMAL : if ( ! bStartA || bShowAux) glNormal3fv( Oga.m_fVal) ; break ; case OgAtom::COLOR : glColor4fv( ( bStdCol ? AdjustColor( Oga.m_fVal, bDark) : fSelMarkCol)) ; break ; case OgAtom::MAT_A : glMaterialfv( GL_FRONT, GL_AMBIENT, ( bStdCol ? Oga.m_fVal : fSelMarkCol)) ; break ; case OgAtom::MAT_D : glMaterialfv( GL_FRONT, GL_DIFFUSE, ( bStdCol ? Oga.m_fVal : fSelMarkCol)) ; break ; case OgAtom::MAT_S : glMaterialfv( GL_FRONT, GL_SPECULAR, ( bStdCol ? Oga.m_fVal : fSelMarkCol)) ; break ; case OgAtom::MAT_SH : glMaterialf( GL_FRONT, GL_SHININESS, Oga.m_fVal[0]) ; break ; case OgAtom::MAT_B : glMaterialfv( GL_BACK, GL_AMBIENT_AND_DIFFUSE, ( bStdCol ? Oga.m_fVal : fSelMarkBackCol)) ; break ; case OgAtom::LINE_STIPPLE : if ( Oga.m_nMode > 0) { bLineStipple = true ; glLineStipple( Clamp( Oga.m_nFactor, 1, 256), Clamp( Oga.m_nPattern, 0, 65535)) ; glEnable( GL_LINE_STIPPLE) ; } else { bLineStipple = false ; glDisable( GL_LINE_STIPPLE) ; } break ; } } if ( bLineStipple) { bLineStipple = false ; glDisable( GL_LINE_STIPPLE) ; } // se marcato e non superficie in shading, disegno halo if ( nMark == GDB_MK_ON && ! bSurfSha) { // cambio test di depth per non sovrascrivere il disegno appena fatto glDepthFunc( GL_LESS) ; // dimensioni per halo glPointSize( (float) m_pScene->GetMarkPointSize()) ; glLineWidth( (float) m_pScene->GetMarkLineWidth()) ; // colore di marcatura Color colMark = ( ( GetScene() != nullptr) ? GetScene()->GetMark() : Color( 192, 192, 0)) ; glColor4f( colMark.GetRed(), colMark.GetGreen(), colMark.GetBlue(), colMark.GetAlpha()) ; // ciclo di disegno bool bStartA = false ; bool bLineStipple = false ; for ( const auto& Oga : m_ogaVect) { switch ( Oga.m_nType) { case OgAtom::START : glBegin( Oga.m_nMode) ; bStartA = false ; break ; case OgAtom::START_A : if ( bShowAux) glBegin( Oga.m_nMode) ; bStartA = true ; break ; case OgAtom::END : if ( ! bStartA || bShowAux) glEnd() ; bStartA = false ; break ; case OgAtom::VERT : if ( ! bStartA || bShowAux) glVertex3fv( Oga.m_fVal) ; break ; case OgAtom::BND_FLAG : if ( ! bStartA || bShowAux) glEdgeFlag( Oga.m_nFlag) ; break ; // non si imposta la normale sono solo curve // non si impostano i colori, si usa quello di marcatura case OgAtom::LINE_STIPPLE : if ( Oga.m_nMode > 0) { bLineStipple = true ; glLineStipple( Clamp( Oga.m_nFactor, 1, 256), Clamp( Oga.m_nPattern, 0, 65535)) ; glEnable( GL_LINE_STIPPLE) ; } else { bLineStipple = false ; glDisable( GL_LINE_STIPPLE) ; } break ; } } if ( bLineStipple) { bLineStipple = false ; glDisable( GL_LINE_STIPPLE) ; } // ripristino test di depth glDepthFunc( GL_LEQUAL) ; } // se necessario, ripristino la normale visualizzazione if ( nStat == GDB_ST_SEL || nMark == GDB_MK_ON) { glPointSize( (float) m_pScene->GetPointSize()) ; glLineWidth( (float) m_pScene->GetLineWidth()) ; } return true ; }