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
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.
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;
}
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);
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?
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)"