Cannot get SDL_SetTextureColorMod to work - c

I am trying to change the color of the image displayed. The image contains characters in black and I want to display them in red. So I am trying to use SDL_SetTextureColorMod but it seems I am doing it wrong since the image rendered is still black. Does someone see the problem with my code?
#include "SDL.h"
#include <stdio.h>
int main(int argc, char **argv) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window;
SDL_Renderer *renderer;
SDL_CreateWindowAndRenderer(640, 480, 0, &window, &renderer);
SDL_Surface *surface = SDL_LoadBMP("font.bmp");
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
int keep_going = 1;
while (keep_going) {
SDL_Event e;
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
keep_going = 0;
}
}
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderClear(renderer);
int ret = SDL_SetTextureColorMod(texture, 255, 0, 0);
if(ret != 0){
printf("%s",SDL_GetError());
}
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
SDL_Quit();
return 0;
}
The image I'm using:

Related

Wrong color with SDL on HDR image?

I have my program that is displaying my image:
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
void Clean_ressources(SDL_Window *w, SDL_Renderer *r, SDL_Texture *t)
{
if (t!= NULL)
SDL_DestroyTexture(t);
if (t!= NULL)
SDL_DestroyRenderer(r);
if (w!= NULL)
SDL_DestroyWindow(w);
SDL_Quit();
}
void SDL_ExitWithError(const char *message);
int main(int argc, char **argv)
{
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Surface *surface = NULL;
SDL_Texture *texture, *tmp = NULL;
SDL_Rect dest_rest = {0, 0, 640, 480};
//SDL Init
if(SDL_Init(SDL_INIT_VIDEO) != 0)
SDL_ExitWithError("SDL init failed");
//Create Window
window = SDL_CreateWindow("My Viewer 10 bits", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED ,1000, 1000, 0);
if(window == NULL)
{
Clean_ressources(NULL, NULL, NULL);
SDL_ExitWithError("Window creation failed");
}
//Create Renderer
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
if(renderer == NULL)
{
Clean_ressources(window, NULL, NULL);
SDL_ExitWithError("Renderer creation failed");
}
//Load image
// https://github.com/codelogic/wide-gamut-tests/blob/master/R2020-sRGB-red.jpg
surface = IMG_Load("src/red.jpg");
if(surface == NULL)
{
Clean_ressources(window, renderer, NULL);
SDL_ExitWithError("Load image failed");
}
tmp = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
if(tmp == NULL)
{
Clean_ressources(window, renderer, NULL);
SDL_ExitWithError("Create texture from surface failed");
}
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB2101010, SDL_TEXTUREACCESS_TARGET, surface->w, surface->h);
if(texture == NULL)
{
Clean_ressources(window, renderer, NULL);
SDL_ExitWithError("Create texture failed");
}
if(SDL_QueryTexture(texture, NULL, NULL, &dest_rest.w, &dest_rest.h) != 0)
{
Clean_ressources(window, renderer, NULL);
SDL_ExitWithError("Query texture failed");
}
if(SDL_RenderCopy(renderer, tmp, NULL, NULL) != 0)
{
Clean_ressources(window, renderer, NULL);
SDL_ExitWithError("Render copy failed");
}
SDL_SetRenderTarget(renderer, texture);
SDL_RenderPresent(renderer);
SDL_DestroyTexture(tmp);
SDL_FreeSurface(surface);
SDL_SetRenderTarget(renderer, NULL);
/*--------------------------------------------------------------*/
SDL_bool program_launched = SDL_TRUE;
while(program_launched)
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
program_launched = SDL_FALSE;
break;
default:
break;
}
}
}
/*--------------------------------------------------------------*/
Clean_ressources(window, renderer, texture);
SDL_Quit();
return EXIT_SUCCESS;
}
void SDL_ExitWithError(const char *message)
{
SDL_Log("ERROR :%s > %s\n", message, SDL_GetError());
exit(EXIT_FAILURE);
}
I tried with different image and everything seems fine, but with this image I don't understand the color is very different in my window.
Here is the image in input:
And this is the image in my window in SDL2:
I'm aware that this image is not a high dynamic range color but I would like to display in my HDR screen an image that have HDR color (10 bits depth color) in SDL but if my sdl window have color problem I won't be able to do that.
I also tried with SDL_PIXELFORMAT_RGBA8888 and nothing changed.

How to create a surface from many textures or renderer

I would like to be able to create a bitmap with SDL2.
For this I want to use SDL_SaveBMP.
However, I do not know how to create the SDL_Surface that I need.
I have to save a map created from a lot of textures.
How can I do?
EDIT : this work, but not when I use the function SDL_CreateWindowAndRenderer like SDL_CreateWindowAndRenderer(0, 0, SDL_WINDOW_MAXIMIZED|SDL_WINDOW_RESIZABLE, &window, &renderer); :
#include <stdlib.h>
#include <stdio.h>
#include <SDL.h>
int main(int argc, char *argv[])
{
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Init(SDL_INIT_VIDEO);
//window = SDL_CreateWindow("Title", 200, 200, 500, 500, 0);
SDL_CreateWindowAndRenderer(500, 500, SDL_WINDOW_MAXIMIZED|SDL_WINDOW_RESIZABLE, &window, &renderer);
SDL_Surface *screenshot = SDL_CreateRGBSurface(0, 500, 500, 32, 0, 0, 0, 0);
//SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_SetRenderDrawColor(renderer, 60, 10, 255, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
SDL_RenderReadPixels(renderer, NULL, 0, screenshot->pixels, screenshot->pitch);
SDL_SaveBMP(screenshot, "screenshot.bmp");
SDL_FreeSurface(screenshot);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

Why am I getting a spurious white pixel when I render a texture in SDL?

I'm using SDL2 to draw some stuff on screen. Here is some code:
#include <SDL.h>
void main()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 500, 500, 0);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Texture *texture;
{
SDL_Surface *window_surface = SDL_GetWindowSurface(window);
Uint32 pixel_format = window_surface->format->format;
SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, 48, 48, 8, pixel_format);
texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
SDL_FreeSurface(window_surface);
}
SDL_Rect target_rectangle;
target_rectangle.x = 100;
target_rectangle.y = 100;
target_rectangle.w = 48;
target_rectangle.h = 48;
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderDrawLine(renderer, 0, 50, 50, 0);
SDL_RenderCopy(renderer, texture, 0, &target_rectangle);
SDL_RenderPresent(renderer);
SDL_Event event;
while(1)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
return;
break;
}
}
SDL_Delay(10);
}
}
The code creates some dummy blank texture texture. I get the same behavior with a texture loaded from a bitmap file. These lines are the important ones:
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderDrawLine(renderer, 0, 50, 50, 0);
SDL_RenderCopy(renderer, texture, 0, &target_rectangle);
SDL_RenderPresent(renderer);
So draw a line somewhere in white pixels, and then copy the dummy texture to the screen, and display it all. When I do this, I get a white pixel at the bottom right of the texture.
As I said, I also get this when the texture comes from a bitmap using code like this:
SDL_Surface *bitmap_surface = SDL_LoadBMP("test.bmp");
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, bitmap_surface);
SDL_FreeSurface(bitmap_surface);

SDL_CreateRenderer cannot find a matching driver to create a renderer

Here is a simple code to control the movement a rectangle on the screen.
The platform is Windows 10 and mingw32 is used to compile the code.
The follwing cmake script is used to build the code.
cmake_minimum_required(VERSION 3.12)
project(main C)
set(CMAKE_C_STANDARD 11)
add_executable(main main.c)
target_link_libraries(main mingw32 SDL2main SDL2)
When ran the following output is generated.
Error in create_renderer Couldn't find matching render driver
Process finished with exit code 1
And the code is as follows.
// #define SDL_MAIN_HANDLED
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
void init() {
int error = SDL_Init(SDL_INIT_EVERYTHING);
if (error){
printf("Error in init: %s\n", SDL_GetError());
SDL_Quit();
exit(1);
}
}
SDL_Window* create_window(SDL_Point size, const char* title) {
SDL_Window *window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, size.x, size.y, SDL_WINDOW_OPENGL);
if (window == NULL) {
printf("Error in create_window %s\n", SDL_GetError());
SDL_Quit();
exit(1);
}
return window;
}
SDL_Renderer* create_renderer(SDL_Window *window, SDL_Point size) {
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE | SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
printf("Error in create_renderer %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
exit(1);
}
SDL_RenderSetLogicalSize(renderer, size.x, size.y);
return renderer;
}
void clean_up(SDL_Renderer *renderer, SDL_Window *window) {
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
int main(int argc, char *argv[]) {
init();
SDL_Window *window;
SDL_Point window_size = {1280, 720};
window = create_window(window_size, "Window");
SDL_Renderer *renderer;
renderer = create_renderer(window, window_size);
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
SDL_Rect player = {100, 100, 20, 20};
int should_exit = 0;
while (!should_exit) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
should_exit = 1;
clean_up(renderer, window);
}
else if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_RIGHT:
player.x++;
break;
case SDLK_LEFT:
player.x--;
break;
case SDLK_DOWN:
player.y++;
break;
case SDLK_UP:
player.y--;
break;
default:
break;
}
}
}
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
SDL_RenderFillRect(renderer, &player);
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
SDL_RenderPresent(renderer);
}
return 0;
}
I searched for duplicate questions and their solution was to update the graphics driver and check that the corresponding subsystems are initialized before calling SDL_CreateRenderer.
I have the latest nvidia drivers installed to no avail, and as you can see the initialization order is correct. Can you guide me as to find the reason why?

SDL2 won't display image

I want to use SDL2 to open a window and display an image (a meme, to be precise). For some reason, the image doesn't appear; when I run the program, only a blank window opens.
This is my code:
#include <stdio.h>
#include <SDL2/SDL.h>
#include <time.h>
#include <stdbool.h>
#include "SDL2_image/SDL_image.h"
typedef struct
{
SDL_Texture *meme1;
SDL_Window *window;
SDL_Renderer *renderer;
}Meme;
void load(Meme *meme)
{
SDL_Surface *surface = NULL;
surface = IMG_Load("meme1.jpg");
meme->meme1 = SDL_CreateTextureFromSurface(meme->renderer, surface);
if(surface == NULL)
{
printf("Could not find meme1.jpg\n");
EXIT_FAILURE;
}
if(SDL_CreateTextureFromSurface(meme->renderer, surface) < 0 )
{
printf("\n\n\nSDL_CreateTextureFromSurface failed: %s\n\n\n", SDL_GetError());
}
SDL_FreeSurface(surface);
}
int process()
{
int quit = 0;
SDL_Event quitEvent;
while(quit==0)
{
while(SDL_PollEvent(&quitEvent))
{
if(quitEvent.type == SDL_QUIT)
{
quit = 1;
}
}
}
return quit;
}
void doRender(SDL_Renderer *renderer, Meme *meme)
{
renderer = SDL_CreateRenderer(meme->window, -1, 0);
SDL_RenderCopy(renderer, meme->meme1, NULL, NULL);
SDL_RenderPresent(renderer);
}
int main(int argc, char *argv[])
{
//creates the main window
SDL_Window *window = NULL;
Meme meme;
SDL_Renderer *renderer = NULL;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("Window",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
800,
600,
0);
if (window == NULL)
{
printf("\nFailed to create window: %s\n", SDL_GetError());
return 1;
}
load(&meme);
int done = 0;
while(!done)
{
done = process();
doRender(renderer, &meme);
}
SDL_DestroyWindow(window);
SDL_DestroyTexture(meme.meme1);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
You should try converting the meme to a bmp image and the using the function SDL_LoadBmp
(use a surface to use this function)
if you need more help or need details check the syntax at
https://wiki.libsdl.org/SDL_LoadBMP
the error comes from the fact that you did not initialize SDL_image
with the function
"IMG_Init (arg)"

Resources