Нарушение доступа с Freetype и OpenGL

Когда я запускаю свою программу, окно отображается в течение примерно 3 секунд (с белым фоном, как и ожидалось, но без текста), а затем прерывается, сообщая, что в коде FreeType было нарушение доступа. Я почти уверен, что это с загрузкой шрифта, потому что мой текст отладки печатает, что он не мог найти его, и он также не может использовать ширину и высоту лица, поэтому он возвращает ошибку. Я пытался поместить arial.ttf в каталог .exe, каталог проекта, везде. Нет кости. Вот мой main.cpp:

int main()
{
int running = GL_TRUE;

debug.Print("Program initialized...");
window.Create( 800, 600, "OpenGL");

TEXT text;

while( running )
{
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT );

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

text.Create("The quick brown fox jumps over the lazy dog", "arial.ttf", 300, 400, 1, 1, 1,   2/600, 2/800);

glfwSwapBuffers();
}

glDeleteTextures(1, &tex);

glDeleteProgram( shaderProgram );
glDeleteShader( fragmentShader );
glDeleteShader( vertexShader );

glDeleteBuffers( 1, &vbo );

debug.Print("Program terminated.");
}

Вот мой Text.h:

#ifndef _TEXT
#define _TEXT

#include "debug.h"#include <GL/glew.h>
#include <GL/glfw.h>
#include <ft2build.h>
#include FT_FREETYPE_H

class TEXT
{
public:
void Create(char* Text, char* fontName, int posx, int posy, int r, int g, int b, int sizex, int sizey);
};

#endif

Вот мой Text.cpp:

#define GLEW_STATIC
#include "text.h"
const char* textvertexSource =
"version 150\n""in vec4 coord;""out vec2 texcoord;""void main {""       gl_Position = vec4(coord.xy, 0, 1);""       texcoord = coord.zw;""}";

const char* textfragmentSource =
"version  150\n""in vec2 texcoord;""uniform sampler2D tex;""uniform vec4 color;""void main() {""       gl_FragColor = vec4(1, 1, 1, texture2D(tex, texcoord).a * color;""}";

void TEXT::Create(char* text, char* fontName, int posx, int posy, int r, int g, int b, int sizex, int sizey)
{

// OpenGL functions
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);

GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
glShaderSource( vertexShader, 1, &textvertexSource, NULL );
glCompileShader( vertexShader );

GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
glShaderSource( fragmentShader, 1, &textfragmentSource, NULL );
glCompileShader( fragmentShader );

GLuint shaderProgram = glCreateProgram();
glAttachShader( shaderProgram, vertexShader );
glAttachShader( shaderProgram, fragmentShader );
glBindFragDataLocation( shaderProgram, 0, "outColor" );
glLinkProgram( shaderProgram );
glUseProgram( shaderProgram );

GLint posAttrib = glGetAttribLocation( shaderProgram, "coord" );
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);

GLint colAttrib = glGetAttribLocation( shaderProgram, "color" );
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 4, GL_INT, GL_FALSE, 0, 0);

GLint uniform_tex = glGetUniformLocation(shaderProgram, "tex");

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

GLuint uniform_color = glGetUniformLocation(shaderProgram, "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);

// Actual font rendering
FT_Library ft;

if(FT_Init_FreeType(&ft))
debug.Print("Could not initiate freetype library.");

FT_Face face;
if(FT_New_Face(ft, fontName, 0, &face))
{
debug.Print("Could not load font: ");
debug.Print(fontName);
}

FT_Set_Pixel_Sizes(face, sizex, sizey);

FT_GlyphSlot glyph = face->glyph;

const char *p;

for(p = text; *p; p++) {
if(FT_Load_Char(face, *p, FT_LOAD_RENDER))
continue;

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

float x2 = posx + glyph->bitmap_left * sizex;
float y2 = -posy - glyph->bitmap_top * sizey;
float w = glyph->bitmap.width * sizex;
float h = glyph->bitmap.rows * sizey;

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);

posx += (glyph->advance.x >> 6) * sizex;
posy += (glyph->advance.y >> 6) * sizey;

GLfloat color[4] = {r, g, b, 1};
glUniform4fv(uniform_color, 1, color);
}
}

1

Решение

Я постараюсь расширить мой комментарий.

В вашем while( running ) петля, вы звоните text.Create("The quick brown fox jumps over the lazy dog", "arial.ttf", 300, 400, 1, 1, 1, 2/600, 2/800);, Если посмотреть на специфику этой функции, она делает гораздо больше, чем просто создает новую текстовую запись, она инициализирует FreeType, нагрузки fonts, так далее…

Вы хотите, чтобы ваша игра / симуляция инициализировались FreeType только один раз и text.Create верните объект, который будет длиться всю вашу игру / симуляцию.

в while(running) часть, вы должны позвонить Render метод объекта, чтобы он отображался на экране.

0

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

Проблема в том, что вы устанавливаете FT_Set_Pixel_Sizes с sizex и sizey, а затем при создании поля для текста вы используете sizex и sizey для масштабирования поля.

Так что, если вы установили sizex и sizey равными 48, это также означает, что вы масштабировали текстовое поле на 48, что является большим, и если вы установили sizex и sizey равными 1, тогда размер шрифта в пикселях будет очень маленьким.

Чтобы исправить: добавьте параметр size или height и width для создания функции и используйте ее для FT_Set_Pixel_Size

ех.

void Create(char* Text, char* fontName, int posx, int posy, int r, int g, int b, int sizex, int sizey, int height, int width){
...
FT_Set_Pixel_Size(face, width, height); //Not sizex and sizey because thats what you are using to scale the text box
}
0

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