|
|
|
@ -1,46 +1,9 @@ |
|
|
|
|
#include "raycaster.hpp" |
|
|
|
|
#include "texture.hpp" |
|
|
|
|
|
|
|
|
|
using namespace fmt; |
|
|
|
|
using std::make_unique; |
|
|
|
|
|
|
|
|
|
#define rgba_color(r,g,b,a) (r<<(0*8))|(g<<(1*8))|(b<<(2*8))|(a<<(3*8)) |
|
|
|
|
#define gray_color(c) rgba_color(c, c, c, 255) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<uint32_t> TexturePack::load_image(const char *filename) { |
|
|
|
|
std::vector<uint32_t> texture(TEXTURE_WIDTH * TEXTURE_HEIGHT); |
|
|
|
|
sf::Image img; |
|
|
|
|
bool good = img.loadFromFile(filename); |
|
|
|
|
dbc::check(good, format("failed to load {}", filename)); |
|
|
|
|
|
|
|
|
|
uint32_t *pixbuf = (uint32_t *)img.getPixelsPtr(); |
|
|
|
|
std::copy_n(pixbuf, texture.size(), texture.begin()); |
|
|
|
|
|
|
|
|
|
return texture; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void TexturePack::load_textures() { |
|
|
|
|
images.emplace_back(load_image("assets/tile16.png")); |
|
|
|
|
images.emplace_back(load_image("assets/tile02.png")); |
|
|
|
|
images.emplace_back(load_image("assets/tile03.png")); |
|
|
|
|
images.emplace_back(load_image("assets/tile32.png")); |
|
|
|
|
images.emplace_back(load_image("assets/tile05.png")); |
|
|
|
|
images.emplace_back(load_image("assets/tile17.png")); |
|
|
|
|
images.emplace_back(load_image("assets/tile10.png")); |
|
|
|
|
images.emplace_back(load_image("assets/tile01.png")); |
|
|
|
|
images.emplace_back(load_image("assets/portal.png")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::vector<uint32_t>& TexturePack::get(size_t num) { |
|
|
|
|
return images[num]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Sprite &TexturePack::get_sprite(size_t sprite_num) { |
|
|
|
|
return SPRITE[sprite_num]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Raycaster::Raycaster(sf::RenderWindow& window, Matrix &map, int width, int height) : |
|
|
|
|
$width(width), $height(height), |
|
|
|
|
$window(window), |
|
|
|
@ -84,12 +47,13 @@ void Raycaster::sprite_casting() { |
|
|
|
|
|
|
|
|
|
// sort sprites from far to close
|
|
|
|
|
for(int i = 0; i < textures.NUM_SPRITES; i++) { |
|
|
|
|
auto& sprite = textures.get_sprite(i); |
|
|
|
|
spriteOrder[i] = i; |
|
|
|
|
// this is just the distance calculation
|
|
|
|
|
spriteDistance[i] = ((posX - textures.SPRITE[i].x) * |
|
|
|
|
(posX - textures.SPRITE[i].x) + |
|
|
|
|
(posY - textures.SPRITE[i].y) * |
|
|
|
|
(posY - textures.SPRITE[i].y)); |
|
|
|
|
spriteDistance[i] = ((posX - sprite.x) * |
|
|
|
|
(posX - sprite.x) + |
|
|
|
|
(posY - sprite.y) * |
|
|
|
|
(posY - sprite.y)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sort_sprites(spriteOrder, spriteDistance, textures.NUM_SPRITES); |
|
|
|
@ -98,9 +62,10 @@ 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); |
|
|
|
|
|
|
|
|
|
double spriteX = sprite_rec.x - posX; |
|
|
|
|
double spriteY = sprite_rec.y - posY; |
|
|
|
|
auto& sprite_texture = textures.get(sprite_rec.texture); |
|
|
|
|
|
|
|
|
|
//transform sprite with the inverse camera matrix
|
|
|
|
|
// [ planeX dirX ] -1 [ dirY -dirX ]
|
|
|
|
@ -234,7 +199,7 @@ void Raycaster::cast_rays() { |
|
|
|
|
int drawEnd = lineHeight / 2 + $height / 2 + PITCH; |
|
|
|
|
if(drawEnd >= $height) drawEnd = $height - 1; |
|
|
|
|
|
|
|
|
|
auto &texture = textures.get($map[mapY][mapX] - 1); |
|
|
|
|
auto &texture = textures.get_texture($map[mapY][mapX] - 1); |
|
|
|
|
|
|
|
|
|
// calculate value of wallX
|
|
|
|
|
double wallX; // where exactly the wall was hit
|
|
|
|
@ -273,9 +238,6 @@ void Raycaster::draw_ceiling_floor() { |
|
|
|
|
const int textureWidth = textures.TEXTURE_WIDTH; |
|
|
|
|
const int textureHeight = textures.TEXTURE_HEIGHT; |
|
|
|
|
|
|
|
|
|
auto& floorTexture = textures.get(textures.floor); |
|
|
|
|
auto& ceilingTexture = textures.get(textures.ceiling); |
|
|
|
|
|
|
|
|
|
for(int y = $height / 2 + 1; y < $height; ++y) { |
|
|
|
|
// rayDir for leftmost ray (x=0) and rightmost (x = w)
|
|
|
|
|
float rayDirX0 = dirX - planeX; |
|
|
|
@ -327,11 +289,11 @@ void Raycaster::draw_ceiling_floor() { |
|
|
|
|
// floorX cellX to find the texture x/y. How?
|
|
|
|
|
|
|
|
|
|
// FLOOR
|
|
|
|
|
color = floorTexture[textureWidth * ty + tx]; |
|
|
|
|
color = textures.floor[textureWidth * ty + tx]; |
|
|
|
|
pixels[pixcoord(x, y)] = color; |
|
|
|
|
|
|
|
|
|
// CEILING
|
|
|
|
|
color = ceilingTexture[textureWidth * ty + tx]; |
|
|
|
|
color = textures.ceiling[textureWidth * ty + tx]; |
|
|
|
|
pixels[pixcoord(x, $height - y - 1)] = color; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|