Bonjour à tous sur ces forums de developpez.net. :)
(je suis tout nouveau ici ou presque car j'ai déjà lu pas mal d'articles du site et des posts mais je n'ai pas été inscrit jusque là...)
Bon, j'ai un problème avec jogl et la visualisation d'une (très) simple scène plus que basique. Il s'agit simplement d'un tile que j'applique en tant que texture sur le sol sur une pseudo-case.
L'application de base crée une JFrame, y ajoute un GLCanvas ainsi qu'un écouteur à ce dernier.
L'écouteur GLEventListener est une classe nommée ViewLoop.
De plus, j'ai une classe utilitaire nommée Tools qui contient des fonctions utiles dans mon cas pour les textures et autres traitements de la vue.
Soit déjà l'utilitaire Tools.java :
Bon, en fait je l'ai posté pour la partie de modification de la vue. J'ai réutilisé le code de cokeandcode (le jeu asteroid) principalement, mais je n'arrive pas réussi à faire ce que je veux... et c'est presque pire car les choses qui fonctionnent normalement (en simple 2d avec jogl) ne fonctionnent plus.Code:
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 public class Tools { /** * Modèle de couleur avec transparence pour opengl */ public static final ColorModel glAlphaColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[]{8, 8, 8, 8}, true, false, ComponentColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE); /** * Modèle de couleur sans transparence pour opengl */ public static final ColorModel glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[]{8, 8, 8, 0}, false, false, ComponentColorModel.OPAQUE, DataBuffer.TYPE_BYTE); /** * Charge une texture * * @param src la source * @return la texture */ public static Texture load(String src){ try{ BufferedImage img = ImageIO.read(new File(src)); return TextureIO.newTexture(resize(img), true); }catch(Exception e){ e.printStackTrace(); return null; } } /** * Renvoie la puissance de 2 la plus proche, * égale ou supérieure à un nombre. * * @param num le nombre * @return la puissance de 2 */ public static int asPower2(int num) { int b = 2; while (b < num) { b *= 2; } return b; } /** * Lie un identifiant à une image * transformée en texture. * * @param id l'identifiant * @param img l'image * @return la texture créée */ public static BufferedImage resize(BufferedImage img) { // image pour opengl BufferedImage glTex = null; // taille de l'image gl int width = asPower2(img.getWidth()); int height = asPower2(img.getHeight()); // création de l'image de bonne taille WritableRaster raster; boolean alpha = img.getColorModel().hasAlpha(); // 4 ou 3 ? le nombre de composantes (rgba ou rgb) if (alpha) { raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, 4, null); glTex = new BufferedImage(glAlphaColorModel, raster, false, new Hashtable()); } else { raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, 3, null); glTex = new BufferedImage(glColorModel, raster, false, new Hashtable()); } // dessin de l'image Graphics g = glTex.getGraphics(); g.setColor(new Color(0f, 0f, 0f, 0f)); g.fillRect(0, 0, width, height); g.drawImage(img, 0, 0, null); g.dispose(); GraphicsConfiguration configuration = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); BufferedImage glTexAlpha = configuration.createCompatibleImage(glTex.getWidth(), glTex.getHeight(), BufferedImage.TRANSLUCENT); Graphics g2 = glTexAlpha.getGraphics(); g2.drawImage(glTex, 0, 0, null); g2.dispose(); return glTexAlpha; } /** * Génère un nombre entier borné * * @param width la valeur maximale exclue * @return un nombre aléatoire */ public static int generate(int width) { return (int) Math.round(Math.random() * width); } /** * Initialise la vue utilisée pour afficher * les composants à l'écran. * * @param gl la ressource opengl * @see <a href="http://www.cokeandcode.com/node/315">http://www.cokeandcode.com/node/315</a> */ public static void initView(GL gl) { // enregistrement de l'état actuel gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT | GL.GL_ENABLE_BIT); gl.glPushMatrix(); gl.glLoadIdentity(); gl.glMatrixMode(GL.GL_PROJECTION); gl.glPushMatrix(); // nouvel état de projection gl.glLoadIdentity(); gl.glOrtho(0, 600, 400, 0, -1, 1); gl.glDisable(GL.GL_DEPTH_TEST); gl.glDisable(GL.GL_LIGHTING); } /** * Replace la vue par défaut. * * @param gl la ressource opengl * @see <a href="http://www.cokeandcode.com/node/315">http://www.cokeandcode.com/node/315</a> */ public static void disposeView(GL gl) { // remet en place la transformation par défaut gl.glPopMatrix(); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glPopMatrix(); gl.glPopAttrib(); } }
Le problème vient, à mon avis, des méthodes d'initialisation de la vue opengl qui se trouve dans ViewLoop.java :
Il y a deux gros problèmes :Code:
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 public class ViewLoop implements GLEventListener { /** * Animateur */ private Animator animator; /** * Initialise la vue * * @param drawable le composant opengl */ public void init(GLAutoDrawable drawable) { GL gl = drawable.getGL(); gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.glViewport(0, 0, 600, 400); animator = new Animator(drawable); animator.start(); init(gl); } /** * Initialise l'application * * @param gl le contexte opengl */ public void init(GL gl) { gl.glEnable(GL.GL_TEXTURE_2D); gl.glEnable(GL.GL_CULL_FACE); gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_DEPTH_TEST); gl.glDepthFunc(GL.GL_LEQUAL); gl.glEnable(GL.GL_LIGHTING); // define the properties for the perspective of the scene gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); new GLU().gluPerspective(45.0f, ((float) 600) / ((float) 400), 0.1f, 100.0f); gl.glMatrixMode(GL.GL_MODELVIEW); // chargement de la texture tex = Tools.load("tex.png"); } /** * Texture */ private Texture tex; /** * Système de rendu du texte */ private TextRenderer tr = new TextRenderer(new Font("Arial", 10, Font.PLAIN)); /** * Nombre de frames exécutées */ int fps = 0; /** * Fps à afficher */ float fpsText = 0f; /** * Dernière date */ long last = System.currentTimeMillis(); /** * Met à jour le rendu * * @param drawable le composant opengl */ public void display(GLAutoDrawable drawable) { GL gl = drawable.getGL(); // affichage d'une case texturée // tex.bind(); gl.glBegin(GL.GL_QUADS); quad: { gl.glNormal3i(0, 0, 1); gl.glTexCoord2i(0, 0); // gl.glTexCoord2f(0f, 0.5f); gl.glVertex3f(-1f, -1f, 0f); gl.glNormal3i(0, 0, 1); gl.glTexCoord2i(0, 1); // gl.glTexCoord2f(0.5f, 1f); gl.glVertex3f(1f, -1f, 0f); gl.glNormal3i(0, 0, 1); gl.glTexCoord2i(1, 1); // gl.glTexCoord2f(1f, 0.5f); gl.glVertex3f(1f, 1f, 0f); gl.glNormal3i(0, 0, 1); gl.glTexCoord2i(1, 0); // gl.glTexCoord2f(0.5f, 0f); gl.glVertex3f(-1f, 1f, 0f); } gl.glEnd(); // fps fps: { long time = System.currentTimeMillis(); long diff = time - last; if (diff >= 1000) { fpsText = fps; last = time; fps = 0; } else { fps++; } // affichage Tools.initView(gl); tr.beginRendering(600, 400); tr.draw(String.format("%5.2f fps", fpsText), 20, 20); tr.endRendering(); Tools.disposeView(gl); } } ...
1. Je ne vois absolument rien à l'écran... c'est tout noir... donc la texture 2D n'a pas été plaquée sur la case. Où alors je suis mal positionné ?
2. Le rendu du texte est totalement détruit - c'est la partie qui marche bien normalement... : je ne vois qu'un morceau de pixel blanc à l'écran qui correspondrait au texte - ce dernier a donc subit des dégats involontaires. :oops:
Alors voici mes quelques questions :
- à propos de la partie d'initialisation (glEnable & co), qu'est-ce qui est utile, qu'est-ce qui est inutile, qu'est-ce qui est faux ou mal placé ?
- je n'ai pas compris les états des matrices, PROJECTION ou MODEL_VIEW... ok, mais pourquoi avoir à définir un état et le remplacer directement par la suite, il ne sera jamais utilisé, non ?
- pourquoi faut-il empiler les deux matrices dans les fonctions utilitaires pour passer en mode ortho ?
- pourquoi le texte ne s'affiche-t-il pas normalement ?
- que faire pour que je puisse enfin voir ma texture appliquée sur une case au sol ?
- comment me positionner correctement avec la caméra ?
- comment fonctionne le système de perspective de GLU ?
- ai-je besoin de rappeller glNormal3x à chaque point vu que c'est toujours la même normale (0,0,1) ?
Ca fait beaucoup de questions et je dois avoir fait plusieurs idioties en reprenant le code de CokeAndCode, mais j'espère que ça ira malgré tout. ;)
Bonnes vacances en passant malgré qu'il fasse si chaud - heureux les nuages et autres orages !