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:
Zed A. Shaw 2025-02-04 22:52:04 -05:00
parent d6c09e111d
commit d0badedbd9
5 changed files with 25 additions and 74 deletions

View file

@ -32,12 +32,11 @@ inline uint32_t dumb_lighting(uint32_t pixel, double distance) {
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),
$view_texture({(unsigned int)width, (unsigned int)height}),
$view_sprite($view_texture),
$width(width), $height(height),
$window(window),
ZBuffer(width),
$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);
}
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) {
$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() {
$view_texture.update((uint8_t *)$pixels.get(), {(unsigned int)$width, (unsigned int)$height}, {0, 0});
$window.draw($view_sprite, $active_shader);
}
void Raycaster::clear() {
std::fill_n($pixels.get(), $width * $height, 0);
$window.clear();
}
void Raycaster::sprite_casting() {
void Raycaster::sprite_casting(sf::RenderTarget &target) {
const int textureWidth = TEXTURE_WIDTH;
const int textureHeight = TEXTURE_HEIGHT;
const int halfHeight = TEXTURE_HEIGHT / 2;
// 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
for(auto& rec : sprite_order) {
Sprite& sprite_rec = $sprites[rec.second];
const Sprite& sprite_rec = $sprites.at(rec.second);
// TODO: this must die
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);
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();
cast_rays();
draw_pixel_buffer();
sprite_casting();
}
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;
target.draw($view_sprite);
sprite_casting(target);
}
void Raycaster::set_level(GameLevel level) {
$level = level;
auto& tiles = $level.map->tiles();
$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);
}
}