glTexImage2D...

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

glTexImage2D...

Beitrag von Eisflamme »

Hi,

Die Funktion macht irgendwie nicht, was ich will, oder ich hab nen Logikfehler. Also erstmal die wesentlichen Sachen, weitere Codes folgen bei Bedarf:

Code: Alles auswählen

		glGenTextures(1, &texture_);

		glBindTexture(GL_TEXTURE_2D, texture_);

		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
   
		 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

	         glTexImage2D(	GL_TEXTURE_2D, 0, 3, bitmapInfoHeader_.width,
						bitmapInfoHeader_.height, 0, GL_RGB,
						GL_UNSIGNED_BYTE, wubu);
Ich lade eigentlich eine Bitmap, aber ich versuche gerade einfach Mal selbst das Array mit Daten zu befüllen, das mache ich vorher so:

Code: Alles auswählen

		unsigned char* wubu = new unsigned char[bitmapInfoHeader_.width * bitmapInfoHeader_.height * 3];

		for(unsigned int n = 0; n < bitmapInfoHeader_.width * bitmapInfoHeader_.height * 3; ++n)
		{
			wubu[n] = 0;
			if((n + 1) % 3 == 0)
				wubu[n] = 255;
		}
Später dann einfach

Code: Alles auswählen

glBindTexture(GL_TEXTURE_2D, texture);
gefolgt von glBegin(GL_QUADS); und dem Rendern eines Rechtecks, das für sich ohne Textur genommen immer schon gut und schön angezeigt wurde.

Vll. ist da jetzt ein Denkfehler drin, aber ich würde doch eigentlich erwarten, dass damit alles blau ist? Statt dessen sehe ich aber nur ein Farbmuster horizontaler 1px-Linien mit rot, blau usw. gemischt. Ist hier schon ein Fehler drin, habt ihr gute Vermutungen oder braucht ihr noch mehr Code? Wenn ja, welchen?
Helmut
Establishment
Beiträge: 237
Registriert: 11.07.2002, 15:49
Wohnort: Bonn
Kontaktdaten:

Re: glTexImage2D...

Beitrag von Helmut »

Du gehst davon aus, dass hinter jeder Zeile im Bitmap direkt die nächste folgt. Das ist nicht so, dazwischen sind ein paar Dummybytes, um ein paar Bruchteile einer Millisekunde zu sparen. Wo das steht, wie viele Bytes das sind, weiß ich jetzt nicht auswendig, aber das findeste schon raus;)

Ciao
Benutzeravatar
Krishty
Establishment
Beiträge: 8246
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: glTexImage2D...

Beitrag von Krishty »

Jede Bildzeile ist durch rechtsseitiges Auffüllen mit Nullen auf ein ganzzahliges Vielfaches von 4 Bytes ausgerichtet.
(Quelle)
Außerdem liegen die Pixel in Bitmaps als BGR statt RGB vor … aber da ich keine Ahnung von OpenGLs Bitmap-Handling habe, stelle ich das einfach mal in den Raum.

Benutz {code=c} statt {code} für deine Listings.

Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: glTexImage2D...

Beitrag von Eisflamme »

Scheiße. Ich probiere seit Stunden rum, ich kann einfach nicht klar denken.
Wieso funktioniert dieser Algorithmus nicht?

Code: Alles auswählen

		for(unsigned int n = 0; n < imageSize; n += 3)
		{
			if(n % (bitmapInfoHeader_.width * 3) < 3)
			{
				while(n % 4 != 0)
				{
					imageData_[n] = 0;
					++n;
				}
			}

			imageData_[n]		= 255;//bitmapPictureData_[n + 2];
			imageData_[n + 1]	= 0;//bitmapPictureData_[n + 1];
			imageData_[n + 2]	= 0;//bitmapPictureData_[n];
		}
Ich will halt einfach alles rot machen. Es geht v.a. um den if-Block. Wenn der Rest von n durch die Breite (in Byte) < 3 ist, bedeutet das ja, dass ich im 3-Byte-Bereich bin, in welchem ich jetzt die Korrektur durchführen muss. Das bedeutet, dass ich ab dann mit 0en auffülle, bis die Anzahl der ns durch 4 teilbar ist. Dann fülle ich einfach weiter Daten nach dem bisher gebräuclichen Prinzip ein.

Was sich auf dem Bildschirm ergibt ist Folgendes:
Bild

Intelligent, wie ich bin, folgere ich daraus, dass die Korrektur Zeile für Zeile etwas zu früh gemacht wird. Heute weniger intelligent verstehe ich aber nicht, wieso. HELP!

Lg
Benutzeravatar
jgl
Establishment
Beiträge: 109
Registriert: 08.04.2009, 08:58

Re: glTexImage2D...

Beitrag von jgl »

Hi,

also ich musste letztens mich auch mit dem "manuellen" befüllen von BMP's befassen (allerdings vom Typ CBitmap).
Dabei musste ich auch noch einen 4.Wert pro Pixel angeben (höchst wahrscheinlich Alpha).
Also um ein rotes Bmp zu schreiben hätte ich es wie folgt gemacht:

Code: Alles auswählen

unsigned char* buffer = new unsigned char[size]
unsigned int ii(0);
for(int xx(0); xx<width; ++xx)
 for(int yy(0); yy<height; ++yy)
 {
	buffer[ii]=0;
	buffer[ii]=0;
	buffer[ii]=(unsigned char)255; 
	buffer[ii]=0;
 }
Mich würde mal interesieren, ob das hier auch funktioniert, da ich keine Zeit habe das auszuprobieren.
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: glTexImage2D...

Beitrag von Eisflamme »

Hm, nein, das ist hier nicht das Problem. Bitmap hat nur 3 Werte und auch keinen Alphachannel. Man muss halt am Ende der Zeile wie bereits gesagt so auffüllen, dass die Anzahl der Bits (nicht das höchstwertige Bit, wie ich erst dachte ._.) durch 4 teilbar ist.
Benutzeravatar
Ingrater
Establishment
Beiträge: 103
Registriert: 18.04.2007, 21:52

Re: glTexImage2D...

Beitrag von Ingrater »

Also ich halte das für einen absoluten Quatsch das man das ende einer Pixelreihe auf 4 byte alignment anpassen muss. Hab ich noch nie gemacht, funktioniert bei mir auch.
Versuch mal den 3. Parameter von glTexImage2D durch GL_RGB8 zu ersetzen.

Falls das nichts bringt hängt es wohl mit dem PixelStore state zusammen. Siehe
http://wiki.delphigl.com/index.php/glPixelStore

MFG Ingrater
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: glTexImage2D...

Beitrag von Eisflamme »

Keine Ahnung, ob sinvoll oder nicht, aber es soll die Performance etwas verbessern und ist so üblich.

Mir geht's ausschließlich um meinen Algo. Da isn Logikfehler drin und ich bin zu blöd, den zu finden. Damit gehört der Post zwar streng genommen nicht mehr in dieses Forum aber nja :)

Den Link schau ich trotzdem beizeiten an, danke!
Benutzeravatar
Krishty
Establishment
Beiträge: 8246
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: glTexImage2D...

Beitrag von Krishty »

Ingrater hat geschrieben:Also ich halte das für einen absoluten Quatsch das man das ende einer Pixelreihe auf 4 byte alignment anpassen muss. Hab ich noch nie gemacht, funktioniert bei mir auch.
Ich halte es für absoluten Quatsch, immer davon auszugehen, dass die Breite eines Bildes einer Zweierpotenz entspricht.
Eisflamme hat geschrieben:Keine Ahnung, ob sinvoll oder nicht, aber es soll die Performance etwas verbessern und ist so üblich.
Vor allem hat es früher die Programmlogik beim Verarbeiten einzelner Zeilen vereinfacht (Bitmaps wurden schließlich eine ganze Zeit lang in VGA-Karten verarbeitet). Wenn du eh Byte-weise parst, wirst du im Hinblick auf Performance nichts bemerken – du musst es machen, weil es so standardisiert ist.
Eisflamme hat geschrieben:Mir geht's ausschließlich um meinen Algo. Da isn Logikfehler drin und ich bin zu blöd, den zu finden.
Der erste Fehler ist, dass du Bytes iterierst, anstatt mit Klassen zu arbeiten … wenn du für jede Zeile ein Array von BGR-Instanzen hättest, wäre das alles ein Kinderspiel.

Achja, Bits sind übrigens keine Bytes.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: glTexImage2D...

Beitrag von Eisflamme »

Für jede Zeile ein Array von BGR-Instanzen zu haben würde aber nicht dafür sorgen, dass ich immer eine durch 4 Bytes teilbare Zeile habe. Und durch Kombination von beidem wäre nicht gewährleistet, dass die Reihenfolge im Speicher gleich ist (struct alignment).

Aber bitte sprich weiter, wenn du weißt, wie ich das umsetzen könnte. Ich überlege auch gerade dran. :)

Edit:
Ich habe jetzt übergangsweise Arrays pro Zeile benutzt. Also ich habe somit eine Tabelle von Zeilen mit 3 * width aufgerundet auf %4==0 unsigned chars pro Zeile.
Doof ist, dass ich das Ding dann auch noch in ein lineares Array umbasteln muss, damit ich es glTexImage2D auch übergeben kann. Sprich, ich hab nochmal ordentlich Overhead.

Die Lösung gefällt mir daher auch nicht so recht =/
Benutzeravatar
Krishty
Establishment
Beiträge: 8246
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: glTexImage2D...

Beitrag von Krishty »

Ich kann es hier nicht testen, aber so sollte es gehen (in D3D nehme ich damit auch Bilder von 16 oder 32 Bytes Pitch entgegen):

Code: Alles auswählen

struct BGR {
    unsigned char B, G, R;
};

const size_t UnalignedPitch = ImageWidth * sizeof(BGR);
const size_t Pitch = ((UnalignedPitch + 3) / 4) * 4; // Auf Vielfaches von vier aufrunden
const char * RawData = new char[Pitch * ImageHeight];

for(size_t CurrentRowsIndex = 0; CurrentRowsIndex < ImageHeight; ++CurrentRowsIndex) {
    BGR * const pCurrentLine = reinterpret_cast<BGR * const>(RawData + Pitch * CurrentRowsIndex);
    for(size_t CurrentColumnsIndex = 0; CurrentColumnsIndex < ImageWidth; ++CurrentColumnsIndex) {
        BGR & CurrentPixel = pCurrentLine[CurrentColumnsIndex];
        CurrentPixel.R =
        CurrentPixel.G = 0;
        CurrentPixel.B = 255;
    } // for column
} // for row
& steht wie immer für den Operator &.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: glTexImage2D...

Beitrag von Eisflamme »

Ok, du simulierst die Zeilen einfach sozusagen. Das ist natürlich auch ne Variante und geht auch schnell. Werd's dann wol sinngemäß übernehmen, ty :)
Psycho
Establishment
Beiträge: 156
Registriert: 16.09.2002, 14:23

Re: glTexImage2D...

Beitrag von Psycho »

Wie läuft Poker? :)
Antworten