[OpenGL] Den Alphakanal von tga-Datein nutzen...



  • Hallo Leute sorry wenn ich euch jetzt mit Quelltext totschlage,
    aber ich hab hier ein sehr merkwürdiges Problem.

    Also ich versuche tga-datein im RBGA Format zu laden und dann anzuzeigen,
    natürlich so das die Alphamaske verwendet wird. Aber wenn ich die Textur anzeige
    sieht es so aus als wenn alle Versionen der Datei die jemals geladen wurden
    irgendwie übereinander liegen - auch wenn es auf der Festplatte immer nur EINE Version gibt. Und das auch nach einem Neustart!!
    Außerdem ist das ganze Bild durchscheinend, und nicht nur die Teile die es eigentlich sein sollten.

    Hiermit lade ich die Bilder und packe sie in Texturen:

    typedef struct
    {
       GLubyte *imageData;        // Hold All The Color Values For The Image.
       GLuint bpp;                // Hold The Number Of Bits Per Pixel.
       GLuint width;              // The Width Of The Entire Image.
       GLuint height;             // The Height Of The Entire Image.
       GLuint texID;              // Texture ID For Use With glBindTexture.
       GLuint type;               // Data Stored In * ImageData (GL_RGB Or GL_RGBA)
    } Texture;
    
    typedef struct
    {
       GLubyte header[6];       // Holds The First 6 Useful Bytes Of The File
       GLuint bytesPerPixel;    // Number Of BYTES Per Pixel (3 Or 4)
       GLuint imageSize;        // Amount Of Memory Needed To Hold The Image
       GLuint type;             // The Type Of Image, GL_RGB Or GL_RGBA
       GLuint Height;           // Height Of Image
       GLuint Width;            // Width Of Image
       GLuint Bpp;              // Number Of BITS Per Pixel (24 Or 32)
    } TGA;
    
    typedef struct
    {
    	GLubyte Header[12];				// TGA File Header
    } TGAHeader;
    
    bool LoadTGA(Texture * texture, char * filename)	// Load a TGA file
    {
        TGAHeader tgaheader;						// TGA header
        TGA tga;												// TGA image data
    
        GLubyte uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0};	// Uncompressed TGA Header
    
        FILE * fTGA;												// File pointer to texture file
    	fTGA = fopen(filename, "rb");
    
    	if(fTGA == NULL)											// If it didn't open....
    	{
    		MessageBox(NULL, "Could not open texture file", "ERROR", MB_OK);
    		return false;
    	}
    
    	if(fread(&tgaheader, sizeof(TGAHeader), 1, fTGA) == 0)					// Attempt to read 12 byte header from file
    	{
    		MessageBox(NULL, "Could not read file header", "ERROR", MB_OK);		// If it fails, display an error message 
    		if(fTGA != NULL)													// Check to seeiffile is still open
    		{
    			fclose(fTGA);													// If it is, close it
    		}
    		return false;														// Exit function
    	}
    
    	if(memcmp(uTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)	// See if header matches the predefined header of 
    	{																		// an Uncompressed TGA image
    		LoadUncompressedTGA(texture, filename, fTGA);				
    	}
    	else																	// If header matches neither type
    	{
    		MessageBox(NULL, "Only uncompressed TGA files are supported", "Invalid Image", MB_OK);	// Display an error
    		fclose(fTGA);
    		return false;																// Exit function
    	}
    	return true;															// All went well, continue on
    }
    
    bool LoadUncompressedTGA(Texture *texture, char *filename, FILE *fTGA)
    {																			// TGA Loading code nehe.gamedev.net)
    	TGA tga;
    
        if(fread(tga.header, sizeof(tga.header), 1, fTGA) == 0)					// Read TGA header
    	{										
    		MessageBox(NULL, "Could not read info header", "ERROR", MB_OK);		// Display error
    		if(fTGA != NULL)													// if file is still open
    		{
    			fclose(fTGA);													// Close it
    		}
    		return false;														// Return failular
    	}	
    
    	texture->width  = tga.header[1] * 256 + tga.header[0];  // Determine The TGA Width (highbyte*256+lowbyte)
    	texture->height = tga.header[3] * 256 + tga.header[2];  // Determine The TGA Height (highbyte*256+lowbyte)
    	texture->bpp	= tga.header[4];										// Determine the bits per pixel
    	tga.Width		= texture->width;										// Copy width into local structure						
    	tga.Height		= texture->height;										// Copy height into local structure
    	tga.Bpp			= texture->bpp;											// Copy BPP into local structure
    
    	if((texture->width <= 0) || (texture->height <= 0) || ((texture->bpp != 24) && (texture->bpp !=32)))
    	{
    		MessageBox(NULL, "Invalid texture information", "ERROR", MB_OK);	// Display Error
    		if(fTGA != NULL)													// Check if file is still open
    		{
    			fclose(fTGA);													// If so, close it
    		}
    		return false;														// Return failed
    	}
    
    	if(texture->bpp == 24)													//If the BPP of the image is 24...
    	{
    		texture->type	= GL_RGB;											// Set Image type to GL_RGB
    	}
    	else																	// Else if its 32 BPP
    	{
    		texture->type	= GL_RGBA;											// Set image type to GL_RGBA
    	}
    
    	tga.bytesPerPixel	= (tga.Bpp / 8);							// Compute the number of BYTES per pixel
    	tga.imageSize		= (tga.bytesPerPixel * tga.Width * tga.Height);	// total amout ofmemory needed
    	texture->imageData	= (GLubyte *)malloc(tga.imageSize);			// Allocate that much
    
    	if(texture->imageData == NULL)											// If no space was allocated
    	{
    		MessageBox(NULL, "Could not allocate memory for image", "ERROR", MB_OK);	// Display Error
    		fclose(fTGA);														// Close the file
    		return false;														// Return failed
    	}
    
    	if(fread(texture->imageData, 1, tga.imageSize, fTGA) != tga.imageSize)	// Attempt to read image data
    	{
    		MessageBox(NULL, "Could not read image data", "ERROR", MB_OK);		// Display Error
    		if(texture->imageData != NULL)										// If imagedata has data in it
    		{
    			free(texture->imageData);										// Delete data from memory
    		}
    		fclose(fTGA);														// Close file
    		return false;														// Return failed
    	}
    
    	for(GLuint cswap = 0; cswap < (int)tga.imageSize; cswap += tga.bytesPerPixel)
    	{
    		texture->imageData[cswap] ^= texture->imageData[cswap+2] ^=
    		texture->imageData[cswap] ^= texture->imageData[cswap+2];
    	}
    
    	glGenTextures(1, &texture->texID);
    	glBindTexture(GL_TEXTURE_2D, texture->texID);
    glTexImage2D(GL_TEXTURE_2D, 0, 3, texture->width, // muss natürlich eigentlich in eine Zeile
    texture->height, 0, texture->type, GL_UNSIGNED_BYTE, texture->imageData);
    	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    
        free(texture->imageData);					// Free The Texture Image Memory 
    
        fclose(fTGA);
    	return true;
    }
    

    Und das ist der Code mitdem das Bild angezeigt werden soll:

    Texture maus;
    LoadTGA( &maus, "Data/Cursor.tga"); //Ist ein RGBA Bild, erstellt mit 'The Gimp'
    
    glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE);
        glBindTexture(GL_TEXTURE_2D, maus.texID);
        glBegin(GL_QUADS);
           glTexCoord2i(0, 0); glVertex2i( 0, 0);
           glTexCoord2i(1, 0); glVertex2i( 16, 0 );
           glTexCoord2i(1, 1); glVertex2i( 16, 16);
           glTexCoord2i(0, 1); glVertex2i( 0, 16);
        glEnd();
    glDisable(GL_BLEND);
    

    Ui, ich hoffe das ist jetzt nicht zuviel 🙂 Wie ihr vielleicht schon gemerkt habt, ist die Grundlage von Nehe.gamedev. Ich habe eigentlich nur eingefügt, dass die Textur beim Laden schon für OpenGL passend gemacht wird.

    Wie gesagt, auch wenn immer nur eine Version geladen wird (und sogar textur.imageData gefreed wird!)sieht man irgendwie alle Versionen übereinander gelegt.

    Für eine kleine Korrektur wäre ich sehr dankbar...
    MfG, fnord



  • Vielleicht sind die Farbdaten der alten Bilder ja unsichtbar.

    Bye, TGGC (Das Jahr des Helden)



  • Aber auch wenn ich ein neues Bild unter einem neuem Namen erstelle und lade, sehe ich noch die vorhergehenden Versionen! Das ist echt merkwürdig.

    Besonders komisch finde ich, dass es nach einem Neustart immer noch so ist. Ich meine der RAM und VideoRAM wird doch wohl gelöscht wenn der PC längere Zeit aus ist??



  • Wie soll denn das mit den vorheriegen Versionen funktionieren ?
    Das ist bestimmt nur irgend ein Grafik Müll 😉

    Ich hab eigentlich keine Ahnung von OpenGL aber wenn du

    GL_ONE_MINUS_SRC_ALPHA anstatt von GL_ONE benutzt sollte zumindest schonmal das durchscheinen weg sein ... vieleicht ergibt sich der rest ja dann 😉



  • fnord23 schrieb:

    Aber auch wenn ich ein neues Bild unter einem neuem Namen erstelle und lade, sehe ich noch die vorhergehenden Versionen! Das ist echt merkwürdig.

    Besonders komisch finde ich, dass es nach einem Neustart immer noch so ist. Ich meine der RAM und VideoRAM wird doch wohl gelöscht wenn der PC längere Zeit aus ist??

    Was siehst du wo. In welchem Programm? Was für Dateien meinst du genau. Was bedeutet neu?

    Bye, TGGC (Das Jahr des Helden)



  • Mit GL_ONE_MINUS_SRC_ALPHA anstatt GL_ONE ist es nicht mehr durchsichtig, auch nicht an den Stellen wo es so sein sollte 🙂 ( an den Stellen ists schwarz)

    Also was ich mit vorherigen Versionen meine ?
    Mit Programm meine ich natürlich das programm welches jenes ich geschrieben habe und wo ich schon Auszüge gepostet habe 😉
    Wenn ich jetzt eine tga-datei mache und das Programm ausführe sehe ich das Bild.
    Wenn ich jetzt aber ein neues, anderes tga-Bild erstelle, das alte lösche und das Programm das neue anzeigen lasse, sehe ich das Alte und Das Neue übereinander!
    Nehmen wir an ich erstelle einen Mauszeiger. Dann lösche ich ihn und erstelle ein Fadenkreuz. Nun sehe ich ein Fadenkreuz und dahinter ein Mauszeiger.

    Ich sehe also alle Versionen die das Programm jemals geladen hat übereinander! Natürlich ist auf der Festplatte immer nur eine Version vorhanden. Auch neustarten hilft nichts!

    Hier ist ein screen:
    http://fnord-23.de/screen.jpg
    Der Zeiger den ich meine ist rot eingekreist. Man kann mehr oder weniger erkenne, dass ich erst zwei verschiedene weisse Zeiger probiert habe und dann ein rotes Fadenkreuz erstellt habe. Auf der Festplatte existiert nurnoch das Fadenkreuz. Alle anderen sind gelöscht. Ich wiederhohle: GE-LÖSCHT 😮

    Also was soll ich jetzt machen? Soll ich einen modernen Geisterjäger rufen, oder meint ihr man kann das Problem irgendwie anders lösen?? Der FEind ist hier irgendwo auf meiner Festplatte und ich musss ihn finden und töten!!



  • Ich kann da erhrlich gesagt nicht viel erkennen. Wahrscheinlich liegen die Daten einfach auf der Grafikkarte und werden nie überschrieben, da du ja behauptest, sie wären nicht in der Datei.

    Bye, TGGC (Das Jahr des Helden)



  • TGGC schrieb:

    Ich kann da erhrlich gesagt nicht viel erkennen. Wahrscheinlich liegen die Daten einfach auf der Grafikkarte und werden nie überschrieben, da du ja behauptest, sie wären nicht in der Datei.

    Das hab' ich mir auch direkt gedacht, aber nach einem NEUSTART nach mehreren Stunden vom Stromnetz sollte selbst der trägste RAM seinen Inhalt verloren haben...

    Überleg' mal lieber, ob Du nicht eine ganz doofe Fallback-Abfrage eingefügt hast, die notfalls Deine Sicherungskopien unter Eigene Dateien oder so noch lädt...



  • Sgt. Nukem schrieb:

    Das hab' ich mir auch direkt gedacht, aber nach einem NEUSTART nach mehreren Stunden vom Stromnetz sollte selbst der trägste RAM seinen Inhalt verloren haben

    Das wurde so nie gesagt.

    Bye, TGGC (Das Jahr des Helden)



  • TGGC schrieb:

    Sgt. Nukem schrieb:

    Das hab' ich mir auch direkt gedacht, aber nach einem NEUSTART nach mehreren Stunden vom Stromnetz sollte selbst der trägste RAM seinen Inhalt verloren haben

    Das wurde so nie gesagt.

    fnord23 schrieb:

    auch wenn es auf der Festplatte immer nur EINE Version gibt. Und das auch nach einem Neustart!!

    fnord23 schrieb:

    Ich sehe also alle Versionen die das Programm jemals geladen hat übereinander! Natürlich ist auf der Festplatte immer nur eine Version vorhanden. Auch neustarten hilft nichts!

    fnord23 schrieb:

    Besonders komisch finde ich, dass es nach einem Neustart immer noch so ist. Ich meine der RAM und VideoRAM wird doch wohl gelöscht wenn der PC längere Zeit aus ist??

    😕



  • Und wo steht was mit mehrere Stunden vom Stromnetz getrennt? Aus kann auch Standby oder sowas bedeuten.

    Bye, TGGC (Das Jahr des Helden)



  • TGGC schrieb:

    Und wo steht was mit mehrere Stunden vom Stromnetz getrennt? Aus kann auch Standby oder sowas bedeuten.

    Dann könnte es auch "Ruhezustand" bedeuten, womit das "vom Stromnetz getrennt" ohnehin keine Rolle mehr spielen würde.

    Trotzdem sollte in beiden Fällen die Grafikkarte nicht mehr mit Strom versorgt werden.

    Vielleicht sollte er zur Verifizierung mal Battlefield 2 oder sowas starten, damit der VRAM auf jeden Fall was anderes enthält. 🤡



  • Also der PC ist aus, aber hat noch eine Verbindung zum Netz. Könnte sein das die GraKa noch ein bischen Strom bekommt. Anders kann es ja eigentlich garnicht sein 😕

    Ich habe das einzige Spiel gestartet das ich installiert habe, Morrowind. Leider hat das wohl nicht gereicht um die 128 Mb Grafik-RAM zu füllen. Das Ding ist nach wie vor so. Die TexID von der Textur ist übrigens immer 3!

    Hier habe ich das Phänomen noch mal stark vergrößert:
    http://fnord-23.de/screen2.jpg
    Als erstes hatte ich einen Cursor ähnlich dem Standart-Windows Cursor gebaut. Danach einen nach links gedrehten und dann das rot-schwarze fadenkreuzähnliche Gebilde.

    Bitte schaut euch nochmal die Lade-routine an, ich kopier sie noch mal raus.

    bool LoadUncompressedTGA(Texture *texture, char *filename, FILE *fTGA)	// Load an uncompressed TGA (note, much of this code is based on NeHe's 
    {																			// TGA Loading code nehe.gamedev.net)
    	TGA tga;
    
        if(fread(tga.header, sizeof(tga.header), 1, fTGA) == 0)					// Read TGA header
    	{										
    		MessageBox(NULL, "Could not read info header", "ERROR", MB_OK);		// Display error
    		if(fTGA != NULL)													// if file is still open
    		{
    			fclose(fTGA);													// Close it
    		}
    		return false;														// Return failular
    	}	
    
    	texture->width  = tga.header[1] * 256 + tga.header[0];					// Determine The TGA Width	(highbyte*256+lowbyte)
    	texture->height = tga.header[3] * 256 + tga.header[2];					// Determine The TGA Height	(highbyte*256+lowbyte)
    	texture->bpp	= tga.header[4];										// Determine the bits per pixel
    	tga.Width		= texture->width;										// Copy width into local structure						
    	tga.Height		= texture->height;										// Copy height into local structure
    	tga.Bpp			= texture->bpp;											// Copy BPP into local structure
    
    	if((texture->width <= 0) || (texture->height <= 0) || ((texture->bpp != 24) && (texture->bpp !=32)))	// Make sure all information is valid
    	{
    		MessageBox(NULL, "Invalid texture information", "ERROR", MB_OK);	// Display Error
    		if(fTGA != NULL)													// Check if file is still open
    		{
    			fclose(fTGA);													// If so, close it
    		}
    		return false;														// Return failed
    	}
    
    	if(texture->bpp == 24)													//If the BPP of the image is 24...
    	{
    		texture->type	= GL_RGB;											// Set Image type to GL_RGB
    	}
    	else																	// Else if its 32 BPP
    	{
    		texture->type	= GL_RGBA;											// Set image type to GL_RGBA
    	}
    
    	tga.bytesPerPixel	= (tga.Bpp / 8);									// Compute the number of BYTES per pixel
    	tga.imageSize		= (tga.bytesPerPixel * tga.Width * tga.Height);		// Compute the total amout ofmemory needed to store data
    	texture->imageData	= (GLubyte *)malloc(tga.imageSize);					// Allocate that much memory
    
    	if(texture->imageData == NULL)											// If no space was allocated
    	{
    		MessageBox(NULL, "Could not allocate memory for image", "ERROR", MB_OK);	// Display Error
    		fclose(fTGA);														// Close the file
    		return false;														// Return failed
    	}
    
    	if(fread(texture->imageData, 1, tga.imageSize, fTGA) != tga.imageSize)	// Attempt to read image data
    	{
    		MessageBox(NULL, "Could not read image data", "ERROR", MB_OK);		// Display Error
    		if(texture->imageData != NULL)										// If imagedata has data in it
    		{
    			free(texture->imageData);										// Delete data from memory
    		}
    		fclose(fTGA);														// Close file
    		return false;														// Return failed
    	}
    
    	for(GLuint cswap = 0; cswap < (int)tga.imageSize; cswap += tga.bytesPerPixel)
    	{
    		texture->imageData[cswap] ^= texture->imageData[cswap+2] ^=
    		texture->imageData[cswap] ^= texture->imageData[cswap+2];
    	}
    
    	glGenTextures(1, &texture->texID);
    	glBindTexture(GL_TEXTURE_2D, texture->texID);
    	glTexImage2D(GL_TEXTURE_2D, 0, 3, texture->width, texture->height, 0, texture->type, GL_UNSIGNED_BYTE, texture->imageData);
    	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    
        free(texture->imageData);					// Free The Texture Image Memory 
    
        fclose(fTGA);
    	return true;
    }
    

    Ich kann mir das nur so erklären, dass bei den durchsichtigen Pixeln nichts aus der Datei geladen wird. Naja, was ja auch logisch ist, schließlich ist es durchsichtig. aber in der GraKa lauern noch die alten Farbwerte und OpenGL liest diese dann aus. Stattdessen müsste die Laderoutine diese alten Farbwerte irgendwie mit durchsichtigen Pixeln überschreiben.

    Ich denke ihr versteht was ich meine oder? Anders kann ich mir das nicht erklären. Leider hab ich noch gar keine Ahnung von der Materie, ich mache das erst seit zwei Wochen. Also wo ist der Fehler 😕



  • fnord23 schrieb:

    Ich kann mir das nur so erklären, dass bei den durchsichtigen Pixeln nichts aus der Datei geladen wird. Naja, was ja auch logisch ist, schließlich ist es durchsichtig.

    Das sagte ich doch schon. Schön, wenn du immer aufmerksam mitliest.

    Bye, TGGC (Das Jahr des Helden)



  • auch die Bereiche die man nicht sehen soll werden mitgeladen ... Sie werden nur nachher nicht oder halt nur abgeschwächt angezeigt ... und das da noch irgendwas im Speicher stehen soll ist unsinn 😉 (es sei denn du schreibst es kurz(unmittelbar) vorher rein ...)

    Du meintest irgendwas von änderungen die du an der Lade funktion gemacht hast ?
    Wie wäre es wenn du mal die Original Version ausm Tutorial versuchst ?



  • ich kenn mich mit opengl nicht aus, aber lädst du vielleicht aus versehen mehrere surfaces in einen stream? wenn nur eine bild auf der festplatte ist und du alle die jemals existiert haben übereinander siehst, ist entweder deine festplatte oder der ram ... naja nicht kaputt aber "voll freeky drauf heute" 🤡



  • Probier' doch mal ein ZeroMemory() nach dem Allokieren von imageData via malloc(). 🤡


Anmelden zum Antworten