domenica 24 febbraio 2013

OpenGL Librerie collegate

OpenGL fornisce un potente set di comandi di rendering primitivo ma potente, tutti i comandi di disegno ad alto livello devono essere tradotti in questi comandi. Inoltre i programmi OpenGL devono sottostare al meccanismo che regola le finestre di sistema. Un certo numero di librerie esistono allo scopo di semplificare il compito di programmazione incluse le seguenti:
La OpenGL Utility Library (GLU) contiene una serie di routine a basso livello che eseguono comandi OpenGL come l'impostazione delle matrici per specificare l'orientamento della prospettiva e la proiezione, esegue la tassellazione dei poligoni e la resa delle superfici. La libreria è fornita come parte dell'implementazione OpenGL. Tutte le routine GLU usano il prefisso glu.
Per ogni sistema operativo a finestra esiste una libreria che estende la funzionalità del sistema a finestra per supportare il rendering OpenGL. Per le macchine che usano il sistema X Window esiste l'estensione OpenGL X Window System (GLX) come aggiunta a OpenGL. Le routine GLX usano il prefisso glX. Per il sistema operativo Windows Microsoft, vi sono le WGL la quale fornisce interfaccia OpenGL. Tutte le routine WGL usano il prefisso wgl.
Open Inventor è un programma ad oggetti basato su OpenGL, il quale fornisce oggetti e metodi per creare applicazioni grafiche a tre dimensioni. E' stato scritto in C++ e fornisce oggetti precostruiti ed eventi già descritti per interagire con essi, si tratta di una applicazione ad alto livello capace di creare ed editare scenari a tre dimensioni, inoltre può salvare oggetti su disco e scambiare dati in vari formati grafici. Open Inventor è separato da OpenGL.

lunedì 11 febbraio 2013

Modellare solidi con OpenGL II

 Seconda parte del programma:
 
GLvoid UccidiFinestraGL(GLvoid)       // Uccide la finestra
{
    if (schermopieno)                                       
    {
        ChangeDisplaySettings(NULL,0);                   
        ShowCursor(TRUE);                               
    }

    if (hRC)                                            // Abbiamo il contesto di rendering
    {
        if (!wglMakeCurrent(NULL,NULL))                   
        {
            MessageBox(NULL,"Rilascio fallito di DC e RC .","ERRORE SHUTDOWN",MB_OK | MB_ICONINFORMATION);
        }

        if (!wglDeleteContext(hRC))                       
        {
            MessageBox(NULL,"Rilascio fallito del contesto di rendering.","ERRORE SHUTDOWN",MB_OK | MB_ICONINFORMATION);
        }
        hRC=NULL;                                        // Imposta RC a NULL
    }

    if (hDC && !ReleaseDC(hWnd,hDC))                    // Possiamo impostare il DC
    {
        MessageBox(NULL,"Rilascio fallito del Dispositivo Contesto.","ERRORE SHUTDOWN",MB_OK | MB_ICONINFORMATION);
        hDC=NULL;                                        // Imposta DC a NULL
    }

    if (hWnd && !DestroyWindow(hWnd))                    // Possiamo distruggere la finestra?
    {
        MessageBox(NULL,"Non riesce a rilasciare hWnd.","ERRORE SHUTDOWN",MB_OK | MB_ICONINFORMATION);
        hWnd=NULL;                                        // Set hWnd To NULL
    }

    if (!UnregisterClass("OpenGL",hInstance))            // Are We Able To Unregister Class
    {
        MessageBox(NULL,"Non riesce a cancellare la classe.","ERRORE SHUTDOWN",MB_OK | MB_ICONINFORMATION);
        hInstance=NULL;                                    // Set hInstance To NULL
    }
}



BOOL CreaFinestraGL(char* titolo, int larghezza, int altezza, int bits, bool schermopienoflag)
{
    GLuint        PixelFormat;           
    WNDCLASS    wc;                       
    DWORD        dwExStyle;               
    DWORD        dwStyle;               
    RECT        WindowRect;               
    WindowRect.left=(long)0;           
    WindowRect.right=(long)larghezza;   
    WindowRect.top=(long)0;               
    WindowRect.bottom=(long)altezza;       

    schermopieno=schermopienoflag;           

    hInstance            = GetModuleHandle(NULL);               
    wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;   
    wc.lpfnWndProc        = (WNDPROC) WndProc;                   
    wc.cbClsExtra        = 0;                                   
    wc.cbWndExtra        = 0;                                   
    wc.hInstance        = hInstance;                           
    wc.hIcon            = LoadIcon(NULL, IDI_WINLOGO);       
    wc.hCursor            = LoadCursor(NULL, IDC_ARROW);           
    wc.hbrBackground    = NULL;                                   
    wc.lpszMenuName        = NULL;                                   
    wc.lpszClassName    = "OpenGL";                               

    if (!RegisterClass(&wc))                                   
    {
        MessageBox(NULL,"Classe Window fallito rilascio.","ERRORE",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                           
    }
   
    if (schermopieno)                                                // Prova schermopieno?
    {
        DEVMODE dmScreenSettings;                                // Modalità del dispositivo
        memset(&dmScreenSettings,0,sizeof(dmScreenSettings));   
        dmScreenSettings.dmSize=sizeof(dmScreenSettings);       
        dmScreenSettings.dmPelsWidth    = larghezza;           
        dmScreenSettings.dmPelsHeight    = altezza;               
        dmScreenSettings.dmBitsPerPel    = bits;                   
        dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

        // Try To Set Selected Mode And Get Results.  NOTE: CDS_schermopieno Gets Rid Of Start Bar.
        if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
        {
            // If The Mode Fails, Offer Two Options.  Quit Or Use Windowed Mode.
            if (MessageBox(NULL,"La scheda video non supporta modalita' a pieno schermo. Usare modalita' finestra?","Open GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
            {
                schermopieno=FALSE;        // Windowed Mode Selected.  schermopieno = FALSE
            }
            else
            {
                // Pop Up A Message Box Letting User Know The Program Is Closing.
                MessageBox(NULL,"Programa chiudera' ora.","ERRORE",MB_OK|MB_ICONSTOP);
                return FALSE;                                    // Return FALSE
            }
        }
    }

    if (schermopieno)                                                // Siamo ancora a pieno schermo?
    {
        dwExStyle=WS_EX_APPWINDOW;                               
        dwStyle=WS_POPUP;                                        // Stile finestra
        ShowCursor(FALSE);                                       
    }
    else
    {
        dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;            // Stile finestra estesa
        dwStyle=WS_OVERLAPPEDWINDOW;                           
    }

    AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);       

    // Crea la finestra
    if (!(hWnd=CreateWindowEx(    dwExStyle,                           
                                "OpenGL",                           
                                titolo,                               
                                dwStyle |                           
                                WS_CLIPSIBLINGS |                   
                                WS_CLIPCHILDREN,                   
                                0, 0,                               
                                WindowRect.right-WindowRect.left,   
                                WindowRect.bottom-WindowRect.top,   
                                NULL,                               
                                NULL,                                // No Menu
                                hInstance,                            // Instanza
                                NULL)))                                //
    {
        UccidiFinestraGL();                                // Resetta lo schermo
        MessageBox(NULL,"Errore creazione finestra.","ERRORE",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                // Ritorna FALSE
    }

    static    PIXELFORMATDESCRIPTOR pfd=                    {
        sizeof(PIXELFORMATDESCRIPTOR),           
        1,                                           
        PFD_DRAW_TO_WINDOW |                       
        PFD_SUPPORT_OPENGL |                       
        PFD_DOUBLEBUFFER,                       
        PFD_TYPE_RGBA,                               
        bits,                                       
        0, 0, 0, 0, 0, 0,                           
        0,                                           
        0,                                           
        0,                                           
        0, 0, 0, 0,                                   
        16,                                             
        0,                                           
        0,                                       
        PFD_MAIN_PLANE,                           
        0,0, 0, 0                                       
    };
   
    if (!(hDC=GetDC(hWnd)))                            // Abbiamo contesto del dispositivo?
    {
        UccidiFinestraGL();                               
        MessageBox(NULL,"Non crea un dispositivo di Contento GL.","ERRORE",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                               
    }

    if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))   
    {
        UccidiFinestraGL();                           
        MessageBox(NULL,"Non trova un Formato Pixel.","ERRORE",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                               
    }

    if(!SetPixelFormat(hDC,PixelFormat,&pfd))        // Possiamo impostare il formato pixel?
    {
        UccidiFinestraGL();                           
        MessageBox(NULL,"Non riesce ad impostare un Formato Pixel.","ERRORE",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                               
    }

    if (!(hRC=wglCreateContext(hDC)))               
    {
        UccidiFinestraGL();                               
        MessageBox(NULL,"Non riesce a creare un Contesto GL.","ERRORE",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                           
    }

    if(!wglMakeCurrent(hDC,hRC))                   
    {
        UccidiFinestraGL();                               
        MessageBox(NULL,"Non attiva un Contesto di rendering GL.","ERRORE",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                               
    }

    ShowWindow(hWnd,SW_SHOW);                       
    SetForegroundWindow(hWnd);                       
    SetFocus(hWnd);                                   
    RidimensioneScenaGL(larghezza, altezza);                   

    if (!InizGL())                                   
    {
        UccidiFinestraGL();                           
        MessageBox(NULL,"Inizializzazione fallita.","ERRORE",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                // Restituisci FALSO
    }

    return TRUE;                                    // Successo
}

LRESULT CALLBACK WndProc(    HWND    hWnd,           
                            UINT    uMsg,           
                            WPARAM    wParam,           
                            LPARAM    lParam)           
{
    switch (uMsg)                                    // Controlla i messaggi
    {
        case WM_ACTIVATE:                           
        {
            if (!HIWORD(wParam))                   
            {
                attivo=TRUE;                        // Programma attivo
            }
            else
            {
                attivo=FALSE;                        // Program non più attivo
            }

            return 0;                               
        }

        case WM_SYSCOMMAND:                            // Intercetta Comandi di sistema
        {
            switch (wParam)                           
            {
                case SC_SCREENSAVE:                   
                case SC_MONITORPOWER:               
                return 0;                           
            }
            break;                                    // Uscita
        }

        case WM_CLOSE:                               
        {
            PostQuitMessage(0);                       
            return 0;                               
        }

        case WM_KEYDOWN:                           
        {
            tasti[wParam] = TRUE;                   
            return 0;                               
        }
       
        case WM_KEYUP:                               
        {
            tasti[wParam] = FALSE;                   
            return 0;                           
        }

        case WM_SIZE:                                // Ridimensiona finestra OpenGL
        {
            RidimensioneScenaGL(LOWORD(lParam),HIWORD(lParam)); 
            return 0;                               
        }
    }

    // Passa i messaggi non gestiti DefWindowProc
    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

int WINAPI WinMain(    HINSTANCE    hInstance,            // Instance
                    HINSTANCE    hPrevInstance,        // Previous Instance
                    LPSTR        lpCmdLine,            // Command Line Parameters
                    int            nCmdShow)            // Window Show State
{
    MSG        msg;                                    // Windows Message Structure
    BOOL    fatto=FALSE;                                // Bool Variable To Exit Loop

    // Chiede all'utente quale modlità schermo preferisce
    if (MessageBox(NULL,"Vuoi eseguire modalita' a pieno schermo?", "Pieno Schermo?",MB_YESNO|MB_ICONQUESTION)==IDNO)
    {
        schermopieno=FALSE;                            // Modalità finestra
    }

    // Crea la finestra OpenGL
    if (!CreaFinestraGL("Tutorial Oggetti Solidi",800,600,16,schermopieno))
    {
        return 0;                                    // Quit se la finestra non viene creata
    }

    while(!fatto)                                    // Loop del programma
    {
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))   
        {
            if (msg.message==WM_QUIT)               
            {
                fatto=TRUE;                       
            }
            else                                   
            {
                TranslateMessage(&msg);               
                DispatchMessage(&msg);               
            }
        }
        else                                        // Se non ci sono messaggi
        {
            // Disegna la scena.  E controlla ESC e DisegnaScenaGL()
            if ((attivo && !DisegnaScenaGL()) || tasti[VK_ESCAPE])   
            {
                fatto=TRUE;                            // ESC o DisegnaScenaGL Segnala Quit
            }
            else                                   
            {
                SwapBuffers(hDC);                    // Swap Buffers (Doppio buffer)
            }

            if (tasti[VK_F1])                       
            {
                tasti[VK_F1]=FALSE;               
                UccidiFinestraGL();                       
                schermopieno=!schermopieno;                // Toggle schermopieno / modalità finestra
                // Ricrea la finestra OpenGL
                if (!CreaFinestraGL("Tutorial oggetti solidi",800,600,32,schermopieno))
                {
                    return 0;                        // Esce dal progrmma se la finestra non viene creata
                }
            }
        }
    }

    // Spegnimento
    UccidiFinestraGL();                                    // Cancella la finstra
    return (msg.wParam);                            // Esce dal programma
}

domenica 10 febbraio 2013

Modellare solidi con OpenGL I

Il seguente programma consente di modellare solidi utilizzando le OpenGL, e ruotarne la posizione nello spazio. Utilizzando la libreria GLEXT e GLU.

#include <windows.h>        // File intestazione necessario
#include <gl\gl.h>           
#include <gl\glu.h>           
#include <gl\glext.h>       

HDC            hDC=NULL;        // GDI privato
HGLRC        hRC=NULL;        // Contesto di rendering
HWND        hWnd=NULL;        // Gestisce la finestra
HINSTANCE    hInstance;        // Gestisce istanza

bool    tasti[256];            // Vettore per le routine tastiera
bool    attivo=TRUE;        // Flag per la finestra attiva
bool    schermopieno=TRUE;    // Flag per lo schermopieno

GLfloat    rtri;                // Angolo per i triangoli
GLfloat    rquad;                // Angolo per i quadrati

LRESULT    CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);    // Dichiarazione di WndProc

GLvoid RidimensioneScenaGL(GLsizei larghezza, GLsizei altezza)        // Ridimensiona ed inizializza GL Window
{
    if (altezza==0)                                        // Previene divisione per 0
    {
        altezza=1;                                       
    }

    glViewport(0,0,larghezza,altezza);                        // Reset dello schermo corrente

    glMatrixMode(GL_PROJECTION);                        // Seleziona la matrice di proiezione
    glLoadIdentity();                                    // Azzera la finestra Matrice

    // Calcola l'aspetto della finstra e le sue dimensioni
    gluPerspective(100.0f,(GLfloat)larghezza/(GLfloat)altezza,0.1f,100.0f);

    glMatrixMode(GL_MODELVIEW);                            // Seleziona la matrice del Modelview
    glLoadIdentity();                                   
}

int InizGL(GLvoid)                                        // Impostazioni per OpenGL
{
    glShadeModel(GL_SMOOTH);                            // Abilita ombreggiatura
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);                // Schermo a sfondo nero
    glClearDepth(1.0f);                                   
    glEnable(GL_DEPTH_TEST);                           
    glDepthFunc(GL_LEQUAL);                               
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);   
    return TRUE;                                        // Inizializzazione OK
}

int DisegnaScenaGL(GLvoid)                                    // Qui vi sono le istruzioni di disegno
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   
    glLoadIdentity();                                   
    glTranslatef(-1.5f,0.0f,-6.0f);                       
    glRotatef(rtri,0.0f,1.0f,0.0f);                       
    glBegin(GL_TRIANGLES);                               
        glColor3f(1.0f,0.0f,0.0f);                       
        glVertex3f( 0.0f, 1.0f, 0.0f);                   
        glColor3f(0.0f,1.0f,0.0f);                       
        glVertex3f(-1.0f,-1.0f, 1.0f);                   
        glColor3f(0.0f,0.0f,1.0f);                       
        glVertex3f( 1.0f,-1.0f, 1.0f);                   
        glColor3f(1.0f,0.0f,0.0f);                       
        glVertex3f( 0.0f, 1.0f, 0.0f);                   
        glColor3f(0.0f,0.0f,1.0f);                       
        glVertex3f( 1.0f,-1.0f, 1.0f);                   
        glColor3f(0.0f,1.0f,0.0f);                       
        glVertex3f( 1.0f,-1.0f, -1.0f);                   
        glColor3f(1.0f,0.0f,0.0f);                       
        glVertex3f( 0.0f, 1.0f, 0.0f);                   
        glColor3f(0.0f,1.0f,0.0f);                       
        glVertex3f( 1.0f,-1.0f, -1.0f);                   
        glColor3f(0.0f,0.0f,1.0f);                       
        glVertex3f(-1.0f,-1.0f, -1.0f);                   
        glColor3f(1.0f,0.0f,0.0f);                       
        glVertex3f( 0.0f, 1.0f, 0.0f);                   
        glColor3f(0.0f,0.0f,1.0f);                       
        glVertex3f(-1.0f,-1.0f,-1.0f);                   
        glColor3f(0.0f,1.0f,0.0f);                       
        glVertex3f(-1.0f,-1.0f, 1.0f);                   
    glEnd();                                            // Disegno della Piramide

    glLoadIdentity();                                   
    glTranslatef(1.5f,0.0f,-6.0f);                       
    glRotatef(rquad,1.0f,1.0f,1.0f);                   
    glBegin(GL_QUADS);                                           
        glColor3f(0.0f,1.0f,0.0f);                       
        glVertex3f( 1.0f, 1.0f,-1.0f);                   
        glVertex3f(-1.0f, 1.0f,-1.0f);                   
        glVertex3f(-1.0f, 1.0f, 1.0f);                   
        glVertex3f( 1.0f, 1.0f, 1.0f);                   
        glColor3f(1.0f,0.5f,0.0f);                       
        glVertex3f( 1.0f,-1.0f, 1.0f);                   
        glVertex3f(-1.0f,-1.0f, 1.0f);                   
        glVertex3f(-1.0f,-1.0f,-1.0f);                   
        glVertex3f( 1.0f,-1.0f,-1.0f);                   
        glColor3f(1.0f,0.0f,0.0f);                       
        glVertex3f( 1.0f, 1.0f, 1.0f);                   
        glVertex3f(-1.0f, 1.0f, 1.0f);                   
        glVertex3f(-1.0f,-1.0f, 1.0f);                   
        glVertex3f( 1.0f,-1.0f, 1.0f);                   
        glColor3f(1.0f,1.0f,0.0f);                       
        glVertex3f( 1.0f,-1.0f,-1.0f);                   
        glVertex3f(-1.0f,-1.0f,-1.0f);                   
        glVertex3f(-1.0f, 1.0f,-1.0f);                   
        glVertex3f( 1.0f, 1.0f,-1.0f);                   
        glColor3f(0.0f,0.0f,1.0f);                       
        glVertex3f(-1.0f, 1.0f, 1.0f);                   
        glVertex3f(-1.0f, 1.0f,-1.0f);                   
        glVertex3f(-1.0f,-1.0f,-1.0f);                   
        glVertex3f(-1.0f,-1.0f, 1.0f);                   
        glColor3f(1.0f,0.0f,1.0f);                       
        glVertex3f( 1.0f, 1.0f,-1.0f);                   
        glVertex3f( 1.0f, 1.0f, 1.0f);                   
        glVertex3f( 1.0f,-1.0f, 1.0f);                   
        glVertex3f( 1.0f,-1.0f,-1.0f);                    // Disegno del cubo
           
    glEnd();
                                               
glLoadIdentity();                                   
    glTranslatef(5.5f,0.0f,-8.0f);                       
    glRotatef(rquad*2,1.0f,0.0f,0.0f);                   
    glBegin(GL_QUADS);                                           
        glColor3f(0.0f,1.0f,0.0f);                       
        glVertex3f( 1.0f, 2.0f,-1.0f);                   
        glVertex3f(-1.0f, 2.0f,-1.0f);                   
        glVertex3f(-1.0f, 2.0f, 1.0f);                   
        glVertex3f( 1.0f, 2.0f, 1.0f);                   
        glColor3f(1.0f,0.5f,0.0f);                       
        glVertex3f( 1.0f,-1.0f, 1.0f);                   
        glVertex3f(-1.0f,-1.0f, 1.0f);                   
        glVertex3f(-1.0f,-1.0f,-1.0f);                   
        glVertex3f( 1.0f,-1.0f,-1.0f);                   
        glColor3f(1.0f,0.0f,0.0f);                       
        glVertex3f( 1.0f, 2.0f, 1.0f);                   
        glVertex3f(-1.0f, 2.0f, 1.0f );                   
        glVertex3f(-1.0f,-1.0f, 1.0f );                   
        glVertex3f( 1.0f,-1.0f, 1.0f );                   
        glColor3f(1.0f,1.0f,0.0f);                       
        glVertex3f( 1.0f,-1.0f,-1.0f );                   
        glVertex3f(-1.0f,-1.0f,-1.0f);                   
        glVertex3f(-1.0f, 2.0f,-1.0f);                   
        glVertex3f( 1.0f, 2.0f,-1.0f);                   
        glColor3f(0.0f,0.0f,1.0f);                       
        glVertex3f(-1.0f, 2.0f, 1.0f);                   
        glVertex3f(-1.0f, 2.0f,-1.0f);                   
        glVertex3f(-1.0f,-1.0f,-1.0f);                   
        glVertex3f(-1.0f,-1.0f, 1.0f);                   
        glColor3f(1.0f,0.0f,1.0f);                   
        glVertex3f( 1.0f, 2.0f,-1.0f);                   
        glVertex3f( 1.0f, 2.0f, 1.0f);                   
        glVertex3f( 1.0f,-1.0f, 1.0f);                   
        glVertex3f( 1.0f,-1.0f,-1.0f);                    // Disegno della scatola
           
    glEnd();                        
    rtri+=0.2f;                                            // Aumenta la rotazione per il triangolo
    rquad-=0.15f;                                        // Diminuisce la rotazione per il quadrato
    return TRUE;                                        // Continua...
}