Précédent   Forum des professionnels en informatique > Applications > Développement 2D, 3D et Jeux > API graphiques > OpenGL
OpenGL Forum d'entraide sur le développement en OpenGL. Avant de poster -> FAQ OpenGL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 06/12/2011, 17h40   #1
Invité régulier
 
Inscription : novembre 2008
Messages : 23
Détails du profil
Informations forums :
Inscription : novembre 2008
Messages : 23
Points : 5
Points : 5
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.
ZeroDono est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2011, 02h38   #2
Membre Expert
 
Programmeur
Inscription : août 2002
Messages : 1 034
Détails du profil
Informations personnelles :
Localisation : Etats-Unis

Informations professionnelles :
Activité : Programmeur

Informations forums :
Inscription : août 2002
Messages : 1 034
Points : 1 310
Points : 1 310
Envoyer un message via ICQ à LeGreg
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
LeGreg est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2011, 07h43   #3
Invité régulier
 
Inscription : novembre 2008
Messages : 23
Détails du profil
Informations forums :
Inscription : novembre 2008
Messages : 23
Points : 5
Points : 5
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?
ZeroDono est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/12/2011, 14h10   #4
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 349
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 349
Points : 2 507
Points : 2 507
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
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2011, 10h47   #5
Invité régulier
 
Inscription : novembre 2008
Messages : 23
Détails du profil
Informations forums :
Inscription : novembre 2008
Messages : 23
Points : 5
Points : 5
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.
ZeroDono est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2011, 11h03   #6
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 349
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 349
Points : 2 507
Points : 2 507
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.
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2011, 14h26   #7
Membre Expert
 
Avatar de oxyde356
 
Homme
Ingénieur Recherche Imagerie
Inscription : février 2006
Messages : 795
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur Recherche Imagerie

Informations forums :
Inscription : février 2006
Messages : 795
Points : 1 062
Points : 1 062
Envoyer un message via MSN à oxyde356
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).
__________________
Computer Graphics Universe
oxyde356 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/12/2011, 19h14   #8
Invité régulier
 
Inscription : novembre 2008
Messages : 23
Détails du profil
Informations forums :
Inscription : novembre 2008
Messages : 23
Points : 5
Points : 5
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?
ZeroDono est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2011, 20h15   #9
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 349
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 349
Points : 2 507
Points : 2 507
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.
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 21h57.


 
 
 
 
Partenaires

Hébergement Web