SDL2 pixel manipulation - c

I need to create a window, and fill all of its pixels with a color. This shouldn't be too hard, but after a hour or so I still can't get it working. Here is my code as it looks right now:
#include <SDL2/SDL.h>
int main(int argc, char** argv)
{
enum {
WIDTH = 640,
HEIGHT = 480
};
SDL_Window* window = SDL_CreateWindow(
"SDL test",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
WIDTH,
HEIGHT,
SDL_WINDOW_SHOWN
);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_Texture* texture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STREAMING,
WIDTH,
HEIGHT
);
SDL_Surface* surface = SDL_CreateRGBSurface(
0,
WIDTH,
HEIGHT,
32,
0x00000000,
0x00000000,
0x00000000,
0xff000000
);
Uint32 gray = SDL_MapRGBA(surface->format, 0x1E, 0x1E, 0x1E, 0xFF);
Uint32 red = SDL_MapRGBA(surface->format, 0xFA, 0x32, 0x32, 0xFF);
int i, j;
Uint32* pixels32 = (Uint32*) surface->pixels;
for (i = 0; i < HEIGHT; ++i)
{
for (j = 0; j < WIDTH; ++j)
{
pixels32[i * WIDTH + j] = j%10 ? gray : red;
}
}
SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
SDL_RenderPresent(renderer);
int quit = 0;
SDL_Event event;
while (!quit)
{
while (SDL_PollEvent(&event) != 0)
{
if (event.type == SDL_QUIT)
quit = 1;
}
}
SDL_FreeSurface(surface);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
But it shows a white window. What am I doing wrong?

You created a texture, but you haven't drawn it yet. In order to draw it on a surface, you still need to call SDL_RenderCopy.

Related

Cannot get SDL_SetTextureColorMod to work

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:

Pixel Manipulation in SDL2.0

I can not display pixels in SDL 2.0.
#include<SDL2/SDL.h>
#include<stdbool.h>
void end( SDL_Window *Window, SDL_Surface *Surface);
void drawPixel( SDL_Surface *Surface, int x, int y);
void main(){
Uint32 start;
const int FPS = 60;
bool running = true;
SDL_Event event;
SDL_Window *main_window = NULL;
SDL_Surface *main_screen = NULL;
SDL_Init( SDL_INIT_EVERYTHING );
main_window = SDL_CreateWindow("Pixel", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,800,600,
SDL_WINDOW_RESIZABLE);
main_screen = SDL_GetWindowSurface ( main_window );
SDL_UpdateWindowSurface( main_window );
//printf("%d\n",main_screen->pixels);
SDL_FillRect( main_screen, NULL, SDL_MapRGB(main_screen->format, 255, 255, 255));
SDL_UpdateWindowSurface( main_window );
for(int i = 0; i <= 3000; i++ ){
drawPixel( main_screen, i, 0);
//break;
}
// SDL_UpdateWindowSurface( main_window );
while( running ) {
// start = SDL_GetTicks();
while ( SDL_PollEvent( &event ) ){
switch( event.type ){
case SDL_QUIT:
running = false;
break;
}
}
}
end( main_window, main_screen);
}
void end(SDL_Window *Window, SDL_Surface *Surface){
SDL_FreeSurface( Surface );
SDL_DestroyWindow( Window );
}
void drawPixel(SDL_Surface *Surface, int x, int y){
Uint8 *pixel_array = (Uint8 *) Surface->pixels;
Uint8 *pixel = pixel_array + Surface->pitch * y + x;
*pixel = SDL_MapRGB(Surface->format, 0, 0, 0 );
}`
I tried to locate pixel position and try to color the pixel black while background color white, but it does not print anything.
Although I tried to create a line in case i am not unable to see the pixel, but it turned out to be not working. I see only white screen.

My code won't display sprite SDL2

The screen is always black. Tell me how to display the sprites correctly.
This is my code:
#define SHAPE_SIZE 32
void aff_map(SDL_Renderer *renderer)
{
SDL_Surface *img;
SDL_Texture *Tfloor
int x = 0;
int y = 0;
int map[4][8] = {{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}};
SDL_Rect SrcR;
SDL_Rect DestR;
DestR.x = 0;
DestR.y = 0;
DestR.w = SHAPE_SIZE;
DestR.h = SHAPE_SIZE;
img = IMG_Load("floor.bmp");
Tfloor = SDL_CreateTextureFromSurface(renderer, img);
while (y < 4)
{
x = 0;
while (x < 8)
{
if (map[y][x] == 0)
SDL_RenderCopy(renderer, Tfloor, NULL, &DestR);
x++;
DestR.x = DestR.x + 32;
}
DestR.x = 0;
DestR.y = DestR.y + 32;
y++;
}
SDL_RenderPresent(renderer);
}
int main()
{
SDL_Window *screen;
SDL_Event evenements;
SDL_Renderer *renderer;
screen = SDL_CreateWindow("Zappy", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 8 * SHAPE_SIZE -32, 4 * SHAPE_SIZE, 0);
renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);
SDL_RenderClear(renderer);
while (42)
{
SDL_WaitEvent(&evenements);
if (evenements.window.event == SDL_WINDOWEVENT_CLOSE ||
evenements.key.keysym.sym == SDLK_ESCAPE)
{
SDL_DestroyWindow(screen);
SDL_Quit();
break;
}
aff_map(renderer);
}
return 0;
}
The error message is explicit.
It says that the "floor.bmp" has not been converted to a surface.
It means that 'img' parameter is NULL.
Try the following :
Specify the full path to your picture in IMG_Load(), for example "/home/quentin/floor.bmp"
Check the return value of IMG_Load().

SDL and C keyboard or touch event

I'm programming in c4droid but I can't get the touch event to work.
Tried switch or if statement but nothing works im sure rendering is ok because if I delete the switch then its renders normally
Here I the code:
#include <SDL2/SDL.h>
int main()
{
SDL_Window *window = NULL;
window = SDL_CreateWindow("Shooter", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
// Setup renderer
SDL_Renderer *renderer = NULL;
renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_ACCELERATED);
// Set render color to red ( background will be rendered in this color )
SDL_SetRenderDrawColor(renderer, 0, 255, 25, 255);
// Clear winow
SDL_RenderClear(renderer);
// Creat a rect at pos ( 50, 50 ) that's 50 pixels wide and 50 pixels
// high.
SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
SDL_Rect r;
r.x = 500;
r.y = 500;
r.w = 50;
r.h = 50;
SDL_Rect e;
e.x = 5;
e.y = 5;
e.w = 50;
e.h = 50;
SDL_Event event;
while(SDL_PollEvent(&event) != 0) {
switch (event.type) {
case SDL_FINGERDOWN :
e.x = e.x + 10;
SDL_RenderFillRect(renderer, &r);
SDL_RenderFillRect(renderer, &e);
SDL_RenderPresent(renderer);
break;
}
}
// Wait for 5 sec
SDL_Delay(50000);
SDL_DestroyWindow(window);
SDL_Quit();
}
You need to make sure to poll the event.
while(true) {
while(SDL_PollEvent(&event) != 0) {
switch (event.type) {
case SDL_FINGERDOWN :
e.x = e.x + 10;
SDL_RenderFillRect(renderer, &r);
SDL_RenderFillRect(renderer, &e);
SDL_RenderPresent(renderer);
break;
// Render rect
}
}
}
Provided event is not NULL, SDL_PollEvent will take the next event from the queue and store it in the SDL_Event that event is pointing at.
Edit: Don't remove the while(true) loop, put this one inside it. Sorry, I probably should have been a bit more clear in the beginning.

Displaying the rectangle using a for loop in SDL2 C

I'm currently using a for loop to create 4 rectangles along the x-axis. When I run the program the image of the rectangle appears for a few millisecond before it disappears. Can you show me what I have to do in order for the image to display on the screen permanently.
When I create individual rectangles it display's the image without vanishing.
An example will be helpful. Thanks
int main(){
int barrack1_xposition = 167,i=1;
int cnt_barrack=0;
SDL_Window *o = NULL;
SDL_Renderer *r = NULL;
SDL_Rect bar1[4];
SDL_Event e;
SDL_Init(SDL_INIT_VIDEO);
o = SDL_CreateWindow("SPACE INVADERS",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1024,
800,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
r = SDL_CreateRenderer(o, -1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
while(i)
{
while(SDL_PollEvent(&e) !=0)
{
if(e.type == SDL_QUIT)
i=0;
}
for(cnt_barrack = 0; cnt_barrack < 4; cnt_barrack++)
{
bar1[cnt_barrack].x=barrack1_xposition;
bar1[cnt_barrack].y=250;
bar1[cnt_barrack].h=50;
bar1[cnt_barrack].w=50;
barrack1_xposition += 200;
}
SDL_SetRenderDrawColor(r,255,255,255,255);
SDL_RenderFillRect(r,&bar1[0]);
SDL_RenderFillRect(r,&bar1[1]);
SDL_RenderFillRect(r,&bar1[2]);
SDL_RenderFillRect(r,&bar1[3]);
SDL_RenderPresent(r);
}
SDL_DestroyWindow(o);
SDL_DestroyRenderer(r);;
SDL_Quit();
}
Your problem caused by the fact you didn't reset barrack1_xposition on each frame, so it keeps going higher and higher. I initially didn't notice that because there was no RenderClear so it seemed to be fine but actually wasn't.
#include "SDL.h"
int main(){
int barrack1_xposition,i=1;
int cnt_barrack=0;
SDL_Window *o = NULL;
SDL_Renderer *r = NULL;
SDL_Rect bar1[4];
SDL_Event e;
SDL_Init(SDL_INIT_VIDEO);
o = SDL_CreateWindow("SPACE INVADERS",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1024,
800,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
r = SDL_CreateRenderer(o, -1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
while(i)
{
while(SDL_PollEvent(&e) !=0)
{
if(e.type == SDL_QUIT)
i=0;
}
barrack1_xposition=167;
for(cnt_barrack = 0; cnt_barrack < 4; cnt_barrack++)
{
bar1[cnt_barrack].x=barrack1_xposition;
bar1[cnt_barrack].y=250;
bar1[cnt_barrack].h=50;
bar1[cnt_barrack].w=50;
barrack1_xposition += 200;
}
SDL_SetRenderDrawColor(r,0,0,0,0);
SDL_RenderClear(r);
SDL_SetRenderDrawColor(r,255,255,255,255);
SDL_RenderFillRect(r,&bar1[0]);
SDL_RenderFillRect(r,&bar1[1]);
SDL_RenderFillRect(r,&bar1[2]);
SDL_RenderFillRect(r,&bar1[3]);
SDL_RenderPresent(r);
}
SDL_DestroyWindow(o);
SDL_DestroyRenderer(r);;
SDL_Quit();
return 0;
}

Resources