//---------------------------------------------------------------------------- // EgalTech 2013-2014 //---------------------------------------------------------------------------- // File : Scene.cpp Data : 03.02.14 Versione : 1.5b1 // Contenuto : Implementazione della classe gestione scena. // // // // Modifiche : 29.01.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "EGrScene.h" #include "/EgtDev/Include/EgtILogger.h" #include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EGkFrame3d.h" using namespace std ; //--------------------------- Constants -------------------------------------- static const double MIN_DIST_CAMERA = 10 ; static const double STD_DIST_CAMERA = 1000 ; static const double MIN_EXTENSION = 50 ; //---------------------------------------------------------------------------- EGrScene::EGrScene( void) { m_pLogger = nullptr ; // Context data m_hDC = nullptr ; m_hRC = nullptr ; memset( &m_wglewc, 0, sizeof( WGLEWContext)) ; memset( &m_glewc, 0, sizeof( GLEWContext)) ; m_bNewWay = false ; // Geom data SetExtension( BBox3d( -MIN_EXTENSION, -MIN_EXTENSION, -MIN_EXTENSION, MIN_EXTENSION, MIN_EXTENSION, MIN_EXTENSION)) ; // Viewport m_nViewportW = 0 ; m_nViewportH = 0 ; // View data m_ptCenter = ORIG ; SetCamera( 0, 0, 0) ; } //---------------------------------------------------------------------------- EGrScene::~EGrScene( void) { } //---------------------------------------------------------------------------- bool EGrScene::Init( ILogger* pLogger) { m_pLogger = pLogger ; return true ; } //---------------------------------------------------------------------------- bool EGrScene::CreateContext( HDC hDC, int nDriver, bool b2Buff, int nColorBits, int nDepthBits) { // verifico validità Device Context if ( hDC == nullptr) return false ; m_hDC = hDC ; // riporto nei limiti il tipo di driver if ( nDriver < OD_SOFT) nDriver = OD_SOFT ; else if ( nDriver > OD_NEW) nDriver = OD_NEW ; // assegno formato pixel PIXELFORMATDESCRIPTOR pfd ; memset( &pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)) ; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR) ; pfd.nVersion = 1 ; pfd.dwFlags = ( b2Buff ? PFD_DOUBLEBUFFER : 0) | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW ; pfd.iPixelType = PFD_TYPE_RGBA ; pfd.cColorBits = nColorBits ; pfd.cDepthBits = nDepthBits ; pfd.iLayerType = PFD_MAIN_PLANE ; int nPixelFormat = ChoosePixelFormat( m_hDC, &pfd) ; if ( nPixelFormat == 0) return false ; if ( nDriver == OD_SOFT) { int nPixFormGen = ChooseGenPixelFormat( nPixelFormat, b2Buff, nColorBits, nDepthBits) ; if ( nPixFormGen != 0) nPixelFormat = nPixFormGen ; } if ( ! SetPixelFormat( m_hDC, nPixelFormat, &pfd)) return false ; HGLRC tempContext = wglCreateContext( m_hDC) ; wglMakeCurrent( m_hDC, tempContext) ; GLenum WglewInitResult ; WglewInitResult = wglewInit() ; if ( WglewInitResult != GLEW_OK) LOG_INFO( m_pLogger, "WGLEW is not initialized !") int attribs[10] ; if ( nDriver == OD_SOFT) { attribs[0] = WGL_CONTEXT_MAJOR_VERSION_ARB ; attribs[1] = 1 ; attribs[2] = WGL_CONTEXT_MINOR_VERSION_ARB ; attribs[3] = 1 ; attribs[4] = 0 ; } else if ( nDriver == OD_OLD) { attribs[0] = WGL_CONTEXT_MAJOR_VERSION_ARB ; attribs[1] = 2 ; attribs[2] = WGL_CONTEXT_MINOR_VERSION_ARB ; attribs[3] = 0 ; attribs[4] = 0 ; } else { attribs[0] = WGL_CONTEXT_MAJOR_VERSION_ARB ; attribs[1] = 3 ; attribs[2] = WGL_CONTEXT_MINOR_VERSION_ARB ; attribs[3] = 0 ; attribs[4] = WGL_CONTEXT_PROFILE_MASK_ARB ; attribs[5] = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ; attribs[6] = 0 ; } if ( wglewIsSupported( "WGL_ARB_create_context") == 1) { m_hRC = wglCreateContextAttribsARB( m_hDC, 0, attribs) ; wglMakeCurrent( m_hDC, NULL) ; wglDeleteContext( tempContext) ; wglMakeCurrent( m_hDC, m_hRC) ; } else { //It's not possible to make a GL 3.x context. Use the old style context (GL 2.1 and before) m_hRC = tempContext ; LOG_INFO( m_pLogger, "WGL_ARB_create_context missing !") } // verifico validità Rendering Context if ( m_hRC == nullptr) return false ; GLenum GlewInitResult ; glewExperimental = GL_TRUE ; GlewInitResult = glewInit() ; if ( GlewInitResult != GLEW_OK) LOG_INFO( m_pLogger, "GLEW is not initialized !") // verifico se posso lavorare in modalità nuova m_bNewWay = ( nDriver == OD_NEW && glewIsSupported( "GL_VERSION_3_0") == 1) ; if ( ! m_bNewWay) LOG_INFO( m_pLogger, "OpenGL old way rendering !") // reset stato di errore di OpenGL glGetError() ; return true ; } //---------------------------------------------------------------------------- int EGrScene::ChooseGenPixelFormat( int nPfd, bool b2Buff, int nColorBits, int nDepthBits) { PIXELFORMATDESCRIPTOR pfdR ; // verifica del pixel format proposto int nTotPfd = DescribePixelFormat( m_hDC, nPfd, sizeof(PIXELFORMATDESCRIPTOR), &pfdR) ; if ( pfdR.dwFlags & PFD_GENERIC_FORMAT && ! ( pfdR.dwFlags & PFD_GENERIC_ACCELERATED)) return nPfd ; // eventuale ricerca di un pixel format soddisfacente int nIOpt = 0 ; int nErrOpt = 1000 ; for ( int nI = 1 ; nI <= nTotPfd ; nI ++) { DescribePixelFormat( m_hDC, nI, sizeof(PIXELFORMATDESCRIPTOR), &pfdR) ; if ( pfdR.dwFlags & PFD_GENERIC_FORMAT && ! (pfdR.dwFlags & PFD_GENERIC_ACCELERATED) && ( ! b2Buff || pfdR.dwFlags & PFD_DOUBLEBUFFER)) { int nErr = abs( nColorBits - pfdR.cColorBits) + abs( nDepthBits - pfdR.cDepthBits) ; if ( nErr < nErrOpt) { nErrOpt = nErr ; nIOpt = nI ; } } } return nIOpt ; } //---------------------------------------------------------------------------- bool EGrScene::MakeCurrent( void) { // se RC della scena non è definito, errore if ( m_hRC == nullptr) return false ; // se RC della scena non è quello corrente, lo imposto HGLRC hRC = wglGetCurrentContext() ; if ( m_hRC != hRC) return ( wglMakeCurrent( m_hDC, m_hRC) != 0) ; return true ; } //---------------------------------------------------------------------------- string EGrScene::GetOpenGLInfo( void) { string sInfo = "OpenGL " ; if ( MakeCurrent()) { const char* p ; if ( ( p = reinterpret_cast ( glGetString( GL_VERSION))) != nullptr) sInfo += p ; sInfo += " " ; if ( ( p = reinterpret_cast ( glGetString( GL_VENDOR))) != nullptr) sInfo += p ; sInfo += " " ; if ( ( p = reinterpret_cast ( glGetString( GL_RENDERER))) != nullptr) sInfo += p ; } else sInfo += "ERROR" ; // reset stato di errore di OpenGL glGetError() ; return sInfo ; } //---------------------------------------------------------------------------- string EGrScene::GetGLSLInfo( void) { string sInfo = "GLSL " ; if ( MakeCurrent()) { const char* p ; if ( ( p = reinterpret_cast ( glGetString( GL_SHADING_LANGUAGE_VERSION))) != nullptr) sInfo += p ; else sInfo += "NONE" ; } else sInfo += "ERROR" ; // reset stato di errore di OpenGL glGetError() ; return sInfo ; } //---------------------------------------------------------------------------- string EGrScene::GetPixelFormatInfo( void) { string sInfo = "PixFmt " ; if ( MakeCurrent()) { int nPixFmt ; PIXELFORMATDESCRIPTOR Pfd ; if ( ( nPixFmt = GetPixelFormat( m_hDC)) > 0 && DescribePixelFormat( m_hDC, nPixFmt, sizeof(PIXELFORMATDESCRIPTOR), &Pfd) > 0) { // indice sInfo += ToString( nPixFmt) ; // tipo di driver if ( ! ( Pfd.dwFlags & PFD_GENERIC_FORMAT)) sInfo += " ICD" ; else if ( Pfd.dwFlags & PFD_GENERIC_ACCELERATED) sInfo += " MCD" ; else sInfo += " GEN" ; // singolo o doppio buffer sInfo += ( ( Pfd.dwFlags & PFD_DOUBLEBUFFER) ? " BUFF2" : " BUFF1") ; // RGBA o COLORINDEX sInfo += ( ( Pfd.iPixelType == PFD_TYPE_RGBA) ? " RGBA" : " CI") ; // color bits sInfo += ToString( Pfd.cColorBits) ; // depth bits sInfo += " Z" + ToString( Pfd.cDepthBits) ; } else sInfo = "NO DESCRIBE" ; } else sInfo += "ERROR" ; // reset stato di errore di OpenGL glGetError() ; return sInfo ; } //---------------------------------------------------------------------------- bool EGrScene::SetCenter( const Point3d& ptCenter) { // assegno il punto m_ptCenter = ptCenter ; // invalido ExtView m_bExtViewOk = false ; // calcolo nuovi dati di Z clipping CalcClippingPlanesFromExtView() ; return true ; } //---------------------------------------------------------------------------- bool EGrScene::SetCamera( double dAngVertDeg, double dAngOrizzDeg, double dDist) { // assegno la direzione e la distanza m_vtDirCamera.FromSpherical( 1, dAngVertDeg, dAngOrizzDeg) ; if ( dDist < EPS_SMALL) m_dDistCamera = STD_DIST_CAMERA ; else m_dDistCamera = __max( dDist, MIN_DIST_CAMERA) ; // invalido Up e ExtView m_bUpOk = false ; m_bExtViewOk = false ; // calcolo nuovi dati di Z clipping CalcClippingPlanesFromExtView() ; return true ; } //---------------------------------------------------------------------------- bool EGrScene::SetCamera( int nDir, double dDist) { const double ANG_VERT_ISOVIEW = 54.73561032 ; double dAngVertDeg ; double dAngOrizzDeg ; switch ( nDir) { case CT_TOP : dAngVertDeg = 0 ; dAngOrizzDeg = 0 ; break ; case CT_FRONT : dAngVertDeg = 90 ; dAngOrizzDeg = -90 ; break ; case CT_RIGHT : dAngVertDeg = 90 ; dAngOrizzDeg = 0 ; break ; case CT_BACK : dAngVertDeg = 90 ; dAngOrizzDeg = 90 ; break ; case CT_LEFT : dAngVertDeg = 90 ; dAngOrizzDeg = 180 ; break ; case CT_BOTTOM : dAngVertDeg = 180 ; dAngOrizzDeg = 0 ; break ; case CT_ISO_SW : dAngVertDeg = ANG_VERT_ISOVIEW ; dAngOrizzDeg = -135 ; break ; case CT_ISO_SE : dAngVertDeg = ANG_VERT_ISOVIEW ; dAngOrizzDeg = -45 ; break ; case CT_ISO_NE : dAngVertDeg = ANG_VERT_ISOVIEW ; dAngOrizzDeg = 45 ; break ; case CT_ISO_NW : dAngVertDeg = ANG_VERT_ISOVIEW ; dAngOrizzDeg = 135 ; break ; default : return false ; break ; } return SetCamera( dAngVertDeg, dAngOrizzDeg, dDist) ; } //---------------------------------------------------------------------------- void EGrScene::GetCamera( double* pdAngVertDeg, double* pdAngOrizzDeg, double* pdDist) { m_vtDirCamera.ToSpherical( nullptr, pdAngVertDeg, pdAngOrizzDeg) ; if ( pdDist != nullptr) *pdDist = m_dDistCamera ; } //---------------------------------------------------------------------------- int EGrScene::GetCameraDir( void) { if ( m_vtDirCamera.IsZplus()) return CT_TOP ; else if ( m_vtDirCamera.IsYminus()) return CT_FRONT ; else if ( m_vtDirCamera.IsXplus()) return CT_RIGHT ; else if ( m_vtDirCamera.IsYplus()) return CT_BACK ; else if ( m_vtDirCamera.IsXminus()) return CT_LEFT ; else if ( m_vtDirCamera.IsZminus()) return CT_BOTTOM ; else if ( AreSameVectorNear( m_vtDirCamera, Vector3d( SQRT1_3, - SQRT1_3, - SQRT1_3))) return CT_ISO_SW ; else if ( AreSameVectorNear( m_vtDirCamera, Vector3d( SQRT1_3, SQRT1_3, - SQRT1_3))) return CT_ISO_SE ; else if ( AreSameVectorNear( m_vtDirCamera, Vector3d( SQRT1_3, SQRT1_3, SQRT1_3))) return CT_ISO_NE ; else if ( AreSameVectorNear( m_vtDirCamera, Vector3d( SQRT1_3, - SQRT1_3, SQRT1_3))) return CT_ISO_NW ; else return CT_NONE ; } //---------------------------------------------------------------------------- bool EGrScene::CalcDirUp( void) { // verifico se il calcolo è necessario if ( m_bUpOk) return true ; // direzione perpendicolare giacente nel piano XY // ( m_vtDirCamera è opposta alla direzione in cui si guarda) Vector3d vtPerpXY = m_vtDirCamera ^ Z_AX ; if ( ! vtPerpXY.Normalize()) { if ( m_vtDirCamera.z < 0) vtPerpXY = X_AX ; else vtPerpXY = - X_AX ; } // direzione Up m_vtUp = vtPerpXY ^ m_vtDirCamera ; m_bUpOk = m_vtUp.Normalize() ; // invalido ExtView m_bExtViewOk = false ; return m_bUpOk ; } //---------------------------------------------------------------------------- bool EGrScene::SetExtension( const BBox3d& b3Ext) { if ( b3Ext.IsEmpty()) return false ; m_b3ExtWorld = b3Ext ; m_bExtViewOk = false ; return true ; } //---------------------------------------------------------------------------- bool EGrScene::CalcExtView( void) { // verifico se il calcolo è necessario if ( m_bExtViewOk && m_bUpOk) return true ; // calcolo direzione camera Up if ( ! CalcDirUp()) return false ; // calcolo il riferimento di vista Frame3d frView ; Vector3d vtZ = m_vtDirCamera ; Vector3d vtY = m_vtUp ; Vector3d vtX = vtY ^ vtZ ; if ( ! frView.Set( m_ptCenter + m_dDistCamera * vtZ, vtX, vtY, vtZ)) return false ; // calcolo l'estensione nel riferimento di vista m_b3ExtView = m_b3ExtWorld ; m_b3ExtView.ToLoc( frView) ; m_bExtViewOk = true ; return m_bExtViewOk ; } //---------------------------------------------------------------------------- bool EGrScene::ZoomAll( void) { // traslo il centro di vista nel centro del box Point3d ptExtCent ; if ( ! m_b3ExtWorld.GetCenter( ptExtCent)) return false ; m_ptCenter = ptExtCent ; m_bExtViewOk = false ; // calcolo nuovi dati di ingombro CalcDimViewFromExtView() ; CalcClippingPlanesFromExtView() ; return true ; } //---------------------------------------------------------------------------- bool EGrScene::ZoomChange( double dCoeff) { const double MIN_COEFF = 0.5 ; const double MAX_COEFF = 2 ; // controllo i limiti if ( dCoeff < MIN_COEFF) dCoeff = MIN_COEFF ; else if ( dCoeff > MAX_COEFF) dCoeff = MAX_COEFF ; // cambio le dimensioni di zoom m_dHalfWidth *= dCoeff ; m_dHalfHeight *= dCoeff ; return true ; } //---------------------------------------------------------------------------- bool EGrScene::CalcDimViewFromExtView( void) { // calcolo estensione nel riferimento di vista if ( ! CalcExtView()) return false ; // recupero gli ingombri Point3d ptMin ; Point3d ptMax ; if ( ! m_b3ExtView.GetMinMax( ptMin, ptMax)) return false ; // ricavo le dimensioni const double COEFF = 1.05 ; double dHalfWidth = COEFF * max( fabs( ptMin.x), fabs( ptMax.x)) ; double dHalfHeight = COEFF * max( fabs( ptMin.y), fabs( ptMax.y)) ; // adatto le dimensioni a quelle della vista return AdjustDimView( dHalfWidth, dHalfHeight) ; } //---------------------------------------------------------------------------- bool EGrScene::AdjustDimView( double dHalfWidth, double dHalfHeight) { // se non assegnate, recupero dimensioni vista if ( m_nViewportW == 0) { HWND hWnd = ::WindowFromDC( m_hDC) ; RECT rect ; if ( ! ::GetClientRect( hWnd, &rect)) return false ; m_nViewportW = rect.right ; m_nViewportH = rect.bottom ; // aggiorno la vista glViewport( 0, 0, m_nViewportW, m_nViewportH) ; // verifico presenza errori GLenum nErr = glGetError() ; if ( nErr != GL_NO_ERROR) { string sOut = "First glViewport OpenGL error " + ToString( (int)nErr) ; LOG_INFO( m_pLogger, sOut.c_str()) } } // adatto il rapporto tra le dimensioni calcolate a quello delle dimensioni della vista double dAspect = m_nViewportH / ( double) m_nViewportW ; if ( dAspect * dHalfWidth > dHalfHeight) { m_dHalfWidth = dHalfWidth ; m_dHalfHeight = dAspect * dHalfWidth ; } else { m_dHalfWidth = dHalfHeight / dAspect ; m_dHalfHeight = dHalfHeight ; } return true ; } //---------------------------------------------------------------------------- bool EGrScene::CalcClippingPlanesFromExtView( void) { // calcolo estensione nel riferimento di vista if ( ! CalcExtView()) return false ; // recupero gli ingombri Point3d ptCenter ; Vector3d vtExtent ; if ( ! m_b3ExtView.GetCenterExtent( ptCenter, vtExtent)) return false ; // ricavo la posizione dei piani di clipping sull'asse Z di vista const double EXP_COEFF = 1.05 ; double dExtent = __max( ( EXP_COEFF * vtExtent.z), MIN_EXTENSION) ; m_dZNear = - ( ptCenter.z + dExtent) ; m_dZFar = - ( ptCenter.z - dExtent) ; return true ; } //---------------------------------------------------------------------------- bool EGrScene::Reshape( int nW, int nH) { if ( ! MakeCurrent()) return true ; // assegno le dimensioni della vista m_nViewportW = nW ; m_nViewportH = nH ; // aggiorno la vista glViewport( 0, 0, m_nViewportW, m_nViewportH) ; // verifico presenza errori GLenum nErr = glGetError() ; if ( nErr != GL_NO_ERROR) { string sOut = "Reshape OpenGL error " + ToString( (int)nErr) ; LOG_INFO( m_pLogger, sOut.c_str()) } // aggiorno AdjustDimView( m_dHalfWidth, m_dHalfHeight) ; // ridisegno return Draw() ; } //---------------------------------------------------------------------------- bool EGrScene::Prepare( void) { // imposto il rendering corrente if ( ! MakeCurrent()) return false ; // imposto il colore dello sfondo glClearColor( 0.1f, 0.1f, 0.5f, 0.0f) ; // eventuale ricalcolo parametri di vista CalcDirUp() ; // imposto matrice di proiezione glMatrixMode( GL_PROJECTION) ; glLoadIdentity() ; glOrtho( - m_dHalfWidth, m_dHalfWidth, - m_dHalfHeight, m_dHalfHeight, m_dZNear, m_dZFar) ; // imposto matrice modello/vista glMatrixMode( GL_MODELVIEW) ; glLoadIdentity() ; Point3d ptCamera = m_ptCenter + m_dDistCamera * m_vtDirCamera ; gluLookAt( ptCamera.x, ptCamera.y, ptCamera.z, m_ptCenter.x, m_ptCenter.y, m_ptCenter.z, m_vtUp.x, m_vtUp.y, m_vtUp.z) ; // verifico presenza errori GLenum nErr = glGetError() ; if ( nErr != GL_NO_ERROR) { string sOut = "Prepare OpenGL error " + ToString( (int)nErr) ; LOG_INFO( m_pLogger, sOut.c_str()) } return true ; } //---------------------------------------------------------------------------- bool EGrScene::Draw( void) { // imposto if ( ! Prepare()) return false ; // cancello glClear( GL_COLOR_BUFFER_BIT) ; // disegno if ( m_bNewWay) { for ( int i = 0 ; i < NUM_VAO ; ++ i) { if ( m_vaoID[i] != 0) { glBindVertexArray( m_vaoID[i]) ; glDrawArrays( m_nMode[i], 0, m_nCount[i]) ; } } } else { for ( int i = 0 ; i < NUM_VAO ; ++ i) { if ( m_nCount[i] != 0) { glBegin( m_nMode[i]) ; for ( int j = 0 ; j < m_nCount[i] ; ++ j) glVertex3f( m_v3fVect[i][j].x, m_v3fVect[i][j].y, m_v3fVect[i][j].z) ; glEnd() ; } } } // aggiorno glFlush() ; // verifico presenza errori GLenum nErr = glGetError() ; if ( nErr != GL_NO_ERROR) { string sOut = "Draw OpenGL error " + ToString( (int)nErr) ; LOG_INFO( m_pLogger, sOut.c_str()) } // scambio i buffer back e front ( eseguita solo se previsti) if ( ! SwapBuffers( m_hDC)) LOG_INFO( m_pLogger, "Draw SwapBuffers error") return true ; } //---------------------------------------------------------------------------- void EGrScene::Destroy( void) { wglMakeCurrent( nullptr, nullptr) ; if ( m_hRC != nullptr) { wglDeleteContext( m_hRC) ; m_hRC = nullptr ; } } //---------------------------------------------------------------------------- void EGrScene::SetData( int nType) { const int SQUARE = 1 ; const int CUBE = 2 ; const int TRIANGLE = 3 ; switch ( nType) { case SQUARE : SetSquare() ; break; case CUBE : SetCube() ; break; case TRIANGLE : default : SetTriangle() ; break; } } //---------------------------------------------------------------------------- void EGrScene::SetSquare( void) { if ( ! MakeCurrent()) return ; // vertici Vert3f Point[4] ; Point[0].Set( -0.5, -0.5, 0.0) ; Point[1].Set( -0.5, 0.5, 0.0) ; Point[2].Set( 0.5, 0.5, 0.0) ; Point[3].Set( 0.5, -0.5, 0.0) ; // dimensioni di ingombro BBox3d b3Ext ; for ( int i = 0 ; i < 4 ; ++ i) b3Ext.Add( Point[i].x, Point[i].y, Point[i].z) ; SetExtension( b3Ext) ; if ( m_bNewWay) { // inizializzo VAOs a non allocati for ( int i = 0 ; i < NUM_VAO ; ++ i) m_vaoID[i] = 0 ; // VAO allocation glGenVertexArrays( 1, &m_vaoID[0]) ; if ( m_vaoID[0] == 0) return ; // First VAO setup glBindVertexArray( m_vaoID[0]) ; glGenBuffers( 1, &m_vboID[0]) ; glBindBuffer( GL_ARRAY_BUFFER, m_vboID[0]) ; m_nMode[0] = GL_LINE_STRIP ; m_nCount[0] = 5 ; glBufferData( GL_ARRAY_BUFFER, 5 * SIZEV3F, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * SIZEV3F, SIZEV3F, &Point[0]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * SIZEV3F, SIZEV3F, &Point[1]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * SIZEV3F, SIZEV3F, &Point[2]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * SIZEV3F, SIZEV3F, &Point[3]) ; glBufferSubData( GL_ARRAY_BUFFER, 4 * SIZEV3F, SIZEV3F, &Point[0]) ; glVertexAttribPointer( (GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0) ; glEnableVertexAttribArray( 0) ; glBindVertexArray( 0) ; } else { } } //---------------------------------------------------------------------------- void EGrScene::SetCube( void) { if ( ! MakeCurrent()) return ; // vertici Vert3f Point[8] ; Point[0].Set( -0.5, -0.5, 0.0) ; Point[1].Set( -0.5, 0.5, 0.0) ; Point[2].Set( 0.5, 0.5, 0.0) ; Point[3].Set( 0.5, -0.5, 0.0) ; Point[4].Set( -0.5, -0.5, 1.0) ; Point[5].Set( -0.5, 0.5, 1.0) ; Point[6].Set( 0.5, 0.5, 1.0) ; Point[7].Set( 0.5, -0.5, 1.0) ; // dimensioni di ingombro BBox3d b3Ext ; for ( int i = 0 ; i < 8 ; ++ i) b3Ext.Add( Point[i].x, Point[i].y, Point[i].z) ; SetExtension( b3Ext) ; if ( m_bNewWay) { // inizializzo VAOs a non allocati for ( int i = 0 ; i < NUM_VAO ; ++ i) m_vaoID[i] = 0 ; // VAO allocation glGenVertexArrays( 3, &m_vaoID[0]) ; if ( m_vaoID[0] == 0) return ; // First VAO setup glBindVertexArray( m_vaoID[0]) ; glGenBuffers( 1, &m_vboID[0]) ; glBindBuffer( GL_ARRAY_BUFFER, m_vboID[0]) ; m_nMode[0] = GL_LINE_STRIP ; m_nCount[0] = 5 ; glBufferData( GL_ARRAY_BUFFER, 5 * SIZEV3F, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * SIZEV3F, SIZEV3F, &Point[0]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * SIZEV3F, SIZEV3F, &Point[1]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * SIZEV3F, SIZEV3F, &Point[2]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * SIZEV3F, SIZEV3F, &Point[3]) ; glBufferSubData( GL_ARRAY_BUFFER, 4 * SIZEV3F, SIZEV3F, &Point[0]) ; glVertexAttribPointer( (GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0) ; glEnableVertexAttribArray( 0) ; glBindVertexArray( 0) ; // Second VAO setup glBindVertexArray( m_vaoID[1]) ; glGenBuffers( 1, &m_vboID[1]) ; glBindBuffer( GL_ARRAY_BUFFER, m_vboID[1]) ; m_nMode[1] = GL_LINE_STRIP ; m_nCount[1] = 5 ; glBufferData( GL_ARRAY_BUFFER, 5 * SIZEV3F, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * SIZEV3F, SIZEV3F, &Point[4]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * SIZEV3F, SIZEV3F, &Point[5]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * SIZEV3F, SIZEV3F, &Point[6]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * SIZEV3F, SIZEV3F, &Point[7]) ; glBufferSubData( GL_ARRAY_BUFFER, 4 * SIZEV3F, SIZEV3F, &Point[4]) ; glVertexAttribPointer( (GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0) ; glEnableVertexAttribArray( 0) ; glBindVertexArray( 0) ; // Third VAO setup glBindVertexArray( m_vaoID[2]) ; glGenBuffers( 1, &m_vboID[2]) ; glBindBuffer( GL_ARRAY_BUFFER, m_vboID[2]) ; m_nMode[2] = GL_LINES ; m_nCount[2] = 8 ; glBufferData( GL_ARRAY_BUFFER, 8 * SIZEV3F, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * SIZEV3F, SIZEV3F, &Point[0]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * SIZEV3F, SIZEV3F, &Point[4]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * SIZEV3F, SIZEV3F, &Point[1]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * SIZEV3F, SIZEV3F, &Point[5]) ; glBufferSubData( GL_ARRAY_BUFFER, 4 * SIZEV3F, SIZEV3F, &Point[2]) ; glBufferSubData( GL_ARRAY_BUFFER, 5 * SIZEV3F, SIZEV3F, &Point[6]) ; glBufferSubData( GL_ARRAY_BUFFER, 6 * SIZEV3F, SIZEV3F, &Point[3]) ; glBufferSubData( GL_ARRAY_BUFFER, 7 * SIZEV3F, SIZEV3F, &Point[7]) ; glVertexAttribPointer( (GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0) ; glEnableVertexAttribArray( 0) ; glBindVertexArray( 0) ; } } //---------------------------------------------------------------------------- void EGrScene::SetTriangle( void) { if ( ! MakeCurrent()) return ; // vertici Vert3f Point[6] ; Point[0].Set( -0.3, 0.5, -1.0) ; Point[1].Set( -0.8, -0.5, -1.0) ; Point[2].Set( 0.2, -0.5, -1.0) ; Point[3].Set( -0.2, 0.5, -1.0) ; Point[4].Set( 0.3, -0.5, -1.0) ; Point[5].Set( 0.8, 0.5, -1.0) ; // dimensioni di ingombro BBox3d b3Ext ; for ( int i = 0 ; i < 6 ; ++ i) b3Ext.Add( Point[i].x, Point[i].y, Point[i].z) ; SetExtension( b3Ext) ; if ( m_bNewWay) { // inizializzo VAOs a non allocati for ( int i = 0 ; i < NUM_VAO ; ++ i) m_vaoID[i] = 0 ; // VAOs allocation glGenVertexArrays( 2, &m_vaoID[0]) ; // First VAO setup glBindVertexArray( m_vaoID[0]) ; glGenBuffers( 1, &m_vboID[0]) ; //VBO allocation glBindBuffer( GL_ARRAY_BUFFER, m_vboID[0]) ; m_nMode[0] = GL_LINE_STRIP ; m_nCount[0] = 4 ; glBufferData( GL_ARRAY_BUFFER, 4 * SIZEV3F, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * SIZEV3F, SIZEV3F, &Point[0]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * SIZEV3F, SIZEV3F, &Point[1]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * SIZEV3F, SIZEV3F, &Point[2]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * SIZEV3F, SIZEV3F, &Point[0]) ; glVertexAttribPointer( (GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0) ; glEnableVertexAttribArray( 0) ; glBindVertexArray( 0) ; // Second VAO setup glBindVertexArray( m_vaoID[1]) ; glGenBuffers( 1, &m_vboID[1]) ; //VBO allocation glBindBuffer( GL_ARRAY_BUFFER, m_vboID[1]) ; m_nMode[1] = GL_LINE_STRIP ; m_nCount[1] = 4 ; glBufferData( GL_ARRAY_BUFFER, 4 * SIZEV3F, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * SIZEV3F, SIZEV3F, &Point[3]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * SIZEV3F, SIZEV3F, &Point[4]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * SIZEV3F, SIZEV3F, &Point[5]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * SIZEV3F, SIZEV3F, &Point[3]) ; glVertexAttribPointer( (GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0) ; glEnableVertexAttribArray( 0) ; glBindVertexArray( 0) ; } else { // First VAO setup m_nMode[0] = GL_LINE_STRIP ; m_nCount[0] = 4 ; m_v3fVect[0].reserve( 4) ; m_v3fVect[0].push_back( Point[0]) ; m_v3fVect[0].push_back( Point[1]) ; m_v3fVect[0].push_back( Point[2]) ; m_v3fVect[0].push_back( Point[0]) ; // Second VAO setup m_nMode[1] = GL_LINE_STRIP ; m_nCount[1] = 4 ; m_v3fVect[1].reserve( 4) ; m_v3fVect[1].push_back( Point[3]) ; m_v3fVect[1].push_back( Point[4]) ; m_v3fVect[1].push_back( Point[5]) ; m_v3fVect[1].push_back( Point[3]) ; // Third VAO null m_nCount[2] = 0 ; } } //---------------------------------------------------------------------------- void EGrScene::ResetData( void) { if ( m_bNewWay) { if ( MakeCurrent()) { glBindBuffer( GL_ARRAY_BUFFER, 0) ; glDeleteBuffers( NUM_VAO, m_vboID) ; glBindVertexArray( 0) ; glDeleteVertexArrays( NUM_VAO, m_vaoID) ; } } else { for ( int i = 0 ; i < NUM_VAO ; ++ i) m_v3fVect[i].clear() ; } }