Bonjour à tous.
Pour un projet à la fac, je dois me mettre à JOGL. J'essaye d'afficher simplement des maillages triangulaires avec des VBO, mais au lieu d'un triceratops, j'ai des lignes dans tous les sens (quand ça ne crash pas). Le pire c'est que ça ne donne pas le même résultat entre 2 executions
J'ai pourtant déjà codé la même chose en C sans souci et je ne fais que simplifier (pas d'éclairages, ni double buffering etc...) et adapter le code en JOGL mais ça coince et je suis à court d'idées. J'ai parcouru le forum mais n'ai rien trouvé qui colle à mon problème.
La classe Main :
Celle qui s'occupe des maillages et des VBO :
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
108
109
110
111
112
113
114
115
116 public class Main implements GLEventListener, KeyListener{ static GLU glu = new GLU(); static GLUT glut = new GLUT(); static GLAutoDrawable drawable; // pour pouvoir s'en servir dans keyPressed static Frame frame = new Frame("Jogl 3D"); static GLCanvas canvas = new GLCanvas(); static Animator animator = new Animator(canvas); private Mesh m; public void display(GLAutoDrawable GLDrawable) { final GL gl = GLDrawable.getGL(); gl.glClear (GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode (GL.GL_MODELVIEW); gl.glLoadIdentity(); glu.gluLookAt(0, 0, -5, 0, 0, 0, 0, 1, 0); m.afficher(gl); // pour se reperer dans l'image pendant le developpement gl.glPushMatrix(); gl.glColor3f(0.0f, 1.0f, 0.0f); glut.glutSolidTeapot(1.); gl.glPopMatrix(); // ... gl.glFlush(); } @Override public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) { // TODO Auto-generated method stub } public void init(GLAutoDrawable GLDrawable) { GLDrawable.addKeyListener(this); drawable=GLDrawable; final GL gl = GLDrawable.getGL(); gl.glShadeModel(GL.GL_SMOOTH); gl.glClearColor (0.1f, 0.1f, 0.1f, 0); gl.glClearDepth(1.0f); gl.glEnable(GL.GL_DEPTH_TEST); gl.glDepthFunc(GL.GL_LEQUAL); gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT,GL.GL_NICEST); gl.glPolygonMode (GL.GL_FRONT_AND_BACK, GL.GL_LINE); float pos[]={0f,0f,0f}; m = new Mesh("triceratops.off",pos,1); m.creerVBO(gl); } public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height) { final GL gl = gLDrawable.getGL(); if(height <= 0) { height = 1; } float h = (float)width / (float)height; gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(50.0f, h, 1.0, 1000.0); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); } public void keyPressed(KeyEvent e) { final GL gl = drawable.getGL(); switch (e.getKeyCode()){ case KeyEvent.VK_ESCAPE : exit(); break; } } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } public static void exit(){ frame.dispose(); animator.stop(); System.exit(0); } public static void main(String[] args) { canvas.addGLEventListener(new Main()); frame.add(canvas); frame.setSize(800, 600); frame.setUndecorated(true); frame.setExtendedState(Frame.MAXIMIZED_BOTH); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { exit(); } } ); frame.setVisible(true); animator.start(); canvas.requestFocus(); } }
Tant que j'y suis j'ai une autre question
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public class Mesh { private int nbSommets; // nombre de sommets du maillage private int nbIndex; // nombre d'index du maillage private FloatBuffer sommets; // tableau des coordonnées x,y,z des sommets du maillage private IntBuffer index; // tableau des index des sommets pour les facettes triangulaires private float minY; // coordonnée Y de sommet la plus petite : pour pouvoir poser le maillage sur un autre objet private int[] idBufferSommets = new int[1]; // nom du buffer des sommets private int[] idBufferIndex = new int[1]; // nom du buffer des index pour private float[] position; // position initiale private float scale; // taille public Mesh(String nomFich, float[] pos, float sc){ position=pos; scale=sc; float centreGx=0,centreGy=0,centreGz=0; // lecture du fichier try { Lecteur fichier = new Lecteur(nomFich); fichier.skip(); // on saute OFF nbSommets=fichier.lireInt(); nbIndex=fichier.lireInt(); fichier.skip(); // on saute le nombre de normales //on recupere tous les sommets float som[]= new float[nbSommets*3]; for(int i=0;i<nbSommets*3;i++){ som[i]=fichier.lireFloat(); } // calcul du centre de gravite for(int i=0;i<nbSommets*3;i=i+3){ centreGx=som[i]+centreGx; centreGy=som[i+1]+centreGy; centreGz=som[i+2]+centreGz; } centreGx=centreGx/nbSommets; centreGy=centreGy/nbSommets; centreGz=centreGz/nbSommets; // recentrage du maillage for(int i=0;i<nbSommets*3;i=i+3){ som[i]=som[i]-centreGx; som[i+1]=som[i+1]-centreGy; som[i+2]=som[i+2]-centreGz; } // calcul de la plus grande coord float max=Math.abs(som[0]); for (int i=1;i<nbSommets*3;i++){ if(Math.abs(som[i])>max){ max=Math.abs(som[i]); } } // redimensionnement for (int i=0; i<nbSommets*3;i++){ som[i]=som[i]/max; } // remplissage du FloatBuffer ByteBuffer bbSom; bbSom=ByteBuffer.allocateDirect( (nbSommets*3)*BufferUtil.SIZEOF_FLOAT); sommets = bbSom.asFloatBuffer().put(som); for(int i=0;i<nbSommets*3;i=i+3){ System.out.println(sommets.get(i)+" "+sommets.get(i+1)+" "+sommets.get(i+2)); } // calcul du plus petit Y minY=som[1]; for(int i=1; i<nbSommets*3; i=i+3){ if(som[i]<minY) minY=som[i]; } //on recupere les facettes int ind[]= new int[nbIndex*3]; for(int i=0;i<nbIndex*3;i=i+3){ fichier.skip(); // on saute le nombre de sommets de la facette (toujours 3) ind[i]=fichier.lireInt(); ind[i+1]=fichier.lireInt(); ind[i+2]=fichier.lireInt(); } // on les mets dans le IntBuffer ByteBuffer bbInd; bbInd=ByteBuffer.allocateDirect( (nbIndex*3)*BufferUtil.SIZEOF_INT ); index = bbInd.asIntBuffer().put(ind); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void creerVBO(GL gl){ // VBO des sommets gl.glGenBuffers(1, idBufferSommets, 0); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, idBufferSommets[0]); gl.glBufferData(GL.GL_ARRAY_BUFFER, nbSommets*3*BufferUtil.SIZEOF_FLOAT, sommets, GL.GL_STATIC_DRAW); // VBO des facettes gl.glGenBuffers(1, idBufferIndex, 0); gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, idBufferIndex[0]); gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, nbIndex*3*BufferUtil.SIZEOF_INT, index, GL.GL_STATIC_DRAW); } public void afficher(GL gl){ gl.glEnableClientState(GL.GL_VERTEX_ARRAY); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, idBufferSommets[0]); gl.glVertexPointer(3, GL.GL_FLOAT, BufferUtil.SIZEOF_FLOAT*3, 0); // transformations gl.glPushMatrix(); gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glTranslatef(position[0], position[1], position[2]); gl.glScalef(scale, scale, scale); gl.glTranslatef(0.f, -minY, 0.f); gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, idBufferIndex[0]); gl.glDrawElements(GL.GL_TRIANGLES, nbIndex*3, GL.GL_UNSIGNED_INT, 0); gl.glPopMatrix(); gl.glDisableClientState(GL.GL_VERTEX_ARRAY); } }
Je n'ai pas trouvé de fonction équivalente à glutPostRedisplay pour rafraichir la fenêtre. Comment on fait pour forcer le rafraichissement, dans keyPressed par exemple ? (j'ai eu ce souci en voulant switcher le mode filaire/plein avec l'appui sur 'W').
Merci d'avance.
Partager