Registriert: Mi Dez 03, 2008 12:01 Beiträge: 167 Wohnort: /country/germany
Programmiersprache: C++ / FreeBASIC
Hi, ich werd langsam irre wegen diesem Problem... Ich habe vor kurzem eine Textur-Klasse in C++ angefangen, die mir verschiedene Formate einliest (aus verschiedenen Gründen möchte ich das so, vorher unter FreeBASIC hatte ich FreeImage). Wichtig waren dabei für mich vor allem PNG und JPEG. Mit PNG hat auch alles wunderbar geklappt, Textur wird einwandfrei geladen und dargestellt. Als ich dann aber den JPEG-Support ergänzt habe, fingen die Probleme an. Mit einem Bild, das bei einer Demo für das nutzen von libjpeg mit OpenGL dabei war, funktioniert alles: http://s10.directupload.net/file/d/2457 ... ko_jpg.htm Bei einem Bild, das mir ein Kumpel zum testen gegeben hat, wird das Bild seltsam verzerrt: http://s13.directupload.net/file/d/2457 ... il_jpg.htm Beim Watchmen-Smily wird das Bild ebenfalls verzerrt, aber die Farbe auch irgendwie (er ist ja eigentlich gelb): http://s10.directupload.net/file/d/2457 ... m6_jpg.htm
Ich habe jetzt schon 3 Tage lang nichts anderes gemacht als den Fehler zu suchen, aber ich konnte einfach nichts finden. Auch google hilft mir hier wenig.
Ich hab den relevanten Teil des Codes mal aufgeräumt und stelle ihn hier rein, in der Hoffnung dass mir irgendjemand sagen kann, was ich da für einen Fehler habe.
Code:
int xenon::texture::load (std::string filename) { if (filename.length()<4) { return false; }
GLint internalformat; GLint format; unsigned char* data = NULL;
if (fileending == "png") { // ausgelassen } else if (fileending == "jpg") { FILE* infile; jpeg_decompress_struct cinfo; jpeg_error_mgr jerr;
if (!(infile = fopen(filename.c_str(), "rb"))) { // file could not be opened return false; }
// set up standard libjpeg error handler cinfo.err = jpeg_std_error(&jerr); // set up decompression jpeg_create_decompress(&cinfo); cinfo.mem->max_memory_to_use = 1024*1024*1024; // tell the library the infile jpeg_stdio_src(&cinfo, infile); // read the header jpeg_read_header(&cinfo, TRUE);
// set the decompression parameters cinfo.out_color_space = JCS_RGB;
// start the decompression jpeg_start_decompress(&cinfo);
unsigned int stride = cinfo.output_width*cinfo.output_components;
// allocate the memory for the buffer data = new unsigned char[cinfo.output_width*cinfo.output_height*cinfo.output_components]; unsigned char *buffer = new unsigned char[stride];
Funktioniert es mit quadratischen Texturen? Für mich sieht das so aus als wäre dort Höhe und Breite vertauscht oder so. Die Verzerrung beim zweiten Bild würdest du erhalten wenn du in jeder Zeile z.B. einen Pixel zu viel kopierst. Dann wäre jede Zeile um jeweils einen Pixel weiter verschoben.
Vielleicht werden die Daten aufgrund einer anderen Systemarchitektur (32 Bit vs 64 Bit) bei deinem Freund anders abgelegt (dass z.B. jede X-Line bei 32 Bit auf die nächsten durch 4 teilbaren Byte und bei 64 Bit durch die nächsten durch 8 teilbaren Byte erweitert wird).
Probier doch mal testweise Texturen, die IMMER durch 8 teilbar sind, vielleicht sogar quadratisch, aber in jedem Fall pot2* sind.
LG Ziz
*pot2 bedeutet, dass jede Seitenlänge eine Potenz von 2 ist. Also 8,16,32,64,128,256,512,1024,2048 usw. Dabei müssen die Seitenkanten aber nicht die gleiche Länge haben.
_________________ Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut. Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’. Und du schaust mich an und fragst ob ich das kann. Und ich denk, ich werd' mich ändern irgendwann. _________________Farin Urlaub - Bewegungslos
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich kenne den Effekt nur, wenn die Farbtiefe von Src. und Dst. unterschiedlich sind, also du 16bit farben hast und OpenGL du 32Bit RGBA gibst. Dann verschieben sich die Pixel, die Farbe ist die, die es nicht sein soll.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: Mi Dez 03, 2008 12:01 Beiträge: 167 Wohnort: /country/germany
Programmiersprache: C++ / FreeBASIC
Schon mal vielen Dank für die Antworten Alle Bilder die ich probiert hatte, hatten 24 Bit. Ich habe dann zuerst probiert, bei dem Truck-Bild einfach Höhe und Breite auf den gleichen Wert zu bringen (563), aber der Effekt blieb der gleiche. Dann hab ich das Bild auf 128x128 skaliert und es hat funktioniert - die Qualität ist zwar nicht so schön, aber das Bild wird korrekt dargestellt. Es hat aber auch noch funktioniert, als ich das Bild dann auf 256x128 skaliert hatte. Mit pot scheint es also zu klappen, aber eigentlich hätte ich auch gerne die Möglichkeit npot Texturen zu verwenden. Zumal libjpeg ja auch noch von jeder Menge anderen Leuten verwendet wird, und bei denen scheint es ja zu klappen.
@Ziz: Also wir haben beide genau das gleiche OS (XP Home SP3 32 Bit mit allen Updates) und auch einen ähnlichen Prozessor (seiner ist nur 600 Mhz langsamer).
_________________ Traue keinem Computer, den du nicht aus dem Fenster werfen kannst -- Steve Wozniak
Zuletzt geändert von darkinsanity am Di Mär 08, 2011 12:42, insgesamt 2-mal geändert.
Mit pot2 scheint es also zu klappen, aber eigentlich hätte ich auch gerne die Möglichkeit npot2 Texturen zu verwenden
Werden den npot2 Texturen von deiner Hardware unterstützt? (Das ist der Fall wenn dein Kontext mindestens OpenGL 2.0 benutzt oder die Extension GL_ARB_texture_non_power_of_two verfügbar ist)
Registriert: Mi Dez 03, 2008 12:01 Beiträge: 167 Wohnort: /country/germany
Programmiersprache: C++ / FreeBASIC
Das wird immmer seltsamer. Als PNG-Testbild hatte ich ein pot-Bild, wenn ich jetzt eine npot-PNG lade, schmiert mein Programm bei glTexImage2D mit der Meldung "Xenon.exe hat ein Problem festgestellt" ab. Ich hab jetzt mal den kompletten Code der Übersichtlichkeit halber auf pastebin abgelegt: http://pastebin.de/15865
GL_ARB_texture_non_power_of_two wird übrigens von meiner GTX 460 unterstüzt.
/edit: Ich hab mal schnell gDEBugger darauf angesetzt, und das bekomme ich raus:
Zitat:
Exception Event Properties Reason: Access violation Address: 0x02e7fee9 Details: The thread tried to read from or write to a virtual address to which it does not have access.
_________________ Traue keinem Computer, den du nicht aus dem Fenster werfen kannst -- Steve Wozniak
Dadurch wird das Alignment deiner Texturdaten auf 1 Byte gestellt. Was sonst per Default 4 ist (meine ich zu mindest). Das hat zur Folge, dass je nach Farbtiefe und Breite des Bildes du 1-3 Spacerbytes am Ende jeder Pixelzeile haben musst. 3 Byte würden dafür sorgen, dass deine Pixel immer noch auf RGB gemappt würden aber sie pro Zeile um 1 Pixel verschoben wären. 1-2 Bytes würden dann auch Farbverschiebung verursachen. Bei allem gleich ist aber, dass du weniger Speicher erstellt hast als OpenGL erwartet. Was wiederrum die Zugriffsverletzung erklären würde, wenn dahinter kein reservierter Speicher liegt. Und da ist es Zufall, dass es vorher nicht auch schon geknallt hat.
Registriert: Mi Dez 03, 2008 12:01 Beiträge: 167 Wohnort: /country/germany
Programmiersprache: C++ / FreeBASIC
Vielen Dank, genau das war es ^^ Bin ich erleichtert dass der Kram endlich funktioniert. Ich wusste bisher gar nicht, dass es bei OpenGL auch dieses Alignment gibt. Wieder was gelernt
_________________ Traue keinem Computer, den du nicht aus dem Fenster werfen kannst -- Steve Wozniak
Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.