Implement Texture Atlases

This commit is contained in:
2025-05-24 21:18:48 +02:00
parent 7fc0c47c69
commit dd287dc667
4 changed files with 92 additions and 14 deletions

View File

@@ -13,16 +13,32 @@ static constexpr uint8_t FRUITS_DATA[] = {
#embed "fruits.jpg"
};
void init_assets(flecs::world &world) {
auto *renderer = world.get<SdlHandles>()->renderer;
auto *background_iostream =
SDL_IOFromConstMem(BACKGROUND_DATA, sizeof(BACKGROUND_DATA));
SDL_Texture *background =
IMG_LoadTexture_IO(renderer, background_iostream, false);
if (background == nullptr) {
SDL_Texture *load_texture(uint8_t const *data, size_t size,
SDL_Renderer *renderer) {
auto *iostream = SDL_IOFromConstMem(data, size);
SDL_Texture *texture = IMG_LoadTexture_IO(renderer, iostream, false);
if (texture == nullptr) {
spdlog::error("Failed to load SDL texture!\nCause: {}", SDL_GetError());
}
world.set<SpriteAssets>(SpriteAssets{.background = background});
return texture;
}
void init_assets(flecs::world &world) {
auto *renderer = world.get<SdlHandles>()->renderer;
auto *background =
load_texture(BACKGROUND_DATA, sizeof(BACKGROUND_DATA), renderer);
TextureAtlasLayout background_layout = {
.width = 866, .height = 510, .rows = 1, .columns = 1};
auto *fruits = load_texture(FRUITS_DATA, sizeof(FRUITS_DATA), renderer);
TextureAtlasLayout fruits_layout = {
.width = 16, .height = 16, .rows = 6, .columns = 38};
world.set<TextureAssets>(TextureAssets{
.background = Texture{.sdl_texture = background,
.texture_atlas_layout = background_layout},
.fruits = Texture{.sdl_texture = fruits,
.texture_atlas_layout = fruits_layout}});
}

View File

@@ -3,9 +3,21 @@
#include <SDL3/SDL.h>
#include <flecs.h>
struct SpriteAssets {
SDL_Texture *background;
SDL_Texture *fruits;
struct TextureAtlasLayout {
uint16_t width;
uint16_t height;
uint8_t rows;
uint8_t columns;
};
struct Texture {
SDL_Texture *sdl_texture;
TextureAtlasLayout texture_atlas_layout;
};
struct TextureAssets {
Texture background;
Texture fruits;
};
void init_assets(flecs::world &world);

View File

@@ -1,6 +1,7 @@
#include "assets.hpp"
#include "sdl_types.hpp"
#include "input.hpp"
#include "sdl_types.hpp"
#include "sprite.hpp"
#include <SDL3/SDL.h>
#include <SDL3/SDL_error.h>
@@ -43,6 +44,42 @@ int main() {
world.set<ButtonInput>(ButtonInput{});
world.set<SdlHandles>(SdlHandles{.window = window, .renderer = renderer});
init_assets(world);
auto *texture_assets = world.get<TextureAssets>();
world.entity("Sprite1")
.set<Position>(Position{.x = 0, .y = 0})
.set<Sprite>(
Sprite{.texture = &texture_assets->fruits, .texture_atlas_index = 0});
world.entity("Sprite2")
.set<Position>(Position{.x = 32, .y = 32})
.set<Sprite>(
Sprite{.texture = &texture_assets->fruits, .texture_atlas_index = 5});
flecs::system sys =
world
.system<SdlHandles const, Position const, Sprite const>(
"RenderSprites")
.term_at(0)
.singleton()
.each([](flecs::entity e, SdlHandles const &sdl_handles,
Position const &pos, Sprite const &sprite) {
TextureAtlasLayout layout = sprite.texture->texture_atlas_layout;
uint8_t row = sprite.texture_atlas_index / layout.columns;
uint8_t column = sprite.texture_atlas_index % layout.columns;
SDL_FRect srcrect{static_cast<float>(column * layout.width),
static_cast<float>(row * layout.height),
static_cast<float>(layout.width),
static_cast<float>(layout.height)};
SDL_FRect dstrect{static_cast<float>(pos.x),
static_cast<float>(pos.y),
static_cast<float>(layout.width),
static_cast<float>(layout.height)};
SDL_RenderTexture(sdl_handles.renderer, sprite.texture->sdl_texture,
&srcrect, &dstrect);
});
bool exit_gameloop = false;
while (!exit_gameloop) {
@@ -84,8 +121,9 @@ int main() {
// Render
SDL_RenderClear(renderer);
SDL_RenderTexture(renderer, world.get<SpriteAssets>()->background, nullptr,
SDL_RenderTexture(renderer, texture_assets->background.sdl_texture, nullptr,
nullptr);
world.progress();
SDL_RenderPresent(renderer);
}

12
sprite.hpp Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include "assets.hpp"
#include <SDL3/SDL.h>
#include <cstdint>
#include <optional>
struct Sprite {
Texture const *texture;
uint16_t texture_atlas_index;
};