繁体   English   中英

SDL2 + OpenGL + SDL2_TTF:显示文字

[英]SDL2 + OpenGL + SDL2_TTF: Displaying text

我无法在OpenGL和SDL2.0中绘制TTF字体。

我记得在SDL版本2之前我没有遇到任何问题,但是似乎缺少有关此主题的文档,这可能是由于新标准的缘故。

我已包含以下代码,以大致显示我在做什么。

当我每帧重新创建Texture时,此代码效率很低,如果复制+粘贴,请考虑到这一点:)

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

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

需要添加过滤器信息才能利用mipmap纠正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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM