Need help to correct the algorithm to set a pixel using sdl2

166 Views Asked by At

I am trying to write a setPixel function using SDL2 but this code is not working as expected.

As this function need, I have window, renderer and texture pointer as global variable.

#include <SDL2/SDL.h>
#include <iostream>

using namespace std;

SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Texture* texture = NULL;

bool running = false;



void handleEvents();
void update();
void render();
void setPixel(int x, int y, Uint8 r, Uint8 g, Uint8 b);

int main(int argc, char const *argv[])
{


    if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
    {
        cout << "SDL init failed " << SDL_GetError() << "\n";
        return 1;
    }
    
    window = SDL_CreateWindow("Testing_01",
                              SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
                              800, 640, 
                              SDL_WINDOW_SHOWN);

    if (window == NULL)
    {
        cout << "Window creation failed " << SDL_GetError() << "\n";
        return 1;
    }

    renderer = SDL_CreateRenderer(window, -1, 0);
    if (renderer == NULL)
    {
        cout << "Renderer creation failed " << SDL_GetError() << "\n";
        return 1;
    }

    SDL_SetRenderDrawColor(renderer, 230, 230, 230, 255);

    setPixel(10, 10, 255, 0, 0);

    running = true;
    while (running)
    {
        handleEvents();
        update();
        render();
    }

    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);

    SDL_Quit();
    return 0;
}

void handleEvents()
{   
    SDL_Event event;
    const Uint8 *keys = SDL_GetKeyboardState(NULL);

    while (SDL_PollEvent(&event))
    {
        switch (event.type)
        {
            case SDL_QUIT:
                running = false;
                break;
            default:
                break;
        }
    }

    if (keys[SDL_SCANCODE_ESCAPE]) 
    {
       running = false;
    }

    if (keys[SDL_SCANCODE_RIGHT]) 
    {
        printf("Right and Up Keys Pressed.\n");
    }
}

void update()
{

}
        
void render()
{
    SDL_RenderClear(renderer);

    SDL_RenderPresent(renderer);
}

void setPixel(int x, int y, Uint8 r, Uint8 g, Uint8 b)
{   

    // Allocate memory for a pixel buffer.
    Uint32 *pixels = new Uint32[800 * 640];

    // Clear the pixel buffer.
    memset(pixels, 0, 800 * 640 * sizeof(Uint32));

    SDL_Rect rect, bound;
    rect.x = 0;
    rect.y = 0;
    rect.w = 800;
    rect.h = 640;
    bound = rect;

    const SDL_Rect* constRect = &rect;

    Uint32 color;

    texture = SDL_CreateTexture(renderer,
                                SDL_PIXELFORMAT_RGB888,
                                SDL_TEXTUREACCESS_STREAMING, 800,
                                640);

    
    SDL_LockTexture(texture,
                    constRect,
                    (void**) pixels, (int*)( 800 * sizeof(Uint32)));

    color = SDL_MapRGB(SDL_AllocFormat(SDL_PIXELFORMAT_RGBA8888), r, g, b);

    pixels[(y*800)+x] = color;

    SDL_UpdateTexture(texture,
                      constRect,
                      pixels, 800 * sizeof(Uint32));

    delete[] pixels;

    SDL_RenderCopy(renderer, texture, &rect, &bound);

    SDL_UnlockTexture(texture);
}
2

There are 2 best solutions below

2
On

You can use SDL_RenderDrawPoint in conjunction with SDL_SetRenderDrawColor to achieve what you want to (assuming you're just aiming to draw pixels straight to the screen). This method doesn't require using an intermediate texture to draw to.

I've changed your set pixel function to:

void setPixel(int x, int y, Uint8 r, Uint8 g, Uint8 b) {
    SDL_SetRenderDrawColor(renderer, r, g, b, SDL_ALPHA_OPAQUE);
    SDL_RenderDrawPoint(renderer, x, y);
}

and your render function to:

void render()
{
    SDL_SetRenderDrawColor(renderer, 230, 230, 230, 255);
    SDL_RenderClear(renderer);
    setPixel(10, 10, 255, 0, 0);
    SDL_RenderPresent(renderer);
}

The pixel will be redrawn each update with the sample I have provided.

You can see this related question for more information.

1
On

Welcome to SDL2!

You should not lock the texture if you are going to write onto it.