Hello,
I’m playing SDL_ComposeCustomBlendMode() with this new function and the result is quite strange:
I’m trying to use additive blending wit the following source code.
To resume, I have a background with a texture, then I first render an image directly in the background as reference.
Secondly I render the image in a black transparent texture and then the result in the background.
The result of the second square is a solid black square around my white disk. How is it possible with the parameters I give??
Around the white disk where the transparency is close to 0, and as the intermediate texture is transparent, so alpha is 0, SDL_BLENDOPERATION_ADD should give
srcAlpha * SDL_BLENDFACTOR_ONE + dstAlpha * SDL_BLENDFACTOR_ONE
= 0 * 1 + 0 * 1 = 0
Please tell me what I don’t understand here?
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Texture *background = NULL;
SDL_Texture *image = NULL;
SDL_Surface* surface = NULL;
SDL_Rect dst = {0, 0, 200, 200};
SDL_BlendMode mode;
#define SOLID 255
#define HALF_TRANSPARENT 128
#define TRANSPARENT 0
SDL_Texture * renderImageInATexture(SDL_Texture *image, Uint8 transparency) {
// Create an intermediate texture
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 200, 200);
SDL_SetTextureBlendMode(texture, mode); // For SDL_RenderCopy()
SDL_SetRenderDrawBlendMode(renderer, mode); // For SDL_RenderFillRect()
SDL_SetRenderTarget(renderer, texture);
// Paint it with transparency value
SDL_SetRenderDrawColor(renderer, (Uint8) 0, (Uint8) 0, (Uint8) 0,(Uint8) transparency);
SDL_RenderFillRect(renderer, NULL);
// Render the image in intermediate texture
SDL_RenderCopy( renderer, image, NULL, NULL);
SDL_SetRenderTarget(renderer, NULL);
return texture;
}
int main(char *argc, char **argv) {
SDL_Init( SDL_INIT_VIDEO);
window = SDL_CreateWindow("Win", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
400, 200, SDL_WINDOW_SHOWN);
// So we can save into pngs to check the value
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderTarget(renderer, NULL);
SDL_BlendMode mode = SDL_ComposeCustomBlendMode(
SDL_BLENDFACTOR_SRC_COLOR,
SDL_BLENDFACTOR_DST_COLOR,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
// Fill the window with a texture to see if semi transparent intermediate texture is OK.
surface = IMG_Load( "./carbone.png" );
background = SDL_CreateTextureFromSurface( renderer, surface );
SDL_FreeSurface( surface );
SDL_SetTextureBlendMode(background, SDL_BLENDMODE_NONE);
// draw background in main display
SDL_RenderCopy( renderer, background, NULL, NULL );
surface = IMG_Load( "./image.png" );
image = SDL_CreateTextureFromSurface( renderer, surface );
SDL_FreeSurface( surface );
// draw image in main background as reference to compare with further renderings
SDL_RenderCopy( renderer, image, NULL, &dst );
// Secondly, the image is rendered in a transparent intermediate texture.
SDL_Texture *texture1 = renderImageInATexture(image, TRANSPARENT);
// render intermediate texture in main display
SDL_Rect dstTexture = {200, 0, 200, 200};
SDL_RenderCopy( renderer, texture1, NULL, &dstTexture );
SDL_RenderPresent(renderer);
SDL_Event e;
int wait = 1;
while (wait) {
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
wait = 0;
}
SDL_Delay(33);
}
}
SDL_DestroyTexture(image);
SDL_DestroyTexture(texture1);
SDL_DestroyTexture(background);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}