Major speed up in rendering by only doing it when we move, but drawing the rendered 3d view texture constantly.
This commit is contained in:
parent
0260e3d345
commit
b43553a563
7 changed files with 39 additions and 17 deletions
|
@ -21,7 +21,6 @@
|
||||||
},
|
},
|
||||||
{"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 1, "dead": false},
|
{"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 1, "dead": false},
|
||||||
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
|
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
|
||||||
{"_type": "LightSource", "strength": 40, "radius": 1.2},
|
|
||||||
{"_type": "EnemyConfig", "hearing_distance": 5},
|
{"_type": "EnemyConfig", "hearing_distance": 5},
|
||||||
{"_type": "Sprite", "name": "armored_knight"}
|
{"_type": "Sprite", "name": "armored_knight"}
|
||||||
]
|
]
|
||||||
|
|
|
@ -248,6 +248,9 @@ namespace gui {
|
||||||
case KEY::Escape:
|
case KEY::Escape:
|
||||||
event(Event::CLOSE);
|
event(Event::CLOSE);
|
||||||
break;
|
break;
|
||||||
|
case KEY::Space:
|
||||||
|
event(Event::ATTACK);
|
||||||
|
break;
|
||||||
case KEY::P:
|
case KEY::P:
|
||||||
$main_ui.debug();
|
$main_ui.debug();
|
||||||
break;
|
break;
|
||||||
|
@ -259,9 +262,9 @@ namespace gui {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSM::draw_gui() {
|
void FSM::draw_gui() {
|
||||||
|
$main_ui.draw();
|
||||||
$status_ui.draw($window);
|
$status_ui.draw($window);
|
||||||
$combat_ui.draw($window);
|
$combat_ui.draw($window);
|
||||||
$main_ui.draw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSM::render() {
|
void FSM::render() {
|
||||||
|
|
10
main_ui.cpp
10
main_ui.cpp
|
@ -65,13 +65,15 @@ namespace gui {
|
||||||
$rayview.init_shaders();
|
$rayview.init_shaders();
|
||||||
$rayview.set_position(RAY_VIEW_X, RAY_VIEW_Y);
|
$rayview.set_position(RAY_VIEW_X, RAY_VIEW_Y);
|
||||||
$rayview.position_camera($player.x + 0.5, $player.y + 0.5);
|
$rayview.position_camera($player.x + 0.5, $player.y + 0.5);
|
||||||
|
|
||||||
$overlay_ui.render();
|
$overlay_ui.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainUI::draw() {
|
void MainUI::draw() {
|
||||||
auto start = std::chrono::high_resolution_clock::now();
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
if($needs_render) $rayview.render();
|
||||||
$rayview.draw($window);
|
$rayview.draw($window);
|
||||||
|
|
||||||
auto end = std::chrono::high_resolution_clock::now();
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
auto elapsed = std::chrono::duration<double>(end - start);
|
auto elapsed = std::chrono::duration<double>(end - start);
|
||||||
$stats.sample(1/elapsed.count());
|
$stats.sample(1/elapsed.count());
|
||||||
|
@ -85,16 +87,20 @@ namespace gui {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainUI::play_rotate() {
|
bool MainUI::play_rotate() {
|
||||||
return $camera.play_rotate($rayview);
|
bool done = $camera.play_rotate($rayview);
|
||||||
|
$needs_render = !done;
|
||||||
|
return done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this could be an optional that returs a Point
|
// this could be an optional that returs a Point
|
||||||
std::optional<Point> MainUI::play_move() {
|
std::optional<Point> MainUI::play_move() {
|
||||||
if($camera.play_move($rayview)) {
|
if($camera.play_move($rayview)) {
|
||||||
|
$needs_render = false;
|
||||||
return std::make_optional<Point>({
|
return std::make_optional<Point>({
|
||||||
size_t($camera.target_x),
|
size_t($camera.target_x),
|
||||||
size_t($camera.target_y)});
|
size_t($camera.target_y)});
|
||||||
} else {
|
} else {
|
||||||
|
$needs_render = true;
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace gui {
|
||||||
|
|
||||||
class MainUI {
|
class MainUI {
|
||||||
public:
|
public:
|
||||||
|
bool $needs_render = true;
|
||||||
Point $player{0,0};
|
Point $player{0,0};
|
||||||
Stats $stats;
|
Stats $stats;
|
||||||
sf::RenderWindow& $window;
|
sf::RenderWindow& $window;
|
||||||
|
@ -26,9 +27,9 @@ namespace gui {
|
||||||
void draw_stats();
|
void draw_stats();
|
||||||
void draw_blood();
|
void draw_blood();
|
||||||
|
|
||||||
std::optional<Point> play_move();
|
|
||||||
void plan_rotate(int dir);
|
void plan_rotate(int dir);
|
||||||
bool play_rotate();
|
bool play_rotate();
|
||||||
|
std::optional<Point> play_move();
|
||||||
Point plan_move(int dir, bool strafe);
|
Point plan_move(int dir, bool strafe);
|
||||||
void abort_plan();
|
void abort_plan();
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,11 @@ union ColorConv {
|
||||||
uint32_t as_int;
|
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) {
|
inline uint32_t new_lighting(uint32_t pixel, int level) {
|
||||||
float factor = level * PERCENT;
|
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_texture(sf::Vector2u{(unsigned int)width, (unsigned int)height}),
|
||||||
$view_sprite($view_texture),
|
$view_sprite($view_texture),
|
||||||
$width(width), $height(height),
|
$width(width), $height(height),
|
||||||
$zbuffer(width),
|
$zbuffer(width)
|
||||||
$anim(256, 256, 10, "assets/monster-1.ogg")
|
|
||||||
{
|
{
|
||||||
$view_sprite.setPosition({0, 0});
|
$view_sprite.setPosition({0, 0});
|
||||||
$pixels = make_unique<RGBA[]>($width * $height);
|
$pixels = make_unique<RGBA[]>($width * $height);
|
||||||
|
@ -99,6 +103,7 @@ void Raycaster::sprite_casting(sf::RenderTarget &target) {
|
||||||
// calculate width the the sprite
|
// calculate width the the sprite
|
||||||
// same as height of sprite, given that it's square
|
// same as height of sprite, given that it's square
|
||||||
int sprite_width = abs(int($height / transform_y));
|
int sprite_width = abs(int($height / transform_y));
|
||||||
|
// CUT
|
||||||
|
|
||||||
int draw_start_x = -sprite_width / 2 + sprite_screen_x;
|
int draw_start_x = -sprite_width / 2 + sprite_screen_x;
|
||||||
if(draw_start_x < 0) draw_start_x = 0;
|
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
|
//calculate lowest and highest pixel to fill in current stripe
|
||||||
int draw_start_y = -sprite_height / 2 + $height / 2;
|
int draw_start_y = -sprite_height / 2 + $height / 2;
|
||||||
if(draw_start_y < 0) draw_start_y = 0;
|
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_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;
|
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 x = float(draw_start_x + $screen_pos_x);
|
||||||
float y = float(draw_start_y + $screen_pos_y);
|
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 d = y * texture_height - $height * half_height + sprite_height * half_height;
|
||||||
int tex_y = ((d * texture_height) / sprite_height) / texture_height;
|
int tex_y = ((d * texture_height) / sprite_height) / texture_height;
|
||||||
|
|
||||||
sf_sprite->setScale({sprite_w, sprite_h});
|
sf_sprite->setScale({sprite_scale_w, sprite_scale_h});
|
||||||
$anim.step(*sf_sprite, tex_x, tex_y, tex_render_width, texture_height);
|
sf_sprite->setTextureRect(sf::IntRect({
|
||||||
|
{tex_x, tex_y},
|
||||||
|
{tex_render_width, texture_height}}));
|
||||||
sf_sprite->setPosition({x, y});
|
sf_sprite->setPosition({x, y});
|
||||||
|
|
||||||
$brightness.setUniform("offsetFactor", sf::Glsl::Vec2{0.0f, 0.0f});
|
$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();
|
draw_ceiling_floor();
|
||||||
cast_rays();
|
cast_rays();
|
||||||
draw_pixel_buffer();
|
draw_pixel_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Raycaster::draw(sf::RenderTarget& target) {
|
||||||
target.draw($view_sprite);
|
target.draw($view_sprite);
|
||||||
sprite_casting(target);
|
sprite_casting(target);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ struct Raycaster {
|
||||||
Matrix $map;
|
Matrix $map;
|
||||||
std::unordered_map<DinkyECS::Entity, textures::SpriteTexture> $sprites;
|
std::unordered_map<DinkyECS::Entity, textures::SpriteTexture> $sprites;
|
||||||
std::vector<double> $zbuffer; // width
|
std::vector<double> $zbuffer; // width
|
||||||
Animator $anim;
|
|
||||||
|
|
||||||
Raycaster(int width, int height);
|
Raycaster(int width, int height);
|
||||||
|
|
||||||
|
@ -47,6 +46,7 @@ struct Raycaster {
|
||||||
void draw_ceiling_floor();
|
void draw_ceiling_floor();
|
||||||
void draw_pixel_buffer();
|
void draw_pixel_buffer();
|
||||||
void sprite_casting(sf::RenderTarget& target);
|
void sprite_casting(sf::RenderTarget& target);
|
||||||
|
void render();
|
||||||
void draw(sf::RenderTarget& target);
|
void draw(sf::RenderTarget& target);
|
||||||
|
|
||||||
void sort_sprites(std::vector<int>& order, std::vector<double>& dist, int amount);
|
void sort_sprites(std::vector<int>& order, std::vector<double>& dist, int amount);
|
||||||
|
|
|
@ -17,8 +17,7 @@ namespace gui {
|
||||||
"[button7 | button8 | button9]"
|
"[button7 | button8 | button9]"
|
||||||
"[*%(100,300)log_view]"
|
"[*%(100,300)log_view]"
|
||||||
"[_]"
|
"[_]"
|
||||||
"[_]"
|
"[_]");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusUI::render() {
|
void StatusUI::render() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue