Bonjour à tous,

Après plusieurs recherches et pas mal de lecture à travers les tutos qu'on peut trouver sur le net, je me résouds à venir demander ici de l'aide.

Je cherche à reprendre un modeleur 3D que j'avais développé il y a quelques temps en C# avec la librairie XNA pour le basculer en Java avec la librairie OpenGL (pour des raisons de compatibilités et surtout de maintenance, Microsoft ayant la désagréable habitude de repenser complètement ses architectures). J'utilise aussi le binding JOGL. J'ai pour le moment pas mal avancé puisque j'arrive à charger mes scènes depuis des fichiers XML, et à les afficher avec couleurs et textures. Le point sur lequel je bloque maintenant est la mise en place des shaders. J'arrive à comprendre la logique très globale qui est Scène 3D → Vertex Shader → Fragment Shader → Rendu à l'écran (je simplifie ici volontairement le pipeline graphique) mais en ce qui concerne les différents appels de structure à lancer, j'avoue que je me perds un peu les pédales.

Pour rentrer dans le vif du sujet, j'ai suivi la logique de rendu suivante : (c'est très très simplifié par rapport à mon projet où tout est découpé dans différentes classes)
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
 
public class Renderer implents GLEventListener {
    ...
    public int shaderProgram;
    public int vertexShader;
    public int fragmentShader;
    ...
    @Override
    public void init(GLAutoDrawable drawable) {
        GL2 gl = drawable.getGL().getGL2();
        shaderProgram = gl.glCreateProgram();
        vertexShader = gl.glCreateShader(GL2.GL_VERTEX_SHADER);
        fragmentShader = gl.glCreateShader(GL2.GL_FRAGMENT_SHADER);
 
        // Compilation du vertex shader
        String content = new String(Files.readAllBytes(Paths.get("vertexShader.glsl")), Charset.defaultCharset());
        String[] shaderContent = new String[] { content };
        gl.glShaderSource(vertexShader, 1, shaderContent, new int[] { shaderContent[0].length() }, 0);
        gl.glCompileShader(vertexShader);
        gl.glGetShaderiv(vertexShader, GL2.GL_COMPILE_STATUS, compiled, 0);
 
        // Compilation du fragment shader
        content = new String(Files.readAllBytes(Paths.get("fragmentShader.glsl")), Charset.defaultCharset());
        shaderContent = new String[] { content };
        gl.glShaderSource(fragmentShader, 1, shaderContent, new int[] { shaderContent[0].length() }, 0);
        gl.glCompileShader(fragmentShader);
        gl.glGetShaderiv(fragmentShader, GL2.GL_COMPILE_STATUS, compiled, 0);
 
        // Ce n'est pas présent ici mais je vérifie bien évidemment la compilation de mes shaders avec gl.glGetShaderInfoLog
    }
 
    ...
 
    @Override
    public void display(GLAutoDrawable drawable) {
        GL2 gl = drawable.getGL().getGL2();
        gl.glClear(GL2.GL_DEPTH_BUFFER_BIT | GL2.GL_COLOR_BUFFER_BIT);
        gl.glEnable(GL2.GL_BLEND);
        gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA);
 
        gl.glViewport(0, 0, largeurEcran, hauteurEcran);
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45.0f, ratioEcran, nearClipping, farClipping);
        glu.gluLookAt(...);
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
 
        // Je boucle ici sur tous les éléments à afficher
        for (Element e : myElements) {
            gl.glAttachShader(shaderProgram, vertexShader);
            gl.glAttachShader(shaderProgram, fragmentShader);
            gl.glLinkProgram(shaderProgram);
            gl.glValidateProgram(shaderProgram);
            gl.glUseProgram(shaderProgram);
 
            gl.glBindAttribLocation(shaderProgram, 0, "inPosition");
            gl.glBindAttribLocation(shaderProgram, 0, "inColor");
 
            int projectionHandler = gl.glGetUniformLocation(vertexShader, "projection");
            int viewHandler = gl.glGetUniformLocation(vertexShader, "view");
            int worldHandler = gl.glGetUniformLocation(vertexShader, "world");
            gl.glUniformMatrix4fv(projectionHandler, 1, false, projectionMatrix, 0);
            gl.glUniformMatrix4fv(viewHandler, 1, false, viewMatrix, 0);
            gl.glUniformMatrix4fv(worldHandler, 1, false, worldMatrix, 0);
 
            // 'toutesLesTextures' contient les textures chargées à partir du fichier XML qui contient ma scène 3D
            Texture texture = toutesLesTextures.get(element);
            texture.bind(gl);
            texture.enable(gl);
            gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
            gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
 
            // Ici, je génère un vertex buffer et un index buffer (je ne le détaille pas)
 
            gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
            gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
 
            gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vertexBufferHandle);
            gl.glBufferData(GL2.GL_ARRAY_BUFFER, vertexBuffer.capacity() * Buffers.SIZEOF_FLOAT, vertexBuffer, GL2.GL_STATIC_DRAW);
            gl.glVertexPointer(3, GL.GL_FLOAT, Vertex.MEMORY_SIZE << 2, 0 << 2);
            // Est-ce que je devrais utiliser glVertexAttribPointer plutôt que glColorPointer ? Ou alors aucune différence ?
            gl.glColorPointer(4, GL.GL_FLOAT, Vertex.MEMORY_SIZE << 2, 6 << 2);
            gl.glTexCoordPointer(2, GL.GL_FLOAT, Vertex.MEMORY_SIZE << 2, 10 << 2);
 
            gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, indexBufferHandle);
            gl.glBufferData(GL2.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.capacity() * Buffers.SIZEOF_INT, indexBuffer, GL2.GL_STATIC_DRAW);
 
            gl.glDrawElements(GL2.GL_TRIANGLES, indices.size(), GL2.GL_UNSIGNED_INT, 0);
 
            gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
            gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0);
 
            gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
            gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
            gl.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
        }
 
        gl.glFlush();
 
        ...
    }
 
    @Override
    public void dispose(GLAutoDrawable drawable) {
        GL2 gl = drawable.getGL().getGL2();
        gl.glUseProgram(0);
        gl.glDetachShader(shaderProgram, vertexShader);
        gl.glDetachShader(shaderProgram, fragmentShader);
        gl.glDeleteShader(vertexShader);
        gl.glDeleteShader(fragmentShader);
        gl.glDeleteProgram(shaderProgram);
    }
}
Première question : j'ai mis un commentaire ci-dessus (ligne 83) concernant l'utilisation de glVertexAttribPointer / glColorPointer : quelle méthode dois-je utiliser ?
Second question, très globale : la logique de mon code est-elle correcte ? (est-ce que j'appelle bien les bonnes fonctions et dans le bon ordre)
Ensuite, troisième question : je vois bien comment se fait le lien entre mes matrices dans mon code Java et celle dans mes shaders via les appels successifs à gl.glGetUniformLocation et gl.glUniformMatrix4fv mais qu'en est-il de mes vertex ? J'ai bien appelé gl.glBindAttribLocation(shaderProgram, 0, "inPosition"); mais quand je fais un gl.glVertexPointer, je ne fais pas l'association avec le nom de variable "inPosition"... (???) C'est vraiment très flou pour moi de ce côté-là

Pour information, voici le code source de mes shaders :
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
 
#version 400
 
uniform mat4 world;
uniform mat4 view;
uniform mat4 projection;
 
in vec3 inPosition;
in vec4 inColor;
out vec4 color;
 
void main() {
    gl_Position = projection * view * world * vec4(inPosition, 1.0);
    // Si je décommente la ligne suivante, ça n'affiche plus rien, si je la laisse commentée, ma scène s'affiche correctement -> ???
    //color = vec4(1, 0, 0, 1);
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
 
#version 400
 
in vec4 color;
out vec4 outColor;
 
void main() {
    outColor = vec4(color);
}
En précision complémentaire, je travaille sous Windows 7 avec Eclipse Juno.

Merci beaucoup d'avance pour votre aide et vos éclaircissements.