Библиотека FreeType не отображается с кодом учебника - PullRequest
1 голос
/ 16 мая 2019

-Использование Mac Retina Display 2304x1440

Мне удалось включить библиотеку FreeType и я пытался нарисовать на основе учебник , но ничего не отображалось.

Нетошибки, поэтому я не могу определить проблему.


// For LoadShaders
#include "shader.hpp"

#include <vector>
#include <cstring>

#include <GL/glew.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;

#include <ft2build.h>
#include FT_FREETYPE_H


FT_Library library;
FT_Face face;

GLuint TextShaderID;
GLuint uniform_tex;
GLuint uniform_color;

GLuint vbo00;

// I have already acquired this font.
const char * fontfilename = "OpenSans-Regular.ttf";

void iii()
{



    /* Initialize the FreeType2 library */
    if (FT_Init_FreeType(&library)) {
        fprintf(stderr, "Could not init freetype library\n");
    }

    /* Load a font */
    if (FT_New_Face(library, fontfilename, 0, &face)) {
        fprintf(stderr, "Could not open font %s\n", fontfilename);
    }

    // Initialize Shader (Here is not problem. Maybe.)
    TextShaderID = LoadShaders( "material/shader/FreeType.vertexshader", "material/shader/FreeType.fragmentshader" );

    // Initialize uniforms' IDs
    uniform_tex = glGetUniformLocation( TextShaderID, "myTextureSampler" );
    uniform_color = glGetUniformLocation( TextShaderID, "texcol" );

    glGenBuffers(1, &vbo00);

}

void render_text(const char *text, float x, float y, float sx, float sy) {
    const char *p;
    FT_GlyphSlot g = face->glyph;

    glActiveTexture(GL_TEXTURE0);

    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glUniform1i(uniform_tex, 0);

    /* We require 1 byte alignment when uploading texture data */
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    /* Clamping to edges is important to prevent artifacts when scaling */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    /* Linear filtering usually looks best for text */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    /* Set up the VBO for our vertex data */
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo00);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

    /* Loop through all characters */
    for (p = text; *p; p++) {
        /* Try to load and render the character */
        if (FT_Load_Char(face, *p, FT_LOAD_RENDER))
            continue;

        /* Upload the "bitmap", which contains an 8-bit grayscale image, as an alpha texture */
        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, g->bitmap.width, g->bitmap.rows, 0, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);

        /* Calculate the vertex and texture coordinates */
        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},
        };

        /* Draw the character on the screen */
        glBufferData(GL_ARRAY_BUFFER, sizeof box, box, GL_DYNAMIC_DRAW);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        /* Advance the cursor to the start of the next character */
        x += (g->advance.x >> 6) * sx;
        y += (g->advance.y >> 6) * sy;
    }



    glDisableVertexAttribArray(0);
    glDeleteTextures(1, &tex);

}

void rrr()
{

    glUseProgram(TextShaderID);

    /* White background */
    glClearColor(1, 1, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT);

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


    float sx = 2/2304/4;
    float sy = 2/1440/4;

    FT_Set_Pixel_Sizes(face, 0, 48);

    /* Effects of alignment */
    GLfloat red[4] = { 1, 0, 0, 1 };
    glUniform4fv(uniform_color, 1, red);
    render_text("The Quick Brown Fox Jumps Over The Lazy Dog", 0, 0, sx, sy);

    glutSwapBuffers();

}

1 Ответ

0 голосов
/ 19 мая 2019
float sx = 2/2304/4;
float sy = 2/1440/4;

являются целочисленными делениями. Если целое число делится на большее целое число, результат равен 0.

Вы должны делать деления с плавающей запятой:

float sx = 2.0f/2304.0f/4.0f;
float sy = 2.0f/1440.0f/4.0f;

glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
             g->bitmap.width, g->bitmap.rows, 0,
             GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);

генерирует текстуру, где данные кодируются в альфа-канал. Это необходимо учитывать в коде шейдера, когда ищется текстура (.a):

, например * * 1016

#version 460

// [...]

uniform sampler2D myTextureSampler;
uniform vec4 texcol;

void main()
{
    vec4 col = texcol * texture(myTextureSampler, uv).a;

    // [...]
}

В любом случае GL_ALPHA устарела и Legacy OpenGL . Это означает, что это не будет работать, если вы используете основной профиль Context .

Используйте GL_RED вместо:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RED,
             g->bitmap.width, g->bitmap.rows, 0,
             GL_RED, GL_UNSIGNED_BYTE, g->bitmap.buffer);

Считать данные из канала красного цвета (.r) во фрагментном шейдере:

#version 460 core

// [...]

uniform sampler2D myTextureSampler;
uniform vec4 texcol;

void main()
{
    vec4 col = texcol * texture(myTextureSampler, uv).r;

    // [...]
}
...