0
\$\begingroup\$

I am self teaching SDL game programming from SDL Game Development Black and White textbook.

I stopped at the second chapter, where I have to display .bmp picture on screen.

Given code:

SDL_Surface* pTempSurface = SDL_LoadBMP("assets/rider.bmp");

m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer,pTempSurface);
SDL_FreeSurface(pTempSurface);

SDL_QueryTexture(m_pTexture, NULL, NULL, &m_sourceRectangle.w, &m_sourceRectangle.h);
m_destinationRectangle.x = m_sourceRectangle.x = 0;
m_destinationRectangle.y = m_sourceRectangle.y = 0;
m_destinationRectangle.w = m_sourceRectangle.w;
m_destinationRectangle.h = m_sourceRectangle.h;

should be loaded inside init function of Game1.cpp, as author tells

#include <iostream>
#include "Game1.h"
#include <stdio.h>
#include <SDL2/SDL.h>

Game::Game()
{

}

bool Game::init(const char* title, int xpos, int ypos, int width, int height, int flags)
{
    SDL_Surface* pTempSurface = SDL_LoadBMP("assets/rider.bmp");

    m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer, pTempSurface);
    SDL_FreeSurface(pTempSurface);

    SDL_QueryTexture(m_pTexture, NULL, NULL, &m_sourceRectangle.w, &m_sourceRectangle.h);
    m_destinationRectangle.x = m_sourceRectangle.x = 0;
    m_destinationRectangle.y = m_sourceRectangle.y = 0;
    m_destinationRectangle.w = m_sourceRectangle.w;
    m_destinationRectangle.h = m_sourceRectangle.h;

    if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
    {
        std::cout << "SDL init success\n";
        m_pWindow = SDL_CreateWindow(title, xpos, ypos, width, height, flags);  

        if(m_pWindow != 0)
        {
            std::cout << "window creation success\n";
            m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0); 

            if(m_pRenderer != 0)
            {
                std::cout << "renderer creation success\n";
                SDL_SetRenderDrawColor(m_pRenderer, 255, 255, 255, 255);
            }
            else
            {
                std::cout << "renderer init fail\n";
                return false;
            }
        }
        else
        {
            std::cout << "window init fail\n";
            return false;
        }
    }
    else
    {
        std::cout << "SDL init fail\n";
        return false;
    }

    std::cout << "init success\n";
    m_bRunning = true;

    return true;
}

void Game::render()
{
    SDL_RenderClear(m_pRenderer);

    SDL_RenderCopy(m_pRenderer, m_pTexture, &m_sourceRectangle, &m_destinationRectangle);

    SDL_RenderPresent(m_pRenderer);
}

void Game::SDL_Quit()
{
    std::cout << "cleaning game\n";
    SDL_DestroyWindow(m_pWindow);
    SDL_DestroyRenderer(m_pRenderer);
}

void Game::clean()
{
    std::cout << "cleaning game\n";
    SDL_DestroyWindow(m_pWindow);
    SDL_DestroyRenderer(m_pRenderer);
    SDL_Quit();
}

Game1.h

#ifndef GAME1_H
#define GAME1_H
#include <iostream>
#include <stdio.h>
#include <SDL2/SDL.h>

class Game

{
public:

    Game();
    ~Game();

    bool init(const char* title, int xpos, int ypos, int width, int height, int flags);

    void render();
    void update();
    void handleEvents();
    void clean();
    void SDL_Quit();

    bool running() { return m_bRunning; }

private:

    SDL_Window* m_pWindow;
    SDL_Renderer* m_pRenderer;

    SDL_Texture* m_pTexture; // the new SDL_Texture variable
    SDL_Rect m_sourceRectangle; // the first rectangle
    SDL_Rect m_destinationRectangle; // another rectangle

    bool m_bRunning;
};



#endif // GAME1_H_INCLUDED

main.cpp

#include "Game1.h"
#include <iostream>
#include <stdio.h>
#include <SDL2/SDL.h>


Game* g_game = 0;

int main(int argc, char* args[])
{

    g_game = new Game();

    g_game->init("Chapter 1", 100, 100, 640, 480, 0);

    while(g_game->running())
    {
        g_game->handleEvents();
        g_game->update();
        g_game->render();
    }
    g_game->clean();

    return 0;
}

void Game::handleEvents()
{
    SDL_Event event;
    if(SDL_PollEvent(&event))
    {
        switch (event.type)
        {
            case SDL_QUIT:
                m_bRunning = false;
            break;

            default:
            break;
        }
    }
}

When build this in CodeBlocks I get no error. Even window loads, but there is no rider.bmp image on window screen.

What is wrong? Should given code be placed somewhere else inside init()? Thank you

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

You need to initialize SDL before calling SDL_LoadBMP and construct the renderer before calling SDL_CreateTextureFromSurface. It's a good rule of thumb to initialize SDL and create the window and renderer before doing anything else.

So simply move that code to bottom of init.

\$\endgroup\$
3
  • \$\begingroup\$ Supposed that problem is in position of author code. But, even with moving code to bottom of init I still get empty screen again. \$\endgroup\$
    – user284901
    Commented Jan 9, 2018 at 21:19
  • \$\begingroup\$ Are you checking SDL_GetError? \$\endgroup\$
    – user35344
    Commented Jan 9, 2018 at 21:23
  • 1
    \$\begingroup\$ Finally, it works. Completely forgot to check SDL_GetError. Error was in wrong path for rider.bmp picture. Thank you! \$\endgroup\$
    – user284901
    Commented Jan 9, 2018 at 21:37

You must log in to answer this question.

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