我正在尝试根据本教程渲染freetype字体: http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Text_Rendering_01
无法看到我的字体,您可以在此处看到:
似乎正在加载位图数据,因为我可以在OSX的OpenGL分析器中看到它:
这家伙正在做我正在做的事情。 我尝试将值从GL_ALPHA更改为GL_R8 / GL_RED,但没有成功
glTexImage2D failing in GLUT/FreeType example with OpenGL 3 and above
#include <iostream>
using namespace std;
#include <cstdlib>
#include <stdio.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
GLFWwindow* window;
#define WINDOW_HEIGHT 768
#define WINDOW_WIDTH 1024
#include <ft2build.h>
#include FT_FREETYPE_H
#include "common/shaders.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
static void error_callback(int error, const char* description);
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
void print(const char *text, float x, float y, float sx, float sy);
FT_Library ft;
FT_Face face;
FT_GlyphSlot g;
int main(void)
{
if (!glfwInit()) {
fprintf( stderr, "Failed to initialize GLFW\n" );
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE , GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Ortho", NULL, NULL);
if (!window) {
fprintf(stderr, "Failed to create window\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glfwSetErrorCallback(error_callback);
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
glfwSetCursorPos(window, WINDOW_WIDTH/2, WINDOW_HEIGHT/2);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
if (GL_EXT_texture_array){
fprintf(stderr, "GL_EXT_texture_array\n");
}
GLuint vbo;
GLuint program;
if(FT_Init_FreeType(&ft)) {
fprintf(stderr, "Could not init freetype library\n");
exit(EXIT_FAILURE);
}
if(FT_New_Face(ft, "fonts/Vera.ttf", 0, &face)) {
fprintf(stderr, "Could not open font\n");
exit(EXIT_FAILURE);
}
FT_Set_Pixel_Sizes(face, 0, 48);
if(FT_Load_Char(face, 'X', FT_LOAD_RENDER)) {
fprintf(stderr, "Could not load character 'X'\n");
exit(EXIT_FAILURE);
}
g = face->glyph;
program = load_shaders("shaders/font.vert", "shaders/font.frag");
glUseProgram(program);
glClearColor(0.0f, 55.0f, 55.0f, 0.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glGenBuffers(1, &vbo);
GLuint vai; // vertex array id
glGenVertexArrays(1, &vai);
glBindVertexArray(vai);
GLuint tex;
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
GLuint uniform_tex = glGetUniformLocation(program, "tex");
GLuint color = glGetUniformLocation(program, "color");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
GLfloat black[4] = {0, 0, 0, 1};
glUniform4fv(color, 1, black);
glUniform1i(uniform_tex, 0);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float sx = 2.0 / 1024;
float sy = 2.0 / 768;
print("The Quick Brown Fox Jumps Over The Lazy Dog",
-1 + 8 * sx,
1 - 50 * sy,
sx,
sy
);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glDeleteProgram(program);
glDeleteVertexArrays(2, &vai);
glfwTerminate();
exit(EXIT_SUCCESS);
}
static void error_callback(int error, const char* description){
fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, 1);
}
void print(const char *text, float x, float y, float sx, float sy) {
const char *p;
for(p = text; *p; p++) {
if(FT_Load_Char(face, *p, FT_LOAD_RENDER))
continue;
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_R8,
g->bitmap.width,
g->bitmap.rows,
0,
GL_RED,
GL_UNSIGNED_BYTE,
g->bitmap.buffer
);
float x2 = x + g->bitmap_left * sx;
float y2 = -y - g->bitmap_top * sy;
float w = g->bitmap.width * sx;
float h = g->bitmap.rows * sy;
GLfloat box[4][4] = {
{x2, -y2 , 0, 0},
{x2 + w, -y2 , 1, 0},
{x2, -y2 - h, 0, 1},
{x2 + w, -y2 - h, 1, 1},
};
glBufferData(GL_ARRAY_BUFFER, sizeof box, box, GL_DYNAMIC_DRAW);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
x += (g->advance.x >> 6) * sx;
y += (g->advance.y >> 6) * sy;
}
}
#version 400 core
layout (location = 0) in vec4 coord;
out vec2 texcoord;
void main(void) {
gl_Position = vec4(coord.xy, 0, 1);
texcoord = coord.zw;
}
#version 400 core
out vec4 fColor;
in vec2 texcoord;
uniform sampler2D tex;
uniform vec4 color;
void main(void) {
fColor = vec4(1, 1, 1, texture(tex, texcoord).a) * color;
}