diff --git a/assets/undead_peasant-256.png b/assets/undead_peasant-256.png index 5aa90ab..10fc965 100644 Binary files a/assets/undead_peasant-256.png and b/assets/undead_peasant-256.png differ diff --git a/constants.hpp b/constants.hpp index 45fd7db..6c2b429 100644 --- a/constants.hpp +++ b/constants.hpp @@ -1,5 +1,7 @@ #pragma once +constexpr const int TEXTURE_WIDTH=256; +constexpr const int TEXTURE_HEIGHT=256; constexpr const int RAY_VIEW_WIDTH=960; constexpr const int RAY_VIEW_HEIGHT=720; constexpr const int RAY_VIEW_X=(1280 - RAY_VIEW_WIDTH); diff --git a/main.cpp b/main.cpp index 77e9bc4..e3d81ba 100644 --- a/main.cpp +++ b/main.cpp @@ -67,7 +67,6 @@ int main() { auto elapsed = std::chrono::duration(end - start); stats.sample(1/elapsed.count()); - draw_gui(window, text, stats); window.display(); diff --git a/raycaster.cpp b/raycaster.cpp index 85c1efe..7e43fb8 100644 --- a/raycaster.cpp +++ b/raycaster.cpp @@ -17,7 +17,7 @@ union ColorConv { }; inline uint32_t dumb_lighting(uint32_t pixel, double distance) { - if(distance < 1) return pixel; + if(distance < 1.0) return pixel; ColorConv conv{.as_int=pixel}; conv.as_color.r /= distance; @@ -84,7 +84,8 @@ void Raycaster::sprite_casting() { for(int i = 0; i < $textures.NUM_SPRITES; i++) { int sprite_index = spriteOrder[i]; Sprite& sprite_rec = $textures.get_sprite(sprite_index); - auto& sprite_texture = $textures.get_texture(sprite_rec.texture); + // auto& sprite_texture = $textures.get_texture(sprite_rec.texture); + sf::Sprite *sf_sprite = sprite_rec.sprite; double spriteX = sprite_rec.x - $posX; double spriteY = sprite_rec.y - $posY; @@ -103,18 +104,10 @@ void Raycaster::sprite_casting() { int spriteScreenX = int(($width / 2) * (1 + transformX / transformY)); - int vMoveScreen = int(sprite_rec.elevation * -1 / transformY); - // calculate the height of the sprite on screen //using "transformY" instead of the real distance prevents fisheye int spriteHeight = abs(int($height / transformY)) / sprite_rec.vDiv; - //calculate lowest and highest pixel to fill in current stripe - int drawStartY = -spriteHeight / 2 + $height / 2 + vMoveScreen; - if(drawStartY < 0) drawStartY = 0; - int drawEndY = spriteHeight / 2 + $height / 2 + vMoveScreen; - if(drawEndY >= $height) drawEndY = $height - 1; - // calculate width the the sprite // same as height of sprite, given that it's square int spriteWidth = abs(int($height / transformY)) / sprite_rec.uDiv; @@ -123,29 +116,29 @@ void Raycaster::sprite_casting() { int drawEndX = spriteWidth / 2 + spriteScreenX; if(drawEndX > $width) drawEndX = $width; - //loop through every vertical stripe of the sprite on screen - for(int stripe = drawStartX; stripe < drawEndX; stripe++) { - int texX = int(256 * (stripe - (-spriteWidth / 2 + spriteScreenX)) * textureWidth / spriteWidth) / 256; - // the conditions in the if are: - // 1) it's in front of the camera plane so you don't see things behind you - // 2) ZBuffer, with perpendicular distance - if(transformY > 0 && transformY < ZBuffer[stripe]) { - for(int y = drawStartY; y < drawEndY; y++) { - //256 and 128 factors to avoid floats - int d = (y - vMoveScreen) * 256 - $height * 128 + spriteHeight * 128; - int texY = ((d * textureHeight) / spriteHeight) / 256; - //get current color from the texture - // BUG: this crashes sometimes when the math goes out of bounds - int index = textureWidth * texY + texX; - if(index < 0 || (size_t)index >= sprite_texture.size()) continue; - uint32_t color = sprite_texture[index]; - // poor person's transparency, get current color from the texture - if((color & 0x00FFFFFF) != 0) { - RGBA pixel = color; - $pixels[pixcoord(stripe, y)] = pixel; - } - } - } + + if(drawStartX < drawEndX && transformY > 0 && transformY < ZBuffer[drawStartX]) { + int vMoveScreen = int(sprite_rec.elevation * -1 / transformY); + //calculate lowest and highest pixel to fill in current stripe + int drawStartY = -spriteHeight / 2 + $height / 2 + vMoveScreen; + if(drawStartY < 0) drawStartY = 0; + int drawEndY = spriteHeight / 2 + $height / 2 + vMoveScreen; + if(drawEndY >= $height) drawEndY = $height - 1; + + float x = float(drawStartX + RAY_VIEW_X); + float y = float(drawStartY + RAY_VIEW_Y); + float sprite_w = float(spriteWidth) / float(textureWidth); + float sprite_h = float(spriteHeight) / float(textureHeight); + int texX = int(256 * (drawStartX - (-spriteWidth / 2 + spriteScreenX)) * textureWidth / spriteWidth) / 256; + int texX_end = int(256 * (drawEndX - (-spriteWidth / 2 + spriteScreenX)) * textureWidth / spriteWidth) / 256; + + int d = (y - vMoveScreen) * 256 - $height * 128 + spriteHeight * 128; + int texY = ((d * textureHeight) / spriteHeight) / 256; + + sf_sprite->setScale({sprite_h, sprite_w}); + sf_sprite->setTextureRect(sf::IntRect({texX, texY}, {texX_end, textureHeight})); + sf_sprite->setPosition({x, y}); + $window.draw(*sf_sprite); } } } @@ -328,8 +321,8 @@ void Raycaster::draw_ceiling_floor() { void Raycaster::render() { draw_ceiling_floor(); cast_rays(); - sprite_casting(); draw_pixel_buffer(); + sprite_casting(); } bool Raycaster::empty_space(int new_x, int new_y) { diff --git a/texture.cpp b/texture.cpp index 991d6a2..bad6f10 100644 --- a/texture.cpp +++ b/texture.cpp @@ -28,6 +28,11 @@ void TexturePack::load_textures() { floor = load_image(assets["floor"]); ceiling = load_image(assets["ceiling"]); + + sf::Texture* sprite_texture = new sf::Texture("assets/undead_peasant-256.png"); + sf::Sprite* sf_sprite = new sf::Sprite(*sprite_texture); + + sprites.push_back({4.0, 3.55, 6, sf_sprite, sprite_texture}); } Image& TexturePack::get_texture(size_t num) { diff --git a/texture.hpp b/texture.hpp index b112f4e..28bf7e4 100644 --- a/texture.hpp +++ b/texture.hpp @@ -3,11 +3,14 @@ #include #include #include +#include struct Sprite { double x; double y; int texture; + sf::Sprite *sprite = nullptr; + sf::Texture *sprite_texture = nullptr; // ZED: this should be a separate transform parameter double elevation=0; int uDiv=1; @@ -22,7 +25,7 @@ struct TexturePack { constexpr static const int TEXTURE_HEIGHT=256; // must be power of two std::vector images; - std::vector sprites{{4.0, 3.55, 6}}; + std::vector sprites; Image floor; Image ceiling;