簡體   English   中英

如何將SDL TTF表面轉換為具有透明背景的GL紋理

[英]How to transform SDL TTF Surface into GL Texture with Transparent background

我想在GL中繪制的內容上繪制文本。 我希望符號本身是不透明的,而其余符號是透明的,從而可以看到繪制的內容。 下面的代碼產生一個文本,它是正確的文本,但是具有完美的白色背景。 我繪制的內容完全不存在。

我該如何解決? 我正在使用SDL 2.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);

這樣想:在創建上面的紋理時,您是在fully transparent background繪制dark grey fully transparent (30,30,30,0)文本(由於TTF_RenderText_Blended導致為0,0,0,0)。 然后,您將使用即時模式顏色混合來光柵化具有相同大小的四邊形(提示:沒有混合功能,也沒有提到禁用z緩沖區!)。

PS,在示例中您像瘋了似的泄漏:

  • glGenTexture每幀都沒有glDeleteTextures(更改后只需要一個新幀)

  • 在每個幀中都沒有TTF_CloseFont的TTF_OpenFont(僅保留它,直到不需要渲染該字體為止)

  • TTF_RenderText_Blended表面沒有泄漏,但是您可以在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);

非常方便的網站在這里: http : //www.andersriggelsen.dk/glblendfunc.php

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM