IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

Opengl sous java : Mouvement camera


Sujet :

OpenGL

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 95
    Points : 131
    Points
    131
    Par défaut Opengl sous java : Mouvement camera
    Bonjour,

    Pour un projet de mathématique, j'ai choisis de programmer un fractale en 3D.
    Le tétraèdre de Sierpinski pour être exacte.

    Mon fractale est terminé et je passe donc à son affichage. Je n'ai jamais utilisé de librairie pour faire de la 3D et je tâtonne un peu mal grès tout les tutoriaux qu'on peut trouver sur internet.

    J'ai réussi à le modéliser et maintenant j'aimerais pouvoir faire tourner la camera autour de son centre pour le voir sous différents angles.

    J'ai pu voir des méthodes glRotate ou glTranslation, d'autre parle de modifier la position de la caméra avec glLookAt. Je comprend bien comment marche glLookAt, mais je ne vois pas du tout comment faire pour modifier la camera après avoir appuyer sur une touche clavier par exemple. (Je voudrais pouvoir tourner la caméra autour de mon fractale avec les flèches directionnelles)

    Mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
     
    import javax.media.opengl.GL;
    import javax.media.opengl.GLAutoDrawable;
    import javax.media.opengl.GLCanvas;
    import javax.media.opengl.GLEventListener;
    import javax.media.opengl.glu.GLU;
    import javax.media.opengl.GLCapabilities;
     
    import com.sun.opengl.util.GLUT;
     
     
     
    public class TetraedreSierpinski3D extends GLCanvas implements GLEventListener, KeyListener{
     
    	TetraedreSierpinski tetra;
    	double base, hauteur;
    	int rang;
     
    	double cameraX, cameraY, cameraZ;
    	public TetraedreSierpinski3D(double base, double hauteur, int rang){
    		super(new GLCapabilities());
    		cameraX =  base/2;
    		cameraY =  base;
    		cameraZ = hauteur/2;
    		addGLEventListener(this);
    		addKeyListener(this);
    		setSize(800, 600);
    		setPreferredSize(getSize());
    		tetra = new TetraedreSierpinski(base, hauteur, rang);
    		this.base = base;
    		this.hauteur = hauteur;
    		this.rang = rang;
    	}
     
    	public void display(GLAutoDrawable drawable){
    		GL gl = drawable.getGL();
    		gl.glMatrixMode(GL.GL_MODELVIEW);
     
    		gl.glEnable(GL.GL_DEPTH_TEST);
    		gl.glDepthMask(true);
    		gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
    		gl.glLoadIdentity();
     
    		GLU glu = new GLU();
    		glu.gluPerspective(80, 1, 1, 1000);
    		glu.gluLookAt(cameraX, cameraY, cameraZ, base/2, Math.sin(60)*base/2, hauteur/2, 0, 0, 1);
     
    		while(!tetra.estVide()){
    			Polygone poly = tetra.depiler();
    			gl.glBegin(GL.GL_TRIANGLE_FAN);
    			for(int i = 0; i < poly.index.length; i++){
    				gl.glColor3d(1.0, 0.0, 0.0);
    				if (i == 1) gl.glColor3d(0.0, 0.5, 0.5);
    				if (i == 2) gl.glColor3d(0.5, 0.5, 0.0);
    				if (i == 3) gl.glColor3d(0.0, 1.0, 0.0);
    				if (i == 4) gl.glColor3d(0.0, 0.0, 1.0);
    				gl.glVertex3d(poly.sommets[poly.index[i]].X(), poly.sommets[poly.index[i]].Y(), poly.sommets[poly.index[i]].Z());
    			}
    			gl.glEnd();
    			gl.glBegin(GL.GL_TRIANGLE_FAN);
    			gl.glColor3d(0.5, 0.5, 0.5);
    			for(int i = 0; i < poly.sommets.length-1; i++){
    				gl.glVertex3d(poly.sommets[i].X(), poly.sommets[i].Y(), poly.sommets[i].Z());
    			}
    			gl.glEnd();
    		}
    		gl.glFlush();
    		swapBuffers();
    	}
     
    	public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged){
     
    	}
     
    	public void init(GLAutoDrawable drawable){
    		GL gl=drawable.getGL();
    		gl.glEnable(GL.GL_COLOR);
    	}
     
    	public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height){
    		GLU glu = new GLU();
    		glu.gluPerspective(80, 1, 1, 1000);
    		glu.gluLookAt(cameraX, cameraY, cameraZ, base/2, Math.sin(60)*base/2, hauteur/2, 0, 0, 1);
     
    	}
     
    	@Override
    	public void keyPressed(KeyEvent e) {
    		// TODO Auto-generated method stub
     
    	}
     
    	@Override
    	public void keyReleased(KeyEvent arg0) {
    		// TODO Auto-generated method stub
     
    	}
     
    	@Override
    	public void keyTyped(KeyEvent arg0) {
    		// TODO Auto-generated method stub
     
    	}
     
    }
    Le fractale qu'il affiche :



    La durée du projet est relativement courte, (à rendre pour lundi en sachant qu'il faut que je fasse un rapport et un poster) je n'ai pas vraiment le temps pour comprendre les subtilités d'opengl.

    Si quelqu'un aurait une méthode rapide pour pouvoir bouger ma caméra, je veux juste pouvoir la voir sous différents angles, la rigidité de la caméra m'importe peu.

    Merci de m'avoir lu.

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 078
    Points : 7 986
    Points
    7 986
    Par défaut
    Salut,

    Si c'est seulement pour faire tourner la camera autour d'un seul axe. Voici une solution très simpliste.

    Avec glulookat, avec comme cible 0,0,0 (en imaginant que le centre de ton objet soit position en 0,0,0).
    La position de la camera se calculant simplement en définissant un angle de rotation de 0 a 360°. Cette angle va varier qd tu appuyeras sur les fleches.

    A partir de la tu n'as plus qu'a utiliser un formule avec sinus et cosinus pour calculer ta position en sur l'axe X,Y (ou X,Z selon).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    float zoom = 25;
    float px = (float) (zoom*Math.cos(Math.toRadians(angleX)));
    float py = (float) (zoom*Math.sin(Math.toRadians(angleX)));
    glu.gluLookAt(px, py, cameraZ, 0,0, 0, 0, 0, 1);
    Avec ceci tu pourra faire tourner ton objet atour de l'axe Z. (Si je ne me suis pas trompé ^^)
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 95
    Points : 131
    Points
    131
    Par défaut
    Oui ça j'ai bien compris. Avec les 3 premiers paramètres de gluLookAt on à la matrice de position de la camera, et si on veux lui faire faire une transformation on lui applique betement une matrice de transformation (rotation ... translation ...) et on récupère ses coordonnées.

    Le problème c'est : Ou dans le code je dois lui dire de regarder après avoir appuyer sur une touche ?

    J'ai essayé dans la méthode KeyPressed(les coordonnées sont inchangé c'est juste pour voir si il me le prenait) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public void keyPressed(KeyEvent e) {
    		GLU glu = new GLU();
    		glu.gluLookAt(cameraX, cameraY, cameraZ, base/2, Math.sin(60)*base/2, hauteur/2, 0, 0, 1);
    	}
    Mais si je presse une touche du clavier j'ai le droit à un jolie
    Exception in thread "AWT-EventQueue-0" javax.media.opengl.GLException: No OpenGL context current on this thread

    Si j'ai bien compris. display() dessine la scène.
    reshape() est appelée si on change la taille de la fenêtre.
    init() la première méthode appelée

    Ensuite je nage un peu

  4. #4
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 641
    Points
    7 641
    Par défaut
    Salut

    Citation Envoyé par Deesmon Voir le message
    Mais si je presse une touche du clavier j'ai le droit à un jolie
    Exception in thread "AWT-EventQueue-0" javax.media.opengl.GLException: No OpenGL context current on this thread

    Si j'ai bien compris. display() dessine la scène.
    reshape() est appelée si on change la taille de la fenêtre.
    init() la première méthode appelée

    Ensuite je nage un peu
    Rooh, du java!

    laisse ton gluLookAt dans ta méthode display(), elle y est très bien.
    Tu gères la modification des coordonnées de la position de la caméra dans ton keypressed (coordonnées qui sont utilisées dans le gluLookAt), et tu rappelles display() à la fin pour remettre à jour l'affichage

    Et ça devrait être bon...
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  5. #5
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 95
    Points : 131
    Points
    131
    Par défaut
    La méthode dans laquelle je dessine est :

    display(GLAutoDrawable drawable){}

    Je veux bien la rappeler mais elle veux un GLAutoDrawable en paramètre.

    J'ai essayé de dessiner dans la méthode display() mais sans le paramètre drawable je n'arrive pas à instancier d'objet GL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public void display(GLAutoDrawable drawable){
    		GL gl = drawable.getGL(); ...
    J'essaye les méthodes un peu partout mais tout ce qui résulte se sont des messages d'erreurs.

    Je prendrais bien le temps d'approfondir ça car beaucoup de chose m'échappe là, mais dans l'immédiat ce n'est pas vraiment prioritaire.
    Enfin c'est pas grave =) je me contenterai de quelques screens sous différents angles ... et d'une vue fixe pour l'exécutable. Le projet étant essentiellement basé sur le fractale en lui même.

    je me mettrai au c++ pendant les vacances promis

    Merci pour vos réponses.

  6. #6
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 641
    Points
    7 641
    Par défaut
    Citation Envoyé par Deesmon Voir le message
    La méthode dans laquelle je dessine est :

    display(GLAutoDrawable drawable){}

    Je veux bien la rappeler mais elle veux un GLAutoDrawable en paramètre.
    Bizarre, elle ne prend pas de paramètre chez moi... quelle version de Jogl?

    Tu as tenté un repaint() sur le panel?
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  7. #7
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 078
    Points : 7 986
    Points
    7 986
    Par défaut
    Tu ne peux pas l'appeler directement dans tes listeners de cette manière. Dans ton listener tu vas juste changer tes positionnement de camera et/ou autres et éventuellement demander un repaint comme Plegat le suggère.

    si tu as l'objet drawable qlq part

    ou si tu as un GLCanvas dans le coin :

    ou eventuellement (mais je doute que ca fonctionne)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((GLAutoDrawable) GLContext.getCurrent().getGLDrawable()).repaint();
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 95
    Points : 131
    Points
    131
    Par défaut
    Beh c'est ça. repaint() redessine la scène, je modifie ma caméra et hop. Je l'ai juste appelé à partir de mon GLCanvas.

    Les problèmes les plus chiants sont souvent les plus bateaux ><

    En tous cas, un grand merci.


  9. #9
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 641
    Points
    7 641
    Par défaut
    Citation Envoyé par Deesmon Voir le message
    Beh c'est ça. repaint() redessine la scène, je modifie ma caméra et hop. Je l'ai juste appelé à partir de mon GLCanvas.
    arf, désolé pour l'appel à display() de mon premier post, je tourne avec un GLJPanel... (et j'ai toujours mes tutos Jogl à finir depuis un an, va falloir que je m'y mette, c'est pas sérieux tout ça!)
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

Discussions similaires

  1. afficher un modele 3ds en opengl sous vb 6
    Par fun31 dans le forum OpenGL
    Réponses: 1
    Dernier message: 10/12/2004, 14h15
  2. Réponses: 5
    Dernier message: 21/11/2004, 18h59
  3. Sauvegarder la fenetre OpenGL sous un fichier bitmap
    Par corey_jx dans le forum OpenGL
    Réponses: 3
    Dernier message: 16/06/2004, 15h48
  4. [kdevelop]linker les lib openGL sous kdevelop
    Par bafman dans le forum OpenGL
    Réponses: 6
    Dernier message: 16/12/2003, 08h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo