182 lines
4.6 KiB
C++
182 lines
4.6 KiB
C++
#include "Base.hpp"
|
|
#include "input.hpp"
|
|
|
|
#include <cmath>
|
|
|
|
#include <motor/basic/bullet_debug_drawer.hpp>
|
|
|
|
namespace games {
|
|
using namespace motor;
|
|
|
|
std::ostream& operator<<(std::ostream& out, Input::Mouse::Button const& rh){
|
|
using Button = Input::Mouse::Button;
|
|
switch(rh){
|
|
case Button::left: return out << "left";
|
|
case Button::middle: return out << "middle";
|
|
case Button::right: return out << "right";
|
|
case Button::wheeldown: return out << "downscroll";
|
|
case Button::wheelup: return out << "upscroll";
|
|
default: {
|
|
return out << rh;
|
|
}
|
|
}
|
|
}
|
|
|
|
Base::Base(int window_width_, int window_height_, std::shared_ptr<Base>& active_base_)
|
|
: window_width(window_width_)
|
|
, window_height(window_height_)
|
|
, active_base(active_base_)
|
|
{
|
|
physics_scene->used_shader = physics_scene->flat_shader;
|
|
}
|
|
|
|
Base::~Base()
|
|
{
|
|
resource_cache.free_all_resources();
|
|
motor::resource_cache.free_all_resources();
|
|
}
|
|
|
|
bool Base::has_ended(){
|
|
return false;
|
|
}
|
|
|
|
void Base::update(float const dt, Input input){
|
|
time += dt;
|
|
|
|
if(physics_update){
|
|
world.physics.update(dt, 10);
|
|
}
|
|
|
|
if(free_camera_mode){
|
|
handle_camera(dt, input);
|
|
}
|
|
|
|
world.ai.update(dt, input, world);
|
|
}
|
|
|
|
void Base::draw(){
|
|
try {
|
|
fbo.unbind();
|
|
moggle::gl::set_viewport(0, 0, window_width, window_height);
|
|
moggle::gl::set_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
|
|
moggle::gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
moggle::gl::enable(GL_DEPTH_TEST);
|
|
moggle::gl::enable(GL_BLEND);
|
|
moggle::gl::blend_function(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
if(draw_physics_world){
|
|
physics_scene->camera = world.scene->camera;
|
|
|
|
for(auto mesh : world.physics.get_debug_draw_result(1 | 2 | 8)){
|
|
assert(mesh != nullptr);
|
|
|
|
auto const b = std::make_shared<Body>(mesh);
|
|
physics_scene->add(b);
|
|
}
|
|
|
|
physics_scene->draw();
|
|
physics_scene->remove_all_bodies();
|
|
}
|
|
|
|
if(!(draw_physics_world && draw_only_physics_world)){
|
|
world.scene->draw();
|
|
}
|
|
|
|
static constexpr bool print_screen = false;
|
|
if(print_screen){
|
|
std::vector<moggle::vector4<unsigned char>> pixels(window_width * window_height);
|
|
moggle::gl::clear_error();
|
|
glReadPixels(0, 0, window_width, window_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
|
|
moggle::gl::print_error();
|
|
for(int y = 0; y < window_height; ++y){
|
|
for(int x = 0; x < window_width; ++x){
|
|
for(int i = 0; i < 4; ++i){
|
|
std::cout << std::setw(3) << std::setfill('0') << size_t(pixels[y * window_height + x][i]) << ((i != 3) ? " " : "");
|
|
}
|
|
std::cout << "|";
|
|
}
|
|
std::cout << std::endl;
|
|
}
|
|
}
|
|
} catch (std::runtime_error& e){
|
|
CERR << "Something went wrong during drawing: " << e.what() << std::endl;
|
|
}
|
|
|
|
try {
|
|
moggle::gl::clear(GL_DEPTH_BUFFER_BIT);
|
|
world.hud->used_shader = world.hud->flat_shader;
|
|
world.hud->draw();
|
|
} catch (std::runtime_error& e){
|
|
CERR << "Something went wrong during drawing: " << e.what() << std::endl;
|
|
}
|
|
}
|
|
|
|
motor::Body* Base::raycast(moggle::vector2<float> const screen_position) const{
|
|
motor::Position const view = {0, 0, window_width, window_height};
|
|
|
|
motor::Position in = {screen_position[0], screen_position[1], 0.0, 1.f};
|
|
|
|
auto const near_point = world.scene->camera.unproject(in, view);
|
|
in[2] = 1.0f;
|
|
auto const far_point = world.scene->camera.unproject(in, view);
|
|
return world.physics.raycast(near_point, far_point);
|
|
}
|
|
|
|
void Base::handle_camera(const float dt, Input input)
|
|
{
|
|
SDL_ShowCursor(SDL_DISABLE);
|
|
|
|
float const distance = camera_speed * dt;
|
|
float const rotation = camera_rotation_speed * dt;
|
|
|
|
auto const move = [](Camera& p, Position const displacement){
|
|
p.set_position(p.get_position() + displacement);
|
|
};
|
|
|
|
Camera& b = world.scene->camera;
|
|
|
|
auto const m = inverse(b.get_rotation_matrix());
|
|
Position const down = m*Position{0, -distance, 0};
|
|
Position const up = m*Position{0, distance, 0};
|
|
Position const left = m*Position{-distance, 0, 0};
|
|
Position const right = m*Position{distance, 0, 0};
|
|
Position const backward = m*Position{0, 0, distance};
|
|
Position const forward = m*Position{0, 0, -distance};
|
|
|
|
if(input.keys_pressed[SDLK_w]){
|
|
move(b, forward);
|
|
}
|
|
|
|
if(input.keys_pressed[SDLK_s]){
|
|
move(b, backward);
|
|
}
|
|
|
|
if(input.keys_pressed[SDLK_d]){
|
|
move(b, right);
|
|
}
|
|
|
|
if(input.keys_pressed[SDLK_a]){
|
|
move(b, left);
|
|
}
|
|
|
|
if(input.keys_pressed[SDLK_t]){
|
|
move(b, up);
|
|
}
|
|
|
|
if(input.keys_pressed[SDLK_g]){
|
|
move(b, down);
|
|
}
|
|
|
|
b.add_pitch(-input.mouse.difference[1] * rotation);
|
|
b.add_yaw(-input.mouse.difference[0] * rotation);
|
|
|
|
input.mouse.position[0] = window_width/2;
|
|
input.mouse.position[1] = window_height/2;
|
|
SDL_WarpMouse(input.mouse.position[0], input.mouse.position[1]);
|
|
|
|
}
|
|
|
|
ResourceCache Base::resource_cache;
|
|
|
|
|
|
}
|