This is something I’ve been trying to do for really long long time, this last few days I managed to get to what I want (see screenshot below).
My next question is how do you blend or tint the mask, say I want the black portion to be blend as a blue-purple-ish to give more of a night ambient rather than just being super dark with a candlelight. The screenshot in the bottom was done by changing the render draw color to something else make it it look transparent and blend into it, but it never goes to tint the actual color selected.
Here is an example in pokemon second generation, it just a purplish tint that blends with actual color instead of just an overlay color on top. I have tried putting an purple texture on top with blend mode, it’s too far from this, and I’m not expecting the same.
Using a white painted brush on a black background I was able to create that effect, and it looks “tinted” when using different colors instead of white.
Here are the light spots I used
Changing the render draw color looks like this:
SDL_SetRenderDrawColor(renderer, 0x36, 0x45, 0x9b, 0xff);
At the end of the day I want to be able to use different color to simulate different time of the day, not like this, but you get an idea in this link: https://www.gamasutra.com/blogs/SvyatoslavCherkasov/20181023/329151/Graveyard_Keeper_How_the_graphics_effects_are_made.php
In summary:
-
How do I change the black color to be transparent while having the “bright” spot?
-
How I blend another color or tint a texture to look like the screenshot of pokemon or the last game linked to gamasutra?
-
Or How do I create a tint in the light black color that blends to the game background to look like tint?
-
Is possible to do all this to create ambient light?
#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> int main(int argc, char ** argv) { SDL_Event event; int quit = 0; SDL_Init(SDL_INIT_VIDEO); SDL_Window * window = SDL_CreateWindow( "2D Light test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0 ); SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); // layers SDL_Texture * backgroundLayer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 640, 480); SDL_Texture * lightLayer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 640, 480); SDL_Texture * resultLayer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 640, 480); // "game" graphics rendered SDL_Surface * bgSurface = IMG_Load("game.jpg"); SDL_Texture * bgTexture = SDL_CreateTextureFromSurface(renderer, bgSurface); SDL_FreeSurface(bgSurface); // light spot SDL_Surface * lightSurface = IMG_Load("spot.jpg"); SDL_Texture * lightTexture = SDL_CreateTextureFromSurface(renderer, lightSurface); SDL_FreeSurface(lightSurface); while (quit != 1) { while( SDL_PollEvent(&event) != 0 ) { switch (event.type) { case SDL_QUIT: quit = 1; break; } } SDL_SetRenderDrawColor( renderer, 0x00, 0x00, 0x00, 0x00 ); SDL_RenderClear( renderer ); // fake game tiles, objects, players rendering SDL_SetRenderTarget( renderer, backgroundLayer ); SDL_SetRenderDrawColor( renderer, 0x00, 0x00, 0x00, 0x00 ); SDL_RenderClear( renderer ); SDL_Rect gameRect = {0, 0, 640, 480}; SDL_RenderCopy(renderer, bgTexture, NULL, &gameRect); SDL_SetRenderTarget(renderer, NULL); // draw light points SDL_SetRenderTarget(renderer, lightLayer); SDL_SetTextureBlendMode(lightLayer, SDL_BLENDMODE_MOD); SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00); // change the black color to a more transparent one // SDL_SetRenderDrawColor(renderer, 0x36, 0x45, 0x9b, 0xff); // ---- SDL_RenderClear(renderer); SDL_Rect spot1 = {10, 10, 200, 200}; SDL_Rect spot2 = {240, 240, 200, 200}; SDL_RenderCopy(renderer, lightTexture, NULL, &spot1); SDL_RenderCopy(renderer, lightTexture, NULL, &spot2); SDL_SetRenderTarget(renderer, NULL); // merge all layers SDL_SetRenderTarget(renderer, resultLayer); SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00); SDL_RenderClear(renderer); SDL_SetTextureBlendMode(resultLayer, SDL_BLENDMODE_BLEND); SDL_RenderCopy(renderer, backgroundLayer, NULL, &gameRect); SDL_RenderCopy(renderer, lightLayer, NULL, &gameRect); SDL_SetRenderTarget(renderer, NULL); SDL_RenderCopy(renderer, resultLayer, NULL, &gameRect); SDL_RenderPresent(renderer); } SDL_DestroyTexture(bgTexture); SDL_DestroyTexture(lightTexture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; }
I have played with different options of blending and creating custom blendmode with all the possible combinations I could come up.