TGA-Ladefunktion funzt nicht



  • Hallo!
    nachdem ich das TGA-Spezifikationsdokument von wotsit.org einigermaßen studiert habe, hab ich mal diesen Code geschrieben, um an ein TGA-Bild heranzukommen, dass ich in OpenGL als Textur verwenden will (zum Test)
    Bloß funktioniert es nicht.
    (es kann sein, das es unvollständig oder nicht ganz ok ist, da ich nicht weiß, wie ich das Image Descripor-Byte zu interpretieren habe, ich meine die orientierung is OpenGL doch eigentlich egal. Eine mögliche Fehlerquelle wäre auch die Reihenfolge der Bytes pro Pixel in der TGA ( A B G R ) und in OpenGL (R G B A), aber woran es immer scheitert: offenbar hat das Bild weder 8, noch 16 noch 24 noch 32 Bits pro Pixel. Wenn ich die bit-pro-Pixel-Angabe ignoriere (wie in meinem Code) tut sich auch nichts. Es ist also ein Wust an Fehlervermutungen in dem ich feststecke ...

    Hier ist der Code meiner TGA-ladefunktion (ich hab sie zunächst auf Truecolor-Bilder ausgelegt):

    GLubyte * LadeTGA(const char* dateiname)
    {
    	GLubyte IDlength;
    
    	GLubyte * header = new GLubyte[18]; 
    	GLubyte * image = NULL;
    	int imageSize;
    
    	ifstream target(dateiname, ios_base::binary);
    	target.seekg(ios_base::beg);
    
    	target.read((char*)header, 18);
    
    	IDlength = header[0];
    
    	// Auswertung zu TrueColor
    	//  Color Map Type   Image Type
    	if (header[1] == 0 && (header[2] == 2 || header[2] == 10))
    	{
    		if (header[2] == 2 && IDlength == 0)
    		{
    			tgaBreite = header[8] & header[9];
    			tgaHoehe = header[10] & header[11];
    			bitsPerPixel = header[12];
    
    			imageSize = tgaBreite*tgaHoehe;
    			image = new GLubyte[imageSize*(bitsPerPixel/8)];
    			target.read((char*)image, imageSize);
    
    			return image;
    		}
    		else if (header[2] == 2 && IDlength != 0)
    		{
    
    			tgaBreite = header[8] & header[9];
    			tgaHoehe = header[10] & header[11];
    			bitsPerPixel = header[12];
    
    			target.ignore(IDlength);
    			imageSize = tgaBreite*tgaHoehe;
    			image = new GLubyte[imageSize*(bitsPerPixel/8)];
    			target.read((char*)image, imageSize);
    
    			return image;
    		}
    	}
    
    	// Auswertung zu Pseudo- oder DirectColor
    	return NULL;
    }
    

    mfg
    Cortex


  • Mod

    was sagt denn dein debugger welche farbtiefe das tga an der stelle angibt?

    rapso->greets();



  • Deine Offsets sind falsch.

    Und alles was 2 Bits sind, musst du als WORD interpretieren. Bei mir sieht das so aus:

    public class AlphaTGA : AlphaImage
    	{
    		byte m_bIdFieldLength;				// 1 
    		byte m_bColorMapType;				// 1
    		byte m_bImageTypeCode;				// 1
    
    		byte m_bColorMapSpecification0;		// 1
    		byte m_bColorMapSpecification1;		// 1
    		byte m_bColorMapSpecification2;		// 1
    		byte m_bColorMapSpecification3;		// 1
    		byte m_bColorMapSpecification4;		// 1
    
    		ushort m_usOriginX;					// 2
    		ushort m_usOriginY;					// 2
    		ushort m_usWidth;					// 2
    		ushort m_usHeight;					// 2
    		byte m_bImagePixelSize;				// 1
    		byte m_bImageDescriptor;			// 1
    

    (C#, aber egal...)

    Bpp wäre bei mir dann Bit 17 und nicht 12.

    Bei C++ musst du dann evtl. auf's aligning aufpassen.

    Bye, TGGC (Zu viele Primitive hier.)



  • @raspo: hab da bisher nicht drauf geachtet, aber wenn ich die LTGA-Klasse von
    http://www.levp.de/3d/ durch den Debugger schickt, steigt die auch jedesmal aus, wenn sie feststellt, das die Bits pro Pixel weder 8 noch 16 noch 24 noch 32 Bit sind. Dabei ist das Bild ein Truecolor-Bild mit 16,7 Millionen Farben.

    @TGGC: Bist du sicher, das bpp Byte 17 ist? Seltsam, ich könnte schwören, das es Bit 12 gewesen war. Na egal.
    das mit den 2 Bytes als WORDs: ich versuchs mal. (Meinst du, weil die Verknüpfung von 2 einzelnen Bytes mit einem bitweisen UND (wie in meinem Code) zu unerwünschten Ergebnissen führt?



  • Ich bin nicht sicher, nur so steht's in meinem Code. Studier besser nochmal die Formatbeschreibung.

    Die korrekte Verknüpfung wäre: hibyte << 8 | lowbyte.

    Bye, TGGC (Hast du's drauf?)



  • Okay, ich schau nochmal rein.
    "|" ist doch ein bitweises ODER, nicht wahr?
    Was ich aber noch nicht verstehe, ist, wie ich das Image Descriptor-byte interpretiere. Ich meine, es sagt doch meines Wissens nur etwas über die Position des "ersten Pixels" des Bildes und die Länge des Alpha-Farbwerts aus, oder? (wobei die Position des ersten Pixels in meinen Fall keine Rolle spielt. Entscheidend ist nur, das die Daten überhaupt sequentiell in das byte-Array kommen (Nimmt man dafür ein byte-Array?)
    Und muss ich die Posttion der Farbbytes noch umkehren, damit glTexImage2D() die Daten interpretieren kann (sowas stand nicht in der Spezifikation)
    mfg
    Cortex



  • IIRC sind diese Bits manchmal falsch gesetzt. Bzw. werden sie von Programmen ignoriert?

    In meinem Code steht dazu:

    /* Scheint ignoriert zu werden
    			if( ( m_bImageDescriptor & 16 ) == 0 )
    			{
    				bMirroredX= true;
    			}
    			if( ( m_bImageDescriptor & 32 ) == 0 )
    			{
    				bMirroredY= true;
    			}*/
    

    Alphabits ist normalerweise 0 oder 8. Das Array sollte einfach dem Bildformat entsprechend, so das in jedem Element ein Pixel liegt. Byte Array geht aber auch.

    HTH

    Bye, TGGC (Reden wie die Großen)



  • Nur das wenn ich ein byte-Array nehme, ein Pixel auf mehrere Elemente verteilt ist ... Ein Pixel pro Arrayelement scheint mir auch besser, ich will es versuchen. Im Fall von RGBA brauch ich dazu doch ein long int (wegen 32 Bits) oder?


Anmelden zum Antworten