C++ 如何将SDL TTF曲面转换为背景透明的GL纹理

C++ 如何将SDL TTF曲面转换为背景透明的GL纹理,c++,opengl,sdl,sdl-2,sdl-ttf,C++,Opengl,Sdl,Sdl 2,Sdl Ttf,我想在GL中绘制的内容上绘制文本。我希望符号本身是不透明的,而其余部分是透明的,这样可以看到绘制的内容。下面的代码生成一个文本,该文本是正确的,但背景是完全白色的。我画的内容完全没有 我该如何解决这个问题?我正在使用SDL2.0,VSC glPushMatrix(); /*Content drawn in GL*/ GLuint TextureID = 0; SDL_Color Color = {30, 30, 30, 0}; TTF_Font * Font =

我想在GL中绘制的内容上绘制文本。我希望符号本身是不透明的,而其余部分是透明的,这样可以看到绘制的内容。下面的代码生成一个文本,该文本是正确的,但背景是完全白色的。我画的内容完全没有

我该如何解决这个问题?我正在使用SDL2.0,VSC

   glPushMatrix();

   /*Content drawn in GL*/

   GLuint TextureID = 0;
   SDL_Color Color = {30, 30, 30, 0};
   TTF_Font * Font = TTF_OpenFont("Times.ttf", 30);
   SDL_Surface * Message = TTF_RenderText_Blended(Font, "ASDASDASD", Color);

   glGenTextures(1, &TextureID);
   glBindTexture(GL_TEXTURE_2D, TextureID);

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

   glBindTexture(GL_TEXTURE_2D, TextureID);

   glBegin(GL_QUADS);
   {
        glColor4f(.5, .5, .5, 1);
        glTexCoord2f(0,0); glVertex2f(MouseX/10, MouseY/10);
        glTexCoord2f(1,0); glVertex2f((MouseX/10) + (Message->w / 10), MouseY/10);
        glTexCoord2f(1,1); glVertex2f((MouseX/10) + (Message->w / 10), (MouseY/10) + (Message->h / 10));
        glTexCoord2f(0,1); glVertex2f(MouseX/10, (MouseY/10) + (Message->h / 10));
   }
   glEnd();

   glPopMatrix();

   SDL_FreeSurface(Message);
   SDL_GL_SwapWindow(GameWindow);

这样想:当您创建上面的纹理时,您正在绘制深灰色完全透明的30,30,30,0文本,背景为完全透明的0,0,0,0,这是由于TTF_RenderText_混合。然后使用即时模式颜色混合对相同大小的四元体进行光栅化提示:没有混合func,也没有提到z缓冲区禁用

注意,在这个例子中,你正在疯狂地泄漏:

glGenTexture没有GLDELETE纹理的每个帧您只需要一个 新的,如果它改变了

TTF_OpenFont在每个 框架仅在不需要呈现该字体之前保留它

TTF_RenderText_混合曲面没有泄漏,但您可以在之后立即释放它 glTexImage2D

我想你是想用字体作为遮罩从纯色背景中减去?我通常创建字体纹理白色全alpha,然后在着色器中应用颜色或遮罩。要在即时模式下实现类似效果,您可以:

// startup
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);

SDL_Color Color = {255, 255, 255, 255};
TTF_Font * Font = TTF_OpenFont("Times.ttf", 30);
SDL_Surface * Message = TTF_RenderText_Blended(Font, "ASDASDASD", Color);
TTF_CloseFont(Font);

glGenTextures(1, &TextureID);
glBindTexture(GL_TEXTURE_2D, TextureID);

glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, Message->w, Message->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, Message->pixels);
SDL_FreeSurface(Message);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);



// frame render
glClear(GL_COLOR_BUFFER_BIT);

// you'll see this in many (immediate mode) 2D rendering examples
// without the blend eq below, this would render the white text on top of the quad's background color
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// use text as a mask to cut away from what is below
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);

glBindTexture(GL_TEXTURE_2D, TextureID);


glBegin(GL_QUADS);
{
    glColor4f(.5, .5, .5, 1);
    glTexCoord2f(0,0); glVertex2f(MouseX/10, MouseY/10);
    glTexCoord2f(1,0); glVertex2f((MouseX/10) + (Message->w / 10), MouseY/10);
    glTexCoord2f(1,1); glVertex2f((MouseX/10) + (Message->w / 10), (MouseY/10) + (Message->h / 10));
    glTexCoord2f(0,1); glVertex2f(MouseX/10, (MouseY/10) + (Message->h / 10));
}
glEnd();

// if done every frame, make sure to: glDeleteTextures(1, &TextureID);

SDL_GL_SwapWindow(GameWindow);

非常方便的站点:

也许可以尝试使用GL_RGBA而不是GL_ALPHA,但不确定为什么要使用GL_ALPHA作为内部格式。它可能会将红色分量作为当前参数的alpha。我已经尝试过了,但它不会起作用。