Bonjour,
J'utilise OpenGL dans une application react-native, je dois mappé la surface avec des tiles.
Pour pouvoir m'adapter à toute taille d'écran, j'ai crée chaque tile avec une taille de 256px et j'utilise le mipmapping couplé à un filtre linear pour dessiner chaque tile à une taille voulu (toujours inférieur à 256).
Le problème est que, lorsque je dessine les tiles dans une taille qui n'est pas POT (power of two), je me retrouve avec des lignes entre les tiles (cf l'image suivante).
Lorsque je force la taille de mes tiles à se dessiner en POT, le problème ne survient pas.
Voici mon code qui me sert à créer une texture:
Et celui qui me sert à la dessiner:
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 createTextureFromAsset(asset) { const gl = this._gl; const tex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255])); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP, gl.TRUE); const textureInfo = { width: asset.width, height: asset.height, texture: tex, }; gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, asset.width, asset.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, asset); gl.generateMipmap(gl.TEXTURE_2D); return (textureInfo); }
(le code complet de la classe est disponible ici: https://pastebin.com/3V2wJE55)
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 // ctx.drawImage(tex, texWidth, texHeight, dstX, dstY); // ctx.drawImage(tex, texWidth, texHeight, dstX, dstY, dstWidth, dstHeight); drawImage(tex, texWidth, texHeight, srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight, srcRotation) { var gl; gl = this._gl; if (dstX === undefined) { dstX = srcX; srcX = 0; } if (dstY === undefined) { dstY = srcY; srcY = 0; } if (srcWidth === undefined) { srcWidth = texWidth; } if (srcHeight === undefined) { srcHeight = texHeight; } if (dstWidth === undefined) { dstWidth = srcWidth; srcWidth = texWidth; } if (dstHeight === undefined) { dstHeight = srcHeight; srcHeight = texHeight; } if (srcRotation === undefined) { srcRotation = 0; } gl.bindTexture(gl.TEXTURE_2D, tex); gl.useProgram(this._program.texture); gl.bindBuffer(gl.ARRAY_BUFFER, this._positionBuffer); gl.enableVertexAttribArray(this._locations.texture.position); gl.vertexAttribPointer(this._locations.texture.position, 2, gl.FLOAT, false, 0, 0); var matrix = m4.orthographic(0, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, -1, 1); matrix = m4.translate(matrix, dstX, dstY, 0); matrix = m4.scale(matrix, dstWidth, dstHeight, 1); gl.uniformMatrix4fv(this._locations.texture.matrix, false, matrix); var texMatrix = m4.scaling(1 / texWidth, 1 / texHeight, 1); var texMatrix = m4.translate(texMatrix, srcX + srcWidth * 0.5, srcY + srcHeight * 0.5, 0); var texMatrix = m4.zRotate(texMatrix, srcRotation); var texMatrix = m4.translate(texMatrix, -(srcX + srcWidth * 0.5), -(srcY + srcHeight * 0.5), 0); var texMatrix = m4.translate(texMatrix, srcX, srcY, 0); var texMatrix = m4.scale(texMatrix, srcWidth, srcHeight, 1); gl.uniformMatrix4fv(this._locations.texture.textureMatrix, false, texMatrix); gl.uniform1i(this._locations.texture.texture, 0); gl.drawArrays(gl.TRIANGLES, 0, 6); }
J'ai testé plusieurs config pour le filtre TEXTURE_MIN_FILTER:
- NEAREST: ne cause pas le problème mais tiles pixelisé (evidemment)
- LINEAR: ne cause pas le problème mais tiles toujours un peu pixelisé
- LINEAR_MIPMAP_LINEAR: problème présent
- LINEAR_MIPMAP_NEAREST: problème présent
Mes images utilisent déjà des alpha pré-multipliées.
En espérant pouvoir trouver de l'aide ici,
Merci d'avance.
Partager