ich versuche gerade eine C++ Klasse zu bauen die Texte ausgeben kann und so ähnlich funktioniert wie std::cout nur halt für 3D Programme.
Ich benutze OpenGL aber ohne X11. Womit ich Probleme habe ist die Zeilenabstände richtig zu berechnen. Mir ist irgendwie nicht ganz klar wie man das richtig macht. Die Freetype Dokumentation ist da ein bisschen verwirrend vielleicht liegt es auch an meinen nicht zu guten Übersetzungsfähigkeiten.
Meine Klasse kann zwar Buchstaben neben einander ausgeben aber Buchstaben aus mehreren Zeilen werden wenn es hohe sind übereinander geschrieben.
So sieht die Klasse im Moment aus:
Code: Alles auswählen
class cout3D
{
public:
FT_Face face;
cout3D (std::string strFont, float fXPos = -1, float fYPos = 1) : fIntXPos (fXPos), fIntYPos (fYPos)
{
FT_Library idFreeType;
if (FT_Init_FreeType (&idFreeType))
{
std::cout << "Initialisierung von FreeType nicht möglich" << std::endl;
exit (0);
}
if (FT_New_Face (idFreeType, strFont.c_str (), 0, &face))
{
std::cout << "Font konnte nicht geöffnet werden." << std::endl;
exit (0);
}
FT_Set_Char_Size( face, 50 * 64, 0, 100, 0);
// Skalierungsfaktoren für die Umrechnung von Pixelkoordinaten in OpenGL Koordinaten
fIntSx = 2.0 / lcdDisplay.width; // Bildschirm Auflösung X (liefert DRM)
fIntSy = 2.0 / lcdDisplay.height; // Bildschirm Auflösung Y (liefert DRM)
}
void setCursor (float fXPos, float fYPos)
{
fIntXPos = fXPos;
fIntYPos = fYPos - ((face->glyph->metrics.horiAdvance / 64) * fIntSy);
}
cout3D operator<< (std::string strText)
{
for (const char &i : strText)
{
this->loadChar (i);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
GLuint tex;
glGenTextures (1, &tex);
glBindTexture (GL_TEXTURE_2D, tex);
glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, face->glyph->bitmap.width, face->glyph->bitmap.rows, 0, GL_ALPHA, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLint texLoc = glGetUniformLocation(gl.program, "myTexture");
glActiveTexture (GL_TEXTURE0);
glUniform1i (texLoc, 0);
// Berechne den Umrechnungsfaktor für Pixelbilder
fIntSx = 2.0 / lcdDisplay.width; // Alien Bildschirm Auflösung X (liefert DRM)
fIntSy = 2.0 / lcdDisplay.height; // Alien Bildschirm Auflösung Y (liefert DRM)
// glWidth und glHeight soll die für OpenGL umgerechnete Pixel größe des Zeichens sein.
GLfloat glWidth = face->glyph->bitmap.width * fIntSx;
GLfloat glHeight = face->glyph->bitmap.rows * fIntSy;
// x, y, z, w (w = 1 vertex, w = 0 transformation)
GLfloat vertices[] = { 0.0 , 0.0 , 0.0, 1.0, // links oben
glWidth, 0.0 , 0.0, 1.0, // rechts oben
glWidth, -glHeight, 0.0, 1.0, // recht unten
0.0 , -glHeight, 0.0, 1.0 }; // links unten
// Vertex Daten an den Shader übergeben und die Art der Daten beschreiben.
glEnableVertexAttribArray (0); // Die 0 wird im Shader an die layout Variable übergeben.
glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, vertices);
// UV-Koordinaten an den Shader übergeben zur Positionierung der Textur
// X = U, Y = V
GLfloat uvCoords[] = { 0.0, 0.0, // links oben
1.0, 0.0, // rechts oben
1.0, 1.0, // rechts unten
0.0, 1.0 }; // links unten
glEnableVertexAttribArray (1); // Die 1 wird im Shader an die ??? Variable übergeben.
glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, uvCoords);
// fIntYPos je nach höhe des Zeichens anpassen.
GLfloat yAnpassung = 0;
if (face->glyph->bitmap_top != 50)
{
yAnpassung = (50 - face->glyph->bitmap_top) * fIntSy;
std::cout << i << " yAnpassung: " << yAnpassung << std::endl;
}
// Erzeuge die Transformationsmatrix um den Buchstaben endgültig zu positionieren.
GLfloat transMatrix[] = { 1.0, 0.0, 0.0, fIntXPos, // X
0.0, 1.0, 0.0, fIntYPos - yAnpassung, // Y
0.0, 0.0, 1.0, 0.00, // Z
0.0, 0.0, 0.0, 1.00 }; // Richtung
fIntXPos = fIntXPos + (face->glyph->metrics.horiAdvance / 64 * fIntSx);
GLint idTransMatrix = glGetUniformLocation(gl.program, "transMatrix");
std::cout << idTransMatrix << std::endl;
glUniformMatrix4fv (idTransMatrix, 1, GL_FALSE, transMatrix);
// Bitmap des Buchstabens ausgeben.
glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
}
}
private:
// Skalierungsfaktoren für die Umrechnung von Pixelkoordinaten in OpenGL Koordinaten.
float fIntSx;
float fIntSy;
// Aktuelle Schreibposition in OpenGL Koordinaten
float fIntXPos;
float fIntYPos;
void loadChar (char cZeichen)
{
if (FT_Load_Char (face, cZeichen, FT_LOAD_RENDER))
{
std::cout << "Zeichen konnte nicht geladen werden." << std::endl;
exit (0);
}
}
};
Grüße
Alexander