Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

  • »Spiele Programmierer« ist der Autor dieses Themas

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

1

17.03.2013, 18:04

"glTexSubImage2D" sorgt für Texturverzerrungen..

Ich bin momentan an einem Fontrenderingsystem in C++ auf Basis von Freetype dran.
Eigentlich funktioniert auch das meiste schon, aber die hochgeladen Buchstabentexturen sind teilweise verzerrt. Genauer gesagt unterschiedlich stark nach oben rechts geschert, wobei die Pixel die links fehlen wieder rechts hereinkommen und anders herum.

Der Code um die Textur(Größe: 4096²) zu Erstellen sieht so aus...

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FontManagementTexture* MTex = new FontManagementTexture(new RectPacker<int>(Size), true);
this->Textures.push_back(MTex);

glGenTextures(1, &(MTex->ID));
    
glBindTexture(GL_TEXTURE_2D, MTex->ID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
//GL_R3_G3_B2, GL_RGB, GL_RGB4, GL_RGB5, 3
//GL_LUMINANCE4, GL_LUMINANCE8, 1
glTexImage2D(GL_TEXTURE_2D, 0, Subpixel ? GL_RGB5 : GL_LUMINANCE4, Size.X, Size.Y, 0, Subpixel ? GL_RGB : GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); // Subpixel ist immer aus...

GLCSHOWERROR();


Und der Code um die Buchstabenbitmaps in die große OpenGL Textur zu laden...

C-/C++-Quelltext

1
2
3
4
Rect<int>& TexArea = MTex_.Packer->operator[](MLetter.RectID).Rect;
const char* BmpFilename = (string("..\\test") + StringConv<int>::ToString(i++) + ".bmp").c_str();
SOIL_save_image(BmpFilename, SOIL_SAVE_TYPE_BMP, TexArea.X2 - TexArea.X1, TexArea.Y2 - TexArea.Y1, 1, MLetter.BmpPixels);
glTexSubImage2D(GL_TEXTURE_2D, 0, TexArea.X1, TexArea.Y1, TexArea.X2 - TexArea.X1, TexArea.Y2 - TexArea.Y1, MLetter.BmpColored ? GL_RGB : GL_LUMINANCE, GL_UNSIGNED_BYTE, MLetter.BmpPixels);


Da ich wie man hier sieht die einzelnen Buchstaben testweise als Bmp ausgebe und dort keine Fehler zu sehen sind, vermute ich stark ein Problem bei "glTexSubImage2D". Die Buchstaben wie sie sein sollten habe ich auch mal angehängt.
Wenn ich unmittelbar danach den Texturinhalt wieder auslesen lasse, dann ist der Fehler bereits da.
So hole ich den Textureninhalt wieder von der Grafikkarte...

C-/C++-Quelltext

1
2
3
4
unsigned char* TexData = new unsigned char[4096*4096];
glGetTexImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, TexData);
SOIL_save_image("..\\testcomplete.bmp", SOIL_SAVE_TYPE_BMP, 4096, 4096, 1, TexData);
GLCSHOWERROR();

Das Problem tritt unverändert auch auf, wenn man eine kleinere Fonttextur anlegt.

Über dem angehängten Bild in dem man im Hintergrund ein Fenster in der GUI erkennt, sollte eigentlich "The Fontmanager is working! :-)" stehen.

(Crosspost zu http://www.delphigl.com/forum/viewtopic.…&p=93417#p93417)
»Spiele Programmierer« hat folgendes Bild angehängt:
  • GUI gerendert Screenhot.png
»Spiele Programmierer« hat folgende Dateien angehängt:

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

17.03.2013, 19:23

Warum GL_RGB5 bzw. GL_LUMINANCE4? In Welchem Format liegen die Daten vor, sieht verdächtig danach aus, als würde der an glTexSubImage2D() übergebene Buffer nicht dem von glTexSubImage2D() erwarteten Format entsprechen...

  • »Spiele Programmierer« ist der Autor dieses Themas

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

3

17.03.2013, 19:30

Zitat

Warum GL_RGB5 bzw. GL_LUMINANCE4?

Naja, die Textur kann sehr groß werden und um Speicherplatz zu sparen GL_RGB5 bzw. GL_LUMINANCE4.
Die 16 Graustufen bei GL_LUMINANCE4 sollten für ein bisschen AntiAliasing am Rand locker reichen.

Wenn ich GL_LUMINANCE8 oder einfach "1" (für einen Kannal) angebe ändert sich am Ergebnis nichts sichtbar. (Gleiche Fehler bei gleichen Buchstaben und gleiche Verzerrung)

CentuCore

Frischling

Beiträge: 43

Wohnort: Wien

  • Private Nachricht senden

4

17.03.2013, 20:15

C-/C++-Quelltext

1
const char* BmpFilename = (string("..\\test") + StringConv<int>::ToString(i++) + ".bmp").c_str();


Erstellt dies nicht ein temporäres string Objekt?
Sprich sollte die Zeichenkette, auf welche BmpFilename zeigt, nicht ungültig sein?

  • »Spiele Programmierer« ist der Autor dieses Themas

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

5

17.03.2013, 20:25

Ja, stimmt. :huh:
Das ist nur so entstanden, weil ich da den Code für bessere Lesbarkeit im Forum schnell umformatiert habe.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

17.03.2013, 20:26

C-/C++-Quelltext

1
const char* BmpFilename = (string("..\\test") + StringConv<int>::ToString(i++) + ".bmp").c_str();


Erstellt dies nicht ein temporäres string Objekt?
Sprich sollte die Zeichenkette, auf welche BmpFilename zeigt, nicht ungültig sein?

jap

7

18.03.2013, 01:00

Das Problem ist aber nicht das temporäre String-Objekt, das Problem ist das 'const char*'. Es gibt heutzutage keinen Vernünftigen Grund mehr, das zu benutzen, und mit einem 'string BmpFilename' wäre das temporäre String-Objekt korrekt kopiert worden und es wären niemals irgendwelche Probleme entstanden.
Oh, und statt 'StringConv<int>::ToString(i++)' gibt es neuerdings auch 'std::to_string(i++)' (aber Vorsicht mit älteren Compilern, evtl. kennen die das noch nicht).
Lieber dumm fragen, als dumm bleiben!

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

18.03.2013, 01:09

Das Problem ist aber nicht das temporäre String-Objekt, das Problem ist das 'const char*'. Es gibt heutzutage keinen Vernünftigen Grund mehr, das zu benutzen [...]

Das würd ich so nicht unterschreiben, es gibt viele gute Gründ const char* zu verwenden. Aber in dem Fall wäre std::string wohl die bessere Idee gewesen. Ich persönlich würd hier allerdings einfach gleich mit einem stringstream arbeiten:

C-/C++-Quelltext

1
2
3
4
std::ostringstream filename;
filename << "..\\test" << i++ << ".bmp";

std::string blub = filename.str();

  • »Spiele Programmierer« ist der Autor dieses Themas

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

9

18.03.2013, 14:16

Zitat

Das Problem ist aber nicht das temporäre String-Objekt, das Problem ist das 'const char*'.

Mir musst du nicht die die Stringklasse verkaufen, weil ich die in der Regel bereits verwende, aber SOIL ist eine C-Bibliothek und kommt daher nur mit einem C-String als Parameter klar.
Der Fehler ist ja nur durch das Kopieren ins Forum entstanden.

Zitat

Oh, und statt 'StringConv<int>::ToString(i++)' gibt es neuerdings auch 'std::to_string(i++)'(aber Vorsicht mit älteren Compilern, evtl. kennen die das noch nicht).

Das ist mir bekannt.
Mein Compiler kennt scheinbar noch nicht alle Überladungen von "std::to_string", aber wieso nicht eine eigens entwickelte Klasse nehmen, die beispielsweise auch noch mit den Vektordatentyp klar kommt und auch noch Strings parsen kann?

Zitat

Ich persönlich würd hier allerdings einfach gleich mit einem stringstream arbeiten:

Stringstreams brauchen unötig viel Code.
Meine "StringConv"-Klasse versucht es übrigens auch über den Stringstream, wenn keine passende Templatespezialisierung vorhanden ist.

Werbeanzeige