我正在将我的OpenGL项目从GLUT转移到GLFW。目前我正在尝试使用FreeType库在屏幕上显示文本。我正在关注他们网站的教程,但我被困住了。我相信我已将所有内容写出来,但由于某种原因它无效。我错过了什么?
这是我的代码:
#include <iostream>
#include <stdlib.h>
// Include GLEW
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "ft2build.h"
#include FT_FREETYPE_H
FT_Library library;
FT_Face face;
static void error_callback(int error, const char* description)
{
fputs(description, stderr);
}
//should only be used for key press or key release
static void key_press(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
void render_text(const std::string &str, FT_Face face, float x, float y, float sx, float sy) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
const FT_GlyphSlot glyph = face->glyph;
for (auto c : str) {
if (FT_Load_Char(face, c, FT_LOAD_RENDER) != 0)
continue;
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8,
glyph->bitmap.width, glyph->bitmap.rows,
0, GL_RED, GL_UNSIGNED_BYTE, glyph->bitmap.buffer);
const float vx = x + glyph->bitmap_left * sx;
const float vy = y + glyph->bitmap_top * sy;
const float w = glyph->bitmap.width * sx;
const float h = glyph->bitmap.rows * sy;
struct {
float x, y, s, t;
} data[6] = {
{ vx, vy, 0, 0 },
{ vx, vy - h, 0, 1 },
{ vx + w, vy, 1, 0 },
{ vx + w, vy, 1, 0 },
{ vx, vy - h, 0, 1 },
{ vx + w, vy - h, 1, 1 }
};
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(float), data, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
x += (glyph->advance.x >> 6) * sx;
y += (glyph->advance.y >> 6) * sy;
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
void Resize(GLFWwindow* window)
{
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-5.f, 5.f, -5.f, 5.f, 5.f, -5.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Setup()
{
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST); // Depth Testing
glDepthFunc(GL_LEQUAL);
glDisable(GL_CULL_FACE);
glCullFace(GL_BACK);
//used for font
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void Display(GLFWwindow* window)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
render_text("TEST", face, 0, 0, 100, 100);
glfwSwapBuffers(window);
glfwPollEvents();
}
void Update(GLFWwindow* window)
{
Display(window);
}
int main(void)
{
GLFWwindow* window;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glewExperimental = true;
if (glewInit() != GLEW_OK)
{
//Problem: glewInit failed, something is seriously wrong.
std::cout << "glewInit failed, aborting." << std::endl;
exit(EXIT_FAILURE);
}
FT_Error error = FT_Init_FreeType(&library);
if (error) {
fprintf(stderr, "Could not init freetype library\n");
return 1;
}
error = FT_New_Face(library, "Stoke-Regular.ttf", 0, &face);
if (error == FT_Err_Unknown_File_Format)
{
std::cout << "font is unsupported" << std::endl;
return 1;
}
else if (error)
{
std::cout << "font could not be read or opened" << std::endl;
return 1;
}
error = FT_Set_Pixel_Sizes(face, 0, 48);
if (error)
{
std::cout << "Problem adjusting pixel size" << std::endl;
return 1;
}
//keyboard controls
glfwSetKeyCallback(window, key_press);
Resize(window);
Setup();
while (!glfwWindowShouldClose(window))
{
Update(window);
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}