Comment détecter les formats de texture OpenGL pris en charge nativement?


10

Par exemple, comment détecter si ma carte vidéo ne prend pas en charge "bgr8" et la convertir en un autre format, tel que "rgba8" en mode logiciel.

MISE À JOUR: Désolé pour la confusion. Cette question concerne davantage la situation lorsque j'ai défini internalFormat dans glTexImage2D sur quelque chose comme "bgra8", mais que le pilote vidéo convertit en interne les données dans un autre format, comme "rgba8".

Réponses:


11

Votre question semble brouiller certains concepts, alors prenons les choses par le haut. Voici la définition de la fonction glTexImage2D:

void glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, void *data );

Il y a deux choses que vous pourriez appeler des "formats de texture". Le premier est le internalformatparamètre. Il s'agit du véritable format de l'image telle qu'OpenGL la stocke. Le formatparamètre décrit une partie du format des données de pixels que vous fournissez avec le dataparamètre.

Pour le dire autrement formatet typedéfinir à quoi ressemblent vos données. internalformatest la façon dont vous dites à OpenGL de stocker vos données. Appelons formatet typele "format de transfert de pixels", tandis que internalformatsera le "format d'image".

Le format d'image d'une texture ne peut jamais être "bgr8". Il n'y a pas d'énumérateur de format d'image GL_BGR8. Il y a une énumération GL_BGR, mais c'est pour le format de transfert de pixels, pas le format d'image.

Ou pour le dire autrement, vos données de pixels que vous donnez à OpenGL peuvent être stockées dans l'ordre BGR. Mais la mise en œuvre d'OpenGL décide seule de la façon de stocker réellement ces données de pixels. Peut-être qu'il le stocke dans un ordre peu endian. Peut-être qu'il le stocke en big-endian. Peut-être qu'il réorganise simplement arbitrairement les octets. Vous ne savez pas, et OpenGL ne fournit aucun moyen de le savoir.

Il n'y a aucun moyen de savoir si un ensemble particulier de paramètres de format de transfert de pixels correspond à la façon dont l'implémentation OpenGL les stockera compte tenu du format d'image.

Il y a un moyen de le dire maintenant. Et par "maintenant", je veux dire dans OpenGL 4.3 et / ou ARB_internalformat_query2. Venir sur une carte graphique près de chez vous:

GLenum format, type;
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_FORMAT, 1, &format);
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_TYPE, 1, &type);

formatet typeont maintenant l'implémentation préférée formatet typepour utiliser les glTex(Sub)Imageappels aux GL_RGBA8images. Il sont séparés formatet les typerequêtes pour les glReadPixelstéléchargements.

Il existe d' autres requêtes que vous pouvez effectuer .

Si vous n'y avez pas accès, vous pouvez utiliser certaines règles générales que la plupart des matériels respecteront:

  • stockera les données de pixels pour les données de 8 bits par canal dans l'ordre BGRA. Donc, si vous souhaitez faire correspondre le format avec vos données de pixels, afin de télécharger plus rapidement les données de texture, vous souhaitez utiliser GL_BGRApour le formatet GL_UNSIGNED_INT_8888ou GL_UNSIGNED_BYTEpour le type.
  • ne stockera pas réellement les couleurs 24 bits en 24 bits. Il les remplira toujours en 32 bits; l'alpha sera simplement ignoré lors de la lecture des données. Donc , si vous voulez faire correspondre les formats, utilisez toujours GL_BGRA formatavec les GL_RGB8formats d'image, même si vous devez mettre des données fictives dans le composant alpha.

4
J'ai également trouvé un meilleur format d'utilisation GL_BGRA avec internalFormat GL_RGBA http.download.nvidia.com/developer/Papers/2005/…
KindDragon

Je m'abstiendrais de renommer le paramètre internalFormat en "format d'image", car c'est tout aussi déroutant. Il est peut-être logique de penser à "internalFormat" comme au "format de pixel de texture". La combinaison de paramètres "format" et "type" est le "format de pixel source" (qui est souvent une image, d'où mon commentaire). Et puis bien sûr, il y a le format GPU, qui est BGRA pour les formats de type entier.
StarShine

6

Généralement, la plupart des matériels ne prennent pas en charge les formats de texture à 3 composants, donc dans cet exemple spécifique, vous pouvez faire une supposition raisonnablement sûre qu'il est converti. Une texture OpenGL à 3 composants est en fait à 4 composants dans le matériel, mais avec le composant alpha ignoré / défini sur 255 / peu importe.

https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_upload_and_pixel_reads (Cette page "erreurs courantes" est une mine d'or - ajoutez-la à vos favoris maintenant!)

Pour un cas plus général, les performances de glTexSubImage2D peuvent vous donner une bonne indication si le téléchargement doit ou non passer par un chemin de conversion logicielle. Vous iriez à ce sujet au démarrage du programme - créez simplement une texture vide (via glTexImage2D avec des données NULL), puis émettez un tas d'appels glTexSubImage2D, chacun suivi d'un glFinish pour vous assurer qu'il se termine. Ignorez le premier car des caches / états / etc sont en cours de configuration pour lui, et chronométrez les autres. Répétez cette opération pour quelques formats différents et choisissez le plus rapide.

Une autre alternative - vu que vous avez marqué cette question "Windows" - consiste à créer un périphérique D3D au démarrage (juste après avoir créé votre fenêtre mais avant de lancer OpenGL), puis utilisez D3D pour vérifier la prise en charge du format. Alors qu'OpenGL permet la conversion logicielle dans un format interne valide, D3D ne le fait pas - s'il n'est pas pris en charge par le matériel, vous ne pouvez pas le faire. Détruisez ensuite D3D et ouvrez OpenGL. (Cette technique peut également être utilisée pour interroger d'autres éléments qu'OpenGL ne vous permet pas d'interroger directement).

C'est en fait une règle d'or utile pour vérifier ce que vous faites dans OpenGL avec la documentation D3D. Si D3D ne peut pas faire quelque chose, cela peut être une bonne indication que le quelque chose en question n'est pas pris en charge par le matériel. Pas toujours vrai, mais un point de départ utile.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.