La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Claudio Rocchini, Visual Computing Group

Presentazioni simili


Presentazione sul tema: "Claudio Rocchini, Visual Computing Group"— Transcript della presentazione:

1 Claudio Rocchini, Visual Computing Group
OpenGL + MFC Claudio Rocchini 12/11/2018 Claudio Rocchini, Visual Computing Group

2 Claudio Rocchini, Visual Computing Group
Introduzione Vedremo come si realizza una applicazione OpenGL in ambiente Windows, utilizzando le Microsoft Foundation Class. 12/11/2018 Claudio Rocchini, Visual Computing Group

3 Claudio Rocchini, Visual Computing Group
MFC Le Microsoft Foundation Class formano la nota libreria di sviluppo di applicazioni per ambiente Windows. Vedremo come siano state realizzate delle opportune chiamate di libreria per l’interfacciamento di OpenGL. 12/11/2018 Claudio Rocchini, Visual Computing Group

4 Claudio Rocchini, Visual Computing Group
OpenGL OpenGL è il famoso standard per la visualizzazione grafica bi e tridimensionale. E’ supportato da tutte le piattaforme. Le schede grafiche di ultima generazione lo implementano in hardware. 12/11/2018 Claudio Rocchini, Visual Computing Group

5 Claudio Rocchini, Visual Computing Group
Cenni su OpenGL (1) Una introduzione ad OpenGL e’ fuori dagli scopi di questa presentazione. Ne evidenzieremo le caratteristiche necessarie all’interfacciamento con il sistema a finestre. 12/11/2018 Claudio Rocchini, Visual Computing Group

6 Claudio Rocchini, Visual Computing Group
Cenni su OpenGL (2) I comandi di OpenGL sottintendono un contesto grafico di default, la seguente serie di comandi visualizza un triangolo: glBegin(GL_TRIANGLES); glVertex3f(0,0,-10); glVertex3f(10,0,-10); glVertex3f(0,10,-10); glEnd(); 12/11/2018 Claudio Rocchini, Visual Computing Group

7 Claudio Rocchini, Visual Computing Group
Cenni su OpenGL (3) In ogni applicazione Windows si puo’ definire un contesto OpenGL corrente che riceve i comandi grafici. Un applicazione multifinestra puo’ alternare vari contesti grafici OpenGL. 12/11/2018 Claudio Rocchini, Visual Computing Group

8 Claudio Rocchini, Visual Computing Group
MFC+OpenGL Una volta costruita una applicazione standard MFC sono necessarie alcune aggiunte per l’utilizzo di OpenGL all’interno di una finestra. 12/11/2018 Claudio Rocchini, Visual Computing Group

9 Claudio Rocchini, Visual Computing Group
Punti principali Scelta del formato pixel. Creazione di un contesto OpenGL (GLRC). Creazione di un Device contest (DC) associato ad una finestra. Collegamento fra GLRC e DC. 12/11/2018 Claudio Rocchini, Visual Computing Group

10 Inclusione file header
Aggiungere nel file header della view: #include <GL\\gl.h> #include <GL\\glu.h> 12/11/2018 Claudio Rocchini, Visual Computing Group

11 Claudio Rocchini, Visual Computing Group
Inclusione librerie File di Libreria aggiuntivi 12/11/2018 Claudio Rocchini, Visual Computing Group

12 Dati aggiuntivi della View
I seguenti dati sono aggiunti alla classe view: CPalette m_cPalette; // Palette Personale CPalette *m_pOldPalette; // Vecchia Palette CClientDC *m_pDC; // DC della finestra HGLRC m_hrc; // Contesto OpenGL 12/11/2018 Claudio Rocchini, Visual Computing Group

13 Dati per multifinestra
In caso di gestione multifinestra e’ necessario aggiunge alla view il seguente: // IL proprietario del contesto GL static CGlwrapperView * m_glOwner; Nel file …view.cpp si dichiara: CGlwrapperView * CGlwrapperView::m_glOwner = 0; 12/11/2018 Claudio Rocchini, Visual Computing Group

14 Inizializzazione variabili
// E’ importante ricordarsi di inizializzare le variabili nel costruttore della classe. CGlwrapperView::CGlwrapperView() { m_pOldPalette = 0; m_pDC = 0; m_hrc = 0; } 12/11/2018 Claudio Rocchini, Visual Computing Group

15 Claudio Rocchini, Visual Computing Group
Funzione di switch inline BOOL SetGL() { if(m_glOwner!=this) { if(!wglMakeCurrent(m_pDC->GetSafeHdc(),m_hrc)) { AfxMessageBox("GlMakeCurrent Error"); return FALSE; } m_glOwner = this; return TRUE; 12/11/2018 Claudio Rocchini, Visual Computing Group

16 Claudio Rocchini, Visual Computing Group
Messaggi e Virtual Attraverso il Class Wizard e’ necessario inserire alcuni gestori di messaggi 12/11/2018 Claudio Rocchini, Visual Computing Group

17 Claudio Rocchini, Visual Computing Group
Gestori necessari I gestori necessari sono: Create PrecreateWindow(*) OnDraw(*) OnSize OnEraseBkgnd OnDestroy (*) Gia’ dichiarati dall’Application Wizard 12/11/2018 Claudio Rocchini, Visual Computing Group

18 Claudio Rocchini, Visual Computing Group
Create (1/5) //Creazione finestra if( !CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext) ) return FALSE; 12/11/2018 Claudio Rocchini, Visual Computing Group

19 Claudio Rocchini, Visual Computing Group
Create (2/5) // Creazione DC (Contesto grafico standard) m_pDC = new CClientDC(this); ASSERT(m_pDC != NULL); // Setta il pixel format e crea la palette if (!SetupPixelFormat(m_pDC)) return FALSE; 12/11/2018 Claudio Rocchini, Visual Computing Group

20 Claudio Rocchini, Visual Computing Group
Create (3/5) // Creazione palette (se necessaria) if( CreateRGBPalette(m_pDC,m_cPalette) ) { m_pOldPalette = m_pD->SelectPalette( &m_cPalette, FALSE); m_pDC->RealizePalette(); } 12/11/2018 Claudio Rocchini, Visual Computing Group

21 Claudio Rocchini, Visual Computing Group
Create (4/5) // Crea e setta il contesto OPENGL m_hrc = wglCreateContext( m_pDC->GetSafeHdc()); if(m_hrc==NULL) { AfxMessageBox("OpenGL contest fail"); return FALSE; } 12/11/2018 Claudio Rocchini, Visual Computing Group

22 Claudio Rocchini, Visual Computing Group
Create (5/5) // Inizializzazioni GL SetGL(); InitGL(); 12/11/2018 Claudio Rocchini, Visual Computing Group

23 Claudio Rocchini, Visual Computing Group
Gestione palette La palette serve solo in caso di schermo a 256 colori(obsoleto). Si realizza tramite le specifiche della Microsoft. Si puo’ scaricare l’implementazione di default dal sito: vcg.iei.pi.cnr.it/˜rocchini/corso.html 12/11/2018 Claudio Rocchini, Visual Computing Group

24 Claudio Rocchini, Visual Computing Group
Pixel Format (1/2) Prima di inizializzare OpenGL e’ necessario settare il tipo di supporto pixel, che comprende: Numero di pixel colore Profondita’ z-buffer Tipo di buffer (singolo/doppio) I settaggi vengono inseriti nella struttura PIXELFORMATDESCRIPTOR. 12/11/2018 Claudio Rocchini, Visual Computing Group

25 Claudio Rocchini, Visual Computing Group
Pixel Format(2/2) // Esempio di codice di richiesta di formato if ( (pixelformat = ChoosePixelFormat(pDC->GetSafeHdc(), &pfd)) == 0 ) { AfxMessageBox("ChoosePixelFormat failed"); return FALSE; } if (SetPixelFormat(pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE) AfxMessageBox("SetPixelFormat failed"); 12/11/2018 Claudio Rocchini, Visual Computing Group

26 Inizializzazioni OpenGL
Le inizializzazioni di OpenGL non fanno parte del sistema di finestre, ma sono state citate perche’ indispensabili per la visualizzazione della finestra OpenGl (per evitare l’effetto “finestra nera”). 12/11/2018 Claudio Rocchini, Visual Computing Group

27 Esempi di settaggi OpenGL
glClearDepth(1.0f); glShadeModel( GL_SMOOTH ); glEnable(GL_DEPTH_TEST); glEnable(GL_COLOR_MATERIAL); glDisable(GL_CULL_FACE); glEnable(GL_LIGHT0); fv4[0]=0.1f; fv4[1]=0.1f; fv4[2]=0.1f; fv4[3]=1.0f; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fv4); glLightfv(GL_LIGHT0, GL_POSITION, fv4); glLightfv(GL_LIGHT0, GL_DIFFUSE, fv4); glEnable(GL_LIGHTING); 12/11/2018 Claudio Rocchini, Visual Computing Group

28 Claudio Rocchini, Visual Computing Group
OnDestroy (1/2) Alla fine dell’utilizzo delle strutture OpenGl e’ importante chiamare le funzioni di rilascio delle risorse. Queste funzioni devono essere chiamate subito prima la distruzione della finestra View. 12/11/2018 Claudio Rocchini, Visual Computing Group

29 Claudio Rocchini, Visual Computing Group
OnDestroy (2/2) void CGlwrapperView::OnDestroy() { SetGL(); glFinish(); wglMakeCurrent(NULL, NULL); if (m_hrc) ::wglDeleteContext(m_hrc); if (m_pOldPalette) m_pDC->SelectPalette(m_pOldPalette, FALSE); if (m_pDC) delete m_pDC; m_glOwner = NULL; CView::OnDestroy(); } 12/11/2018 Claudio Rocchini, Visual Computing Group

30 Claudio Rocchini, Visual Computing Group
PreCreateWindow // Lo stile della finestra deve contenere le seguenti specifiche: BOOL CGlwrapperView::PreCreateWindow( CREATESTRUCT& cs) { cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_OWNDC; return CView::PreCreateWindow(cs); } 12/11/2018 Claudio Rocchini, Visual Computing Group

31 Claudio Rocchini, Visual Computing Group
Erase Background // Questa callback impedisce al sistema di disegnare lo sfondo bianco di defalt: BOOL CGlwrapperView::OnEraseBkgnd(CDC* pDC) { return TRUE; } 12/11/2018 Claudio Rocchini, Visual Computing Group

32 Claudio Rocchini, Visual Computing Group
OnSize (1/3) OnSize e’ chiamata alla creazione della Finestra e ad ogni cambiamento di dimensione. Si deve occupare di comunicare ad OpenGL l’effettiva dimensione della finestra (viewport) Deve settare il tipo di proiezione di visualizzazione (ortogonale/prospettica) 12/11/2018 Claudio Rocchini, Visual Computing Group

33 Claudio Rocchini, Visual Computing Group
OnSize (2/3) void CGlwrapperView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); if(cx!=0 && cy!=0) … gestione dimensione… } 12/11/2018 Claudio Rocchini, Visual Computing Group

34 Claudio Rocchini, Visual Computing Group
OnSize (3/3) const float fNearP = 0.1f; const float fFarP = 20.0f; const float fPAngle = 45.0f; SetGL(); glViewport(0, 0, cx, cy); GLfloat fAspect; if (cy) fAspect = GLfloat(cx)/cy; else fAspect = 1.0f; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(fPAngle, fAspect, fNearP, fFarP); glMatrixMode(GL_MODELVIEW); 12/11/2018 Claudio Rocchini, Visual Computing Group

35 Claudio Rocchini, Visual Computing Group
OnDraw, introduzione OnDraw, finalmente, visualizza effettivamente il contesto OpenGl. Deve contenere il codice utente per la visualizzazione 12/11/2018 Claudio Rocchini, Visual Computing Group

36 OnDraw, sezione critica (1/2)
OpenGL e intrinsecamente asincrono, vale a dire che la visualizzazione continua in parallelo con il programma. E’ possibile che il sistema chiami più volte OnDraw, prima che la visualizzazione sia terminata. 12/11/2018 Claudio Rocchini, Visual Computing Group

37 OnDraw, sezione critica (2/2)
void CGlwrapperView::OnDraw(CDC* pDC) { if(pDC==NULL) return; static BOOL bBusy = FALSE; if(bBusy) return; bBusy = TRUE; … SEZIONE PRINCIPALE… bBusy = FALSE; } 12/11/2018 Claudio Rocchini, Visual Computing Group

38 OnDraw, sezione principale
SetGL(); // Setta il contesto corrente // Cancellazione buffer glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); … COMANDI UTENTE… glFinish(); SwapBuffers(wglGetCurrentDC()); 12/11/2018 Claudio Rocchini, Visual Computing Group

39 Claudio Rocchini, Visual Computing Group
OnDraw Ottimizzata SetGL(); // Setta il contesto corrente glLoadIdentity(); … COMANDI UTENTE… glFinish(); SwapBuffers(wglGetCurrentDC()); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 12/11/2018 Claudio Rocchini, Visual Computing Group

40 Claudio Rocchini, Visual Computing Group
OnDraw, comandi utente Esempio di comandi utente (visualizzazione triangolo): glBegin(GL_TRIANGLES); glVertex3f(0,0,-10); glVertex3f(10,0,-10); glVertex3f(0,10,-10); glEnd(); 12/11/2018 Claudio Rocchini, Visual Computing Group

41 Claudio Rocchini, Visual Computing Group
Applicazione L’applicazione e’ finalmente pronta per essere compilata ed eseguita. 12/11/2018 Claudio Rocchini, Visual Computing Group

42 Un comodo tool: Trackball
Nel sito web del corso e’ possibile scaricare il sorgente del programma, che comprende la classe Trackball per La manipolazione della vista. 12/11/2018 Claudio Rocchini, Visual Computing Group

43 Visualizzazioni animate, intro
La visualizzazione della finestra OpenGl avviene su richiesta del sistema, quando e’ necessario ridisegnarne il contenuto. In alcune applicazioni e’ necessario invece ridisegnare la finestra OpenGL su richiesta dell’applicazione. 12/11/2018 Claudio Rocchini, Visual Computing Group

44 Claudio Rocchini, Visual Computing Group
Animazioni, il Timer Una prima possibilità è quella di usare un timer (classe Ctimer), che periodicamente genera il messaggio WM_TIMER. Il messaggio può essere gestito dall’applicazione per generare animazioni. Questa soluzione non è però efficace; infatti il timer non è affidabile per intervalli inferiori al secondo. 12/11/2018 Claudio Rocchini, Visual Computing Group

45 Claudio Rocchini, Visual Computing Group
Animazioni, OnIdle Una soluzione migliore è l’utilizzo della funzione OnIdle, della classe Applicazione. Tale funzione viene chiamata tutte le volte che il sistema ha finito le sue operazioni. 12/11/2018 Claudio Rocchini, Visual Computing Group

46 Claudio Rocchini, Visual Computing Group
Esercizi Scaricare lo scheletro di applicazione glwrapper, oppure rigenerarlo da zero e: Visualizzare grafici di funzioni da R2 a R. Visualizzare oggetti animati nel tempo, utilizzando Onidle Realizzare una versione di graphedit visualizzata in OpenGL. 12/11/2018 Claudio Rocchini, Visual Computing Group

47 Claudio Rocchini, Visual Computing Group
Contatti Claudio Rocchini Visual Computing Group Istituto Elaborazione Informazione Area della Ricerca di Pisa Tel: 12/11/2018 Claudio Rocchini, Visual Computing Group


Scaricare ppt "Claudio Rocchini, Visual Computing Group"

Presentazioni simili


Annunci Google