Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

Texture non puissance de 2


Sujet :

OpenGL

  1. #1
    Futur Membre du Club
    Texture non puissance de 2
    Bonjour,

    J'ai parcouru un bon nombre de tutorial sur internet qui assurent de devoir utiliser une image dont les dimensions sont puissance de 2 en tant que texture.
    Mais aucun tutorial n'explique pourquoi. Ou certains affirment que la carte graphique ne le supporte pas.


    J'ai à utiliser des images non carrées, et au moment de réaliser mon programme OpenGL, je ne connaissais pas cette limitation. J'ai programmé l'affichage de la texture de la sorte :
    (j'utilise jogl)

    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
     
    	gl.glColor3f(1.0f, 1.0f, 1.0f);
            gl.glEnable(GL.GL_TEXTURE_2D);
     
            textures[currentTexture].bind();
            textureRatio = textures[currentTexture].getAspectRatio();
     
            if(textureRatio>=1) {
                gl.glBegin(GL.GL_QUADS);
                gl.glTexCoord2f(0, 0); gl.glVertex2f(-textureRatio, 1);
                gl.glTexCoord2f(1, 0); gl.glVertex2f(textureRatio, 1);
                gl.glTexCoord2f(1, 1); gl.glVertex2f(textureRatio, -1);
                gl.glTexCoord2f(0, 1); gl.glVertex2f(-textureRatio, -1);
                gl.glEnd();
            }else{
                textureRatio = 1/textureRatio;
                gl.glBegin(GL.GL_QUADS);
                gl.glTexCoord2f(0, 0); gl.glVertex2f(-1, textureRatio);
                gl.glTexCoord2f(1, 0); gl.glVertex2f(1, textureRatio);
                gl.glTexCoord2f(1, 1); gl.glVertex2f(1, -textureRatio);
                gl.glTexCoord2f(0, 1); gl.glVertex2f(-1, -textureRatio);
                gl.glEnd();
            }
     
            gl.glBindTexture(GL.GL_TEXTURE_2D, 0);



    Et je n'ai aucun problème apparent.

    Alors ma question,
    - Est ce que ce que je fais est contraire à la "bonne programmation" OpenGL ?
    - Mon programme est basé sur la rapidité d'affichage, donc je me demandais si cette "méthode" influait sur les performances ?


    Merci d'avance

  2. #2
    Membre confirmé
    Bonjour,

    la restriction aux textures de dimensions "puissance de 2" a été levée à partir d'OpenGL 2.0. Sur les cartes plus anciennes, c'est au cas par cas: soit il n'y rien de prévu et il FAUT une puissance de 2, soit des extensions sont implémentées, qui permettent d'utiliser n'importe quelle texture.

    - Est ce que ce que je fais est contraire à la "bonne programmation" OpenGL ?
    Disons que si votre programme est lancé sur un PC doté d'une vieille carte graphique, ca risque de poser des problèmes...
    Dans mes programmes, lau moment de charger une texture je fais comme ca:
    1 - Verifier si les textures "non puissance de 2" sont supportées. Si oui, on charge sans se poser de question
    2 - Si non, on vérifie les dimensions de la texture, et si elle n'est pas puissance de 2, on la redimensionne (avec gluScaleImage).

    Je peux vous donner le code qui fait ca si vous voulez. Et après, quoiqu'il arrive, ca marchera!

    - Mon programme est basé sur la rapidité d'affichage, donc je me demandais si cette "méthode" influait sur les performances ?
    Il me semble que même si les textutes de taille arbitraire sont supportées, il est toujours plus rapide pour la carte graphique de travailler avec des puissances de 2. Après, il me semble comme dit, donc...à confirmer!

  3. #3
    Membre expert
    les textures en non puissance de 2 ne sont simplement pas supportées sur toutes les cartes graphiques, surtout celles un peu ancienne, pour du hardware moderne, normalement ce n'est pas le cas.

    ensuite, il est possible que certaines opérations sur les textures en puissance de 2 soient plus rapides, mais là ça dépend des implémentations des algos tant sur le plan logiciel que sur le plan matériel.

    disons donc qu'en utilisant des textures en puissance de 2, tu es sur de pas avoir ni d'incompatibilité ni de perte de performance.

  4. #4
    Futur Membre du Club
    Merci beaucoup pour vos réponses.

    Mon programme n'est pas déstiné à être utilisé avec des cartes graphiques anciennes. Donc je peux garder ma méthode.


    Concernant les performances, j'ai effectué de simple test.
    Avec une image basique non carré (1400*2900), et en prenant son "équivalent" carré (j'ai rajouté des bordures sur les cotés, 2900*2900)
    J'ai mesuré le temps d'affichage de 1.000 frames, et je n'ai constaté aucune différence.

    Je referai des tests plus tard dans le développement pour voir si ce paramètre influe sur certaines fonctions.

    Encore merci pour vos réponses si rapide !

  5. #5
    Membre expérimenté
    Citation Envoyé par Bertrand88 Voir le message

    Concernant les performances, j'ai effectué de simple test.
    Avec une image basique non carré (1400*2900), et en prenant son "équivalent" carré (j'ai rajouté des bordures sur les cotés, 2900*2900)
    J'ai mesuré le temps d'affichage de 1.000 frames, et je n'ai constaté aucune différence.
    Ton test est invalide, ta texture "carrée" n'a toujours pas de dimensions puissance de deux (puissance de deux = 1, 2, 4 , 8, 16, 32, .. 512, 1024, 4096 etc).

    Une texture puissance de deux peut être rectangulaire (1024x256). Les cartes graphiques supportent les textures rectangulaires depuis la nuit des temps et si tu en trouves une qui ne les supporte pas elle a sans doute sa place dans un musée. Pour les textures non puissance de deux, leur support complet est beaucoup plus récent, mais il y a eu un support partiel un peu plus ancien. En fait elles sont apparues quand il a fallu supporter le Render to Texture. Le backbuffer lié à la taille de l'écran n'étant généralement pas une puissance de deux (768, 1280, 640 etc).

    Pour les différences de perf entre texture puissance de deux et textures non puissance de deux, le problème est un peu complexe. Si tu fais de la programmation un peu avancée tu as besoin des détails sinon, tu te contentes de suivre les recommandations (puissance de deux recommandées).

    Pour quelques petits détails :
    - une texture puissance de deux est optimisée pour les degrés de mipmaps. La mipmap étant décomposée en suite de textures de taille moitié moindre, pour une texture de 1024, tu as la décomposition naturelle : 512->256->128->64->32->16->8->4. Si tu as une texture non puissance de deux, un niveau ou plus de mipmap suivant le choix d'implémentation sera soit trop filtré, soit pas assez filtré.
    - Les anciennes cartes graphiques avaient une représentation des textures que l'on appelait "swizzled". Swizzled c'est comme un pavage du plan fractal (Peano, Hilbert, boustrophédon). L'intérêt du swizzled est la moindre importance des directions privilégiées pour le cache de texture.. Mais leur inconvénient est leur incompatibilité avec le sens de rasterisation classique, et la contrainte sur les dimensions (textures swizzled typiquement puissance de deux). Les nouvelles cartes graphiques ont d'autres représentations possibles pour les textures.
    - même si une carte graphique a une autre représentation possible pour les textures ce n'est pas forcément optimal. Par exemple les cartes comme le Geforce series 6/7 (6800/7900 etc), la lecture est optimale en swizzled mais l'écriture est optimale dans un autre format. Donc pour les textures en lecture seul il est important que la texture soit swizzled (et/où compressée avec DXTC si possible) donc avec des dimensions puissance de deux. Ces cartes graphiques ne sont pas si anciennes que ça et elles sont toujours parties du hardware de la Playstation 3 par exemple.

    LeGreg

    Mon site web | Mon blog | Mes photos | Groupe USA
    > BONJOUR, JE SUIS NOUVEAU SUR CE FORUM
    > presse la touche caps lock, stp
    > OH.. MERCI C EST BEAUCOUP PLUS FACILE COMME CA

  6. #6
    Futur Membre du Club
    Ah oui j'avoue, je ne sais pas pourquoi je m'etais mis dans la tête "multiple de 2"...

    J'ai refait un simple test avec mon image précédente (1300*6500 - je l'ai agrandie pour avoir à peu près le même nombre de pixel que l'autre) et la même avec des dimensions puissances de 2 (1024*8192)

    Je n'ai vue aucune différence notable.
    Bon d'accord le test est très simple, mais il est suffisant pour mon projet à l'état actuel.



    J'aurai dû le préciser avant, je n'utilise que des fonctions très basiques d'OpenGL.
    Je ne fais qu'afficher une texture sur la majeure partie de l'écran, une partie de cette même texture à un autre endroit de l'écran. Et une autre petite texture à côté.
    En fait je n'ai aucun aspect 3D dans mon programme, mais j'ai besoin d'OpenGL car j'utilise les pixel shader.

    Donc pour répondre à ton premier détail. Je n'utilise pas du tout de mipmap. Je les ai désactivé partout.
    Et concernant les autres détails dont tu parles, j'ai recherché sur internet, mais je t'avoue que mon niveau en OpenGL n'est pas suffisant pour le moment pour comprendre.
    Si vraiment je constate des différences de performances, je m'y pencherai plus sérieusement.



    En tout cas merci beaucoup pour ta réponse.
    Je posterai si je rencontre des problèmes plus tard.

###raw>template_hook.ano_emploi###