0

I would like to draw text over content drawn in GL. I want the symbols themselves to be opaque, whilst the rest transparent, allowing the drawn content to be seen. The following code yields a text, which is the correct one, yet with a perfectly white background. My drawn content is completely absent.

How am I to solve this? I am using 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);
Martin G
  • 17,357
  • 9
  • 82
  • 98
user3228136
  • 157
  • 6
  • maybe try `GL_RGBA` instead of `GL_ALPHA`, not sure why you want `GL_ALPHA` as your internal format. It's probably taking the red component as alpha with your current parameters. – PeterT Sep 20 '14 at 16:43
  • I've already tried it and it won't work. – user3228136 Sep 20 '14 at 16:52

1 Answers1

-1

Think of it this way: When you create the texture above, you're drawing dark grey fully transparent (30,30,30,0) text against a fully transparent background (0,0,0,0 due to TTF_RenderText_Blended). You're then using immediate mode color blending to raster a quad of the same size (HINT: with no blend func and no mention of z buffer disable!).

P.S. you're leaking like crazy in the example:

  • glGenTexture every frame without a glDeleteTextures (you only need a new one if it changes)

  • TTF_OpenFont without a TTF_CloseFont in every frame (keep it only until you do not require rendering of that font)

  • TTF_RenderText_Blended surface isn't leaked but you could free it right after glTexImage2D

I assume you're meaning to use the font as a mask to subtract from a solid color background? I generally create font textures white (full alpha) then apply color or masking in the shader. To accomplish a similar effect in immediate mode you could:

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

Very handy site here: http://www.andersriggelsen.dk/glblendfunc.php

Graeme Wicksted
  • 1,770
  • 1
  • 18
  • 21