Changing the color of a pixel


#1

Hello

I’m new to SDL and i’m trying to change the color of a single pixel with no success. I got the following function from a tutorial:

Uint32 *m_buffer = new Uint32[screen_width * screen_height];

void screen::setPixel(int x, int y, Uint8 red, Uint8 green, Uint8 blue)
{
Uint32 color = 0;

	color += red;
	color <<= 8;
	color += green;
	color <<= 8;
	color += blue;
	color <<= 8;
	color += 0xff;

	cout << "setPixel funct was called" << endl;
	cout << setfill('0') << setw(8) << hex << color << endl;

	m_buffer[(y * screen_width) + x] = color;

	cout << "buffer was set" << endl;
}

I’m having trouble setting the m_buffer element to the color, Does it have something to do with color not having the prefix 0x for hexdecimal? When I call the function, it crashed at the m_buffer[(y * screen_width) + x] = color; statement.

I have been stuck with this problem for three days. I know there is a better way to do this, but I’m suborn.


#2

run your code in a debugger, when it crashes, look at the values of m_buffer, screen_width, x, and y. it shouldn’t crash from having a wrong value for color, so, it’s probably that m_buffer was not correctly set, m_buffer was deleted or changed, screen_width was changed, or (most likely) x and y are out of range.


#3

Thanks Jacob,
I think I found the problem. I set the m_buffer in my Init function and lose it when it exit the function. Where can set at? or do I have to make it a const static?

Thanks for your help.


#4

To give a more accurate answer, I’d need to know where do you declare the m_buffer variable and see the source code for the Init function. I’m guessing that m_buffer is declared either as a global variable or as a member variable of the screen class; in either case, if you also declare m_buffer in your Init function, it will create a new variable with the same name, hiding the original m_buffer for the rest of Init. If that’s the case, just use m_buffer = new Uint32[screen_width * screen_height]; without the Uint32 * part inside your Init function.

class screen
{
private:
    Uint32 *m_screen;
    size_t screen_width, screen_height;
    SDL_Window *window;
    // more members...
public:
    screen()
        : m_buffer(NULL),
          screen_width(0),
          screen_height(0),
          window(NULL)
    {
        Init();
    }
    ~screen()
    {
        delete []m_buffer; // don't forget to release memory
        // call SDL_DestroyWindow, shut down sdl, other cleanup...
    }
private:
    void Init()
    {
        // code to start sdl, create a window and other initialization; assigns the new window to the window variable...
        int w, h;
        SDL_GetWindowSize(window, &w, &h);
        window_width = w;
        window_height = h;
        // if you had Uint32 *m_buffer = ...; it would create a new variable named m_buffer that hides the one declared in the screen class
        m_buffer = new Uint32[screen_width * screen_height];
        // clear m_buffer's contents
        for(size_t i = 0, size = screen_width * screen_height; i < size; i++)
            m_buffer[i] = 0; // black, transparent
    }
public:
    void setPixel(int x, int y, Uint8 red, Uint8 green, Uint8 blue)
    {
        Uint32 color = 0;

        color += red;
        color <<= 8;
        color += green;
        color <<= 8;
        color += blue;
        color <<= 8;
        color += 0xff;

        cout << "setPixel funct was called" << endl;
        cout << setfill('0') << setw(8) << hex << color << endl;

        m_buffer[(y * screen_width) + x] = color;

        cout << "buffer was set" << endl;
    }
    // more member functions...
};

int main(int argc, char **argv)
{
    screen s; // constructor calls Init
    bool done = false;
    while(!done) // render loop
    {
        // event loop and other stuff...

        screen.setPixel(0, 0, 0xFF, 0, 0xFF); // set top left pixel to magenta

        // code to draw screen.m_buffer...
    }
    // screen's destructor runs cleanup, don't need to explicitly do it here
    return 0;
}