Freetype字形在加载到openGL时会换行

4
我正在尝试通过freetype加载TrueTypeFonts,并使用OpenGL显示它们。但是,以下是我得到的结果:Font application
从大多数情况下看起来还好,但是如果你仔细看每个字符,您会发现边界周围有一些小不协调性。我注意到这些奇怪的线实际上是从另一侧的像素中传递过来的。特别是查看'T'和'h',您可以看到与纹理相反的小条形。这种情况也会出现在其他字体中。以下是将字形位图缓冲区复制到OpenGL的代码:
    void load(FT_GlyphSlot glyphSlot, double loadedHeight){
        this->loadedHeight = loadedHeight;
        int width = glyphSlot->bitmap.width;
        int height = glyphSlot->bitmap.rows;

        sizeRatios = Vector2D(width / loadedHeight, height / loadedHeight);
        offsetRatios = Vector2D(glyphSlot->bitmap_left / loadedHeight, glyphSlot->metrics.horiBearingY / loadedHeight);
        advanceRatios = Vector2D((glyphSlot->advance.x >> 6) / loadedHeight, (glyphSlot->advance.y >> 6) / loadedHeight);

        std::cout << width << ", " << height << std::endl;

        GLubyte * textureData = new GLubyte[width * height * 4];

        for(int y = 0; y < height; y++){
            for(int x = 0; x < width; x++){
                for(int i = 0; i < 4; i++){
                    textureData[(x + y * width) * 4 + i] = glyphSlot->bitmap.buffer[x + width * y];
                }
            }
        }

        texture.bind();
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        texture.load(GL_TEXTURE_2D, 0, GL_RGBA, glyphSlot->bitmap.width, glyphSlot->bitmap.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
        // glGenerateMipmap(GL_TEXTURE_2D);

        delete [] textureData;
    }

字体大小在其他地方设置,并与我想要加载的字形槽一起传递到此方法中。纹理对象只是一个创建纹理句柄并跟踪它的类,load方法将参数直接传递到glTexImage2D()中。
我尝试使用模数旋转将像素向左或向右移动一个像素,垂直方向可以正常工作,但是水平方向不行。我还尝试通过将格式更改为GL_RED并直接将缓冲区传递给load方法来加载纹理,如这里所述,但问题仍然存在,所以我认为这可能甚至是freetype的一个缺陷?
我想知道是否有一些我不理解的纹理加载的基本元素。
如果您需要一些额外的源代码来了解出了什么问题,请告诉我。

为了优化,也许您应该提前生成所有字形,将其放在单独的纹理上(在x和y轴上给定偏移量),然后将单个纹理传输到卡片上,并用更大纹理的部分进行绘制。由此,您只需要生成位图一次,并且由于给定的非零偏移量,纹理不会出现混合。否则,@genpfault的答案应该足够。 - baderman
我不熟悉一次性加载字体中的每个字形,而且我想要支持Unicode,所以决定在需要时进行加载。有一个字体类调用加载函数,仅当字符尚未加载并且之前加载的大小对于请求的绘制大小太小时才会加载。如果以后证明这种方法效率太低,我会换一种方法,但现在我希望保持灵活性。 - HonestHeuristic
1个回答

4

GL_TEXTURE_WRAP_S/GL_TEXTURE_WRAP_T 默认使用GL_REPEAT

应该使用GL_CLAMP_TO_EDGE代替。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接