#include "Base.hpp" #include "input.hpp" #include #include 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& 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(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> 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 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; }