|
|
|
@ -23,6 +23,11 @@ union ColorConv { |
|
|
|
|
uint32_t as_int; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/* It's hard to believe, but this is faster than any bitfiddling
|
|
|
|
|
* I could devise. Just use a union with a struct, do the math |
|
|
|
|
* and I guess the compiler can handle it better than shifting |
|
|
|
|
* bits around. |
|
|
|
|
*/ |
|
|
|
|
inline uint32_t new_lighting(uint32_t pixel, int level) { |
|
|
|
|
float factor = level * PERCENT; |
|
|
|
|
|
|
|
|
@ -38,8 +43,7 @@ Raycaster::Raycaster(int width, int height) : |
|
|
|
|
$view_texture(sf::Vector2u{(unsigned int)width, (unsigned int)height}), |
|
|
|
|
$view_sprite($view_texture), |
|
|
|
|
$width(width), $height(height), |
|
|
|
|
$zbuffer(width), |
|
|
|
|
$anim(256, 256, 10, "assets/monster-1.ogg") |
|
|
|
|
$zbuffer(width) |
|
|
|
|
{ |
|
|
|
|
$view_sprite.setPosition({0, 0}); |
|
|
|
|
$pixels = make_unique<RGBA[]>($width * $height); |
|
|
|
@ -99,6 +103,7 @@ void Raycaster::sprite_casting(sf::RenderTarget &target) { |
|
|
|
|
// calculate width the the sprite
|
|
|
|
|
// same as height of sprite, given that it's square
|
|
|
|
|
int sprite_width = abs(int($height / transform_y)); |
|
|
|
|
// CUT
|
|
|
|
|
|
|
|
|
|
int draw_start_x = -sprite_width / 2 + sprite_screen_x; |
|
|
|
|
if(draw_start_x < 0) draw_start_x = 0; |
|
|
|
@ -119,8 +124,6 @@ void Raycaster::sprite_casting(sf::RenderTarget &target) { |
|
|
|
|
//calculate lowest and highest pixel to fill in current stripe
|
|
|
|
|
int draw_start_y = -sprite_height / 2 + $height / 2; |
|
|
|
|
if(draw_start_y < 0) draw_start_y = 0; |
|
|
|
|
int draw_end_y = sprite_height / 2 + $height / 2; |
|
|
|
|
if(draw_end_y >= $height) draw_end_y = $height - 1; |
|
|
|
|
|
|
|
|
|
int tex_x = int(texture_width * (draw_start_x - (-sprite_width / 2 + sprite_screen_x)) * texture_width / sprite_width) / texture_width; |
|
|
|
|
int tex_render_width = tex_x_end - tex_x; |
|
|
|
@ -130,14 +133,22 @@ void Raycaster::sprite_casting(sf::RenderTarget &target) { |
|
|
|
|
|
|
|
|
|
float x = float(draw_start_x + $screen_pos_x); |
|
|
|
|
float y = float(draw_start_y + $screen_pos_y); |
|
|
|
|
float sprite_w = float(sprite_width) / float(texture_width); |
|
|
|
|
float sprite_h = float(sprite_height) / float(texture_height); |
|
|
|
|
|
|
|
|
|
if(x < $screen_pos_x) fmt::println("X < rayview left bounds"); |
|
|
|
|
if(y < $screen_pos_y) fmt::println("Y < rayview top bounds"); |
|
|
|
|
if(x >= SCREEN_WIDTH) fmt::println("OUT OF BOUNDS X"); |
|
|
|
|
if(y >= $height) fmt::println("OUT OF BOUNDS Y"); |
|
|
|
|
|
|
|
|
|
float sprite_scale_w = float(sprite_width) / float(texture_width); |
|
|
|
|
float sprite_scale_h = float(sprite_height) / float(texture_height); |
|
|
|
|
|
|
|
|
|
int d = y * texture_height - $height * half_height + sprite_height * half_height; |
|
|
|
|
int tex_y = ((d * texture_height) / sprite_height) / texture_height; |
|
|
|
|
|
|
|
|
|
sf_sprite->setScale({sprite_w, sprite_h}); |
|
|
|
|
$anim.step(*sf_sprite, tex_x, tex_y, tex_render_width, texture_height); |
|
|
|
|
sf_sprite->setScale({sprite_scale_w, sprite_scale_h}); |
|
|
|
|
sf_sprite->setTextureRect(sf::IntRect({ |
|
|
|
|
{tex_x, tex_y}, |
|
|
|
|
{tex_render_width, texture_height}})); |
|
|
|
|
sf_sprite->setPosition({x, y}); |
|
|
|
|
|
|
|
|
|
$brightness.setUniform("offsetFactor", sf::Glsl::Vec2{0.0f, 0.0f}); |
|
|
|
@ -333,10 +344,13 @@ void Raycaster::draw_ceiling_floor() { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Raycaster::draw(sf::RenderTarget& target) { |
|
|
|
|
void Raycaster::render() { |
|
|
|
|
draw_ceiling_floor(); |
|
|
|
|
cast_rays(); |
|
|
|
|
draw_pixel_buffer(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Raycaster::draw(sf::RenderTarget& target) { |
|
|
|
|
target.draw($view_sprite); |
|
|
|
|
sprite_casting(target); |
|
|
|
|
} |
|
|
|
|