2016-07-05 15 views
1

現在、アンドロイドndk/openglプロジェクトで作業しています。私はフォントレンダリングライブラリとしてfreetypeを使用しようとしていますが、スクリーンにテキストをレンダリングすると奇妙なエラーが続きます。ここではいくつかのサンプルテキストに示しているものである:(注:下の1は "これがある" と言うことになっている)フリースタイルライブラリは三重テクスチャと奇妙なシンボルを与えます

Text rendering oddities

セットアップ:

void TextRenderer::SetupGlyphs(std::string fontPath, int size){ 
    __android_log_print(ANDROID_LOG_INFO, "SetupGlyphs", "Font location: %s", fontPath.c_str()); 
    if(shadersInitialized == 0) 
     CreateShader(); 
    glUseProgram(this->shader); 

    // FreeType 
    FT_Library ft; 
    if (FT_Init_FreeType(&ft)) 
     __android_log_print(ANDROID_LOG_INFO, "SetupGlyphs", "ERROR::FREETYPE: Could not init FreeType Library."); 

    FT_Face face; 
    if (FT_New_Face(ft, fontPath.c_str(), 0, &face)) 
     __android_log_print(ANDROID_LOG_INFO, "SetupGlyphs", "ERROR::FREETYPE: Failed to load font: %s", fontPath.c_str()); 

    FT_Set_Pixel_Sizes(face, 0, size); 
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 

    for (GLubyte c = 0; c < 128; c++){ 
     if(FT_Load_Char(face, c, FT_LOAD_RENDER)){ 
      __android_log_print(ANDROID_LOG_INFO, "SetupGlyphs", "ERROR::FREETYPE: Failed to load Glyph"); 
      continue; 
     } 
     GLuint texture; 
     glGenTextures(1, &texture); 
     glBindTexture(GL_TEXTURE_2D, texture); 
     glTexImage2D(
       GL_TEXTURE_2D, 
       0, 
       GL_RGB, 
       face->glyph->bitmap.width, 
       face->glyph->bitmap.rows, 
       0, 
       GL_RGB, 
       GL_UNSIGNED_BYTE, 
       face->glyph->bitmap.buffer 
     ); 
     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); 

     Character character = { 
       texture, 
       ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows), 
       ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top), 
       static_cast<GLuint>(face->glyph->advance.x) 
     }; 
     characters.insert(std::pair<GLchar, Character>(c, character)); 
    } 
    glBindTexture(GL_TEXTURE_2D, 0); 
    FT_Done_Face(face); 
    FT_Done_FreeType(ft); 
} 

レンダリング:

void TextRenderer::RenderTexts() 
{ 
    if(shadersInitialized == 0) 
     CreateShader(); 
    // Activate corresponding render state 
    glUseProgram(this->shader); 

    GLuint projectionLocation = glGetUniformLocation(this->shader, "projection"); 
    glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, projectionMatrix); 

    for (int i=0; i<projects.size(); i++) { 

     ProjectLabel project = projects.at(i); 
     glUniform3f(glGetUniformLocation(this->shader, "textColor"), project.textColor.x, project.textColor.y, project.textColor.z); 
     glActiveTexture(GL_TEXTURE0); 

     GLuint vertexBuffer; 
     glGenBuffers(1, &vertexBuffer); 

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

     // Iterate through all characters 
     std::string::const_iterator c; 
     GLuint x = project.x; 
     for (c = project.text.begin(); c != project.text.end(); c++) 
     { 

      Character ch = characters[*c]; 

      GLfloat xpos = x + ch.Bearing.x; 
      GLfloat ypos = project.y - (ch.Size.y - ch.Bearing.y); 

      GLfloat w = ch.Size.x; 
      GLfloat h = ch.Size.y; 
      // Update VBO for each character 
      GLfloat vertices[6*4] = { 
        xpos,  ypos + h, 0.0, 0.0 , 
        xpos,  ypos,  0.0, 1.0 , 
        xpos + w, ypos,  1.0, 1.0 , 

        xpos,  ypos + h, 0.0, 0.0 , 
        xpos + w, ypos,  1.0, 1.0 , 
        xpos + w, ypos + h, 1.0, 0.0 
      }; 

      glBindTexture(GL_TEXTURE_2D, ch.TextureID); 

      glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW); 
      glDrawArrays(GL_TRIANGLES, 0, 6); 

      x += (ch.Advance/64); // Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels)) 
     } 
     glDisableVertexAttribArray(0); 
    } 
    glBindTexture(GL_TEXTURE_2D, 0); 

} 

答えて

2

だから、この投稿を見つけることができた人なら誰でも、何時間もWebを手に入れて、すべてがファンキーに見える理由を理解しようとすると、私はその答えを見つけました。 FreetypeはGL_RGBで整列されず(少なくとも私のプロジェクトではない)、代わりにGL_LUMINANCEに整列されます。 glTexImage2Dでこのようなことを変えることで、私は上記の問題を解決しただけでなく、SIGABRTのエラーも出てきました。

TLDR;

glTexImage2D(
      GL_TEXTURE_2D, 
      0, 
      GL_RGB,      => GL_LUMINANCE 
      face->glyph->bitmap.width, 
      face->glyph->bitmap.rows, 
      0, 
      GL_RGB,      => GL_LUMINANCE 
      GL_UNSIGNED_BYTE, 
      face->glyph->bitmap.buffer 
    ); 
関連する問題