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.
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 delete
d or changed, screen_width
was changed, or (most likely) x
and y
are out of range.
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.
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;
}