2011-09-11 4 views
5

J'ai eu une erreur de segmentation lorsque j'ai essayé de charger une image 771x768. Essayé avec une image 24x24 et 768x768 et ils ont travaillé, pas de problème.glTexImage2D Segfault lié à la largeur/hauteur

Est-ce prévu? Pourquoi ne pas simplement échouer gracieusement avec une erreur GL?

L'erreur de segmentation se produit dans l'appel glTexImage2D. Je charge un fichier binaire PPM afin qu'il soit compressé 24 bits par pixel. Ce nombre impair combiné avec une dimension impaire produit probablement une structure alignée non-4 octets (ou même 2 octets) (et le référencement en dehors de mon tampon alloué exactement assez peut être la cause de l'erreur mais gdb ne me montre pas de mémoire adresse (que je pourrais utiliser pour savoir si c'est ce qui le provoque)).

glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, dataptr); 
// in this specific case of failure, width = 771, height = 768, 
// dataptr contains 1776384 bytes of binary RGB image data (771*768*3 = 1776384) 
+2

D'où vient le segfault? À quoi ressemble votre code? – Goz

+0

question mise à jour avec quelques détails. Je pense avoir une idée de ce qui ne va pas. Besoin de tester plus. –

+0

Toujours pas de code cependant. – Goz

Répondre

14

Ce nombre impair associée à une dimension impaire produit probablement une structure alignée non-4-octet (ou même 2 octets) (et de référencement en dehors de ma tampon assez exactement alloué peut être la cause de l'erreur

C'est probablement la cause. Heureusement, vous pouvez définir l'alignement OpenGL utilise la lecture des données de pixels. Juste avant d'appeler glTexImage…(…) faire

glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 
+0

Cela a fait l'affaire. –

+0

Existe-t-il un lien pour en savoir plus sur la structure alignée 4/2-octets? –

+1

@BenediktBock: Il n'y a pas vraiment grand-chose. n-alignement signifie simplement que le début d'un ensemble particulier de données (une ligne de pixels, un pixel lui-même) arrive donc à une adresse mémoire qui est un multiple entier de n. La plupart des architectures de CPU ont certaines restrictions d'alignement, il faut suivre; par exemple, ARM 32 bits veut que tout soit aligné à 16 bits = 2 octets ou 32 bits = 4 octets (en fonction de la version de l'architecture ARM). Les processeurs Intel peuvent effectuer des opérations atomiques uniquement avec un alignement de 4 octets. Vous trouverez donc des formats de structure qui alignent les données sur n = 2, 4 ou 8 pour simplifier les choses. – datenwolf

1

Je l'ai lu dans les forums opengl:

width must be 2^m + 2(border) for some integer m. 
height must be 2^n + 2(border) for some integer n. 

(source)

J'ai trouvé ce que je crois qu'il clarifie ce qui se passe:

1. What should this extension be called? 

    STATUS: RESOLVED 

    RESOLUTION: ARB_texture_non_power_of_two. Conventional OpenGL 
    textures are restricted to size dimensions that are powers of two. 

de GL_ARB_texture_non_power_of_two

+0

Cela concerne uniquement OpenGL-1.x. Depuis les tailles de texture arbitraires OpenGL-2.x sont autorisés. – datenwolf

+0

Depuis que j'ai résolu le problème d'écrasement, j'ai écrit un petit test qui itère à travers toutes les permutations de paires d'entiers de 64 à 1024, en chargeant une texture avec ces dimensions. (par exemple 64x64, 64x65 ... 64x1024, 65x64, ...), Jusqu'à présent, il est presque à mi-chemin à travers les 921 600 résolutions possibles dans cet ensemble. Pas d'accidents, et pas de segfaults encore. Donc, oui, l'implémentation d'OpenGL que je suis en train d'exécuter semble accommoder des tailles de texture arbitraires, et je peux en témoigner parce que j'en ai chargé plus de 500 000 différentes. –