Exploring raycasters and possibly make a little "doom like" game based on it.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
raycaster/textures.cpp

108 lines
3.1 KiB

#include "textures.hpp"
#include <SFML/Graphics/Image.hpp>
#include "dbc.hpp"
#include <fmt/core.h>
#include "config.hpp"
#include "constants.hpp"
#include <memory>
namespace textures {
using std::shared_ptr, std::make_shared;
static TextureManager TMGR;
static bool initialized = false;
void load_sprites() {
Config assets("assets/config.json");
for(auto& [name, settings] : assets["sprites"].items()) {
auto texture = make_shared<sf::Texture>(settings["path"]);
texture->setSmooth(assets["graphics"]["smooth_textures"]);
auto sprite = make_shared<sf::Sprite>(*texture);
int width = settings["frame_width"];
int height = settings["frame_height"];
sprite->setTextureRect({{0,0}, {width, height}});
TMGR.sprite_textures.try_emplace(name, sprite, texture);
}
}
void load_tiles() {
Config assets("assets/tiles.json");
auto &tiles = assets.json();
TMGR.surfaces.resize(tiles.size());
TMGR.ceilings.resize(tiles.size());
TMGR.map_tile_set.resize(tiles.size());
for(auto &el : tiles.items()) {
auto &config = el.value();
const std::string& texture_fname = config["texture"];
size_t surface_i = config["id"];
if(surface_i >= tiles.size()) {
TMGR.surfaces.resize(surface_i + 1);
TMGR.ceilings.resize(surface_i + 1);
TMGR.map_tile_set.resize(surface_i + 1);
}
TMGR.map_tile_set[surface_i] = config["display"];
TMGR.surfaces[surface_i] = load_image(texture_fname);
// NOTE: ceilings defaults to 0 which is floor texture so only need to update
if(config.contains("ceiling")) {
const std::string& name = config["ceiling"];
dbc::check(tiles.contains(name), fmt::format("invalid ceiling name {} in tile config {}", name, (std::string)el.key()));
auto& ceiling = tiles[name];
TMGR.ceilings[surface_i] = ceiling["id"];
}
}
}
void init() {
if(!initialized) {
load_tiles();
load_sprites();
initialized = true;
}
}
SpriteTexture get(const std::string& name) {
dbc::check(initialized, "you forgot to call textures::init()");
dbc::check(TMGR.sprite_textures.contains(name),
fmt::format("!!!!! texture pack does not contain {} sprite", name));
auto result = TMGR.sprite_textures.at(name);
dbc::check(result.sprite != nullptr,
fmt::format("bad sprite from textures::get named {}", name));
dbc::check(result.texture != nullptr,
fmt::format("bad texture from textures::get named {}", name));
return result;
}
sf::Image load_image(const std::string& filename) {
sf::Image texture;
bool good = texture.loadFromFile(filename);
dbc::check(good, fmt::format("failed to load {}", filename));
return texture;
}
std::vector<wchar_t>& get_map_tile_set() {
return TMGR.map_tile_set;
}
const uint32_t* get_surface(size_t num) {
return (const uint32_t *)TMGR.surfaces[num].getPixelsPtr();
}
const uint32_t* get_ceiling(size_t num) {
size_t ceiling_num = TMGR.ceilings[num];
return (const uint32_t *)TMGR.surfaces[ceiling_num].getPixelsPtr();
}
};