Ho cercato di sviluppare un semplice motore di gioco 2D e ho bisogno di essere in grado di disegnare testo, così ho deciso di utilizzare la famosa libreria freetype. Il mio obiettivo attuale è quello di rendere ogni carattere da 0 a 255, e memorizzare le informazioni appropriate in un oggetto glifo, le posizioni superiore e sinistra del carattere, la larghezza e l'altezza e una trama OpenGL. (In futuro desidero rimuovere una texture per glifo, ma prima di iniziare a lavorarci ho bisogno che i miei caratteri siano visualizzati correttamente). Prima ho ottenuto caratteri confusi, ma poi ho controllato this question e ho capito che dovevo copiare il buffer bitmap in uno nuovo con dimensioni di trama richieste OpenGL (vale a dire una potenza di due per larghezza e altezza). Da quel momento in poi, ogni personaggio sembrava fantastico, quindi ho provato diverse dimensioni dei caratteri per vedere se tutto andava bene, indovina un po '... non era, su caratteri piccoli (ad esempio < 30) ogni carattere con una larghezza ridotta ('l', 'i', ';', ':') si presentarono confusi.Problema di rendering dei caratteri con Freetype e OpenGL
http://img17.imageshack.us/img17/2963/helloworld.png
caratteri distorti Tutto aveva una larghezza di 1, che è uscito per due, perché questa è la prima potenza di due, ecco il codice per il rendering ogni personaggio.
bool Font::Render(int PixelSize)
{
if(FT_Set_Pixel_Sizes(mFace, 0, PixelSize) != 0)
return false;
for(int i = 0; i < 256; ++i)
{
FT_UInt GlyphIndex;
GlyphIndex = FT_Get_Char_Index(mFace, i);
if(FT_Load_Glyph(mFace, GlyphIndex, FT_LOAD_RENDER) != 0)
return false;
int BitmapWidth = mFace->glyph->bitmap.width;
int BitmapHeight = mFace->glyph->bitmap.rows;
int TextureWidth = NextP2(BitmapWidth);
int TextureHeight= NextP2(BitmapHeight);
printf("Glyph is %c, BW: %i, BH: %i, TW: %i, TH: %i\n", i, BitmapWidth, BitmapHeight, TextureWidth, TextureHeight);
mGlyphs[i].SetAdvance(mFace->glyph->advance.x >> 6);
mGlyphs[i].SetLeftTop(mFace->glyph->bitmap_left, mFace->glyph->bitmap_top);
GLubyte * TextureBuffer = new GLubyte[ TextureWidth * TextureHeight ];
for(int j = 0; j < TextureHeight; ++j)
{
for(int i = 0; i < TextureWidth; ++i)
{
TextureBuffer[ j*TextureWidth + i ] = (j >= BitmapHeight || i >= BitmapWidth ? 0 : mFace->glyph->bitmap.buffer[ j*BitmapWidth + i ]);
}
}
for(int k = 0; k < TextureWidth * TextureHeight; ++k)
printf("Buffer is %i\n", TextureBuffer[k]);
Texture GlyphTexture;
GLuint Handle;
glGenTextures(1, &Handle);
GlyphTexture.SetHandle(Handle);
GlyphTexture.SetWidth(TextureWidth);
GlyphTexture.SetHeight(TextureHeight);
glBindTexture(GL_TEXTURE_2D, Handle);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, TextureWidth, TextureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, TextureBuffer);
mGlyphs[i].SetTexture(GlyphTexture);
delete [] TextureBuffer;
}
return true;
}
L'unica soluzione che ho trovato è stato un po 'if, cambiando il TextureWidth a 4 se ha il valore di 2, e in questo modo il testo guarda bene in ogni dimensione del carattere. Ma questo non ha senso per me, perché OpenGL rifiuta la larghezza di 2 trame? Oh, e ho determinato che il problema non risiede nel buffer, l'ho stampato e sembra perfetto.
Riesci a pensare a qualche motivo per cui questo sta accadendo?
Ecco il resto del codice (estremamente) disordinato, nel caso in cui il problema non risieda nella funzione Render.
int NextP2(int Val)
{
int RVal = 2;
while(RVal < Val) RVal <<= 1;
return RVal;
}
class Texture
{
public:
void Free() { glDeleteTextures(1, &mHandle); }
void SetHandle(GLuint Handle) { mHandle = Handle; }
void SetWidth(int Width) { mWidth = Width; }
void SetHeight(int Height) { mHeight = Height; }
inline GLuint Handle() const { return mHandle; }
inline int Width() const { return mWidth; }
inline int Height() const { return mHeight; }
private:
GLuint mHandle;
int mWidth;
int mHeight;
};
class Glyph
{
public:
void SetAdvance(int Advance) { mAdvance = Advance; }
void SetLeftTop(int Left, int Top) { mLeft = Left; mTop = Top; }
void SetTexture(Texture texture) { mTexture = texture; }
Texture & GetTexture() { return mTexture; }
int GetAdvance() const { return mAdvance; }
int GetLeft() const { return mLeft; }
int GetTop() const { return mTop; }
private:
int mAdvance;
int mLeft;
int mTop;
Texture mTexture;
};
class Font
{
public:
~Font() { for(int i = 0; i < 256; ++i) mGlyphs[i].GetTexture().Free(); }
bool Load(const std::string & File);
bool Render(int PixelSize);
Glyph & GetGlyph(unsigned char CharCode) { return mGlyphs[CharCode]; }
private:
FT_Face mFace;
Glyph mGlyphs[256];
};
Penso che sia tutto, per favore fatemi sapere se avete trovato il problema.
Cordiali saluti e grazie in anticipo,
Hai provato a farlo su un altro computer? Potrebbe essere un problema di driver. –
No, non l'ho fatto, ci proverò e posteremo più tardi. Grazie per l'idea! :) – Carlos