Render texture on top of texture created from surface with SDL2 - c++

I want to load a png into a texture and then draw another text texture on top of it. I'm doing something like this:
SDL_Surface *bgImg = IMG_Load(PNG_PATH);
SDL_Texture *bg = SDL_CreateTextureFromSurface(renderer, bgImg);
SDL_Surface *textSurface = TTF_RenderText_Blended(font, text, red);
SDL_Texture *txt = SDL_CreateTextureFromSurface(renderer, textSurface);
SDL_SetTextureBlendMode(bg, SDL_BLENDMODE_NONE);
SDL_SetRenderTarget(renderer, bg);
SDL_RenderCopy(renderer, txt, NULL, &textDstRect);
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderPresent(renderer);
I'm basing the code on this answer. The comment says that won't work in case the texture is loaded from a surface, and indeed it doesn't. The text appears behind the background image, instead of on top of it. I know the text is rendered, because it is visible if I set the blend mode to SDL_BLENDMODE_ADD, but that's not what I want.
I thought of trying to change the access of the bg texture to SDL_TEXTUREACCESS_TARGET, in case that's the problem, but I can't figure out a way to do that for textures created from surfaces.
Any other way to render text on a texture loaded from a PNG file? Performance isn't too important because this will happen only once on application startup.

I created a new texture with SDL_TEXTUREACCESS_TARGET and copied the surface loaded texture into it.

Related

C/C++ DirectX9 copy pixels at rect to another rect on the screen

Background:
Sorry for my English . So I am in a slightly unique situation in the scenario. I am working on a project that involves using a DLL proxy to intercept DirectX9 calls and dnd control drawing of a game.They are things that are statically draw and I want to be able to draw them in another part of the screen.
The Question:
I am wanting to be able to save pixels in a rect on the screen and then draw exact rect somewhere else on the screen. So if I can grab the pixels at x100, y100, w30, h30 and copy that that to another location on the screen that would be great.
This is the code that I have so far which I assume is making a texture from a memory rect.
HRESULT myIDirect3DDevice9::EndScene(void)
{
GetInput();
// Draw anything you want before the scene is shown to the user
m_pIDirect3DDevice9->GetBackBuffer(iSwapChain, iBackBuffer, Type, ppBackBuffer);
LPDIRECT3DTEXTURE9 textureMap;
D3DXCreateTexture(m_pIDirect3DDevice9, 100, 100, D3DX_DEFAULT, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &textureMap);
m_pIDirect3DDevice9->SetTexture(0, textureMap);
// SP_DX9_draw_text_overlay();
return(m_pIDirect3DDevice9->EndScene());
}
Project is based off this:
Library_Wrappers
Other notes:
I want to avoid DLL injection to accomplish this.

Transparency issue: SDL_SetTextureBlendMode

I have this PNG file that has a transparent background.
Snippet of transparent background
I set it to surface then to tex :
SDL_Texture* m_Tex = SDL_CreateTextureFromSurface(renderer, surface);
And I want this texture to have a blinking effect so I'm passing it to setTextureBlendMode function
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
Uint8 m_Alpha = 255;
I will use the m_Alpha for the blinking purpose. I will activate the blinking by pressing a particular button.
And it is working fine. But Why is the background of my texture not transparent anymore after I turn it back to SDL_BLENDMODE_NONE:
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_NONE);
Snippet of not transparent anymore after BLENDMODE_NONE
Is there a way to make my texture's background transparent again?
I mean, after researching enough, I can't seem to find a way except the SDL_SetColorKey.
But the SDL_SetColorKey needs the loaded surface again. It only means that I will set the PNG file again on surface, then on tex. I think it's not ideal to do this everytime I want the tex to stop blinking. Please help. Thanks.
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_NONE);
To render textures with Alpha != 1, you will need some blend mode.
In blend mode, you are describing to the system How you want to merge the background color with the foreground color.
You can have a basic idea from this thread.
SDL2: Generate fully transparent texture

Draw Text to Screen

So I just want to point out that I am pretty new to code outside engines so this is somewhat new to me.
I am using SDL as a base for my game and would like to know a easy way to draw text, in the form of score/time, on the screen.
So far when searching I have not found anything that I've really understood or how to use. The thing I find most when searching with the tag SDL is SDL_ttf and I've tried to look into it but with no success.
So again, I am looking for an easy way to display text, string and float/int, in the form of score/time.
Library SDL alone do not have support for writing text to the screen. Your search leads to SDL_ttf, which is right library to use.
Example of usage (only extra code, supposing you already called SDL_Init, created SDL_Window and you have SDL_Renderer* renderer for that window.
const SDL_Rect* dstrect;
SDL_Color color;
TTF_Init();
TTF_Font* font = TTF_OpenFont("font.ttf" /*path*/, 15 /*size*/);
SDL_Surface* textSurface = TTF_RenderText_Blended(font, "Text to render", color);
SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
SDL_RenderCopy(renderer, textTexture, NULL, dstrect);
SDL_FreeSurface(textSurface);
SDL_DestroyTexture(textTexture);
TTF_CloseFont(font);
TTF_Quit();
Look into docs for other TTF_RenderText_* methods and how they differ.
And since you are using C++ (both SDL and SDL_ttf is in C), you probably want to write some wrappers around TTF rendering.
you'll want the SDL ttf library - it handles truetype fonts relatively straightforwardly.
http://www.libsdl.org/projects/SDL_ttf/
and documentation
http://jcatki.no-ip.org:8080/SDL_ttf/
http://jcatki.no-ip.org:8080/SDL_ttf/SDL_ttf.html
see especially documentation for TTF_OpenFont, TTF_CloseFont (to open & close a font file)
and the rendering functions eg TTF_RenderText_Solid
In your position I'd probably write a couple of helper functions to handle drawing text that wraps these, passing on the string, location to draw etc. and call them whenever you need to print score/etc.

Alpha Blending in SDL resets after resizing window

I wanted to implement alpha blending within my Texture class. It works almost completely. I use the following functions for manipulating the alpha value:
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
SDL_SetTextureAlphaMod(texture, alpha);
The only problem I have is that the textures that have been manipulated seem to reset to the normal alpha value of 255 when I resize or maximize the window. I checked the alpha value and recognized that it is still the value I manipulated it to be before. So the value is not 255. Why is the renderer rendering it as if the alpha value was 255 then?
Information about how and when I use these functions:
Within the main game loop I change the alpha value of the texture with a public method of my Texture class:
Texture::setAlphaValue(int alpha)
There the private alpha variable of the Texture class is changed.
Within the Draw method of my Texture class the texture is drawn and I call
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
SDL_SetTextureAlphaMod(texture, alpha);
before
SDL_RenderCopyEx(renderer, texture, &sourceRectangle, &destinationRectangle, 0, 0, SDL_Flip);
Information about how I resize the window:
I basically just set the window mode to a resizable window in my SDL initialization. Then handling it like any normal window is possible:
SDL_CreateWindow(window_Title, x_Position, y_Position, window_Width, window_Height, SDL_WINDOW_RESIZABLE);
My primary loop area:
This is the main game loop:
void Game::Render()
{
// set color and draw window
SDL_SetRenderDrawColor(renderer, windowColor.R(), windowColor.G(), windowColor.B(), 0);
SDL_RenderClear(renderer);
texture.setAlphaValue(100);
texture.Draw(SDL_FLIP_NONE);
// present/draw renderer
SDL_RenderPresent(renderer);
}
Test my project:
I also uploaded my alpha-blending test project to dropbox. In this project I simplified everything, there isn't even a texture class anymore. So the code is really simple, but the bug is still there. Here is the link to the Visual Studio project: http://www.dropbox.com/s/zaipm8751n71cq7/Alpha.rar
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
You should directly change the alpha in this area.
example: alpha = 100;
SDL_SetTextureAlphaMod(texture, alpha); //remember that alpha is an int
SDL_RenderCopy(renderer, texture, NULL, &rect);
P.S. If you're going for a fade-out/fade-in effect, resizing will temporarily pausa alpha changes (in-case you used SDL_GetTicks() and made a float to slowly reduce/increase alpha as time goes by. This is because windows pauses the rendering inside the program but once you stop resizing, it resumes.
Another P.S. Since you're resizing the window make sure to assign the w and h values not as numbers but as products or dynamic numbers(Multiplication is faster than division but you can also use division).
Assigning static numbers would cause the window to resize but the textures inside won't change size.
Happy Coding :)
This has been a reported bug in the SDL library. It is fixed for some time now: https://bugzilla.libsdl.org/show_bug.cgi?id=2202, https://github.com/libsdl-org/SDL/issues/1085

How can I draw a patternBrush with transparent backround (GDI)?

I can't draw a pattern with a transparent background. This is my snippet :
bitmap.CreateBitmap(8, 8, 1, 1, &bits)
brush.CreatePatternBrush(&bitmap)
hbrush = pCgrCurrentDC->SelectObject(&brush);
// set text color
TextCol = pCgrCurrentDC->SetTextColor(CgrColourPalRGB);
int oldBkgrdMode = pCgrCurrentDC->SetBkMode(TRANSPARENT);
//draw polygon
pCgrCurrentDC->Polygon(CgrBuffer, n);
The doc on msdn doesn't mention anything about transparency. I guess this mode could be used? Or is this a bug ?
Thanks!
Mode TRANSPARENT means that background will not be filled before your brush is drawn. But your brush does not contain any transparent pixels in it and it redraws background pixels anyway. Fourth argument in CreateBitmap was set to 1 in your sample. That means bitmap is monochrome.
You need to use 32-bit bitmap to use transparency in brushes. GDI supports transparency with some limits. Use GDI+ for full transparency support.