在OSX上使用OpenGL渲染字体(Freetype)不起作用

时间:2014-12-11 20:43:13

标签: c++ opengl fonts alphablending freetype

我正在尝试根据本教程渲染freetype字体: http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Text_Rendering_01

无法看到我的字体,您可以在此处看到: enter image description here

似乎正在加载位图数据,因为我可以在OSX的OpenGL分析器中看到它:

enter image description here

有类似问题的人

这家伙正在做我正在做的事情。 我尝试将值从GL_ALPHA更改为GL_R8 / GL_RED,但没有成功

glTexImage2D failing in GLUT/FreeType example with OpenGL 3 and above

的main.cpp

#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;
  }
}

font.vert

#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;
}

font.frag

#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;
}

0 个答案:

没有答案
相关问题