Ошибка сегментации OpenGL с использованием TrueType

Я пытался принять TrueType Учебник OpenGL в мой движок. Когда я компилирую и запускаю их пример, все работает правильно, но когда я пытался переписать код в свой движок, я продолжаю получать ошибку сегментации. Затем я попытался скопировать их код в мой заголовочный файл Utils, но это не сработало. Я провел небольшую отладку с помощью cout, и похоже, что ошибка происходит в моем методе рендеринга. Сначала я опубликую метод рендеринга, а затем все остальные связанные с TrueType функции. Если тебе нужно что-то спросить, не стесняйся.

Метод рендеринга:

void Util::Font::render(const char *text, Atlas *a, float x, float y, float sx, float sy)
{
glUseProgram(shaderID);

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

const uint8_t *p;

/* Use the texture containing the atlas */
glBindTexture(GL_TEXTURE_2D, a->tex);
glUniform1i(samplerID, 0);

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

point coords[6 * strlen(text)];
int c = 0;

/* Loop through all characters */
for (p = (const uint8_t *)text; *p; p++) {
/* Calculate the vertex and texture coordinates */
float x2 = x + a->c[*p].bl * sx;
float y2 = -y - a->c[*p].bt * sy;
float w = a->c[*p].bw * sx;
float h = a->c[*p].bh * sy;

/* Advance the cursor to the start of the next character */
x += a->c[*p].ax * sx;
y += a->c[*p].ay * sy;

/* Skip glyphs that have no pixels */
if (!w || !h)
continue;

coords[c++] = (point) {
x2, -y2, a->c[*p].tx, a->c[*p].ty};
coords[c++] = (point) {
x2 + w, -y2, a->c[*p].tx + a->c[*p].bw / a->w, a->c[*p].ty};
coords[c++] = (point) {
x2, -y2 - h, a->c[*p].tx, a->c[*p].ty + a->c[*p].bh / a->h};
coords[c++] = (point) {
x2 + w, -y2, a->c[*p].tx + a->c[*p].bw / a->w, a->c[*p].ty};
coords[c++] = (point) {
x2, -y2 - h, a->c[*p].tx, a->c[*p].ty + a->c[*p].bh / a->h};
coords[c++] = (point) {
x2 + w, -y2 - h, a->c[*p].tx + a->c[*p].bw / a->w, a->c[*p].ty + a->c[*p].bh / a->h};
}

/* Draw all the character on the screen in one go */
glBufferData(GL_ARRAY_BUFFER, sizeof coords, coords, GL_DYNAMIC_DRAW);
glDrawArrays(GL_TRIANGLES, 0, c);

glDisableVertexAttribArray(0);}

Инициация шрифта

bool Util::Font::init()
{
if (FT_Init_FreeType(&ft))
{
std::cout << "Failed to load Freetype!" << std::endl;
return false;
}

if (FT_New_Face(ft, "res/fonts/Ubuntu-R.ttf", 0 , &face))
{
std::cout << "Failed to load font file!" << std::endl;
return false;
}

shaderID = Util::Shader::loadShaders("res/shaders/font.vert", "res/shaders/font.frag");

samplerID = glGetUniformLocation(shaderID, "textureSampler");
colorID = glGetUniformLocation(shaderID, "color");

glGenBuffers(1, &vertexBufferID);

font12px = new Atlas(face, 12);
font24px = new Atlas(face, 24);
font48px = new Atlas(face, 48);

return true;
}

Заголовок шрифта внутри Utils.h

namespace Font {

static FT_Library ft;
static FT_Face face;
static GLuint shaderID;
static GLuint samplerID;
static GLuint colorID;
static GLuint vertexBufferID;
static GLuint coordID;

bool init();

struct point {
GLfloat x;
GLfloat y;
GLfloat s;
GLfloat t;

};

struct Atlas {
GLuint tex;     // texture object

int w;          // width of texture in pixels
int h;          // height of texture in pixels

struct {
float ax;   // advance.x
float ay;   // advance.y

float bw;   // bitmap.width;
float bh;   // bitmap.height;

float bl;   // bitmap_left;
float bt;   // bitmap_top;

float tx;   // x offset of glyph in texture coordinates
float ty;   // y offset of glyph in texture coordinates
} c[128];       // character information

Atlas(FT_Face face, int height) {
FT_Set_Pixel_Sizes(face, 0, height);
FT_GlyphSlot g = face->glyph;

int roww = 0;
int rowh = 0;
w = 0;
h = 0;

memset(c, 0, sizeof c);

/* Find minimum size for a texture holding all visible ASCII characters */
for (int i = 32; i < 128; i++) {
if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {
fprintf(stderr, "Loading character %c failed!\n", i);
continue;
}
if (roww + g->bitmap.width + 1 >= 1024) {
w = std::max(w, roww);
h += rowh;
roww = 0;
rowh = 0;
}
roww += g->bitmap.width + 1;
rowh = std::max(rowh, g->bitmap.rows);
}

w = std::max(w, roww);
h += rowh;

/* Create a texture that will be used to hold all ASCII glyphs */
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(samplerID, 0);

glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 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);

/* Paste all glyph bitmaps into the texture, remembering the offset */
int ox = 0;
int oy = 0;

rowh = 0;

for (int i = 32; i < 128; i++) {
if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {
fprintf(stderr, "Loading character %c failed!\n", i);
continue;
}

if (ox + g->bitmap.width + 1 >= 1024) {
oy += rowh;
rowh = 0;
ox = 0;
}

glTexSubImage2D(GL_TEXTURE_2D, 0, ox, oy, g->bitmap.width, g->bitmap.rows, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);
c[i].ax = g->advance.x >> 6;
c[i].ay = g->advance.y >> 6;

c[i].bw = g->bitmap.width;
c[i].bh = g->bitmap.rows;

c[i].bl = g->bitmap_left;
c[i].bt = g->bitmap_top;

c[i].tx = ox / (float)w;
c[i].ty = oy / (float)h;

rowh = std::max(rowh, g->bitmap.rows);
ox += g->bitmap.width + 1;
}

fprintf(stderr, "Generated a %d x %d (%d kb) texture atlas\n", w, h, w * h / 1024);
}

~Atlas() {
glDeleteTextures(1, &tex);
}
};

static Atlas *font48px;
static Atlas *font24px;
static Atlas *font12px;

void render(const char *text, Atlas *atlas, float x, float y, float sx, float sy);
}

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]