gpt4 book ai didi

c++ - 将 freetype 位图复制到 opengl 纹理时出现问题

转载 作者:搜寻专家 更新时间:2023-10-31 00:16:45 26 4
gpt4 key购买 nike

我正在尝试为从 ' ''~' 的字符生成所有位图,并将它们添加到一个长纹理中。我打算将它们放置在固定宽度的纹理中,但现在我只想确保这个概念可行。

但是我遇到了问题。我没有得到预期的纹理,而是得到了下面的 16px 字体: enter image description here

在我看来,好像我复制错了,但无论我做什么,我似乎总是得到相同的输出。

最后是代码:

字体.h

#ifndef _FONT_H_
#define _FONT_H_

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <GL/gl.h>

#include <ft2build.h>
#include FT_FREETYPE_H

#include "vector2.h"
#include "math_helper.h"

class Font {
public:
Font(const std::string font_path, int size);
~Font();

int get_texture() const { return texture_; }

private:
unsigned int width_, height_, texture_;

static FT_Library LIBRARY;
static const char START_CHAR = ' ';
static const char END_CHAR = '~';

static void initialize_library();
};

#endif

字体.cpp

#include "font.h"

FT_Library Font::LIBRARY = NULL;

Font::Font(const std::string font_path, int size)
: width_(64), height_(2), texture_(0) {
initialize_library();

FT_Face face = NULL;
int error = FT_New_Face(Font::LIBRARY, font_path.c_str(), 0, &face);

if(error == FT_Err_Unknown_File_Format) {
std::cout << "Error: Unknown file format for font \"" << font_path << "\"" << std::endl;
} else if(error) {
std::cout << "Error: Could not open font \"" << font_path << "\"" << std::endl;
}

error = FT_Set_Pixel_Sizes(face, 0, size);
if(error) {
std::cout << "Error: Could not set pixel size for font \"" << font_path << "\"" << std::endl;
}

int num_chars = (END_CHAR - START_CHAR);
width_ = to_nearest_pow2(num_chars * size);
height_ = to_nearest_pow2(size);
std::vector<unsigned char> buffer(width_ * height_, 0);
Vector2 pen;

for(char c = START_CHAR; c <= END_CHAR; ++c) {
error = FT_Load_Char(face, c, FT_LOAD_RENDER);

if(error) {
std::cout << "Error: Could not load char \"" << c << "\"" << std::endl;
continue;
}

FT_Bitmap bmp = face->glyph->bitmap;
int advance = (face->glyph->advance.x >> 6);
int bitmapWidth = bmp.width; //I have tried pitch, same problem
int bitmapHeight = bmp.rows;

for(int h = 0; h < bitmapHeight; ++h) {
for(int w = 0; w < bitmapWidth; ++w) {
int index = h * bitmapWidth + pen.x;

buffer[index + w] = bmp.buffer[w + bitmapWidth * h];
}
}

pen.x += advance;
}

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texture_);
glBindTexture(GL_TEXTURE_2D, texture_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width_, height_, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &buffer[0]);

FT_Done_Face(face);
}

Font::~Font() {
if(texture_ != 0) {
glDeleteTextures(1, &texture_);
}
}

void Font::initialize_library() {
if(Font::LIBRARY == NULL) {
if(FT_Init_FreeType(&Font::LIBRARY) != 0) {
std::cout << "Error: Unable to initialize FreeType Library" << std::endl;
return;
}
}
}

Vector2 只是一个简单的结构,具有在构造时初始化为 0 的 x 和 y 字段。

to_nearest_pow2 定义为:

template<typename T>
T to_nearest_pow2(const T num) {
T nearest = 2;

while((nearest <<= 1) < num);

return nearest;
}

哦,这就是我将它绘制到屏幕上的方式(我使用的是正交投影)

  glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, test->get_texture());
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(0, 0);
glTexCoord2i(1, 0); glVertex2i(400, 0);
glTexCoord2i(1, 1); glVertex2i(400, 400);
glTexCoord2i(0, 1); glVertex2i(0, 400);
glEnd();

编辑

我将 index 更改为@shouston 建议的内容,现在我得到了这个输出

enter image description here

最佳答案

将输出图像重新调整为 1000x60 之类的尺寸,您会大吃一惊。这是 paint.net 使用您附加的 PNG 制作的内容。

enter image description here

首先是显而易见的事情。字符基本上在那里,但出于某种原因,您只是将它们渲染得非常小(您传递的 size 值是多少?)

此外,您并没有尝试处理任何自由字体字符指标,因此不要指望它们都能很好地排列。然而……

关于c++ - 将 freetype 位图复制到 opengl 纹理时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15209494/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com