Freetype Opengl Glyph无法渲染

时间:2011-04-16 20:35:09

标签: c rendering freetype2

我试图通过利用freetype字形提供的位图缓冲区在opengl中渲染单个char作为演示。我知道我的三角扇是正确的,因为现在我看到一个黑色纹理triangle_fan绿色背景。理想情况下,我应该在triangle_fan原语中看到一个字符,而不仅仅是一个完整的实心黑色方块。

void fontDataNums_init(const char * fname) {
    float h = font.h = 16; 

    /*Dynamically allocated variables, clean before exit */ 
    FT_Face face;
    FT_Library library;
    GLubyte * expanded_data; 
    /* Create And Initilize A FreeType Font Library. */
    if(FT_Init_FreeType( &library )) {
        printf("fontDataNums_init::FT_Init_FreeType failed\n");
        exit(1);
    }
    /* Initialize face, load font from ttf file */
    if(FT_New_Face( library, fname, 0, &face )){ 
        printf("fontDataNums_init::FT_New_Face failed\n");
        exit(1);
    }

    if(FT_Set_Char_Size( face, h * 64, h * 64, 96, 96)){
        printf("fontDataNums_init::FT_Set_Char_Size failed.\n");
        exit(1);
    }

    font.textures = (GLuint *) malloc(sizeof(GLuint) * 10);
    glGenTextures(10, font.textures);

    /* CREATE CHARACTER BITMAPS I WANT LOADED */
    unsigned char g;
    int i, j;
    for( g='A'; g < 'J'; g++){
        if(FT_Load_Char(face, g, FT_LOAD_RENDER)){
            printf("fontDataNums::FT_Load_Char unable to load glyph for character\n");
            exit(1);
        }

        FT_Glyph glyph;
        if(FT_Get_Glyph(face->glyph, &glyph) ) { printf("GetGlyph failed.\n");}

        if(FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1)){
            printf("fontDataNums::FT_Glyph_To_Bitmap failed to create bitmap.\n");
            exit(1);
        }
        FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;

        int width = next_p2( bitmap_glyph->bitmap.width );
        int height = next_p2( bitmap_glyph->bitmap.rows );
        printf("WIDTH: %i and HEIGHT: %i \n", width, height);
        /* PADDING FOR BITMAP */ 
        expanded_data = (GLubyte *) malloc(sizeof(GLubyte) * 2 * width * height);
        for(j=0; j <height;j++) {
            for(i=0; i < width; i++){
                expanded_data[2*(i+j*width)] = expanded_data[2*(i+j*width)+1] = 
                    (i>=bitmap_glyph->bitmap.width || j>=bitmap_glyph->bitmap.rows) ? 
                         0 : 
                         bitmap_glyph->bitmap.buffer[i + bitmap_glyph->bitmap.width*j];
            }
        }
        /* LOAD TEXTURE INTO OPENGL */
        glActiveTexture(GL_TEXTURE0);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glBindTexture( GL_TEXTURE_2D, font.textures[g]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data );
        free(expanded_data);
        FT_Done_Glyph(glyph);
    }
    /* Clean Up */
    FT_Done_Face(face);
    FT_Done_FreeType(library);
}

int next_p2 (int a )
{
    int rval=1;
    /* rval<<=1 Is A Prettier Way Of Writing rval*=2; */
    while(rval<a) rval<<=1;
    return rval;
}

void drawGlyph(){
    renderGlyph(font.textures[1]);
}

void renderGlyph(GLuint textureName) {
    GLuint tbo = 0;
    GLuint vbo = 0;

    glClear(GL_COLOR_BUFFER_BIT);
    /* SETUP VERTICES */
    GLfloat verts[8]={ 0.0f, 16.0f, 
        0.0f, 0.0f, 
        17.0f , 0.0f, 
        17.0f , 16.0f};
    glEnableVertexAttribArray(GLT_ATTRIBUTE_VERTEX);
    if(vbo == 0){glGenBuffers(1, &vbo);}
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, verts, GL_DYNAMIC_DRAW);
    glVertexAttribPointer(GLT_ATTRIBUTE_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, 0); 

    /* Setup Texture Buffer */
    float x = 17.0f / 32.0f;
    float y = 16.0f / 16.0f;
    GLfloat vTex[8] = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }; 
    glEnableVertexAttribArray(GLT_ATTRIBUTE_TEXTURE0);
    if(tbo == 0) { glGenBuffers(1, &tbo);} 
    glBindBuffer(GL_ARRAY_BUFFER, tbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, vTex, GL_DYNAMIC_DRAW);
    glVertexAttribPointer(GLT_ATTRIBUTE_TEXTURE0, 2, GL_FLOAT, GL_FALSE, 0, 0);
    /*Create Shaders*/
    static const char *szIdentityShaderVP =                                             
        "#version 330\n"
        "in vec4 vVertex;\n"
        "in vec2 TexCoords;\n"
        "out vec2 varyingTexCoords;\n"
        "uniform mat4 mvp;\n"
        "void main(void) \n"
        "{" 
            "varyingTexCoords = TexCoords;\n"
            "gl_Position = mvp * vVertex;\n"
        "}\n";

    static const char *szIdentityShaderFP =
        "#version 330\n"
        "uniform sampler2D colormap;\n"
        "uniform vec4 showFan;"
        "in vec2 varyingTexCoords;\n"
        "void main(void) \n"
        "{" 
             //"gl_FragColor = showFan;\n"
            "gl_FragColor = texture(colormap, varyingTexCoords);\n"
        "}\n";

    GLuint shaderName = 0;
    shaderName = gltLoadShaderPairSrcWithAttributes(szIdentityShaderVP, szIdentityShaderFP, 2, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_TEXTURE0, "TexCoords");
    if(shaderName == 0) { printf("***shader compile failed****\n");}
    glUseProgram(shaderName);

    vmathM4MakeOrthographic( &pmatrix, -50.0f, 50.0f, -50.0f, 50.0f, -50.0f, 50.0f);
    GLint mvp = 0;
    mvp = glGetUniformLocation(shaderName, "mvp");
    glUniformMatrix4fv(mvp, 1, GL_FALSE, (GLfloat *) &pmatrix); 

    GLint texUniform = 0;
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureName);
    texUniform = glGetUniformLocation(shaderName, "colormap");
    glUniform1i(texUniform, 0);

    GLint showFan= 0;
    showFan = glGetUniformLocation(shaderName, "showFan");
    glUniform4f(showFan, 1.0f, 0.0f, 0.0f, 1.0f);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    SDL_GL_SwapWindow(gcore.mainwindow);

    glDisableVertexAttribArray(GLT_ATTRIBUTE_VERTEX);
    glDisableVertexAttribArray(GLT_ATTRIBUTE_TEXTURE0);
    glDeleteProgram(shaderName);
    glDeleteBuffers(1, &vbo);
    glDeleteBuffers(1, &tbo);
    glCheckError();    
}

void glCheckError(){
    GLenum checkError = glGetError();
    if(checkError != GL_NO_ERROR)
        printf("Error: %i\n", checkError);
}

1 个答案:

答案 0 :(得分:1)

我在iPhone设备中使用freetype,它可以用...创建纹理

    glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);