2
\$\begingroup\$

I have done the following using C++:

1) I used SDL_CreateWindow() to create an SDL window

m_window = SDL_CreateWindow("My First Side-scroller
    SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH,
    SCREEN_HEIGHT, SDL_WINDOW_SHOWN);

2) I used SDL_CreateRenderer() to create a renderer for the SDL window

m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_PRESENTVSYNC);

3) I used SDL_CreateTexture() to create a texture

m_texture = SDL_CreateTexture(m_renderer, SDL_PIXELFORMAT_RGBA8888,
        SDL_TEXTUREACCESS_STATIC, SCREEN_WIDTH, SCREEN_HEIGHT);

4) I created a buffer of type Uint32 to hold texture information which is passed to the SDL_Texture

m_buffer = new Uint32[SCREEN_WIDTH * SCREEN_HEIGHT];

5) I created a custom pixel drawing function which is use to draw pixels at a low level and pass it to the buffer.

void Screen::setPixel(int x, int y, Uint8 red, Uint8 green, Uint8 blue) {
    // Checking for pixels  off screen 
    // This is sufficient because the rand function can generate a negative number
    if (x < 0 || x >= SCREEN_WIDTH || y < 0 || y >= SCREEN_HEIGHT) {
        return;
    }

    Uint32 colour = 0;

    colour += red;
    colour <<= 8;
    colour += green;
    colour <<= 8;
    colour += blue;
    colour <<= 8;
    colour += 0xFF;

    m_buffer[(y * SCREEN_WIDTH) + x] = colour;
}

6) I used 5) along with other functions to help draw pixels on random locations in the window and make them move vertically and loop from the top of the window to the bottom of the window (like moving stars).

Stars::Stars()
{
    m_x_star=((2.0*rand())/RAND_MAX)-1;
    m_y_star=((2.0*rand())/RAND_MAX)-1;
}

void Stars::moveStar(){
    // starSpeed is the desired change in co-ordinate position for each pixel plotted
    double const starSpeed = 0.001;


    if(m_y_star<-0.998 && m_y_star>-1) {
        m_y_star=0.995;
    }

    m_y_star-=starSpeed;
}

1) to 6) works with no-error

So, onto my issue: Blitting an image using SDL_BlitSurface seems to require that the window is created using SDL_Surface() for its third flag. I want to load a .png image of a spaceship I drew. Here is the code I use to load the image.

void Screen::update_spaceShip() {
    SDL_Surface *Image;
    Image= IMG_Load("spaceship_stock2.png");
    SDL_BlitSurface(Image,NULL,m_window,NULL);
}

Error message:

cannot convert 'SDL_Window*' to 'SDL_Surface*' for argument '3' to 'int SDL_UpperBlit(SDL_Surface*, const SDL_Rect*, SDL_Surface*, SDL_Rect*)'

What am I doing wrong?

\$\endgroup\$

1 Answer 1

7
\$\begingroup\$

It seems that you are looking for SDL_CreateTextureFromSurface. As you seem to have learned (the hard way), SDL2 doesn't really support rendering surfaces directly anymore. There are ways to do that I believe, but you should be using hardware rendering, which is implemented using surfaces. So, the modern way is to load a surface, convert that into a texture that you can use and then get rid of the surface. So something like

SDL_Surface* image = IMG_Load("yourimage.png");
SDL_Texture* texture = SDL_CreateTextureFromSurface(m_Renderer, image);
SDL_FreeSurface(image);

So, you can load a surface using IMG_Load and then convert that into a texture that you can render using SDL_RenderCopy or I believe SDL_Image even comes with a IMG_LoadTexture these days. You should note that calling IMG_Load in your render-method is a bad idea as it allocates memory each time, so you want to do this at initialization instead.

I recommend you do some reading on the SDL_Renderer and it's uses. However, if you are insistent on using SDL_BlitSurface instead of the faster new way to render, please let me know.

\$\endgroup\$
8
  • \$\begingroup\$ I now get an error on the line "SDL_Surface* image = IMG_Load("yourimage.png");stating the following" stating the f \$\endgroup\$
    – The Ace
    Jan 19, 2017 at 16:41
  • \$\begingroup\$ @TheAce You have a typo. :) \$\endgroup\$ Jan 19, 2017 at 17:00
  • \$\begingroup\$ I now get an error on the line "SDL_Surface* image = IMG_Load("yourimage.png");stating that there is an 'undefined reference to IMG_Load'. I have the following DLL's in my debug folder. libjpeg-9dll, libpng16-16.dll, SDL2_image.dll, SDL2.dll. My spaceship_stock2.png file is the destination folder. I have included the following flags in my Libraries: mingw32, SDL2main, SDL2, SDL2_image in that order. I've set the paths for the library and includes aswell as copied all of the necessary files from SDL_image into the correct folder. ...MinGW\include\SDL2 and ...MinGW\lib. \$\endgroup\$
    – The Ace
    Jan 19, 2017 at 17:04
  • \$\begingroup\$ I'm not sure about that @TheAce, there seem to be a lot of resources about that specific error on the internet though, so Google might be your best bet here. \$\endgroup\$
    – user35344
    Jan 19, 2017 at 17:13
  • 1
    \$\begingroup\$ I don't understand what this has to do with the answer here, @Owl? If you are having issues with something other than what OP asked about, you should post a question about that. \$\endgroup\$
    – user35344
    Sep 18, 2018 at 3:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .