Implement Texture Atlases
This commit is contained in:
34
assets.cpp
34
assets.cpp
@@ -13,16 +13,32 @@ static constexpr uint8_t FRUITS_DATA[] = {
|
|||||||
#embed "fruits.jpg"
|
#embed "fruits.jpg"
|
||||||
};
|
};
|
||||||
|
|
||||||
void init_assets(flecs::world &world) {
|
SDL_Texture *load_texture(uint8_t const *data, size_t size,
|
||||||
auto *renderer = world.get<SdlHandles>()->renderer;
|
SDL_Renderer *renderer) {
|
||||||
|
auto *iostream = SDL_IOFromConstMem(data, size);
|
||||||
auto *background_iostream =
|
SDL_Texture *texture = IMG_LoadTexture_IO(renderer, iostream, false);
|
||||||
SDL_IOFromConstMem(BACKGROUND_DATA, sizeof(BACKGROUND_DATA));
|
if (texture == nullptr) {
|
||||||
SDL_Texture *background =
|
|
||||||
IMG_LoadTexture_IO(renderer, background_iostream, false);
|
|
||||||
if (background == nullptr) {
|
|
||||||
spdlog::error("Failed to load SDL texture!\nCause: {}", SDL_GetError());
|
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}});
|
||||||
}
|
}
|
||||||
|
|||||||
18
assets.hpp
18
assets.hpp
@@ -3,9 +3,21 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <flecs.h>
|
#include <flecs.h>
|
||||||
|
|
||||||
struct SpriteAssets {
|
struct TextureAtlasLayout {
|
||||||
SDL_Texture *background;
|
uint16_t width;
|
||||||
SDL_Texture *fruits;
|
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);
|
void init_assets(flecs::world &world);
|
||||||
|
|||||||
42
main.cpp
42
main.cpp
@@ -1,6 +1,7 @@
|
|||||||
#include "assets.hpp"
|
#include "assets.hpp"
|
||||||
#include "sdl_types.hpp"
|
|
||||||
#include "input.hpp"
|
#include "input.hpp"
|
||||||
|
#include "sdl_types.hpp"
|
||||||
|
#include "sprite.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <SDL3/SDL_error.h>
|
#include <SDL3/SDL_error.h>
|
||||||
@@ -43,6 +44,42 @@ int main() {
|
|||||||
world.set<ButtonInput>(ButtonInput{});
|
world.set<ButtonInput>(ButtonInput{});
|
||||||
world.set<SdlHandles>(SdlHandles{.window = window, .renderer = renderer});
|
world.set<SdlHandles>(SdlHandles{.window = window, .renderer = renderer});
|
||||||
init_assets(world);
|
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;
|
bool exit_gameloop = false;
|
||||||
while (!exit_gameloop) {
|
while (!exit_gameloop) {
|
||||||
@@ -84,8 +121,9 @@ int main() {
|
|||||||
|
|
||||||
// Render
|
// Render
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
SDL_RenderTexture(renderer, world.get<SpriteAssets>()->background, nullptr,
|
SDL_RenderTexture(renderer, texture_assets->background.sdl_texture, nullptr,
|
||||||
nullptr);
|
nullptr);
|
||||||
|
world.progress();
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
sprite.hpp
Normal file
12
sprite.hpp
Normal 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;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user