2015-05-03 2 views
0

У меня возникли проблемы с получением шрифта TTF для рисования в OpenGL plus SDL2.0.SDL2 + OpenGL + SDL2_TTF: Отображение текста

Я помню, что до версии SDL 2 у меня не было проблем, но, похоже, недостатка в документации по этому вопросу, возможно, из-за нового стандарта.

Я включил код ниже, чтобы показать, что я делаю.

Этот код очень неэффективно, поскольку я воссоздать текстуру каждый кадр, принимать это во внимание, если копия + вставка :)

void main_render() { 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    //Set our color back to white (Full texture color) 
    glColor3f(1.0f, 1.0f, 1.0f); 

    mainCamera->perspective(); 
    mainCamera->translate(); 

    //Load the font 
    TTF_Font *font = TTF_OpenFont("../resource/font.ttf", 10); 
    if (font == nullptr) { 
    std::cout << "TTF_OpenFont error: " << std::endl; 
    return; 
    } 

    //Render font to a SDL_Surface 
    SDL_Color color = {0,0,255,80}; 
    SDL_Surface *surface = TTF_RenderText_Blended(font, "Hi!", color); 
    if (surface == nullptr) { 
    TTF_CloseFont(font); 
    std::cout << "TTF_RenderText error: " << std::endl; 
    return; 
    } 

    //Create a SDL_Texture * from the surface 
    SDL_Texture * text = SDL_CreateTextureFromSurface(fontRender, surface); 
    if (text == nullptr){ 
    std::cout << "SDL_CreateTextureFromSurface error: " << std::endl; 
    return; 
    } 

    //Bind the SDL_Texture in OpenGL 
    SDL_GL_BindTexture(text, NULL, NULL); 

    //Draw the SDL_Texture * as a Quad 
    glEnable(GL_TEXTURE_2D); 
    glBegin(GL_QUADS); { 
    glTexCoord2d(0, 0); glVertex3f(0,    0,    0); 
    glTexCoord2d(1, 0); glVertex3f(0 + surface->w, 0,    0); 
    glTexCoord2d(1, 1); glVertex3f(0 + surface->w, 0 + surface->h, 0); 
    glTexCoord2d(0, 1); glVertex3f(0,    0 + surface->h, 0); 
    } glEnd(); 
    glDisable(GL_TEXTURE_2D); 

    //Cleanup 
    TTF_CloseFont(font); 
    SDL_DestroyTexture(text); 
    SDL_FreeSurface(surface); 

    //Swap the buffers to refresh the window 
    mainWindow->swap_buffers(); 
} 

ответ

0

Так OpenGL требует, чтобы все текстуры имеют размеры Base2 на моей системе (2, 4,16,32,64 ...)

Я исправил эту проблему, делая инкрементный поиск ближайшей степени двойки к исходному размеру:

unsigned int power_two_floor(unsigned int val) { 
    unsigned int power = 2, nextVal = power*2; 

    while((nextVal *= 2) <= val) 
     power*=2; 

    return power*2; 
    } 

затем я столкнулся Захват: текстура была правильного цвета, но пиксели были скремблированы. Это было исправлено путем копирования изображения на RGB SDL_Surface с использованием скорректированных габаритов OpenGL.

//Find the first power of two for OpenGL image 
    int w = power_two_floor(surface->w)*2; 
    int h = power_two_floor(surface->h)*2; 

    //Create a surface to the correct size in RGB format, and copy the old image 
    SDL_Surface * s = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000,0x0000ff00,0x000000ff,0xff000000); 
    SDL_BlitSurface(surface, NULL, s, NULL); 

информация Добавление фильтра требуется исправить OpenGL с использованием мипмапов:

//Avoid mipmap filtering 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 

Вот мой ответ:

unsigned int power_two_floor(unsigned int val) { 
    unsigned int power = 2, nextVal = power*2; 
    while((nextVal *= 2) <= val) 
    power*=2; 
    return power*2; 
} 

void main_render() { 
    //Load the font 
    TTF_Font *font = TTF_OpenFont("../resource/font.ttf", 10); 
    if (font == nullptr) { 
    std::cout << "TTF_OpenFont error: " << std::endl; 
    return; 
    } 

    SDL_Color colorFg = {0,0,255}; 
    SDL_Surface *surface; 

    //Render font to a SDL_Surface 
    if ((surface = TTF_RenderText_Blended(font, "Hi!", colorFg)) == nullptr) { 
    TTF_CloseFont(font); 
    std::cout << "TTF_RenderText error: " << std::endl; 
    return; 
    } 

    GLuint texId; 

    //Generate OpenGL texture 
    glEnable(GL_TEXTURE_2D); 
    glGenTextures(1, &texId); 
    glBindTexture(GL_TEXTURE_2D, texId); 

    //Avoid mipmap filtering 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 

    //Find the first power of two for OpenGL image 
    int w = power_two_floor(surface->w)*2; 
    int h = power_two_floor(surface->h)*2; 

    //Create a surface to the correct size in RGB format, and copy the old image 
    SDL_Surface * s = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000,0x0000ff00,0x000000ff,0xff000000); 
    SDL_BlitSurface(surface, NULL, s, NULL); 

    //Copy the created image into OpenGL format 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, s->pixels); 

    //Draw the OpenGL texture as a Quad 
    glBegin(GL_QUADS); { 
    glTexCoord2d(0, 1); glVertex3f(0,    0,    0); 
    glTexCoord2d(1, 1); glVertex3f(0 + surface->w, 0,    0); 
    glTexCoord2d(1, 0); glVertex3f(0 + surface->w, 0 + surface->h, 0); 
    glTexCoord2d(0, 0); glVertex3f(0,    0 + surface->h, 0); 
    } glEnd(); 
    glDisable(GL_TEXTURE_2D); 

    //Cleanup 
    TTF_CloseFont(font); 
    SDL_FreeSurface(s); 
    SDL_FreeSurface(surface); 
    glDeleteTextures(1, &texId); 
} 
Смежные вопросы