Bonjour
Dans mon objectif de dessiner diverses géométries à l'aide des VBOs je m'attaque maintenant aux cercles. Or, mon code souffre d'un bug que je suspecte être un "effet de bord". En effet, voici ma classe représentant un cercle:
Donc, il s'agit de représenter un cercle constitué de 100 points, d'un rayon de 2 avec un centre donné. Le dessin se fera à l'aide des VBO avec la primitive GL_LINE_LOOP.
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 class MyCircle{ private float x, y, z; float[][]coords; private int sizeOfBufferVertices; private FloatBuffer nodeVertices; private int sizeOfBufferColor; private FloatBuffer nodeColor; private ByteBuffer nodeIndices; private static final float RADIUS = 2f; private static final int CIRCLE_POINTS_NUMBER = 100; private byte[]indices; public MyCircle(float x, float y, float z){ this.x = x; this.y = y; this.z = z; indices = new byte[CIRCLE_POINTS_NUMBER]; byte b = 0; for(int i=0; i<CIRCLE_POINTS_NUMBER; i++){ indices[i] = b++; } setCoordinates(); setupNodeVerticesBuffer(); setupNodeColorBuffer(); setupNodeIndicesBuffer(); } private float[][]calculateCircle(float[]center){ float[][]points = new float[CIRCLE_POINTS_NUMBER][3]; float x0 = center[0]; float y0 = center[1] + RADIUS; float z0 = center[2]; for (int i = 0; i < CIRCLE_POINTS_NUMBER; i++) { double angle = i * 2 * Math.PI / CIRCLE_POINTS_NUMBER; points[i][0] = (float)(x0 + RADIUS * Math.cos(angle)); points[i][1] = (float)(y0 + RADIUS * Math.sin(angle)); points[i][2] = z0; } return points; } public FloatBuffer getBufferVertices(){ return this.nodeVertices; } public int sizeofBufferVertices(){ return this.sizeOfBufferVertices; } public FloatBuffer getBufferColor(){ return this.nodeColor; } public int sizeofBufferColor(){ return this.sizeOfBufferColor; } public int getBufferIndicesSize(){ return this.indices.length; } private void setCoordinates(){ float[]center = new float[3]; center[0] = x;center[1] = y;center[2] = z; coords = calculateCircle(center); } private void setupNodeVerticesBuffer(){ int bufferVerticesSize = coords.length * coords[0].length; this.sizeOfBufferVertices = bufferVerticesSize * BufferUtil.SIZEOF_FLOAT; nodeVertices = BufferUtil.newFloatBuffer(bufferVerticesSize); for(int i=0; i<coords.length; i++){ for(int j=0; j<coords[0].length; j++){ nodeVertices.put(coords[i][j]); } } nodeVertices.rewind(); } private void setupNodeColorBuffer(){ float[]colorComponds = {0, 1, 0, 0}; int bufferColorSize = colorComponds.length * this.indices.length; this.sizeOfBufferColor = bufferColorSize * BufferUtil.SIZEOF_FLOAT; float[]allColorComponds = new float[bufferColorSize]; int j=0; for(int i=0; i<allColorComponds.length; i++){ allColorComponds[i] = colorComponds[j++]; if(j==colorComponds.length){ j=0; } } nodeColor = BufferUtil.newFloatBuffer(allColorComponds. length); nodeColor.put(allColorComponds); nodeColor.rewind(); } private void setupNodeIndicesBuffer(){ nodeIndices = BufferUtil.newByteBuffer(this.indices.length); nodeIndices.put(this.indices); nodeIndices.rewind(); } }
Voici comment je dessine:
Or, à l'affichage, j'ai bien mes 4 cercles dessinés PLUS des droites et autres lignes dessinées non demandées
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 private List<MyCircle>circles; private float[]centers = { -5, 5, 0, 5, 5, 0, 5, -5, 0, -5, -5, 0 }; private FloatBuffer positionCircleData; private FloatBuffer colorCircleData; private IntBuffer startsCircle; private IntBuffer countsCircle; public MultiOVBOTest(){ circles = new ArrayList<MyCircle>(); for(int i=0; i<centers.length; i+=3){ circles.add(new MyCircle(centers[i], centers[i+1], centers[i+2])); } this.bufferName = BufferUtil.newIntBuffer(2); } public void init(GLAutoDrawable drawable) { final GL gl = drawable.getGL(); drawable.addMouseWheelListener(this); gl.glShadeModel(gl.GL_SMOOTH); gl.glEnable(gl.GL_DEPTH_TEST); gl.glGenBuffers(LIMIT, bufferName); int constant = circles.size() * BufferUtil.SIZEOF_FLOAT; this.positionCircleData = BufferUtil.newFloatBuffer(circles.get(0).sizeofBufferVertices() * constant); this.colorCircleData = BufferUtil.newFloatBuffer(circles.get(0).sizeofBufferColor() * constant); this.startsCircle = BufferUtil.newIntBuffer(circles.size()); this.countsCircle = BufferUtil.newIntBuffer(circles.size()); pushCirclesDataBuffers(gl); } private void pushCirclesDataBuffers(final GL gl){ Iterator<MyCircle> it = this.circles.iterator(); int i = 0; int j = circles.get(0).getBufferIndicesSize(); while (it.hasNext()) { MyCircle circle = it.next(); this.positionCircleData.put(circle.getBufferVertices()); this.colorCircleData.put(circle.getBufferColor()); startsCircle.put(i); countsCircle.put(j); i += circle.getBufferIndicesSize(); j += circle.getBufferIndicesSize(); } this.positionCircleData.rewind(); this.colorCircleData.rewind(); gl.glBindBuffer(gl.GL_ARRAY_BUFFER, bufferName.get(4)); gl.glBufferData(gl.GL_ARRAY_BUFFER, this.circles.get(0).sizeofBufferVertices() * this.circles.size() * BufferUtil.SIZEOF_FLOAT, positionCircleData, gl.GL_STATIC_DRAW); gl.glVertexPointer(3, gl.GL_FLOAT, 0, 0); gl.glBindBuffer(gl.GL_ARRAY_BUFFER, bufferName.get(5)); gl.glBufferData(gl.GL_ARRAY_BUFFER, this.circles.get(0).sizeofBufferColor() * this.circles.size() * BufferUtil.SIZEOF_FLOAT, colorCircleData, gl.GL_STATIC_DRAW); gl.glColorPointer(4, gl.GL_FLOAT, 0, 0); this.startsCircle.rewind(); this.countsCircle.rewind(); } public void display(GLAutoDrawable drawable) { final GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glClearColor(1, 1, 1, 0); gl.glMatrixMode(gl.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0, 0, zoom); gl.glLineWidth(2f); gl.glEnableClientState(GL.GL_VERTEX_ARRAY); gl.glEnableClientState(GL.GL_COLOR_ARRAY); gl.glBindBuffer(gl.GL_ARRAY_BUFFER, bufferName.get(0)); gl.glVertexPointer(3, gl.GL_FLOAT, 0, 0); gl.glBindBuffer(gl.GL_ARRAY_BUFFER, bufferName.get(1)); gl.glColorPointer(4, gl.GL_FLOAT, 0, 0); gl.glMultiDrawArrays(gl.GL_LINE_LOOP, startsCircle, countsCircle, this.circles.size()); gl.glFlush(); }
D'où ma question, où me suis-je planté ?
Merci d'avance de vos réponses.
PS: question subsidiaire, je projette de m'acheter le dernier red book OpenGL. Traitent-ils des VBO ?
@++
Partager