Bonjour à tous.

Actuellement, j'essaie simplement d'afficher du texte avec le TextRenderer ainsi que quelques petits éléments graphiques en 2D, puis d'appliquer un effet de blur sur le tout.

J'ai trouvé le tutorial de nehe à ce sujet : http://nehe.gamedev.net/data/lessons....asp?lesson=36
De plus, j'ai trouvé une conversion jogl : http://www.java-tips.org/other-api-t...rial-jogl.html

J'ai testé l'exemple jogl et ça fonctionne.
Cependant, j'ai réutilisé ça dans mon code pour faire un simple blur sur des objets plus que simples :

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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
 
// fenêtre principale
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.LinkedList;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.swing.KeyStroke;
import nehe.common.GLDisplay;
 
public class MainFrame implements GLEventListener {
 
    public static void main(String[] args) {
        // création de la fenêtre opengl
        GLDisplay display = GLDisplay.createGLDisplay("Blur");
        MainFrame frame = new MainFrame(display);
        // gestionnaire de touches
        InputHandler inputHandler = new InputHandler(frame, display);
        // ajout de l'écouteur opengl
        display.addGLEventListener(frame);
        // ajout du gestionnaire de touches
        display.addKeyListener(inputHandler);
        // on démarre l'affichage
        display.start();
    }
 
    /**
     * Affichage global
     */
    private GLDisplay display;
    /**
     * Liste des scènes à afficher
     */
    private LinkedList<Scene> scenes = new LinkedList<Scene>();
    {
        scenes.add(new EntryScene());
    }
 
    /**
     * Crée la fenêtre principale
     *
     * @param display l'affichage opengl
     */
    public MainFrame(GLDisplay display){
        this.display = display;
    }
 
    /**
     * Initialise les ressources opengl
     *
     * @param drawable l'élément graphique
     */
    @Override
    public void init(GLAutoDrawable drawable) {
        // initialisation de base
        GL gl = drawable.getGL();
        // l'effacement
        gl.glClearColor(0f, 0f, 0f, 1f);
        gl.glClearDepth(1f);
        // on utilise une profondeur de base
        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glDepthFunc(GL.GL_LEQUAL);
        // on veut un lissage
        gl.glShadeModel(GL.GL_SMOOTH);
        gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
        // antialiasing
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
        // gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
        for (Scene scene : scenes) {
            scene.init(gl);
        }
        // si la première scène écoute les touches, on l'ajoute aux
        // écouteurs opengl
        Scene firstScene = scenes.peek();
        if(firstScene != null && firstScene instanceof KeyListener){
            display.addKeyListener((KeyListener) firstScene);
        }
    }
 
    /**
     * Affiche la scène actuelle
     *
     * @param drawable l'élément graphique
     */
    @Override
    public void display(GLAutoDrawable drawable) {
        GL gl = drawable.getGL();
        // nettoyage
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        gl.glLoadIdentity();
        // on récupère la scène actuelle
        Scene scene = scenes.peek();
        while (scene != null && !scene.display(gl, drawable.getWidth(), drawable.getHeight())) {
            // on supprime la scène
            scene = scenes.poll();
            if(scene instanceof KeyListener){
                display.removeKeyListener((KeyListener)scene);
            }
            // on passe à la scène suivante
            scene = scenes.peek();
            if(scene == null){
                break;
            }
            if(scene instanceof KeyListener){
                display.addKeyListener((KeyListener)scene);
            }
        }
    }
 
    /**
     * Redéfinition de la vue
     *
     * @param drawable ressource
     * @param x abscisse de base
     * @param y ordonnée de base
     * @param width largeur de la scène
     * @param height hauteur de la scène
     */
    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        GL gl = drawable.getGL();
        if (height == 0) {
            height = 1;
        }
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f);
        //glu.gluPerspective(45.0f, width / height, 0.1f, 100.0f);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }
 
    @Override
    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
    }
}
 
/**
 * Gestionnaire de touches
 */
class InputHandler extends KeyAdapter {
 
    private MainFrame renderer;
 
    public InputHandler(MainFrame renderer, GLDisplay display) {
        this.renderer = renderer;
        display.registerKeyStrokeForHelp(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "Do something");
    }
 
    @Override
    public void keyReleased(KeyEvent e) {
        switch (e.getKeyCode()) {
            // Toggle properties
            case KeyEvent.VK_SPACE:
                System.out.println("Space !");
                // renderer.toggleShader();
                break;
        }
    }
}
avec la scène et celle d'entrée :
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
public abstract class Scene {
 
    /**
     * Texte de rendu
     */
    public final TextRenderer textRenderer = new TextRenderer(new Font("Arial", Font.BOLD, 18));
 
    /**
     * Initialise la scène opengl
     *
     * @param gl la ressource opengl
     */
    public abstract void init(GL gl);
 
    /**
     * Affiche la scène opengl
     *
     * @param gl la ressource opengl
     * @param width la largeur
     * @param height la hauteur
     * @return si quelque chose a été affiché (<code>true</code>)
     *          ou s'il n'y a plus rien à afficher
     *          et qu'il faut donc passer à la scène suivante (<code>false</code>)
     */
    public abstract boolean display(GL gl, int width, int height);
 
    /**
     * Crée une texture opengl carrée
     * 
     * @param gl
     * @param size
     * @return la texture
     */
    public Texture createTexture(GL gl, int size) {
        return createTexture(gl, size, size);
    }
 
    /**
     * Crée une texture opengl
     *
     * @param gl
     * @param width
     * @param height
     * @return
     */
    public Texture createTexture(GL gl, int width, int height) {
        // on génère la texture
        int[] id = new int[1];
        gl.glGenTextures(1, id, 0);
        ByteBuffer data = BufferUtil.newByteBuffer(width * height * 4);
        data.limit(data.capacity());
        // liaison de la texture
        gl.glBindTexture(GL.GL_TEXTURE_2D, id[0]);
        // on remplit la texture
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 4, width, height, 0,
                GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, data);
        // on spécifie les paramètres de texture
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
        // on renvoie la texture
        return new Texture(id[0], width, height);
    }
    /**
     * Texture actuellement utilisée
     */
    private Texture texture;
 
    /**
     * Démarre le processus de texture
     *
     * @param gl
     * @param texWidth
     * @param texHeight
     */
    public void beginTexture(GL gl, Texture texture) {
        // viewport de la texture
        gl.glViewport(0, 0, texture.width, texture.height);
        this.texture = texture;
    }
 
    /**
     * Finit le processus de texture
     * 
     * @param gl
     * @param frameWidth
     * @param frameHeight
     */
    public void endTexture(GL gl, int frameWidth, int frameHeight) {
        // on lie la texture
        gl.glBindTexture(GL.GL_TEXTURE_2D, texture.id);
 
        // copie du viewport dans la texture, sans bordure
        gl.glCopyTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_LUMINANCE, 0, 0, texture.width, texture.height, 0);
 
        // on efface l'écran
        gl.glClearColor(0.0f, 0.0f, 0f, 0.5f);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
 
        // on rétablit le viewport normal (non-texture)
        gl.glViewport(0, 0, frameWidth, frameHeight);
    }
 
    /**
     * Blur d'une texture
     *
     * @param gl
     * @param frameWidth
     * @param frameHeight
     * @param texture
     * @param times
     */
    public void blur(GL gl, int frameWidth, int frameHeight,
            Texture texture, int times) {
        float spost = 0.0f;						// Starting Texture Coordinate Offset
        float alphainc = 0.9f / times;					// Fade Speed For Alpha Blending
        float alpha = 0.2f;						// Starting Alpha Value
        float inc = 0.02f;
 
        // Disable AutoTexture Coordinates
        gl.glDisable(GL.GL_TEXTURE_GEN_S);
        gl.glDisable(GL.GL_TEXTURE_GEN_T);
 
        gl.glEnable(GL.GL_TEXTURE_2D);					// Enable 2D Texture Mapping
        gl.glDisable(GL.GL_DEPTH_TEST);					// Disable Depth Testing
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE);				// Set Blending Mode
        gl.glEnable(GL.GL_BLEND);						// Enable Blending
        gl.glBindTexture(GL.GL_TEXTURE_2D, texture.id);			// Bind To The Blur Texture
 
        viewOrtho(gl, frameWidth, frameHeight);
        alphainc = alpha / times;					// alphainc=0.2f / Times To Render Blur
 
        gl.glBegin(GL.GL_QUADS);						// Begin Drawing Quads
        for (int num = 0; num < times; num++) // Number Of Times To Render Blur
        {
            gl.glColor4f(1.0f, 1.0f, 1.0f, alpha);		// Set The Alpha Value (Starts At 0.2)
            gl.glTexCoord2f(0 + spost, 1 - spost);			// Texture Coordinate	(   0,   1 )
            gl.glVertex2f(0, 0);				// First Vertex		(   0,   0 )
 
            gl.glTexCoord2f(0 + spost, 0 + spost);			// Texture Coordinate	(   0,   0 )
            gl.glVertex2f(0, frameHeight);				// Second Vertex	(   0, 480 )
 
            gl.glTexCoord2f(1 - spost, 0 + spost);			// Texture Coordinate	(   1,   0 )
            gl.glVertex2f(frameWidth, frameHeight);				// Third Vertex		( 640, 480 )
 
            gl.glTexCoord2f(1 - spost, 1 - spost);			// Texture Coordinate	(   1,   1 )
            gl.glVertex2f(frameWidth, 0);				// Fourth Vertex	( 640,   0 )
 
            spost += inc;					// Gradually Increase spost (Zooming Closer To Texture Center)
            alpha = alpha - alphainc;			// Gradually Decrease alpha (Gradually Fading Image Out)
        }
        gl.glEnd();							// Done Drawing Quads
 
        viewPerspective(gl, frameWidth, frameHeight);
 
        gl.glEnable(GL.GL_DEPTH_TEST);					// Enable Depth Testing
        gl.glDisable(GL.GL_TEXTURE_2D);					// Disable 2D Texture Mapping
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
    }
 
    /**
     * Vue orthogonale
     *
     * @param gl
     * @param width
     * @param height
     */
    public static void viewOrtho(GL gl, int width, int height) {
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glPushMatrix();
        gl.glLoadIdentity();
        gl.glOrtho(0, width, height, 0, -1, 1);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPushMatrix();
        gl.glLoadIdentity();
    }
 
    /**
     * Vue en perspective
     * 
     * @param gl
     * @param width
     * @param height
     */
    public static void viewPerspective(GL gl, int width, int height) {
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glPopMatrix();
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPopMatrix();
    }
 
    /**
     * Texture d'affichage
     */
    public class Texture {
 
        /**
         * Identifiant de la texture
         */
        public final int id;
        /**
         * Largeur de la texture
         */
        public final int width;
        /**
         * Hauteur de la texture
         */
        public final int height;
 
        public Texture(int id, int width, int height) {
            this.id = id;
            this.width = width;
            this.height = height;
        }
    }
}
et
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
public class EntryScene extends Scene{
 
    /**
     * Texte de bienvenue
     */
    private String welcome = String.format("Welcome %s", System.getProperty("user.name", "the holy man"));
    private Rectangle2D wbounds = textRenderer.getBounds(welcome);
 
    private Texture screen;
 
    private Loader loader = new Loader();
 
    @Override
    public void init(GL gl){
        screen = createTexture(gl, 128);
    }
 
    @Override
    public boolean display(GL gl, int width, int height) {
        // on capture l'écran
        beginTexture(gl, screen);
        // affichage
        displayText(gl, width, height);
        drawLine(gl);
        // on stoque cela en texture
        endTexture(gl, width, height);
        // reaffichage
        displayText(gl ,width, height);
        drawLine(gl);
        blur(gl, width, height, screen, 25);
 
        // loader.display(gl, 50, 50, 150, 210);
        // flush
        gl.glFlush();
        return true;
    }
 
    public void drawLine(GL gl){
        gl.glLoadIdentity();  // Reset The Modelview Matrix
        gl.glPushMatrix();
        gl.glBegin(GL.GL_LINES);
        gl.glVertex2i(20, 20);
        gl.glVertex2i(200, 200);
        gl.glEnd();
        gl.glPopMatrix();
    }
 
    public void displayText(GL gl, int width, int height){
        textRenderer.beginRendering(width, height);
        // affichage
        textRenderer.setColor(Color.green);
        textRenderer.draw(welcome, (int)(width - wbounds.getWidth()) / 2, (int)(height - wbounds.getHeight()) / 2);
        textRenderer.endRendering();
    }
 
}
Malheureusement, ça affiche bien la partie graphique, mais la texture doit être vide car le blur ne donne rien du tout.
Qu'est-ce qui coince ?

Autre question sur le code :
- je vois que l'exemple utilise glFlush à la fin, est-ce utile, même avec jogl ? je crois que jogl le fait automatiquement tout seul, non ?
- dans l'exemple jogl, j'ai vu que le pushMatrix et popMatrix était nécessaire pour afficher quelque chose, c'est normal où c'est juste un problème de caméra ?

PS : les classes spéciales, genre GLDisplay viennent des tutoriaux de Nehe.