Проблема с отображением символов с помощью Freetype и OpenGL

Я пытаюсь разработать простой движок для 2D-игр, и мне нужно уметь рисовать текст, поэтому я решил использовать знаменитый freetype. библиотека. Моя текущая цель - визуализировать каждый символ от 0 до 255 и сохранить соответствующую информацию в объекте глифа, верхнем и левом положениях символа, ширине и высоте, а также текстуре OpenGL. (В будущем я хочу убрать по одной текстуре на глиф, но перед тем, как начать работать над этим, мне нужно, чтобы мои символы отображались правильно). Сначала у меня были искажены все символы, но затем я проверил этот вопрос и выяснил, что мне нужно скопировать буфер растрового изображения в новый с требуемыми размерами текстур OpenGL (т.е. степень двойки для ширины и высоты) . С этого момента каждый символ выглядел великолепно, поэтому я пробовал разные размеры шрифта, чтобы проверить, все ли работает нормально, угадайте, что ... не было, на небольших размерах шрифта (т.е.

http://img17.imageshack.us/img17/2963/helloworld.png

Все искаженные символы имели ширину 1, что дало два, потому что это первая степень двойки, вот код для визуализации каждого символа.

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;
}

Единственное решение, которое я смог найти, - это небольшой оператор if, изменение TextureWidth на 4, если оно имеет значение 2, и таким образом текст будет выглядеть нормально при любом размере шрифта. Но для меня это не имеет никакого смысла, почему OpenGL отклоняет ширину в 2 текстуры? О, и я определил, что проблема не в буфере, я распечатал его, и все выглядит нормально.

Можете ли вы придумать причину, по которой это происходит?

Вот остальная часть ( чрезвычайно) запутанный код, на случай, если проблема не в функции рендеринга.

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];

};

Я думаю, что это все, пожалуйста, дайте мне знать, если вы нашли проблему.

С уважением и заранее спасибо,

9
задан Community 23 May 2017 в 11:45
поделиться