Hello,
I am following LazyFoo’s tutorial on using textures, as far as I can see my setup is correct, but the loaded texture only shows for like one frame when I close the window, and not the whole time the window is open.
I’m using macOS Tahoe 26.3, SDL3, screen resolution 2560x1440 144hz.
This the my main.cpp:
#include <print>
#include <SDL3/SDL.h>
#include "main.h"
#include "texture.h"
constexpr int screenWidth {1024};
constexpr int screenHeight {768};
constexpr int renderWidth {320};
constexpr int renderHeight {180};
auto title = "First Game";
SDL_Window *window {nullptr};
SDL_Renderer *renderer {nullptr};
Texture texture;
void close() {
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
window = nullptr;
renderer = nullptr;
SDL_Quit();
}
int main() {
if (!SDL_Init(SDL_INIT_VIDEO)) {
std::println("SDL could not initialize! SDL Error: {}", SDL_GetError());
return 1;
}
if (!SDL_CreateWindowAndRenderer(title, screenWidth, screenHeight, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
std::println("Failed to create window and renderer! SDL_Error: {}", SDL_GetError());
return 1;
}
// Scale the window resolution to a render resolution of 320x180
if (!SDL_SetRenderLogicalPresentation(renderer, renderWidth, renderHeight, SDL_LOGICAL_PRESENTATION_LETTERBOX)) {
std::println("Setting Render logical presentation failed! SDL_Error: {}\n", SDL_GetError());
return 1;
}
if (!SDL_SetRenderVSync(renderer, 1)) { // 0 disabled, 1 enabled
std::println("Could not set VSYNC! SDL_Error: {}", SDL_GetError());
return 1;
}
if (!texture.loadFromFile(*renderer, "../../images/loaded.png")) {
std::println("Failed to load media! SDL Error: {}", SDL_GetError());
return 1;
}
bool quit {false};
SDL_Event event;
SDL_zero(event);
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_EVENT_QUIT)
quit = true;
}
}
SDL_SetRenderTarget(renderer, nullptr);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); // white
SDL_RenderClear(renderer);
texture.render(*renderer ,0.f, 0.f);
SDL_RenderPresent(renderer); // only call once per frame
close();
return 0;
}
texture.cpp:
#include "texture.h"
#include <print>
#include "SDL3_image/SDL_image.h"
Texture::Texture()
: mTexture{nullptr}, mWidth{0}, mHeight{0}
{}
Texture::~Texture() {
destroy();
}
bool Texture::loadFromFile(SDL_Renderer& renderer, const std::string& path) {
destroy();
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
if (loadedSurface == nullptr)
{
std::println("Could not load surface '{}'", SDL_GetError());
return false;
}
if (mTexture = SDL_CreateTextureFromSurface(&renderer, loadedSurface); mTexture == nullptr) {
std::println("Could not create texture from surface '{}'", SDL_GetError());
return false;
}
mWidth = loadedSurface->w;
mHeight = loadedSurface->h;
SDL_DestroySurface(loadedSurface);
return mTexture;
}
void Texture::destroy() {
SDL_DestroyTexture(mTexture);
mTexture = nullptr;
mWidth = 0;
mHeight = 0;
}
void Texture::render(SDL_Renderer& renderer, float x, float y) const {
SDL_FRect dstRect{x, y, static_cast<float>(mWidth), static_cast<float>(mHeight)};
SDL_RenderTexture(&renderer, mTexture, nullptr, &dstRect);
}
int Texture::getWidth() const {
return mWidth;
}
int Texture::getHeight() const {
return mHeight;
}
bool Texture::isLoaded() const {
return mTexture != nullptr;
}
Setting Vsync to 0 or 1 in the Init phase does not seem to make a difference either.
Using SDL_SetRenderTarget(renderer, nullptr); or not also didn’t make a difference.
Does anyone know what could cause this?
Thanks in advance for any insights!
