使用SDL将文本绘制到OpenGL表面上

时间:2013-04-01 18:59:11

标签: c++ opengl sdl

我正在使用SDL,我有OpenGL渲染设置,我想在屏幕上绘制一些文字。

我发现了这个问题:Using SDL_ttf with OpenGL这似乎解决了同样的问题,但我认为我的GL-fu不足以理解下一步该做什么。

也就是说,我有来自其他帖子的texture,如果我理解正确的话,它是一个整数ID,表示包含渲染文本的GL纹理。我如何在屏幕上实际渲染此纹理(这里的所有内容都是2D,所以我只想将其渲染为屏幕上的平面文本,而不是3D场景中的某些奇特表面或任何东西)。

或者,有没有更简单的方法让这个工作? (即,通过SDL渲染一些文本,同时还能够渲染GL形状)

编辑:或者,更一般地说,是否有更简单的方法可以通过SDL将文本和形状渲染到屏幕上?

2 个答案:

答案 0 :(得分:3)

  1. 使用SDL_ttf将字符串转换为位图;这只是一个函数调用。

  2. 使用您发布的链接中的代码将其转换为纹理。

  3. 使用所述纹理绘制一个矩形。也就是说,glBindTexture,glBegin,(glTexCoord,glVertex)x4,glEnd。如果您对此步骤有疑问,最好首先阅读一些基本的OpenGL教程(当然包括纹理映射)。

答案 1 :(得分:0)

尝试使用此代码段,它会从屏幕左下角开始呈现SDL true类型字体扩展库字体。

请注意将纹理布置为屏幕上的形状。文本纹理中的像素从图像左上角的0,0开始。所以我需要翻转它以使其在屏幕上正确显示,左下角是x,y。

void RenderText(std::string message, SDL_Color color, int x, int y, 
                TTF_Font* font) 
{

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();

  gluOrtho2D(0, gWindow->getWidth(),0,gWindow->getHeight()); 
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();

  glDisable(GL_DEPTH_TEST);
  glEnable(GL_TEXTURE_2D);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  GLuint texture;
  glGenTextures(1, &texture);
  glBindTexture(GL_TEXTURE_2D, texture);

  SDL_Surface * sFont = TTF_RenderText_Blended(font, message.c_str(), color);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sFont->w, sFont->h, 0, GL_BGRA, 
                GL_UNSIGNED_BYTE, sFont->pixels);

  glBegin(GL_QUADS);
  {
    glTexCoord2f(0,1); glVertex2f(x, y);
    glTexCoord2f(1,1); glVertex2f(x + sFont->w, y);
    glTexCoord2f(1,0); glVertex2f(x + sFont->w, y + sFont->h);
    glTexCoord2f(0,0); glVertex2f(x, y + sFont->h);
  }
  glEnd();

  glDisable(GL_BLEND);
  glDisable(GL_TEXTURE_2D);
  glEnable(GL_DEPTH_TEST);

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

  glDeleteTextures(1, &texture);
  SDL_FreeSurface(sFont);
}