Intento desarrollar un motor de juego en 2D simple y necesito poder dibujar texto, así que decidí usar la famosa biblioteca de tipos de freetype. Mi objetivo actual es representar todos los caracteres de 0 a 255 y almacenar la información adecuada en un objeto de glifo, las posiciones superior e izquierda del personaje, el ancho y el alto, y una textura OpenGL. (En el futuro deseo eliminar 1 textura por glifo, pero antes de comenzar a trabajar en eso necesito que mis personajes se muestren correctamente). Primero tengo todos los caracteres distorsionados pero luego revisé this question y descubrí que tenía que copiar el buffer de mapa de bits en uno nuevo con los tamaños de textura requeridos OpenGL (es decir, una potencia de dos para ancho y alto). A partir de ahí, cada personaje se veía genial, así que probé diferentes tamaños de fuente para ver si todo estaba funcionando bien, adivinen qué ... no lo era, en tamaños de letra pequeños (es decir, < 30) cada carácter con un ancho pequeño ('l', 'i', ';', ':') aparecieron distorsionados.Problema de representación de caracteres con Freetype y OpenGL
http://img17.imageshack.us/img17/2963/helloworld.png
caracteres distorsionados Todos tenían una anchura de 1, que salió a dos, porque esa es la primera potencia de dos, aquí está el código para la prestación de cada personaje.
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;
}
La única solución que pude encontrar fue un poco si la declaración, el cambio de la TextureWidth a 4 si tiene el valor de 2, y de esa manera el texto se ve bien en todos los tamaños de fuente. Pero esto no tiene ningún sentido para mí, ¿por qué OpenGL rechazaría el ancho de 2 texturas? Ah, y he determinado que el problema no está en el buffer, lo imprimí y se ve bien.
¿Puedes pensar en alguna razón por la que esto está sucediendo?
Aquí está el resto del código (extremadamente) desordenado, en caso de que el problema no se encuentre dentro de la función 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];
};
creo que eso es todo, por favor, hágamelo saber si usted ha encontrado el problema.
Saludos y gracias de antemano,
¿Ha intentado ejecutar esto en una computadora diferente? Puede ser un problema con el controlador. –
No, no lo he intentado y lo volveré a publicar más tarde. ¡Gracias por la idea! :) – Carlos