More cleanup of the raycaster, finally removed the window as a dependency but I went against making it an sf::Drawable since that had a lot of code quality problems.
This commit is contained in:
parent
d6c09e111d
commit
d0badedbd9
5 changed files with 25 additions and 74 deletions
13
gui.cpp
13
gui.cpp
|
@ -13,7 +13,7 @@ namespace gui {
|
||||||
$window(sf::VideoMode({SCREEN_WIDTH, SCREEN_HEIGHT}), "Zed's Raycaster Thing"),
|
$window(sf::VideoMode({SCREEN_WIDTH, SCREEN_HEIGHT}), "Zed's Raycaster Thing"),
|
||||||
$font{"./assets/text.otf"},
|
$font{"./assets/text.otf"},
|
||||||
$text{$font},
|
$text{$font},
|
||||||
$rayview($window, $textures, RAY_VIEW_WIDTH, RAY_VIEW_HEIGHT)
|
$rayview($textures, RAY_VIEW_WIDTH, RAY_VIEW_HEIGHT)
|
||||||
{
|
{
|
||||||
$window.setVerticalSyncEnabled(VSYNC);
|
$window.setVerticalSyncEnabled(VSYNC);
|
||||||
$window.setFramerateLimit(FRAME_LIMIT);
|
$window.setFramerateLimit(FRAME_LIMIT);
|
||||||
|
@ -21,7 +21,6 @@ namespace gui {
|
||||||
$text.setPosition({10,10});
|
$text.setPosition({10,10});
|
||||||
$textures.load_tiles();
|
$textures.load_tiles();
|
||||||
$textures.load_sprites();
|
$textures.load_sprites();
|
||||||
$rayview.init_shaders();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSM::event(Event ev) {
|
void FSM::event(Event ev) {
|
||||||
|
@ -132,13 +131,6 @@ namespace gui {
|
||||||
case KEY::R:
|
case KEY::R:
|
||||||
$stats.reset();
|
$stats.reset();
|
||||||
break;
|
break;
|
||||||
case KEY::P:
|
|
||||||
if($rayview.$active_shader == nullptr) {
|
|
||||||
$rayview.$active_shader = &$rayview.$paused;
|
|
||||||
} else {
|
|
||||||
$rayview.$active_shader = nullptr;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break; // ignored
|
break; // ignored
|
||||||
}
|
}
|
||||||
|
@ -182,7 +174,7 @@ namespace gui {
|
||||||
|
|
||||||
void FSM::render() {
|
void FSM::render() {
|
||||||
auto start = std::chrono::high_resolution_clock::now();
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
$rayview.render();
|
$rayview.draw($window);
|
||||||
auto end = std::chrono::high_resolution_clock::now();
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
auto elapsed = std::chrono::duration<double>(end - start);
|
auto elapsed = std::chrono::duration<double>(end - start);
|
||||||
$stats.sample(1/elapsed.count());
|
$stats.sample(1/elapsed.count());
|
||||||
|
@ -194,7 +186,6 @@ namespace gui {
|
||||||
|
|
||||||
void FSM::mouse() {
|
void FSM::mouse() {
|
||||||
if(sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
|
if(sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
|
||||||
$rayview.$anim.play(false);
|
|
||||||
$rotation = -30.0f;
|
$rotation = -30.0f;
|
||||||
} else {
|
} else {
|
||||||
$rotation = -10.0f;
|
$rotation = -10.0f;
|
||||||
|
|
|
@ -32,12 +32,11 @@ inline uint32_t dumb_lighting(uint32_t pixel, double distance) {
|
||||||
return conv.as_int;
|
return conv.as_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
Raycaster::Raycaster(sf::RenderWindow& window, TexturePack &textures, int width, int height) :
|
Raycaster::Raycaster(TexturePack &textures, int width, int height) :
|
||||||
$textures(textures),
|
$textures(textures),
|
||||||
$view_texture({(unsigned int)width, (unsigned int)height}),
|
$view_texture({(unsigned int)width, (unsigned int)height}),
|
||||||
$view_sprite($view_texture),
|
$view_sprite($view_texture),
|
||||||
$width(width), $height(height),
|
$width(width), $height(height),
|
||||||
$window(window),
|
|
||||||
ZBuffer(width),
|
ZBuffer(width),
|
||||||
$anim(256, 256, 10, "assets/monster-1.ogg")
|
$anim(256, 256, 10, "assets/monster-1.ogg")
|
||||||
{
|
{
|
||||||
|
@ -46,13 +45,6 @@ Raycaster::Raycaster(sf::RenderWindow& window, TexturePack &textures, int width,
|
||||||
$view_texture.setSmooth(false);
|
$view_texture.setSmooth(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Raycaster::init_shaders() {
|
|
||||||
bool good = $paused.loadFromFile("shaders/modal.frag", sf::Shader::Type::Fragment);
|
|
||||||
dbc::check(good, "shader could not be loaded");
|
|
||||||
$paused.setUniform("offsetFactor", sf::Glsl::Vec2{0.01f, 0.01f});
|
|
||||||
$paused.setUniform("darkness", 0.01f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Raycaster::set_position(int x, int y) {
|
void Raycaster::set_position(int x, int y) {
|
||||||
$view_sprite.setPosition({(float)x, (float)y});
|
$view_sprite.setPosition({(float)x, (float)y});
|
||||||
}
|
}
|
||||||
|
@ -65,25 +57,19 @@ void Raycaster::position_camera(float player_x, float player_y) {
|
||||||
|
|
||||||
void Raycaster::draw_pixel_buffer() {
|
void Raycaster::draw_pixel_buffer() {
|
||||||
$view_texture.update((uint8_t *)$pixels.get(), {(unsigned int)$width, (unsigned int)$height}, {0, 0});
|
$view_texture.update((uint8_t *)$pixels.get(), {(unsigned int)$width, (unsigned int)$height}, {0, 0});
|
||||||
$window.draw($view_sprite, $active_shader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Raycaster::clear() {
|
void Raycaster::sprite_casting(sf::RenderTarget &target) {
|
||||||
std::fill_n($pixels.get(), $width * $height, 0);
|
|
||||||
$window.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Raycaster::sprite_casting() {
|
|
||||||
const int textureWidth = TEXTURE_WIDTH;
|
const int textureWidth = TEXTURE_WIDTH;
|
||||||
const int textureHeight = TEXTURE_HEIGHT;
|
const int textureHeight = TEXTURE_HEIGHT;
|
||||||
const int halfHeight = TEXTURE_HEIGHT / 2;
|
const int halfHeight = TEXTURE_HEIGHT / 2;
|
||||||
|
|
||||||
// sort sprites from far to close
|
// sort sprites from far to close
|
||||||
auto sprite_order = $collision.distance_sorted({(size_t)$posX, (size_t)$posY});
|
auto sprite_order = $level.collision->distance_sorted({(size_t)$posX, (size_t)$posY});
|
||||||
|
|
||||||
// after sorting the sprites, do the projection
|
// after sorting the sprites, do the projection
|
||||||
for(auto& rec : sprite_order) {
|
for(auto& rec : sprite_order) {
|
||||||
Sprite& sprite_rec = $sprites[rec.second];
|
const Sprite& sprite_rec = $sprites.at(rec.second);
|
||||||
// TODO: this must die
|
// TODO: this must die
|
||||||
auto sf_sprite = sprite_rec.sprite.sprite;
|
auto sf_sprite = sprite_rec.sprite.sprite;
|
||||||
|
|
||||||
|
@ -148,7 +134,7 @@ void Raycaster::sprite_casting() {
|
||||||
$anim.step(*sf_sprite, texX, texY, texX_end - texX, textureHeight);
|
$anim.step(*sf_sprite, texX, texY, texX_end - texX, textureHeight);
|
||||||
sf_sprite->setPosition({x, y});
|
sf_sprite->setPosition({x, y});
|
||||||
|
|
||||||
$window.draw(*sf_sprite, $active_shader);
|
target.draw(*sf_sprite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -333,32 +319,22 @@ void Raycaster::draw_ceiling_floor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Raycaster::render() {
|
void Raycaster::draw(sf::RenderTarget& target) {
|
||||||
draw_ceiling_floor();
|
draw_ceiling_floor();
|
||||||
cast_rays();
|
cast_rays();
|
||||||
draw_pixel_buffer();
|
draw_pixel_buffer();
|
||||||
sprite_casting();
|
target.draw($view_sprite);
|
||||||
}
|
sprite_casting(target);
|
||||||
|
|
||||||
bool Raycaster::empty_space(int new_x, int new_y) {
|
|
||||||
dbc::check((size_t)new_x < matrix::width($map),
|
|
||||||
format("x={} too wide={}", new_x, matrix::width($map)));
|
|
||||||
dbc::check((size_t)new_y < matrix::height($map),
|
|
||||||
format("y={} too high={}", new_y, matrix::height($map)));
|
|
||||||
|
|
||||||
return $map[new_y][new_x] == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DinkyECS::Entity Raycaster::position_sprite(Point pos, string name) {
|
|
||||||
auto sprite_txt = $textures.sprite_textures[name];
|
|
||||||
$sprites.emplace_back(pos.x + 0.5, pos.y + 0.5, sprite_txt);
|
|
||||||
DinkyECS::Entity ent = $sprites.size() - 1;
|
|
||||||
$collision.insert({pos.x, pos.y}, ent);
|
|
||||||
return ent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Raycaster::set_level(GameLevel level) {
|
void Raycaster::set_level(GameLevel level) {
|
||||||
$level = level;
|
$level = level;
|
||||||
auto& tiles = $level.map->tiles();
|
auto& tiles = $level.map->tiles();
|
||||||
$map = $textures.convert_char_to_texture(tiles.$tile_ids);
|
$map = $textures.convert_char_to_texture(tiles.$tile_ids);
|
||||||
|
|
||||||
|
// this will need to go away too but for now everything is evil eye
|
||||||
|
for(auto &thing : $level.collision->table) {
|
||||||
|
auto sprite_txt = $textures.sprite_textures.at("evil_eye");
|
||||||
|
$sprites.try_emplace(thing.second, thing.first.x + 0.5, thing.first.y + 0.5, sprite_txt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,42 +32,26 @@ struct Raycaster {
|
||||||
|
|
||||||
int $width;
|
int $width;
|
||||||
int $height;
|
int $height;
|
||||||
sf::RenderWindow& $window;
|
|
||||||
GameLevel $level;
|
GameLevel $level;
|
||||||
Matrix $map;
|
Matrix $map;
|
||||||
SpatialMap $collision;
|
std::unordered_map<DinkyECS::Entity, Sprite> $sprites;
|
||||||
std::vector<Sprite> $sprites;
|
|
||||||
std::vector<double> ZBuffer; // width
|
std::vector<double> ZBuffer; // width
|
||||||
Animator $anim;
|
Animator $anim;
|
||||||
sf::Shader $paused;
|
|
||||||
sf::Shader* $active_shader = nullptr;
|
|
||||||
|
|
||||||
Raycaster(sf::RenderWindow& window, TexturePack &textures, int width, int height);
|
Raycaster(TexturePack &textures, int width, int height);
|
||||||
|
|
||||||
void draw_pixel_buffer();
|
|
||||||
void clear();
|
|
||||||
void cast_rays();
|
void cast_rays();
|
||||||
void draw_ceiling_floor();
|
void draw_ceiling_floor();
|
||||||
void sprite_casting();
|
void draw_pixel_buffer();
|
||||||
|
void sprite_casting(sf::RenderTarget& target);
|
||||||
|
void draw(sf::RenderTarget& target);
|
||||||
|
|
||||||
void sort_sprites(std::vector<int>& order, std::vector<double>& dist, int amount);
|
void sort_sprites(std::vector<int>& order, std::vector<double>& dist, int amount);
|
||||||
void render();
|
|
||||||
|
|
||||||
bool empty_space(int new_x, int new_y);
|
|
||||||
void position_camera(float player_x, float player_y);
|
void position_camera(float player_x, float player_y);
|
||||||
|
|
||||||
void set_position(int x, int y);
|
void set_position(int x, int y);
|
||||||
void init_shaders();
|
|
||||||
DinkyECS::Entity position_sprite(Point pos, string name);
|
|
||||||
|
|
||||||
inline size_t pixcoord(int x, int y) {
|
inline size_t pixcoord(int x, int y) {
|
||||||
if(!(x >=0 && x < $width)) {
|
|
||||||
dbc::sentinel(fmt::format("pixcoord x={} but $width={}", x, $width));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!(y >= 0 && y < $height)) {
|
|
||||||
dbc::sentinel(fmt::format("pixcoord y={} but $height={}", y, $height));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((y) * $width) + (x);
|
return ((y) * $width) + (x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ SortedEntities SpatialMap::distance_sorted(Point from) {
|
||||||
sprite_distance.push_back({inside, rec.second});
|
sprite_distance.push_back({inside, rec.second});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(sprite_distance.begin(), sprite_distance.end());
|
std::sort(sprite_distance.begin(), sprite_distance.end(), std::greater<>());
|
||||||
|
|
||||||
return sprite_distance;
|
return sprite_distance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,10 +154,10 @@ TEST_CASE("confirm can iterate through all", "[spatialmap-sort]") {
|
||||||
|
|
||||||
auto sprite_distance = collider.distance_sorted(player);
|
auto sprite_distance = collider.distance_sorted(player);
|
||||||
|
|
||||||
int prev_dist = 0;
|
int prev_dist = sprite_distance[0].first;
|
||||||
|
|
||||||
for(auto dist : sprite_distance) {
|
for(auto dist : sprite_distance) {
|
||||||
REQUIRE(prev_dist <= dist.first);
|
REQUIRE(prev_dist >= dist.first);
|
||||||
prev_dist = dist.first;
|
prev_dist = dist.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue