IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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 :

OpenGL et les textures


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 23
    Par défaut OpenGL et les textures
    Bonjour,

    J'essaie de comprendre tous les aspects d'OpenGL et de la 3D en général, et je bloque sur un problème concernant les fonctions glActiveTexture() et glClientActiveTexture().
    Je pense que je ne saisis pas ce qui se passe en amont en fait, donc je vais m'assurer que je comprend bien de quoi il en retourne (arretez moi si je me trompe).

    glGenTextures() reserve un nom de texture. Elle doit certainement maintenir une liste des noms utilisés et en retourne un qui ne l'est pas, de manière à éviter les collisions. Je pense que ça doit se passer côté client.
    glBindTexture() lie un nom de texture au contexte OpenGL, et tous les appels suivants qui touchent aux textures seront fait sur cette texture.
    Question n°1 : que se passe-t-il lors de l'appel à cette fonction? (est-ce que ça agit sur le hardware, est-ce que ça provoque un changement d'état côté client, ...)
    glTexImage2D() défini l'image de la texture, ses dimensions, etc...
    Question n°2 : où est stockée cette image? (côté client/serveur, ...)
    glTexCoordPointer() défini les coordonnées de texture d'un modèle.
    Question n°3 : où sont stockées ces coordonnées? (côté client/serveur, ... je suppose que c'est côté client mais bon)

    Pour en revenir au problème initial, il me faut comprendre ce que sont les unités de textures. De ce que j'ai compris, ce sont des processus gérés par le hardware pour le traitement des textures. Donc si je comprend bien, quand on bind une texture ses données sont envoyées au hardware, ce qui fait qu'on peut utiliser plusieurs textures (une par unité de texture) sans à avoir à appeler glBindTexture() et donc sans renvoyer les données non?
    Si c'est bien le cas, le fonctionnement de glActiveTexure() me parait évident, mais qu'en est-il de glClientActiveTexture() ? Dans la mesure où les données des coordonnées de texture sont maintenues côté client, quel est l'interet de cette fonction?

    Encore une petite chose : que se passe-t-il s'il n'y a pas de GPU (comme ça peut être le cas sur une plateforme mobile comme Android), l'utilité des unités de textures est limitée non?

    J'utilise l'API OpenGL ES sur Android mais je suppose que le principe reste le même sur toutes les implémentations d'OpenGL.

    Merci d'avance à tous ceux qui prendront le temps de me lire.

  2. #2
    Membre Expert

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Par défaut
    Ce qu'il y a derrière ces appels de fonction est une une black box : tu n'as pas au premier degré (pour la fonctionnalité) à t'en soucier ni à savoir ce qui constitue un appel au hardware ou une émulation (pour la performance c'est une autre histoire).

    En première approche donc, ces fonctions font exactement ce que la spec dit de faire (modulo quelques bugs d'implémentation ou specs imprécises). La manière dont c'est réalisé n'est pas ton problème.

    Les unités de texture décrites dans la doc sont des unités de texture logique (et non physique): elles représentent une fonctionnalité là encore qui peut correspondre à une ou plusieurs ressources physiques voire à des ressources partagées.

    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

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 23
    Par défaut
    Merci de ta réponse.

    Donc en fait OpenGL fourni un mécanisme d'unité de textures interne, et fait appel ou non au hardware ce qui explique qu'il y en ai quand même 2 même sans GPU. Ok je comprend mieux.

    Reste que je ne suis pas sûr de comprendre la différence entre glActiveTexture() et glClientActiveTexture(). Prenons un exemple : j'ai une scène avec 2 modèles, chacun ayant une texture différente (donc 2 textures en tout). Au premier rendu, je bind la texture 1 sur l'unité de texture 0 et la texture 2 sur l'unité de texture 1. J'envoi les coordonnées de texture du modèle 1 sur l'unité de texture 0, et celles du modèle 2 sur l'unité de texture 1. Dans les rendus suivants, je n'ai plus besoin de "rebinder" les textures ni de renvoyer les coordonnées, je n'ai qu'a faire un glActiveTexture() et un glClientActiveTexture() avec le bon numéro d'unité de texture je me trompe?

  4. #4
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Bonjour.

    glClientActiveTexture n'est utilisé que pour spécifier glTexCoordPointer et l'état correspondant. En somme, pour un développement moderne avec un pur pipeline programmable (où les coordonnées sont spécifiées en attribut du shader) on n'en n'a pas besoin.

    Pour du vieux OpenGL, en revanche, on peut très bien faire :
    // Préparation du rendu
    - glActiveTexture 1
    - Spécifier la texture n°1
    - glActiveTexture 2
    - Spécifier la texture n°2

    // Rendu
    - glClientActiveTexture 1
    - glEnable -- texcoords
    - glTexCoordPointer
    - glClientActiveTexture 2
    - glEnable -- texcoords
    - glTexCoordPointer
    - glDrawArrays

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 23
    Par défaut
    Ok donc ce n'est utile que pour faire du multi texturing en fait? Je pensais qu'on pouvais l'utiliser pour ne pas avoir à switcher de texture et éviter le reupload des données des textures.

  6. #6
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Apparemment, tu ne m'as pas bien compris.

    Ton besoin ou non d'utiliser glClientActiveTexture dépend uniquement de la façon dont tu utilises OpenGL :
    * pipeline fixe/mixte (à l'ancienne) : les coordonnées de texture sont spécifiées via glTexPointer et tu dois donc auparavant avoir sélectionné la bonne unité via glClientActiveTexture.
    * pur pipeline programmable (OpenGL 2+) : les coordonnées de textures sont spécifiées comme attribut du shader, pas besoin d'appeler glClientActiveTexture.

    Les deux méthodes permettent de faire ce que tu veux : utiliser les deux unités de textures pour rendre deux objets en un seul batch alors qu'ils utilisent chacun une texture distincte.

  7. #7
    Membre très actif Avatar de oxyde356
    Homme Profil pro
    Ingénieur Recherche Imagerie
    Inscrit en
    Février 2006
    Messages
    797
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Recherche Imagerie

    Informations forums :
    Inscription : Février 2006
    Messages : 797
    Par défaut
    D'une manière général et optimale (bien que ça dépende de l'environnement) et de façon simplifiée :

    Citation Envoyé par ZeroDono Voir le message
    glGenTextures() reserve un nom de texture. Elle doit certainement maintenir une liste des noms utilisés et en retourne un qui ne l'est pas, de manière à éviter les collisions. Je pense que ça doit se passer côté client.
    glBindTexture() lie un nom de texture au contexte OpenGL, et tous les appels suivants qui touchent aux textures seront fait sur cette texture.
    Question n°1 : que se passe-t-il lors de l'appel à cette fonction? (est-ce que ça agit sur le hardware, est-ce que ça provoque un changement d'état côté client, ...)
    A l'appel de glGenTextures, un objet texture est crée côté serveur, l'identifiant que tu reçois côté client est l'équivalent d'un pointeur sur cet objet. Il n'y a pas d'allocation mémoire pour la texture à proprement dit, juste pour l'objet texture qui ne contient pas encore de donnée, en gros il contient un pointeur sur données init à NULL pour l'instant.
    A l'appel de glBindTexture tu lui donne l'identifiant de la texture que tu veux utilisé, du côté serveur il va stocké l'identifiant que tu lui donne (qui correspond à une texture) dans un registre (ça dépend lequel selon le texture stage [texture unit sur opengl je crois] activé). Quand un shader ou le pipeline fixe passera à l'étape de rasterization, il vérifiera si le texturing est activé et ira chercher le registre qui convient pour voir quel identifiant (celui que tu as bindé) et donc qu'elle texture il doit utiliser, selon le format et les param que tu auras définis et qui est lié à l'objet texture qui est côté serveur donc.

    Citation Envoyé par ZeroDono Voir le message
    glTexImage2D() défini l'image de la texture, ses dimensions, etc...
    Question n°2 : où est stockée cette image? (côté client/serveur, ...)
    Cette fonction est LA fonction d'initialisation d'un objet texture. Plus que définir, elle alloue aussi la mémoire pour la texture à proprement dit (et donc init le pointeur auquel je faisais référence dans le paragraphe précédent). Tout est côté serveur, la carte graphique doit pouvoir travailler le plus vite possible avec les données de la texture (grand nombre de fetch) il faut bien sûr que celle-ci soit stocké sur la mémoire graphique.

    Citation Envoyé par ZeroDono Voir le message
    glTexCoordPointer() défini les coordonnées de texture d'un modèle.
    Question n°3 : où sont stockées ces coordonnées? (côté client/serveur, ... je suppose que c'est côté client mais bon)
    Cette fois je ne continuerais pas dans l'optimalité. En gros il y a deux possibilités, ou tes coordonnées de textures sont dans la ram via un vertex array (VA) et donc le pointeur que tu renseigne pointe sur la mémoire centrale, ou bien (et c'est plus optimal) tu as renseigné précédemment que le buffer de base est un vertex buffer object (VBO) et le pointeur que tu renseigne dans glTexCoordPointer n'est alors plus qu'un offset pour situer où commence les coordonnées de texture dans ce buffer. Là c'est transparent car le VBO peut être dans la mémoire centrale comme dans la mémoire graphique bien qu'il soit incomparablement plus avantageux qu'il soit stocké dans la ram graphique dans la grande majorité des cas (hormis celui où les données changent à chaque frame, tout dépend ce que tu en fais).

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 23
    Par défaut
    Désolé pour le retard...

    Merci pour toutes ces précisions

    Encore une petite question. Sur une scène basique (une surface de quatre points) j'ai essayé de rendre la scène avec une seule texture, sur l'unité de texture 1 (donc avec les textures désactivées sur l'unité 0) et l'application plante directement, sans même un message d'erreur. Est-ce le comportement normal ou est-ce que j'aurais pu faire une boulette?

  9. #9
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Non, pour autant que je sache, les commandes OpenGL ne devraient jamais provoquer de plantage, freeze ou autre (sauf shader qui bouclerait à l'infini - et encore, maintenant ces blocages sont détectés). Toutes les erreurs OpenGL devraient être silencieuses et récupérées via glGetError.

    Donc soit c'est un bug du driver (ce qui est loin d'être rare - et encore, c'était bien pire il y a dix ans), soit cela n'a rien à voir et tu as fais une erreur quelque part dans ton code.

Discussions similaires

  1. SDL/Opengl : Probleme de texture avec les thread
    Par tektotodu96 dans le forum OpenGL
    Réponses: 3
    Dernier message: 25/04/2011, 01h42
  2. Conserver les texture OpenGL
    Par Max9419 dans le forum OpenGL
    Réponses: 1
    Dernier message: 03/03/2011, 02h12
  3. [OpenGL/C++] Opérations sur les Textures
    Par Bob.Killer dans le forum OpenGL
    Réponses: 6
    Dernier message: 10/08/2005, 10h27
  4. Afficher une image sans passer par les textures
    Par Black_Daimond dans le forum DirectX
    Réponses: 3
    Dernier message: 09/05/2003, 19h13
  5. OpenGL et les ATI ?
    Par Twofy dans le forum OpenGL
    Réponses: 4
    Dernier message: 11/09/2002, 16h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo