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 :
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 // 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; } } }
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
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; } } }Malheureusement, ça affiche bien la partie graphique, mais la texture doit être vide car le blur ne donne rien du tout.
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(); } }
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.
Partager