Brought in Amit's latest and tweaked a few more build options for enabling some safety checks in GCC.
This commit is contained in:
parent
eef13bd325
commit
308fe4bed2
6 changed files with 62 additions and 33 deletions
|
@ -57,6 +57,9 @@ int main() {
|
|||
|
||||
Stats stats;
|
||||
|
||||
// NOTE: Enable this to lock frames at 60
|
||||
window.setFramerateLimit(60);
|
||||
|
||||
while(window.isOpen()) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
rayview.render();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "amt/texture.hpp"
|
||||
#include "amt/pixel.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "thread.hpp"
|
||||
|
||||
#define AMT_LIGHT
|
||||
|
||||
|
@ -11,14 +12,14 @@ using namespace fmt;
|
|||
#ifdef AMT_LIGHT
|
||||
static constexpr auto room_brightness = 0.3f; // increse this to increase the room brightness. Higher value means brighter room.
|
||||
|
||||
inline static constexpr amt::RGBA dumb_lighting(amt::RGBA pixel, double distance, double distance_from_center) {
|
||||
inline static constexpr amt::RGBA dumb_lighting(amt::RGBA pixel, float distance, float distance_from_center) {
|
||||
auto const dim_pixel = pixel * room_brightness;
|
||||
if (distance_from_center >= 0) {
|
||||
auto const min_brightness = 1. / std::max(distance_from_center, 0.5); // farther away from the center darker it gets
|
||||
auto const max_brightness = 1.; // brighness should not exceed 1
|
||||
auto const min_brightness = 1.f / std::max(distance_from_center, 0.5f); // farther away from the center darker it gets
|
||||
auto const max_brightness = 1.f; // brighness should not exceed 1
|
||||
auto const pixel_brightness = std::max(min_brightness, std::min(max_brightness, distance));
|
||||
auto const yellow_brightness = float(distance_from_center * 60);
|
||||
|
||||
auto const yellow_brightness = float(distance_from_center * 60);
|
||||
amt::RGBA const yellow = amt::HSLA(40, 20, yellow_brightness);
|
||||
|
||||
auto temp = (pixel / pixel_brightness).blend<amt::BlendMode::softLight>(yellow);
|
||||
|
@ -29,6 +30,7 @@ inline static constexpr amt::RGBA dumb_lighting(amt::RGBA pixel, double distance
|
|||
}
|
||||
#else
|
||||
inline static constexpr amt::RGBA dumb_lighting(amt::RGBA pixel, double distance, double distance_from_center) {
|
||||
(void)distance_from_center;
|
||||
if(distance < 0.9) return pixel;
|
||||
return pixel / distance;
|
||||
}
|
||||
|
@ -45,7 +47,9 @@ Raycaster::Raycaster(sf::RenderWindow& window, Matrix &map, unsigned width, unsi
|
|||
$map(map),
|
||||
spriteOrder(textures.NUM_SPRITES),
|
||||
spriteDistance(textures.NUM_SPRITES),
|
||||
ZBuffer(width)
|
||||
ZBuffer(width),
|
||||
$radius(std::min($height, $width) / 2),
|
||||
$r_sq($radius * $radius)
|
||||
{
|
||||
$window.setVerticalSyncEnabled(VSYNC);
|
||||
view_sprite.setPosition({0, 0});
|
||||
|
@ -74,9 +78,6 @@ void Raycaster::clear() {
|
|||
}
|
||||
|
||||
void Raycaster::sprite_casting() {
|
||||
const int textureWidth = textures.TEXTURE_WIDTH;
|
||||
const int textureHeight = textures.TEXTURE_HEIGHT;
|
||||
|
||||
// sort sprites from far to close
|
||||
for(int i = 0; i < textures.NUM_SPRITES; i++) {
|
||||
auto& sprite = textures.get_sprite(i);
|
||||
|
@ -90,8 +91,10 @@ void Raycaster::sprite_casting() {
|
|||
|
||||
sort_sprites(spriteOrder, spriteDistance, textures.NUM_SPRITES);
|
||||
|
||||
/*for(int i = 0; i < textures.NUM_SPRITES; i++) {*/
|
||||
// after sorting the sprites, do the projection
|
||||
for(int i = 0; i < textures.NUM_SPRITES; i++) {
|
||||
// Be careful about capturing stack variables.
|
||||
amt::parallel_for<1>(pool, 0, textures.NUM_SPRITES, [this, textureWidth = textures.TEXTURE_WIDTH, textureHeight = textures.TEXTURE_HEIGHT](size_t i){
|
||||
int sprite_index = spriteOrder[i];
|
||||
Sprite& sprite_rec = textures.get_sprite(sprite_index);
|
||||
auto& sprite_texture = textures.get_texture(sprite_rec.texture);
|
||||
|
@ -139,33 +142,39 @@ void Raycaster::sprite_casting() {
|
|||
// 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 (texX < 0) continue;
|
||||
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;
|
||||
if ((size_t)texY >= sprite_texture.rows()) continue;
|
||||
//get current color from the texture
|
||||
// BUG: this crashes sometimes when the math goes out of bounds
|
||||
if(texY < 0 || texY >= (int)sprite_texture.rows()) continue;
|
||||
auto color = sprite_texture[texY][texX];
|
||||
// poor person's transparency, get current color from the texture
|
||||
pixels[y][stripe] = (color.to_hex() & 0xffffff00) ? color: pixels[y][stripe];
|
||||
}
|
||||
if (!(color.to_hex() & 0xffffff00)) continue;
|
||||
auto dist = get_distance_from_center(stripe, y);
|
||||
pixels[y][stripe] = dumb_lighting(color, d, dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
float Raycaster::get_distance_from_center(int x, int y) const noexcept {
|
||||
float cx = $width / 2;
|
||||
float cy = $height / 2;
|
||||
auto dx = cx - x;
|
||||
auto dy = cy - y;
|
||||
return ($r_sq - dx * dx - dy * dy) / $r_sq;
|
||||
}
|
||||
|
||||
void Raycaster::cast_rays() {
|
||||
double perpWallDist = 0;
|
||||
|
||||
auto const cx = $width / 2;
|
||||
auto const cy = $height / 2;
|
||||
double const radius = std::min($height, $width) / 2;
|
||||
double const r_sq = radius * radius;
|
||||
|
||||
// WALL CASTING
|
||||
for(int x = 0; x < $width; x++) {
|
||||
/*for(int x = 0; x < $width; x++) {*/
|
||||
amt::parallel_for<32>(pool, 0, static_cast<std::size_t>($width), [this](size_t x){
|
||||
double perpWallDist = 0;
|
||||
// calculate ray position and direction
|
||||
double cameraX = 2 * x / double($width) - 1; // x-coord in camera space
|
||||
double rayDirX = dirX + planeX * cameraX;
|
||||
|
@ -260,23 +269,24 @@ void Raycaster::cast_rays() {
|
|||
for(int y = drawStart; y < drawEnd; y++) {
|
||||
int texY = (int)texPos & (textures.TEXTURE_HEIGHT - 1);
|
||||
texPos += step;
|
||||
auto const dx = cx - x;
|
||||
auto const dy = cy - y;
|
||||
double const dist = dx * dx + dy * dy;
|
||||
auto color = dumb_lighting(texture[texY][texX], perpWallDist, (r_sq - dist) / r_sq);
|
||||
auto dist = get_distance_from_center(x, y);
|
||||
auto color = dumb_lighting(texture[texY][texX], perpWallDist, dist);
|
||||
pixels[y][x] = color;
|
||||
}
|
||||
|
||||
// SET THE ZBUFFER FOR THE SPRITE CASTING
|
||||
ZBuffer[x] = perpWallDist;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Raycaster::draw_ceiling_floor() {
|
||||
|
||||
/*for(int y = $height / 2 + 1; y < $height; ++y) {*/
|
||||
|
||||
auto const h = static_cast<size_t>($height);
|
||||
amt::parallel_for<32>(pool, h / 2, h, [this, $height=h](size_t y){
|
||||
const size_t textureWidth = textures.TEXTURE_WIDTH;
|
||||
const size_t textureHeight = textures.TEXTURE_HEIGHT;
|
||||
|
||||
for(int y = $height / 2 + 1; y < $height; ++y) {
|
||||
// rayDir for leftmost ray (x=0) and rightmost (x = w)
|
||||
float rayDirX0 = dirX - planeX;
|
||||
float rayDirY0 = dirY - planeY;
|
||||
|
@ -327,10 +337,12 @@ void Raycaster::draw_ceiling_floor() {
|
|||
|
||||
#ifdef AMT_LIGHT
|
||||
// FLOOR
|
||||
pixels[y][x] = textures.floor[ty][tx] * room_brightness;
|
||||
auto dist_floor = get_distance_from_center(x, y);
|
||||
pixels[y][x] = dumb_lighting(textures.floor[ty][tx], p, dist_floor);
|
||||
|
||||
// CEILING
|
||||
pixels[$height - y - 1][x] = textures.ceiling[ty][tx] * room_brightness;
|
||||
auto dist_ceiling = get_distance_from_center(x, $height - y - 1);
|
||||
pixels[$height - y - 1][x] = dumb_lighting(textures.ceiling[ty][tx], p, dist_ceiling);
|
||||
#else
|
||||
// FLOOR
|
||||
pixels[y][x] = textures.floor[ty][tx];
|
||||
|
@ -340,14 +352,18 @@ void Raycaster::draw_ceiling_floor() {
|
|||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void Raycaster::render() {
|
||||
draw_ceiling_floor();
|
||||
// This wait to prevent data-race
|
||||
pool.wait(); // Try to remove this to see unbelievable performance
|
||||
cast_rays();
|
||||
pool.wait(); // Try to remove this too
|
||||
sprite_casting();
|
||||
pool.wait();
|
||||
draw_pixel_buffer();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "amt/pixel.hpp"
|
||||
#include "amt/texture.hpp"
|
||||
#include <memory>
|
||||
#include "thread.hpp"
|
||||
|
||||
using Matrix = amt::Matrix<int>;
|
||||
|
||||
|
@ -43,6 +44,9 @@ struct Raycaster {
|
|||
std::vector<int> spriteOrder;
|
||||
std::vector<double> spriteDistance;
|
||||
std::vector<double> ZBuffer; // width
|
||||
float $radius; // std::min($height, $width) / 2;
|
||||
float $r_sq; // = radius * radius;
|
||||
amt::thread_pool_t pool;
|
||||
|
||||
Raycaster(sf::RenderWindow& window, Matrix &map, unsigned width, unsigned height);
|
||||
|
||||
|
@ -59,6 +63,7 @@ struct Raycaster {
|
|||
void run(double speed, int dir);
|
||||
void rotate(double speed, int dir);
|
||||
void position_camera(float player_x, float player_y);
|
||||
float get_distance_from_center(int x, int y) const noexcept;
|
||||
|
||||
void set_position(int x, int y);
|
||||
inline size_t pixcoord(int x, int y) {
|
||||
|
|
|
@ -7,6 +7,7 @@ constexpr const int RAY_VIEW_Y=0;
|
|||
constexpr const int SCREEN_HEIGHT=720;
|
||||
constexpr const int SCREEN_WIDTH=1280;
|
||||
constexpr const bool VSYNC=false;
|
||||
constexpr const int FRAME_LIMIT=30;
|
||||
#ifdef NDEBUG
|
||||
constexpr const bool DEBUG_BUILD=false;
|
||||
#else
|
||||
|
|
2
main.cpp
2
main.cpp
|
@ -57,6 +57,8 @@ int main() {
|
|||
|
||||
Stats stats;
|
||||
|
||||
window.setFramerateLimit(FRAME_LIMIT);
|
||||
|
||||
while(window.isOpen()) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
rayview.render();
|
||||
|
|
|
@ -63,5 +63,7 @@ executable('amtcaster', [
|
|||
'amt/texture.cpp',
|
||||
'amt/raycaster.cpp',
|
||||
'amt/main.cpp'
|
||||
], override_options: exe_defaults,
|
||||
],
|
||||
cpp_args: ['-std=c++23'],
|
||||
override_options: exe_defaults,
|
||||
dependencies: dependencies)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue