Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    [OpenGL] un problema con l'animazione

    ciao!
    devo fare un piccolo programmino in C che usa le API OpenGL per creare un piccolo giochino, il cubo di Rubik (quello colorato che si deve rimettere a posto, avete presente?).
    Voglio che il cubo abbia di default un piccolo movimento oscillatorio attorno al proprio baricentro, e questo l'ho implementato...
    Ma quando voglio che il cubo ruoti di 90 gradi premendo la freccia in alto (ho registrato correttamente la callback che gestisce l'evento con
    codice:
    glutSpecialFunc();
    )
    non succede niente!

  2. #2
    Utente di HTML.it L'avatar di gokan
    Registrato dal
    Feb 2003
    Messaggi
    262
    perchè non provi ad usare glutKeyboardFunc ?
    non dovrebbe essere più semplice?
    http://www.opengl.org/resources/libr...c3/node49.html

  3. #3
    ma glutKeyboardFunc non si usa per i caratteri ascii? io devo gestire la pressione dei tasti freccia...

  4. #4
    Utente di HTML.it L'avatar di gokan
    Registrato dal
    Feb 2003
    Messaggi
    262
    Hai ragione, quindi se usi una cosa simile, mi hai detto che non ti funziona?
    codice:
    void tastiera(int key,int x, int y)
    {
       switch (key) {
       case GLUT_KEY_LEFT:  /*vai a sinistra*/; break;
       case GLUT_KEY_RIGHT: /*vai a destra*/;  break;
       case GLUT_KEY_UP:    /*vai su*/;  break;
       case GLUT_KEY_DOWN:  /*vai giù*/;  break;
       }
    }
    e poi nel main ti chiami:
    codice:
    glutSpecialFunc(tastiera);
    Tu, nel tuo esempio, con
    GLUT_KEY_UP
    vai a modificare l'angolo di 90 gradi.
    Strano che non ti funzioni, forse dimentichi qualcosa?
    Secondo me l'errore non sta nell'uso della funzione glut, ma in qualche variabile (tipo quella che gestice l'angolo di rotazione) usata.
    Non sono molto esperto di opengl, però credo che l'errore stia lì

  5. #5
    ora inserisco il codice fatto finora:

    codice:
    #include <windows.h>
    #include <gl/glut.h>
    #include <math.h>
    
    void init(void)
    { /* Abilita il Culling e il Depth testing */
     glEnable(GL_DEPTH_TEST);
     glEnable(GL_CULL_FACE);
    
     /* Imposta lo smooth shading */
     glShadeModel(GL_SMOOTH);
     
     /* colore di sfondo nero */
     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }
    
    void timer(int valore)
    {
     switch(valore)
    	{case 0:
    		glutPostRedisplay();
    		glutTimerFunc(100, timer, 0);
    		break;
    
    	 case 1:
    		 glutPostRedisplay();
    		 break;
    	}
    }
    
    void specialKeyboard(int key, int x, int y)
    {
     static GLfloat rot=0.0;
    
     if(key == GLUT_KEY_UP)
    	{
    	 glMatrixMode(GL_MODELVIEW);
    	 
             glRotatef(90.0, 1.0, 0.0, 0.0);
    	}
    
     if(key == GLUT_KEY_DOWN)
     {
     
     }
    
     if(key == GLUT_KEY_LEFT)
     {
     
     }
          
     if(key == GLUT_KEY_RIGHT)
     {
     
     }
                            
     /* Aggiorna l'immagine */
     glutPostRedisplay();
    }
    
    void drawGround(void)
        {   
        glBegin(GL_QUADS);
            glColor3ub(0, 0, 0);
            glVertex3f(600.0f, -50.0f, -400.0f);
            glVertex3f(-600.0f, -50.0f, -400.0f);
            glColor3ub(200, 200, 200);
            glVertex3f(-600.0f, -50.0f, -20.0f);
            glVertex3f(600.0f, -50.0f, -20.0f);
        glEnd();
        }
    
    void drawColumn(int direzione, GLfloat spostamento, GLfloat lato)
    {
     switch(direzione)
    	{
    	 case 1: 
    		 glTranslatef(spostamento, 0.0, 0.0);
    		 break;
    
    	 case -1: 
    		 glTranslatef(-spostamento, 0.0, 0.0);
    		 break;
    
    	 case 3: 
    		 glTranslatef(0.0, 0.0, spostamento);
    		 break;
    
    	 case -3: 
    		 glTranslatef(0.0, 0.0, -spostamento);
    		 break;
    	}
    
     glutWireCube(lato);
    
    	glPushMatrix();
    
    		glTranslatef(0.0, spostamento, 0.0);
    		glutWireCube(lato);
    
    	glPopMatrix();
    
    	glPushMatrix();
    
    		glTranslatef(0.0, -spostamento, 0.0);
    		glutWireCube(lato);
    
    	glPopMatrix();
    }
    
    void drawRubikCube(GLfloat edge)
    {
     /* salva la posizione corrente e spostati in alto per disegnare il cubo */
     glPushMatrix();
    
        glTranslatef(0.0, edge, 0.0);
    
    	glColor3ub(255, 0, 0);
    	glutWireCube(edge);
    	glColor3ub(0, 255, 0);
    
     /* ripristina la posizione iniziale */
     glPopMatrix();
    
     /* salva la posizione corrente e spostati in basso per disegnare il cubo */
     glPushMatrix();
    
        glTranslatef(0.0, -edge, 0.0);
    
        glutWireCube(edge); 
    
     /* ripristina la posizione iniziale */
     glPopMatrix();
    
     drawColumn(1, edge, edge);
     drawColumn(3, edge, edge);
     drawColumn(-1, edge, edge);
     drawColumn(-1, edge, edge);
     drawColumn(-3, edge, edge);
     drawColumn(-3, edge, edge);
     drawColumn(1, edge, edge);
     drawColumn(1, edge, edge);
    }
    
    void display(void)
    {
     GLfloat offset=0.1;
     GLfloat maxAngleSize=15.0;
     static GLfloat angle=90.0;
     static GLfloat angleOld;
     GLfloat zRot=sin(angle)*3;
     GLfloat xRot=cos(angle)*3;
    
     angleOld=angle+offset;
     /* inizializza il color buffer e il depth buffer */
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
     /* d'ora in poi si modifica la matrice modelview*/
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
    
     drawGround();
     
     glTranslatef(0.0, 0.0, -50.0);
     glRotatef(45.0, 1.0, 0.0, 0.0);
     glRotatef(45.0, 0.0, 1.0, 0.0);
    
     glRotatef(zRot, 0.0, 0.0, 1.0);
     glRotatef(xRot, 0.0, 1.0, 0.0);
    
     drawRubikCube(10.0);
    
     /* imposta un leggero movimento oscillatorio di default */
     if(angleOld-angle > 0 && angle > -maxAngleSize)
    {
     angle-=offset;
     angleOld-=offset;
    }
     else if(angle <= maxAngleSize)
    {
     if(angle < -maxAngleSize)
    	angle+=offset;
     
     else
    	{
    	 angle+=offset;
    	 angleOld+=offset;
    	}
    }
     else
    	 angleOld+=offset;
    
     glutSwapBuffers();
    }
    
    void reshape(GLsizei w, GLsizei h)
    {
     GLfloat ratio;
    
     if(h==0)
    	 h=1;
    
     glViewport(0, 0, w, h);
    
     ratio=(GLfloat) w/ (GLfloat) h;
    
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
    
     gluPerspective(90.0, ratio, 20.0, 500.0);
     //glOrtho(-100.0, 100.0, -75.0, 75.0, 20.0, 300.0);
    
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
    }
    
    main()
    {
     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    
     glutInitWindowSize(800, 600);
     glutInitWindowPosition(0, 0);
     glutCreateWindow("Prova");
    
     glutDisplayFunc(display);
     glutReshapeFunc(reshape);
     glutSpecialFunc(specialKeyboard);
     glutTimerFunc(250, timer, 0);
    
     init();
    
     glutMainLoop();
    Ho disegnato un cubo rosso in cima per poter vedere se la rotazione ha effetto...
    Credo che il problema sia nel fatto che nella funzione display() richiamo la funzione drawRubikCube() che disegna il cubo sempre nello stesso modo, ma non so in che altro modo fare...

  6. #6
    qualcosa l'ho risolto, ora effettua le rotazioni, ma non capisco perchè, dopo un minuto circa l'oscillazione di default del cubo si blocca... Mah! ora devo fare in modo che premendo le frecce si abbia un'animazione del cubo che ruota di 90 gradi (cioè, senza tenere premute le frecce, solo premendo un attimo il pulsante)...

    codice:
    #include <windows.h>
    #include <gl/glut.h>
    #include <math.h>
    
    void drawRubikCube(GLfloat edge);
    
    GLfloat arrowXrot=0.0;
    GLfloat arrowYrot=0.0;
    GLfloat arrowZrot=0.0;
    
    void init(void)
    { /* Abilita il Culling e il Depth testing */
     glEnable(GL_DEPTH_TEST);
     glEnable(GL_CULL_FACE);
    
     /* Imposta lo smooth shading */
     glShadeModel(GL_SMOOTH);
     
     /* colore di sfondo nero */
     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }
    
    void oscilla()
    {
     GLfloat offset=0.1;
     GLfloat maxAngleSize=15.0;
     static GLfloat angle=90.0;
     static GLfloat angleOld;
     GLfloat zRot=sin(angle)*3;
     GLfloat xRot=cos(angle)*3;
    
     angleOld=angle+10.0;
    
     glRotatef(zRot, 0.0, 0.0, 1.0);
     glRotatef(xRot, 0.0, 1.0, 0.0);
    
    /* imposta un leggero movimento oscillatorio di default */
    if(angleOld != angle && angle > -maxAngleSize)
    	{
    	 angle-=offset;
    	}
    else if(angle <= maxAngleSize)
    	{
    	 angle+=offset;
    	 angleOld=angle;
    	}
    else if(angleOld == angle && angle < maxAngleSize)
    	{
    	 angle+=offset; 
    	 angleOld+=offset;
    	}
    else
    	angleOld=angle+10.0;
    }
    
    void timer(int valore)
    {
     switch(valore)
    	{case 0:
    		
    		glutPostRedisplay();
    		glutTimerFunc(100, timer, 0); 
    		
    		break;
    
    	 case 1:
    		 glutPostRedisplay();
    		 glutTimerFunc(100, timer, 1); 
    		 break;
    	}
    }
    
    /*void keyboard(unsigned char key, int x, int y)
    {
     
    }*/
    
    void specialKeyboard(int key, int x, int y)
    {
     if(key == GLUT_KEY_UP)
    	{
    	 arrowXrot-=3;
    	 if(arrowXrot < -360.0)
    		 arrowXrot=0;
    	}
    
     if(key == GLUT_KEY_DOWN)
    	{
    	 arrowXrot+=3;
    	 if(arrowXrot>360.0)
    		 arrowXrot=0;
    	}
    
     if(key == GLUT_KEY_LEFT)
    	{
    	 arrowZrot+=3;
    	 if(arrowZrot > 360.0)
    		 arrowZrot=0;
    	}
          
     if(key == GLUT_KEY_RIGHT)
    	{
    	 arrowZrot-=3;
    	 if(arrowZrot < -360.0)
    		 arrowZrot=0;
    	}
    
     if(key == GLUT_KEY_PAGE_DOWN)
    	{
    	 arrowYrot-=3;
    	 if(arrowYrot < -360.0)
    		 arrowYrot=0;
    	}
          
     if(key == GLUT_KEY_END)
    	{
    	 arrowYrot+=3;
    	 if(arrowYrot>360.0)
    		 arrowYrot=0;
    	}
                            
     /* Aggiorna l'immagine */
     glutPostRedisplay();
    }
    
    void drawGround(void)
        {   
        glBegin(GL_QUADS);
            glColor3ub(0, 0, 0);
            glVertex3f(600.0f, -50.0f, -400.0f);
            glVertex3f(-600.0f, -50.0f, -400.0f);
            glColor3ub(200, 200, 200);
            glVertex3f(-600.0f, -50.0f, -20.0f);
            glVertex3f(600.0f, -50.0f, -20.0f);
        glEnd();
        }
    
    void drawColumn(int direzione, GLfloat spostamento, GLfloat lato)
    {
     switch(direzione)
    	{
    	 case 1: 
    		 glTranslatef(spostamento, 0.0, 0.0);
    		 break;
    
    	 case -1: 
    		 glTranslatef(-spostamento, 0.0, 0.0);
    		 break;
    
    	 case 3: 
    		 glTranslatef(0.0, 0.0, spostamento);
    		 break;
    
    	 case -3: 
    		 glTranslatef(0.0, 0.0, -spostamento);
    		 break;
    	}
    
     glutWireCube(lato);
    
    	glPushMatrix();
    
    		glTranslatef(0.0, spostamento, 0.0);
    		glutWireCube(lato);
    
    	glPopMatrix();
    
    	glPushMatrix();
    
    		glTranslatef(0.0, -spostamento, 0.0);
    		glutWireCube(lato);
    
    	glPopMatrix();
    }
    
    void drawRubikCube(GLfloat edge)
    {
     /* salva la posizione corrente e spostati in alto per disegnare il cubo */
     glPushMatrix();
    
        glTranslatef(0.0, edge, 0.0);
    
    	glColor3ub(255, 0, 0);
    	glutWireCube(edge);
    	glColor3ub(0, 255, 0);
    
     /* ripristina la posizione iniziale */
     glPopMatrix();
    
     /* salva la posizione corrente e spostati in basso per disegnare il cubo */
     glPushMatrix();
    
        glTranslatef(0.0, -edge, 0.0);
    
    	glutWireCube(edge); 
    
     /* ripristina la posizione iniziale */
     glPopMatrix();
    
     drawColumn(1, edge, edge);
     drawColumn(3, edge, edge);
     drawColumn(-1, edge, edge);
     drawColumn(-1, edge, edge);
     drawColumn(-3, edge, edge);
     drawColumn(-3, edge, edge);
     drawColumn(1, edge, edge);
     drawColumn(1, edge, edge);
    }
    
    void display(void)
    {
     /* inizializza il color buffer e il depth buffer */
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
     /* d'ora in poi si modifica la matrice modelview*/
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
    
     drawGround();
     
     glTranslatef(0.0, 0.0, -50.0);
     
     glRotatef(45.0, 1.0, 0.0, 0.0);
     glRotatef(45.0, 0.0, 1.0, 0.0);
    
     glRotatef(arrowXrot, 1.0, 0.0, 0.0);
     glRotatef(arrowYrot, 0.0, 1.0, 0.0);
     glRotatef(arrowZrot, 0.0, 0.0, 0.0);
    
     oscilla();
     drawRubikCube(10.0);
    
     glutSwapBuffers();
    }
    
    void reshape(GLsizei w, GLsizei h)
    {
     GLfloat ratio;
    
     if(h==0)
    	 h=1;
    
     glViewport(0, 0, w, h);
    
     ratio=(GLfloat) w/ (GLfloat) h;
    
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
    
     gluPerspective(90.0, ratio, 20.0, 500.0);
     //glOrtho(-100.0, 100.0, -75.0, 75.0, 20.0, 300.0);
    
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
    }
    
    main()
    {
     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    
     glutInitWindowSize(800, 600);
     glutInitWindowPosition(0, 0);
     glutCreateWindow("Prova");
    
     glutTimerFunc(250, timer, 0);
     glutDisplayFunc(display);
     glutReshapeFunc(reshape);
     //glutKeyboardFunc(keyboard);
     glutSpecialFunc(specialKeyboard);
     //glutIdleFunc(idle);
    
     init();
    
     glutMainLoop();
    }

  7. #7
    Utente di HTML.it L'avatar di gokan
    Registrato dal
    Feb 2003
    Messaggi
    262
    Originariamente inviato da ciammarica
    cioè, senza tenere premute le frecce, solo premendo un attimo il pulsante)...
    Purtroppo non ti so aiutare in questa cosa, tu ha già una mezza idea su come realizzare ciò?
    sono curioso

  8. #8
    sto provando con un ciclo while che incrementa l'angolo e aggiorna lo schermo finche' l'angolo non arriva a 90 gradi, ma a quanto pare mi va in crash il programma! boh?!

  9. #9
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Le animazioni non si fanno col ciclo for, ma incrementando delle variabili in modo che ogni volta che opengl rieffettua il disegno queste abiano nuovi valori, dando origine all'animazione.

    Per far ruotare il cuobo di 90 gradi premendo un tasto puoi utilizzare ad esempio una vriabile booleana inizialmente settata a zero; quando il taso è premeto viene settata a uno; nel codice per l'nimazione ti basta verificare il valore di questa variabile, se vale zero non fai nulla, se vale 1 incrementi l'angolo se è minore di 90 gradi. Bada inoltre che se devi far ruotare qualcosa in continuazione non devi incrementare l'angolo all'infinito se no il numero puo diventare troppo grande; devi increemntarlo, ma appena raggiunge 360 lo rimetti a zero.

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  10. #10
    grazie per i consigli!
    qualcosa l'ho risolto, pero' quello che non riesco a risolvere è questo:
    uso la glutTimerFunc() per effettuare l'animazione, però, poichè la glutTimerFunc non si può "stoppare", ma solo sovrapporne gli effetti con altre glutTimerFunc, alla fine mi gira in modo imprevisto
    come faccio a fermare momentaneamente l'effetto di una glutTimerFunc?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.