|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Invité régulier
![]() Inscription : novembre 2008 Messages : 23 ![]() |
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. |
|
|
00
|
|
|
#2 |
|
Membre Expert
![]() ![]() |
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 |
|
00
|
|
|
#3 |
|
Invité régulier
![]() Inscription : novembre 2008 Messages : 23 ![]() |
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? |
|
|
00
|
|
|
#4 |
|
Expert Confirmé
![]() Inscription : septembre 2010 Messages : 1 349 ![]() |
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 |
|
|
00
|
|
|
#5 |
|
Invité régulier
![]() Inscription : novembre 2008 Messages : 23 ![]() |
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.
|
|
|
00
|
|
|
#6 |
|
Expert Confirmé
![]() Inscription : septembre 2010 Messages : 1 349 ![]() |
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. |
|
|
00
|
|
|
#7 | ||
|
Membre Expert
![]() |
D'une manière général et optimale (bien que ça dépende de l'environnement) et de façon simplifiée :
Citation:
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:
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 |
||
|
10
|
|
|
#8 |
|
Invité régulier
![]() Inscription : novembre 2008 Messages : 23 ![]() |
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? |
|
|
00
|
|
|
#9 |
|
Expert Confirmé
![]() Inscription : septembre 2010 Messages : 1 349 ![]() |
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. |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com