0
votes

I'm writing a basic 2D game in C++ with SDL, and just yesterday I converted from 1.2 to 2.0.

I wanted to create a moving camera, and I realized that I should switch from using SDL_Surfaces to SDL_Textures to use some of 2.0's new features. My previous setup involved blitting a bunch of sprite surfaces to a main surface called buffer, and then flipping that to the screen, and it worked well.

So, I created a renderer and assigned it to the window. Then I used SDL_CreateTextureFromSurface to create a texture from my main SDL_Surface. My surface is currently set to nullptr at this point, and I realize that I should probably initialize it to something, but I can't figure out what. Here is the relevant code.

    void Game::Init() {
// Initialize SDL.
SDL_Init(SDL_INIT_EVERYTHING);

window = nullptr;
buffer = nullptr;
camera = { player.GetLocation().x - 50, player.GetLocation().y - 50, player.GetLocation().x + 50, player.GetLocation().y + 50 };

fullscreen = false;
screenWidth = 640, screenHeight = 480;

if (fullscreen) {
    window = SDL_CreateWindow("Rune", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screenWidth, screenHeight, SDL_WINDOW_FULLSCREEN_DESKTOP);
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
}
else {
    // Initialize our window.
    window = SDL_CreateWindow("Rune", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screenWidth, screenHeight, SDL_WINDOW_SHOWN);
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
    // Assign the buffer surface to the window.

}

texture = SDL_CreateTextureFromSurface(renderer, buffer);
SDL_SetRenderTarget(renderer, texture);

// Run the game loop.
Run();
}

In Run, there's normal working code that involves a game loop, but in the game loop I have a method, Render(), which is causing problems. Here it is.

    void Game::Render() {
// Clear the buffer.
SDL_FillRect(buffer, NULL, 0x000000);


// Draw everything to the buffer.
level.Draw(buffer);
if (enemy.IsAlive()) enemy.Draw(buffer); 
player.Draw(buffer);

SDL_UpdateTexture(texture, NULL, buffer->pixels, buffer->pitch);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);

// Draw buffer to the screen.
//SDL_UpdateWindowSurface(window);
}

Running this code gives me the error that buffer is nullptr, which comes up on the SDL_UpDateTexture line. If I allocate memory for buffer in the Init() function, I get a memory access error. Can anyone offer a solution? Thank you.

1
If you're going to draw from surfaces (which are stored in main memory) every frame, you lose all the benefits of using textures (which are usually stored on the graphics card memory, if available). You should replace all your surfaces with textures, and draw them directly to the renderer (with SDL_RenderCopy), skipping the middle man. - Benjamin Lindley
Thanks for the quick response. So now I pass the renderer by reference to all my draw functions, which call RenderCopy. But now, all I can get is a black screen. It's not frozen or anything, and all the proper functions are being called. - Salami
After some testing I discovered that using CreateTextureFromSurface has left all my textures as nullptrs. Do you know why this would happen? - Salami
And, (I'm sorry for the consecutive posts) now I've figured out that although my renderer does not initialize to NULL, I'm getting an invalid renderer error when I try to use it in CreateTextureFromSurface. - Salami

1 Answers

0
votes

After changing all my SDL_Surfaces to Textures, I realized that in my header file I had been calling constructors that relied on the renderer to have already been initialized, which it wasn't. I set them to blank constructors and then initialized them in the Game.cpp file, after the renderer, and now everything works. Thanks Benjamin for your help!