//---------------------------------------------------------------------------- // 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/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 ; //--------------------------- Structs ---------------------------------------- struct Vert3f { GLfloat x ; GLfloat y ; GLfloat z ; } ; #define SET_VERT3F( P, X, Y, Z) {P.x=X;P.y=Y;P.z=Z;} //---------------------------------------------------------------------------- EGrScene::EGrScene( void) { // 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::CreateContext( HDC hDC, int nDriver, bool bDouBuff, int nColorBits, int nDepthBits) { // verifico validità Device Context if ( hDC == nullptr) return false ; m_hDC = hDC ; // assegno formato pixel PIXELFORMATDESCRIPTOR pfd ; memset( &pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)) ; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR) ; pfd.nVersion = 1 ; pfd.dwFlags = ( bDouBuff ? 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, bDouBuff, 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) { AfxMessageBox( _T("WGLEW is not initialized!")) ; } int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 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; } // verifico validità Rendering Context if ( m_hRC == nullptr) return false ; GLenum GlewInitResult ; glewExperimental = GL_TRUE ; GlewInitResult = glewInit() ; if ( GlewInitResult != GLEW_OK) { AfxMessageBox( _T("GLEW is not initialized!")) ; } // verifico se posso lavorare in modalità nuova m_bNewWay = ( glewIsSupported( "GL_VERSION_3_0") == 1) ; return true ; } //---------------------------------------------------------------------------- int EGrScene::ChooseGenPixelFormat( int nPfd, bool bDouBuff, 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) && ( ! bDouBuff || 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" ; 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" ; 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" ; 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 ; } // 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) ; // 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) ; GLenum nErr = glGetError() ; // 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) ; nErr = glGetError() ; return true ; } //---------------------------------------------------------------------------- bool EGrScene::Draw( void) { // imposto if ( ! Prepare()) return false ; // cancello glClear( GL_COLOR_BUFFER_BIT) ; // disegno 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]) ; } } // aggiorno glFlush() ; // scambio i buffer back e front (se previsti) SwapBuffers( m_hDC) ; 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 size_t nSizeV3f = sizeof( Vert3f) ; Vert3f Point[4] ; SET_VERT3F( Point[0], -0.5f, -0.5f, 0.0f) SET_VERT3F( Point[1], -0.5f, 0.5f, 0.0f) SET_VERT3F( Point[2], 0.5f, 0.5f, 0.0f) SET_VERT3F( Point[3], 0.5f, -0.5f, 0.0f) // 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) ; // inizializzo VAOs a non allocati for ( int i = 0 ; i < NUM_VAO ; ++ i) m_vaoID[i] = 0 ; if ( m_bNewWay) { // 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 * nSizeV3f, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * nSizeV3f, nSizeV3f, &Point[0]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * nSizeV3f, nSizeV3f, &Point[1]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * nSizeV3f, nSizeV3f, &Point[2]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * nSizeV3f, nSizeV3f, &Point[3]) ; glBufferSubData( GL_ARRAY_BUFFER, 4 * nSizeV3f, nSizeV3f, &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 size_t nSizeV3f = sizeof( Vert3f) ; Vert3f Point[8] ; SET_VERT3F( Point[0], -0.5f, -0.5f, 0.0f) SET_VERT3F( Point[1], -0.5f, 0.5f, 0.0f) SET_VERT3F( Point[2], 0.5f, 0.5f, 0.0f) SET_VERT3F( Point[3], 0.5f, -0.5f, 0.0f) SET_VERT3F( Point[4], -0.5f, -0.5f, 1.0f) SET_VERT3F( Point[5], -0.5f, 0.5f, 1.0f) SET_VERT3F( Point[6], 0.5f, 0.5f, 1.0f) SET_VERT3F( Point[7], 0.5f, -0.5f, 1.0f) // 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) ; // inizializzo VAOs a non allocati for ( int i = 0 ; i < NUM_VAO ; ++ i) m_vaoID[i] = 0 ; if ( m_bNewWay) { // 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 * nSizeV3f, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * nSizeV3f, nSizeV3f, &Point[0]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * nSizeV3f, nSizeV3f, &Point[1]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * nSizeV3f, nSizeV3f, &Point[2]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * nSizeV3f, nSizeV3f, &Point[3]) ; glBufferSubData( GL_ARRAY_BUFFER, 4 * nSizeV3f, nSizeV3f, &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 * nSizeV3f, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * nSizeV3f, nSizeV3f, &Point[4]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * nSizeV3f, nSizeV3f, &Point[5]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * nSizeV3f, nSizeV3f, &Point[6]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * nSizeV3f, nSizeV3f, &Point[7]) ; glBufferSubData( GL_ARRAY_BUFFER, 4 * nSizeV3f, nSizeV3f, &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 * nSizeV3f, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * nSizeV3f, nSizeV3f, &Point[0]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * nSizeV3f, nSizeV3f, &Point[4]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * nSizeV3f, nSizeV3f, &Point[1]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * nSizeV3f, nSizeV3f, &Point[5]) ; glBufferSubData( GL_ARRAY_BUFFER, 4 * nSizeV3f, nSizeV3f, &Point[2]) ; glBufferSubData( GL_ARRAY_BUFFER, 5 * nSizeV3f, nSizeV3f, &Point[6]) ; glBufferSubData( GL_ARRAY_BUFFER, 6 * nSizeV3f, nSizeV3f, &Point[3]) ; glBufferSubData( GL_ARRAY_BUFFER, 7 * nSizeV3f, nSizeV3f, &Point[7]) ; glVertexAttribPointer( (GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0) ; glEnableVertexAttribArray( 0) ; glBindVertexArray( 0) ; } } //---------------------------------------------------------------------------- void EGrScene::SetTriangle( void) { if ( ! MakeCurrent()) return ; // vertici size_t nSizeV3f = sizeof( Vert3f) ; Vert3f Point[6] ; SET_VERT3F( Point[0], -0.3f, 0.5f, -1.0f) SET_VERT3F( Point[1], -0.8f, -0.5f, -1.0f) SET_VERT3F( Point[2], 0.2f, -0.5f, -1.0f) SET_VERT3F( Point[3], -0.2f, 0.5f, -1.0f) SET_VERT3F( Point[4], 0.3f, -0.5f, -1.0f) SET_VERT3F( Point[5], 0.8f, 0.5f, -1.0f) // 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) ; // inizializzo VAOs a non allocati for ( int i = 0 ; i < NUM_VAO ; ++ i) m_vaoID[i] = 0 ; if ( m_bNewWay) { // 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 * nSizeV3f, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * nSizeV3f, nSizeV3f, &Point[0]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * nSizeV3f, nSizeV3f, &Point[1]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * nSizeV3f, nSizeV3f, &Point[2]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * nSizeV3f, nSizeV3f, &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 * nSizeV3f, NULL, GL_STATIC_DRAW) ; glBufferSubData( GL_ARRAY_BUFFER, 0 * nSizeV3f, nSizeV3f, &Point[3]) ; glBufferSubData( GL_ARRAY_BUFFER, 1 * nSizeV3f, nSizeV3f, &Point[4]) ; glBufferSubData( GL_ARRAY_BUFFER, 2 * nSizeV3f, nSizeV3f, &Point[5]) ; glBufferSubData( GL_ARRAY_BUFFER, 3 * nSizeV3f, nSizeV3f, &Point[3]) ; glVertexAttribPointer( (GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0) ; glEnableVertexAttribArray( 0) ; glBindVertexArray( 0) ; } } //---------------------------------------------------------------------------- void EGrScene::ResetData( void) { if ( m_bNewWay && MakeCurrent()) { glBindBuffer( GL_ARRAY_BUFFER, 0) ; glDeleteBuffers( NUM_VAO, m_vboID) ; glBindVertexArray( 0) ; glDeleteVertexArrays( NUM_VAO, m_vaoID) ; } }