Problem creating/copying transparent surfaces

Greetings all,

I have been struggling with an issue (SDL2) for the past week and I figured
that it was about time that I asked the community for help.

So what I am trying to is create a text render using
TTF_RenderText_Blended (which appears to use alpha blending), and to
apply/copy this text at a position onto a larger transparent surface
“referred to as the intermediate surface in my code sample”. Finally, I
would like to copy the contents of this largely transparent “intermediate
surface” onto the actual main window surface.

In my first attempt to do this, I had been using colorkey transparency on
the intermediate surface and had some horrible magenta color set as the
transparent color, the issue with this however was that when I would apply
the rendered text from TTF_RenderText_Blended, it would slightly change
the colors of some of the transparent background pixels, thereby making
them visible.

From this experience and reading documentation online, I came to the
conclusion that I probably wanted to be using alpha transparency and to
just set the initial background pixel colors to an alpha value of 0. The
problem that I am having is that even though I’ve set the alpha values to 0
when initially clearing the renderer of the intermediate surface, these
background pixels and their color still appear to be copied over onto the
main window surface.

I have prepared a code sample to illustrate the issue I am having:

#ifdef PLATFORM_OSX #include <SDL.h> #include <SDL_ttf.h>#else
#include <SDL2/SDL.h> #include <SDL2/SDL_ttf.h>#endif /
PLATFORM OSX
/#include <stdio.h>static const char TestStr[] = “Hello
World!!!”;SDL_Color Color_White = {255, 255, 255, 255};SDL_Color
Color_Black = { 10, 10, 10, 255};int main(){ int textW;
int textH; SDL_Rect r; SDL_Color c;
SDL_Event event; SDL_Window * mw = NULL; /
main window
/ SDL_Renderer * mwRend = NULL; / main window renderer /
SDL_Surface * textSurf = NULL; /
TTF_text surface / SDL_Texture *
textTex = NULL; /
TTF_text texture / SDL_Renderer * imRend = NULL;
/
intermediate surface renderer / SDL_Surface * imSurf = NULL; /
intermediate surface / SDL_Texture * imTex = NULL; / intermediate
texture / TTF_Font * font = NULL;
SDL_Init(SDL_INIT_VIDEO); TTF_Init(); mw = SDL_CreateWindow(
“standalone_TTF_text example”, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN
); if (mw == NULL) { fprintf(stderr, “ERROR: Unable to create
SDL2 window.\n”); return 1; }
/
------------------------------------------------------------------------/
/
Create the associated renderer for the window
/
/
------------------------------------------------------------------------/
mwRend = SDL_CreateRenderer( mw, -1,
SDL_RENDERER_ACCELERATED); if (mwRend == NULL) {
fprintf(stderr, “ERROR: Unable to create SDL2 renderer.\n”); return
1; } c = Color_White; SDL_SetRenderDrawColor(mwRend, c.r, c.g,
c.b, c.a); SDL_RenderClear(mwRend);
/
------------------------------------------------------------------------/
/
Load and render the TTF_Font
/
/
------------------------------------------------------------------------/
font = TTF_OpenFont(“Cousine-Regular.ttf”, 15); if (font == NULL)
{ fprintf(stderr, “ERROR: Unable to create TTF_Font.\n”);
return 1; } TTF_SizeText(font, TestStr, &textW, &textH); textSurf
= TTF_RenderText_Blended(font, TestStr, Color_Black); if (textSurf ==
NULL) { fprintf(stderr, “ERROR: Failure in
TTF_RenderText_Blended.\n”); return 1; } textTex =
SDL_CreateTextureFromSurface(mwRend, textSurf); r.x = 0; r.y = 0;
r.w = 5
textW; r.h = 5textH; // copy first text, normal rendering
SDL_RenderCopy(mwRend, textTex, NULL, &r);
/
------------------------------------------------------------------------/
/
Create an RGB surface, copy textTex to it, then prepare a texture for
/ / the main window renderer from this intermediate
surface. /
/
------------------------------------------------------------------------/
imSurf = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, 0); if (imSurf
== NULL) { fprintf(stderr, “ERROR: Unable to create SDL2
Surface.\n”); return 1; } SDL_SetSurfaceBlendMode(imSurf,
SDL_BLENDMODE_BLEND); // ^^^ SDL_BLENDMODE_BLEND alpha blending
// // dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)) // dstA
= srcA + (dstA * (1-srcA)) imRend =
SDL_CreateSoftwareRenderer(imSurf); SDL_SetRenderDrawColor(imRend, 100,
100, 150, 0); SDL_RenderClear(imRend); // ^^^ Shouldn’t this set the
individual pixel alpha values to zero everywhere? // copy text to
intermediate surface SDL_DestroyTexture(textTex); textTex =
SDL_CreateTextureFromSurface(imRend, textSurf); SDL_RenderCopy(imRend,
textTex, NULL, &r); SDL_RenderPresent(imRend); imTex =
SDL_CreateTextureFromSurface(mwRend, imSurf); r.y = 10 + r.h; // copy
intermediate text texture SDL_RenderCopy(mwRend, imTex, NULL, &r);
SDL_RenderPresent(mwRend); for (;:wink: { SDL_WaitEvent(&event);
/
----------------------------------------------------------------/
/
Otherwise, there is an event to handle /
/
----------------------------------------------------------------/
switch (event.type) { case SDL_QUIT: goto
out; } }out: TTF_Quit(); SDL_Quit(); return 1;}

This code produces a single SDL_Window with two instances of a
TTF_textRender on it. The first (top) instance of text is created using
TTF_RenderText_Blended and then applied directly onto the renderer for
the main window. The second (lower) instance of text was created using
TTF_RenderText_Blended, applied to an intermediate (supposedly
transparent) surface, and then copied onto the renderer for the main window

Imgur

The link above shows a screenshot of the resulting operation (notice how
the second text instance is within a light blue box). What I would like to
accomplish is to make the second instance of text appear just like the
first while still preserving the structure of having an intermediate
“mostly transparent” surface inbetween the rendered text and the main
window surface.

I must admit that I am quite new to asking for help from mailing lists but,
I am hoping that I have explained me question clearly and have not
unintentionally exercised poor etiquette.

Many thanks,
-Mike