2010-12-05 7 views
0

Il y a quelque temps, j'ai converti un programme C# pour utiliser OpenGL et j'ai trouvé qu'il fonctionnait parfaitement (et plus rapidement) sur mon ordinateur à la maison. Cependant, j'ai 2 problèmes. Tout d'abord, le code que j'utilise pour libérer des textures de la carte graphique ne contient pas de mot, il me donne une exception de violation d'accès mémoire lors de l'exécution. Deuxièmement, la plupart des graphiques ne fonctionnent sur aucune autre machine que la mienne.Problèmes de qualité de la texture OpenGL

Par accident, j'ai réussi à convertir certains des graphiques en PNG 8 bits (tous les autres sont 32 bits) et ceux-ci fonctionnent bien sur d'autres machines. Reconnaissant cela, j'ai essayé de régler la qualité lors du chargement des images. Mes tentatives ont échoué (c'était il y a quelque temps, je pense qu'ils impliquaient en grande partie d'essayer de formater un bitmap puis d'utiliser le GDI pour dessiner la texture dessus, créant une version de qualité inférieure). Est-il possible dans .NET de prendre un bitmap et de bien changer la qualité? Le code concerné est ci-dessous. Je me souviens qu'il est largement basé sur certains que j'ai trouvé sur Stack Overflow dans le passé, mais qui ne correspondait pas tout à fait à mes besoins. 'img' comme image .NET, et 'd' est une dimension entière, que j'utilise pour m'assurer que les images sont carrées.

uint[] output = new uint[1]; 

Bitmap bMap = new Bitmap(img, new Size(d, d)); 

System.Drawing.Imaging.BitmapData bMapData; 
Rectangle rect = new Rectangle(0, 0, bMap.Width, bMap.Height); 

bMapData = bMap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bMap.PixelFormat); 

gl.glGenTextures(1, output); 
gl.glBindTexture(gl.GL_TEXTURE_2D, output[0]); 
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST); 

gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST); 
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP); 
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP); 
gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1); 
if (use16bitTextureLimit) 
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA_FLOAT16_ATI, bMap.Width, bMap.Height, 0, gl.GL_BGRA, gl.GL_UNSIGNED_BYTE, bMapData.Scan0); 
else 
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, bMap.Width, bMap.Height, 0, gl.GL_BGRA, gl.GL_UNSIGNED_BYTE, bMapData.Scan0); 

bMap.UnlockBits(bMapData); 
bMap.Dispose(); 

return output; 

Le « use16bitTextureLimit » est un bool, et je préfère le code affiché espéré réduirait la qualité 16bit, mais je havn't remarqué aucune différence. Il se peut que cela fonctionne et les cartes graphiques ne l'aiment toujours pas. J'ai été incapable de trouver une indication d'un moyen d'utiliser PNgs 8 bits. Il s'agit d'une fonction qui renvoie le tableau uint (en tant qu'adresse de texture) à utiliser lors du rendu. La texture défectueuse implique simplement: gl.glDeleteTextures(1, imgsGL[i]); Où imgGL est un tableau de matrices d'unités. Comme dit, le rendu est correct sur certains ordinateurs, et la suppression de texture provoque une erreur d'exécution sur tous les systèmes (sauf mon netbook, où je ne peux pas créer de textures, mais je pense que cela peut être lié à la qualité problème).

Si quelqu'un peut fournir des informations pertinentes, ce serait génial. J'ai passé plusieurs jours sur le programme, et voudrais vraiment plus compatible avec moins de bonnes cartes graphiques.

Répondre

0

Le type de violation d'accès que vous rencontrez se produit généralement si l'appel de glTexImage2D provoque un dépassement de la mémoire tampon. Vérifiez que tous les paramètres glPixelStore liés au déballage sont correctement définis et que le paramètre de format (le second) correspond au type et à la taille des données que vous fournissez. Je connais très bien ce genre de bg, et ce sont les premiers contrôles que je fais habituellement, chaque fois que je le rencontre.

Pour la texture n'apparaissant pas: Avez-vous vérifié que les dimensions de la texture sont réellement des puissances de deux? En C utilisant une macro, le test de puissance de deux peut être écrit comme ceci (celui-ci se résume à tester, qu'il n'y a qu'un seul des bits d'un entier est réglé)

#define ISPOW2(x) (x && !((x) & ((x) - 1))) 

Il est non nécessaire qu'une image de texture est carrée, cependant. Idée fausse commune, mais vous devez juste vous assurer que chaque dimension est une puissance de 2. Une image 16 × 128 est parfaitement bien. Changer le format interne en GL_RGBA_FLOAT16_ATI augmentera probablement même la qualité, mais on ne peut pas être sûr, car GL_RGBA peut contraindre à tout ce que le pilote juge bon. En outre, il s'agit d'un format spécifique au fournisseur, donc je ne tiens pas compte de son utilisation. Il y a toutes sortes de formats ARB, aussi un demi flottant (que FLOAT16_ATI est).

+0

Oui, la dimension 'd' est également calculée comme une puissance de 2. Merci pour le post, je vais essayer cela. Je ne suis pas un expert avec OpenGL, mais j'ai demandé à un ami de vérifier le chargement avant - je vais lui donner votre avis et voir s'il peut aider à diagnostiquer le problème cette fois. – VisualMelon