"OpenGL error: 1282 - Failed to upload texture data" при загрузке шрифта с библиотекой FreeType для отрисовки в OpenGL
Пишу простую программу для работы с библиотекой FreeType. Скачал исходники, скомпилировал библиотеку, так же добавил для работы с OpenGL другие необходимые библиотеки (GLEW, GLFW, GLM). Ниже привожу код:
#include <iostream>
// FreeType
#include <ft2build.h>
#include FT_FREETYPE_H
#include <freetype/ftglyph.h>
FT_Library ft;
FT_Face face;
//OpenGL
#include <GLEW/glew.h>
#include <GLFW/glfw3.h>
//Инициализация и загрузка шрифта
void initFreeType() {
if (FT_Init_FreeType(&ft)) {
std::cerr << "Не удалось инициализировать FreeType" << std::endl;
return;
}
if (FT_New_Face(ft, "Arial.ttf", 0, &face)) {
std::cerr << "Загрузка шрифта не удалась" << std::endl;
return;
}
FT_Set_Pixel_Sizes(face, 0, 48); // Устанавливаем размер шрифта
}
void renderText(const char* text, float x, float y) {
// Создание и настройка текстурного объекта
GLuint tex;
glGenTextures(1, &tex);
if (tex == 0) {
std::cerr << "Failed to generate texture" << std::endl;
return;
}
glBindTexture(GL_TEXTURE_2D, tex);
if (glGetError() != GL_NO_ERROR) {
std::cerr << "Failed to bind texture" << std::endl;
glDeleteTextures(1, &tex);
return;
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for (const char* p = text; *p; p++) {
if (FT_Load_Char(face, *p, FT_LOAD_RENDER)) {
std::cerr << "Failed to load glyph" << std::endl;
continue;
}
// Загрузка данных изображения в текстурный буфер OpenGL
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RED,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RED,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);
GLenum error = glGetError();
if (error != GL_NO_ERROR) {
std::cerr << "OpenGL error: " << error << std::endl;
std::cerr << "Failed to upload texture data" << std::endl;
glDeleteTextures(1, &tex);
return;
}
// Отрисовка квадрата с текстурой
float x2 = x + face->glyph->bitmap_left;
float y2 = y - face->glyph->bitmap_top;
float w = face->glyph->bitmap.width;
float h = face->glyph->bitmap.rows;
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(x2, y2);
glTexCoord2f(0, 1); glVertex2f(x2, y2 + h);
glTexCoord2f(1, 1); glVertex2f(x2 + w, y2 + h);
glTexCoord2f(1, 0); glVertex2f(x2 + w, y2);
glEnd();
// Смещение позиции X
x += (face->glyph->advance.x >> 6);
}
glDeleteTextures(1, &tex);
}
int main() {
if (std::setlocale(LC_ALL, "ru_RU.UTF-8") == nullptr) {
std::cerr << "Failed to set locale." << std::endl;
return 1;
}
// Инициализация GLFW
if (!glfwInit()) {
std::cerr << "Failed to init GLFW" << std::endl;
return -1;
}
// Установка параметров контекста GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Создание окна GLFW
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Window", nullptr, nullptr);
if (!window) {
std::cerr << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
// Создание контекста OpenGL и установка его в окно GLFW
glfwMakeContextCurrent(window);
// Инициализация GLEW
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
std::cerr << "Failed to init GLEW" << std::endl;
glfwTerminate();
return -1;
}
//Инициализация и загрузка шрифта
initFreeType();
// ---Основной цикл---
while (!glfwWindowShouldClose(window)) {
// Очистка буферов кадра
glClear(GL_COLOR_BUFFER_BIT);
// Рендеринг текста
renderText("Привет, мир!", 100, 100);
// Обновление содержимого окна
glfwSwapBuffers(window);
// Проверка событий и вызов обработчиков
glfwPollEvents();
}
// Освобождение ресурсов
FT_Done_Face(face);
FT_Done_FreeType(ft);
glfwTerminate();
return 0;
}
Программа компилируется и запускается, однако в консоль выводятся отладочные сообщения об ошибке:
OpenGL error: 1282
Failed to upload texture data
А если убрать фрагмент:
GLenum error = glGetError();
if (error != GL_NO_ERROR) {
std::cerr << "OpenGL error: " << error << std::endl;
std::cerr << "Failed to upload texture data" << std::endl;
glDeleteTextures(1, &tex);
return;
}
То выводится ошибка:
Failed to bind texture
Чуть позже добавил вывод значений face->glyph->bitmap. width, height, и указатель не = 0 и не пустые.