[FreeImage] Textur bleibt weiss
-
Ich hab eine Klasse die die Texturen lädt, in ein Handle verpackt und der Resourcen-Manager kümmert sich um den Rest. Bisher habe ich corona verwendet, aber der kann keine RLE-komprimierten TGA laden.. ich brauch es zwar nicht unbedingt, aber es wäre nice to have, da die Bilder deutlich weniger Platz brauchen. Klar, man könnte sie auch mit .zip und so aber naja darum gehts nicht.
Jetzt habe ich versucht FreeImage einzubauen, aber die Texturen bleiben weiss.
Ich weiss ehrlich gesagt nicht woran es liegt. Wenn ich über ein #ifdef zurück zu Corona gehe, funktioniert wieder alles.
Hier mal der Ladecode:NLITextureHandle* NLTextureLoader::getTexture(const char* name, const char* filename) { FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; FIBITMAP* dib(0); BYTE* bits = NULL; u32 width = 0, height = 0; u32 numcol = 3; fif = FreeImage_GetFileType(filename); if ( fif == FIF_UNKNOWN ) { NLError(std::string("Cannot determine filetype from '") + name + std::string("'")); return NULL; } if(FreeImage_FIFSupportsReading(fif)) { dib = FreeImage_Load(fif, filename); if(!dib) { NLError(std::string("Cannot load Image '") + name + std::string("' due to missing plugin from FreeImage.")); return NULL; } bits = FreeImage_GetBits(dib); width = FreeImage_GetWidth(dib); height = FreeImage_GetHeight(dib); numcol = this->getColorsFromFormat(FreeImage_GetColorType(dib)); u32 id = this->makeGLTexture(bits, width, height, numcol); FreeImage_Unload(dib); NLTextureHandle* handle = new NLTextureHandle(name, id); return handle; } return NULL; } u32 NLTextureLoader::makeGLTexture(void* data, const u32 width, const u32 height, const u32 numcolor) { GLuint glImage = 0; GLint oldTexture = 0; u32 mode = GL_TEXTURE_2D; glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); glGenTextures(1, &glImage); glBindTexture(mode, glImage); glTexParameteri(mode, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(mode, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(mode, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(mode, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if ( numcolor == 3 ) { glTexImage2D(mode, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); } else if ( numcolor == 4) { glTexImage2D(mode, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); } glBindTexture(GL_TEXTURE_2D, oldTexture); return glImage; }
Sieht jemand auf Anhieb nen Fehler?
Im Debugger sieht es so aus als wär alles ok. Die Variable bits ist nicht NULL, OpenGL generiert eine ID oberhalb der 0 etc...
Benutze das erste mal FreeImage, vllt habe ich ja was falsch gemacht, hab mich aber strikt an die Doku und die Samples gehalten.
rya.
-
Schau mal, ob bei "TexImage2D" data null ist.
glBindTexture(GL_TEXTURE_2D, oldTexture);
Warum stellst du die alte Textur wieder her ??
Die müsste doch weiß werden, weil da noch nichts war...
-
DarkShadow44 schrieb:
Schau mal, ob bei "TexImage2D" data null ist.
glBindTexture(GL_TEXTURE_2D, oldTexture);
Warum stellst du die alte Textur wieder her ??
Die müsste doch weiß werden, weil da noch nichts war...
Nein, ist eine gültige Adresse. Bei NULL würde ausserdem eine Exception (Speicherzugriff auf NULL) fliegen durch OpenGL.
Ich stelle die alte Textur wieder her, damit durch den Code nicht Fehler auftreten wie eben falsche Textur etc, oder falls man gerade Texturen abgeschaltet hat nicht Beeinträchtigungen auftreten.
Aber ich habe den Fehler gefunden beim Antworten.
Ich habe im Corona-Code diesen Teil drin:if ( !glIsEnabled(GL_TEXTURE_2D) ) { glEnable(GL_TEXTURE_2D); }
Den hab ich beim FreeImage-Code vergessen *g*.
Allerdings wird komischerweise von FreeImage eine Textur nicht geladen, die von Corona anstandslos akzeptiert wird :(:
http://www.fileuploadx.de/919497edit:
Auch andere Texturen werden nicht richtig dargestellt... mit corona dagegen schon. Ich glaube irgendwas mach ich falsch....
rya.
-
Du musst *ConvertTo24Bits() aufrufen, bevor du irgendwas etwas anderes machst.
Das von dir verlinkte Bild ist z.B. ein 8-bit-Bild (oder gar ein 2-bit-Bild?).
-
Nanyuki schrieb:
Du musst *ConvertTo24Bits() aufrufen, bevor du irgendwas etwas anderes machst.
Das von dir verlinkte Bild ist z.B. ein 8-bit-Bild (oder gar ein 2-bit-Bild?).Hab verschiedene Konvertierungen versucht, es ändert sich nix.
Bei einer Grastextur schauts als Beispiel so aus:
http://img249.imageshack.us/img249/3007/screenshotua.png
Ich verstehe es nicht.. corona ist schlanker und da gibts keine Probleme ausser dass der keine RLE-komprimierten Texturen lädt... naja:
http://img22.imageshack.us/img22/4707/screenshotzl.png
rya.
-
Teste es nochmal so:
u32 NLTextureLoader::makeGLTexture(void* data, const u32 width, const u32 height, const u32 numcolor) { GLuint glImage = 0; GLint oldTexture = 0; u32 mode = GL_TEXTURE_2D; glGenTextures(1, &glImage); glBindTexture(mode, glImage); if ( numcolor == 3 ) { glTexImage2D(mode, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); } else if ( numcolor == 4) { glTexImage2D(mode, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); } glTexParameteri(mode, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(mode, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, oldTexture); return glImage; }
Verändert sich was?
-
Danke für Deine Hilfe aber der Hintergrund schaut immer noch genauso aus.
Die Sprites werden halt nicht mehr geblendet weil durch die 3 der Alpha-Kanal fehlt. Aber sonst ist alles beim alten.
rya.
-
Hum, dann probier doch mal ob es mit einer Farbumkehrung funktioniert, also mal GL_RGBA oder GL_ABGR_EXT probieren.
-
NLITextureHandle* NLTextureLoader::getTexture(const char* name, const char* filename) { FIBITMAP* dib(0); BYTE* pixels = NULL; u32 width = 0; u32 height = 0; u32 numcol = 3; // Enable Textures if ( !glIsEnabled(GL_TEXTURE_2D) ) { glEnable(GL_TEXTURE_2D); } // Check image if ( FreeImage_GetFileType(filename) == FIF_UNKNOWN ) { NLError(std::string("Cannot determine filetype from '") + name + std::string("'")); return NULL; } if(FreeImage_FIFSupportsReading(FreeImage_GetFileType(filename))) { // Load Image dib = FreeImage_Load(FreeImage_GetFileType(filename), filename); if(!dib) { NLError(std::string("Cannot load Image '") + name + std::string("' due to missing plugin from FreeImage.")); return NULL; } // Convert Image FreeImage_FlipVertical(dib); //FreeImage_ConvertTo32Bits(dib); // Get Metrics pixels = FreeImage_GetBits(dib); width = FreeImage_GetWidth(dib); height = FreeImage_GetHeight(dib); numcol = this->getColorsFromFormat(FreeImage_GetColorType(dib)); // Swap Bytes BYTE *bits = new BYTE[width * height * numcol]; for(u32 pix=0; pix<width * height; pix++) { bits[pix*numcol+0]=pixels[pix*numcol+2]; bits[pix*numcol+1]=pixels[pix*numcol+1]; bits[pix*numcol+2]=pixels[pix*numcol+0]; if (numcol == 4){ bits[pix*numcol+3]=pixels[pix*numcol+3]; } } // Gen Texture u32 id = this->makeGLTexture(bits, width, height, numcol); // Unload all images and free memory FreeImage_Unload(dib); delete bits; // Create handle NLTextureHandle* handle = new NLTextureHandle(name, id); return handle; } return NULL; }
So funktioniert es nun indem ich das Bild nach RGB(A) scheinbar konvertiere.
FreeImage scheint die im BGR-Format zu laden. Hab ich aber in der Doku keinen Hinweis gefunden.
Okay, eine Textur wird geladen und schaut auch so aus wie sie soll. Andere Texturen verweigern sich die mit Corona richtig aussehen.. ich verstehe es nicht. An RLE liegt es nicht, ich habe bereits die Bilder nach RLE und zurück konvertiert, kein Unterschied.
Auch nach einer Konvertierung nach .png das selbe Bild...Hier die Gras-Textur:
http://img145.imageshack.us/img145/7957/screenshotgrasfreeimage.pngUnd die Steintextur:
http://img519.imageshack.us/img519/5157/screenshotstonesfreeima.pngDownload der Texturen:
http://www.fileuploadx.de/103857
Die sind aus dem NVIDIA-SDK bzw dem Beispiel-Paket.Hab mit verschiedenen Texturoptionen rumgespielt, aber kein Erfolg..
GIMP zeigt bei beiden Texturen das gleiche an quasi und beide scheinen einen Alphakanal zu haben, aber FreeImage sagt es sind nur 3 Kanäle wenn ich im Debugger numcol beobachte.
Corona kann damit umgehen, bei FreeImage der gezeigte Fehler.
Danke für Deine Hilfe.
rya.
-
Das Verhalten von FreeImage scheint bei der Steintextur in der Tat etwas merkwürdig zu sein.
Kannst du aber mit einem kleinen Hack wie diesem umgehen:if (FreeImage_GetPitch(dib)==width*4 && FreeImage_GetColorFormat(dib)==FIC_RGB)dib=FreeImage_ConvertTo24Bits(dib); //altes Ding freigeben nicht vergessen
Edit: in deinem Code in Zeile 58 muss das natürlich delete[] bits; heißen!
-
Nanyuki schrieb:
Das Verhalten von FreeImage scheint bei der Steintextur in der Tat etwas merkwürdig zu sein.
Kannst du aber mit einem kleinen Hack wie diesem umgehen:if (FreeImage_GetPitch(dib)==width*4 && FreeImage_GetColorFormat(dib)==FIC_RGB)dib=FreeImage_ConvertTo24Bits(dib); //altes Ding freigeben nicht vergessen
Yay! Danke dir vielmals! Hat geklappt.
Edit: in deinem Code in Zeile 58 muss das natürlich delete[] bits; heißen!
Nochmal danke... auch wenn VC kein MemoryLeak angezeigt hat muss das natürlich seine Ordnung haben. Hab ich wohl in der Hektik falsch gemacht.
rya.