Now I can attach arbitrary shaders to sprites based on things that happen in the world.
This commit is contained in:
parent
bec8fe0a13
commit
787be78a69
6 changed files with 53 additions and 16 deletions
|
@ -4,6 +4,7 @@
|
||||||
#include "dinkyecs.hpp"
|
#include "dinkyecs.hpp"
|
||||||
#include "point.hpp"
|
#include "point.hpp"
|
||||||
#include <SFML/Graphics/Rect.hpp>
|
#include <SFML/Graphics/Rect.hpp>
|
||||||
|
#include <SFML/Graphics/Shader.hpp>
|
||||||
#include <SFML/System/Vector2.hpp>
|
#include <SFML/System/Vector2.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -15,6 +16,11 @@
|
||||||
namespace components {
|
namespace components {
|
||||||
using namespace nlohmann;
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
struct SpriteEffect {
|
||||||
|
int frames;
|
||||||
|
std::shared_ptr<sf::Shader> effect;
|
||||||
|
};
|
||||||
|
|
||||||
struct Position {
|
struct Position {
|
||||||
Point location;
|
Point location;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <numbers>
|
#include <numbers>
|
||||||
#include "components.hpp"
|
#include "components.hpp"
|
||||||
#include "textures.hpp"
|
#include "textures.hpp"
|
||||||
|
#include "systems.hpp"
|
||||||
|
|
||||||
using namespace fmt;
|
using namespace fmt;
|
||||||
using std::make_unique;
|
using std::make_unique;
|
||||||
|
@ -180,10 +181,9 @@ void Raycaster::sprite_casting(sf::RenderTarget &target) {
|
||||||
// float level = sqrt(rec.first);
|
// float level = sqrt(rec.first);
|
||||||
float level = lights[sprite_pos.location.y][sprite_pos.location.x] * PERCENT;
|
float level = lights[sprite_pos.location.y][sprite_pos.location.x] * PERCENT;
|
||||||
|
|
||||||
shared_ptr<sf::Shader> effect = nullptr;
|
shared_ptr<sf::Shader> effect = System::sprite_effect($level, rec.second);
|
||||||
|
|
||||||
if(rec.second == aiming_at) {
|
if(effect) {
|
||||||
effect = $flame;
|
|
||||||
apply_sprite_effect(effect, sprite_width, sprite_height);
|
apply_sprite_effect(effect, sprite_width, sprite_height);
|
||||||
} else {
|
} else {
|
||||||
effect = $brightness;
|
effect = $brightness;
|
||||||
|
@ -411,7 +411,4 @@ void Raycaster::update_level(GameLevel level) {
|
||||||
|
|
||||||
void Raycaster::init_shaders() {
|
void Raycaster::init_shaders() {
|
||||||
$brightness = shaders::get("rayview_sprites");
|
$brightness = shaders::get("rayview_sprites");
|
||||||
$brightness->setUniform("source", sf::Shader::CurrentTexture);
|
|
||||||
$flame = shaders::get("flame");
|
|
||||||
$flame->setUniform("source", sf::Shader::CurrentTexture);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ struct Raycaster {
|
||||||
int $pitch=0;
|
int $pitch=0;
|
||||||
sf::Clock $clock;
|
sf::Clock $clock;
|
||||||
std::shared_ptr<sf::Shader> $brightness = nullptr;
|
std::shared_ptr<sf::Shader> $brightness = nullptr;
|
||||||
std::shared_ptr<sf::Shader> $flame = nullptr;
|
|
||||||
double $pos_x = 0;
|
double $pos_x = 0;
|
||||||
double $pos_y = 0;
|
double $pos_y = 0;
|
||||||
|
|
||||||
|
|
20
shaders.cpp
20
shaders.cpp
|
@ -7,17 +7,25 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace shaders {
|
namespace shaders {
|
||||||
using std::shared_ptr, std::make_shared;
|
using std::shared_ptr, std::make_shared;
|
||||||
|
|
||||||
static ShaderManager SMGR;
|
static ShaderManager SMGR;
|
||||||
static bool INITIALIZED = false;
|
static bool INITIALIZED = false;
|
||||||
static int VERSION = 0;
|
static int VERSION = 0;
|
||||||
|
|
||||||
bool load_shader(std::string name, nlohmann::json& settings) {
|
inline void configure_shader_defaults(std::shared_ptr<sf::Shader> ptr) {
|
||||||
|
ptr->setUniform("source", sf::Shader::CurrentTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool load_shader(std::string name, nlohmann::json& settings) {
|
||||||
std::string file_name = settings["file_name"];
|
std::string file_name = settings["file_name"];
|
||||||
auto ptr = std::make_shared<sf::Shader>();
|
auto ptr = std::make_shared<sf::Shader>();
|
||||||
bool good = ptr->loadFromFile(file_name, sf::Shader::Type::Fragment);
|
bool good = ptr->loadFromFile(file_name, sf::Shader::Type::Fragment);
|
||||||
if(good) SMGR.shaders.try_emplace(name, name, file_name, ptr);
|
|
||||||
|
if(good) {
|
||||||
|
configure_shader_defaults(ptr);
|
||||||
|
SMGR.shaders.try_emplace(name, name, file_name, ptr);
|
||||||
|
}
|
||||||
return good;
|
return good;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
24
systems.cpp
24
systems.cpp
|
@ -15,6 +15,7 @@
|
||||||
#include "rituals.hpp"
|
#include "rituals.hpp"
|
||||||
#include "battle.hpp"
|
#include "battle.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "shaders.hpp"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using namespace fmt;
|
using namespace fmt;
|
||||||
|
@ -176,6 +177,7 @@ void System::death(GameLevel &level, components::ComponentMap& components) {
|
||||||
world.remove<Personality>(ent);
|
world.remove<Personality>(ent);
|
||||||
world.remove<ai::EntityAI>(ent);
|
world.remove<ai::EntityAI>(ent);
|
||||||
world.remove<Animation>(ent);
|
world.remove<Animation>(ent);
|
||||||
|
world.remove<SpriteEffect>(ent);
|
||||||
|
|
||||||
if(auto snd = world.get_if<Sound>(ent)) {
|
if(auto snd = world.get_if<Sound>(ent)) {
|
||||||
sound::stop(snd->attack);
|
sound::stop(snd->attack);
|
||||||
|
@ -235,6 +237,11 @@ void System::combat(GameLevel &level) {
|
||||||
player_combat.attack(enemy.combat), 0
|
player_combat.attack(enemy.combat), 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if(result.player_did > 0) {
|
||||||
|
auto effect = shaders::get("flame");
|
||||||
|
world.set<SpriteEffect>(enemy.entity, {100, effect});
|
||||||
|
}
|
||||||
|
|
||||||
if(enemy.ai.wants_to("kill_enemy")) {
|
if(enemy.ai.wants_to("kill_enemy")) {
|
||||||
result.enemy_did = enemy.combat.attack(player_combat);
|
result.enemy_did = enemy.combat.attack(player_combat);
|
||||||
animate_entity(world, enemy.entity);
|
animate_entity(world, enemy.entity);
|
||||||
|
@ -390,3 +397,20 @@ std::wstring System::draw_map(GameLevel level, size_t view_x, size_t view_y, int
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<sf::Shader> System::sprite_effect(GameLevel &level, DinkyECS::Entity entity) {
|
||||||
|
if(level.world->has<SpriteEffect>(entity)) {
|
||||||
|
auto& se = level.world->get<SpriteEffect>(entity);
|
||||||
|
|
||||||
|
if(se.frames > 0) {
|
||||||
|
se.frames--;
|
||||||
|
return se.effect;
|
||||||
|
} else {
|
||||||
|
level.world->remove<SpriteEffect>(entity);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,4 +21,7 @@ namespace System {
|
||||||
|
|
||||||
void enemy_ai(GameLevel &level);
|
void enemy_ai(GameLevel &level);
|
||||||
void combat(GameLevel &level);
|
void combat(GameLevel &level);
|
||||||
|
|
||||||
|
std::shared_ptr<sf::Shader> sprite_effect(GameLevel &level, DinkyECS::Entity entity);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue