【问题标题】:SDL2 + OpenGL + SDL2_TTF: Displaying textSDL2 + OpenGL + SDL2_TTF:显示文本
【发布时间】:2015-05-03 16:09:26
【问题描述】:

我无法在 OpenGL 和 SDL2.0 中绘制 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();
}

【问题讨论】:

    标签: c++ opengl rendering sdl-2 sdl-ttf


    【解决方案1】:

    所以 OpenGL 要求我的系统上的所有纹理都具有 Base2 的尺寸(2、4、16、32、64...)

    我通过增量搜索最接近原始维度的 2 次方解决了这个问题:

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

    然后我遇到了一个障碍:纹理是正确的颜色,但像素被打乱了。已通过使用调整后的 OpenGL 尺寸将图像复制到 RGB SDL_Surface 来解决此问题。

    //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 使用 mipmap:

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

    【讨论】:

      猜你喜欢
      • 2019-10-12
      • 1970-01-01
      • 2021-04-08
      • 2015-05-06
      • 1970-01-01
      • 2016-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多