diff --git a/include/Camera.h b/include/Camera.h index 817f9fb..ae8d166 100644 --- a/include/Camera.h +++ b/include/Camera.h @@ -2,8 +2,9 @@ #include #include #include "util.hpp" +#include "Pub_Sub.hpp" -class Camera { +class Camera : public SfEventSubscriber{ public: enum DIRECTION { FORWARD, REARWARD, LEFT, RIGHT, UP, DOWN }; @@ -33,6 +34,9 @@ public: sf::Vector3f get_position(); sf::Vector2f get_direction(); + + virtual void update(SfEventPublisher* p, sf::Event e) override; + private: float friction_coefficient = 0.1f; diff --git a/include/Input.h b/include/Input.h new file mode 100644 index 0000000..6b5d7aa --- /dev/null +++ b/include/Input.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include +#include "Pub_Sub.hpp" + + +class Input : public SfEventPublisher { +public: + + Input(); + ~Input(); + + // Keep track of keys that are not released + // Keep track of mouse up and downs in conjunction with dragging + // Keep track of joystick buttons + + void consume_events(sf::RenderWindow *window); + void set_flags(); + void dispatch_events(); + +private: + std::vector held_keys; + std::vector held_mouse_buttons; + + std::vector keyboard_flags; + std::vector mouse_flags; + +private: + std::list event_queue; +}; diff --git a/include/Pub_Sub.hpp b/include/Pub_Sub.hpp new file mode 100644 index 0000000..205551b --- /dev/null +++ b/include/Pub_Sub.hpp @@ -0,0 +1,133 @@ +#pragma once +#include + + +class SfEventPublisher; + +class SfEventSubscriber { +public: + virtual ~SfEventSubscriber() {}; + virtual void update(SfEventPublisher* p, sf::Event e) = 0; +}; + +class SfEventPublisher { +public: + + // Allows the subscription to classes of events + enum Event_Class { + JoystickButtonEvent, + JoystickConnectEvent, + JoystickMoveEvent, + KeyEvent, + MouseButtonEvent, + MouseMoveEvent, + MouseWheelEvent, + MouseWheelScrollEvent, + SensorEvent, + SizeEvent, + TextEvent, + TouchEvent, + WindowEvent + }; + + virtual ~SfEventPublisher() {}; + virtual void subscribe(SfEventSubscriber *s, Event_Class c) { + subscribers[c].push_back(s); + }; + virtual void unsubscribe(SfEventSubscriber *s, Event_Class c) { + std::remove(subscribers[c].begin(), subscribers[c].end(), s); + }; + virtual void notify(sf::Event e) { + + // I don't quite like that some event classes contained multiple types of events: + // KeyPressed, and KeyReleased under KeyEvent for example. + // While others are not represented by classes: + // Closed, LostFocus, and GainedFocus have no representing class. + // So, we'll add another "class", WindowEvent which contains those previously mentioned, + // and use those new identifiers to group our events + + // This will also make it a bit easier when subscribing to certain events + + Event_Class event_class; + + if (e.type == sf::Event::Closed || + e.type == sf::Event::LostFocus || + e.type == sf::Event::GainedFocus ){ + + event_class = Event_Class::WindowEvent; + } + + // Preserve a little of sfml's default behavior and separate resized event + else if (e.type == sf::Event::Resized) { + event_class = Event_Class::SizeEvent; + } + + else if (e.type == sf::Event::TextEntered) { + event_class = Event_Class::TextEvent; + } + + else if (e.type == sf::Event::KeyPressed || + e.type == sf::Event::KeyReleased ){ + + event_class = Event_Class::KeyEvent; + } + + else if (e.type == sf::Event::MouseWheelMoved || + e.type == sf::Event::MouseWheelScrolled ){ + + event_class = Event_Class::MouseWheelScrollEvent; + } + + else if (e.type == sf::Event::MouseButtonPressed || + e.type == sf::Event::MouseButtonReleased ){ + + event_class = Event_Class::MouseButtonEvent; + } + + // Is this a good idea, mixing events that contain data, and don't contain data? + else if (e.type == sf::Event::MouseMoved || + e.type == sf::Event::MouseEntered || + e.type == sf::Event::MouseLeft ){ + + event_class = Event_Class::MouseMoveEvent; + } + + else if (e.type == sf::Event::JoystickButtonPressed || + e.type == sf::Event::JoystickButtonReleased ){ + + event_class = Event_Class::JoystickButtonEvent; + } + + else if (e.type == sf::Event::JoystickMoved) { + event_class = Event_Class::JoystickMoveEvent; + } + + else if (e.type == sf::Event::JoystickConnected || + e.type == sf::Event::JoystickDisconnected ){ + + event_class = Event_Class::JoystickConnectEvent; + } + + else if (e.type == sf::Event::TouchBegan || + e.type == sf::Event::TouchEnded || + e.type == sf::Event::TouchMoved ){ + + event_class = Event_Class::TouchEvent; + } + + else if (e.type == sf::Event::SensorChanged) { + event_class = Event_Class::SensorEvent; + } + + + std::vector *event_type_bucket = &subscribers[event_class]; + + for (auto s : *event_type_bucket) { + s->update(this, e); + } + }; +private: + std::map> subscribers; + +}; + diff --git a/include/util.hpp b/include/util.hpp index a33caa6..5865d33 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -1,13 +1,12 @@ #pragma once #include -#include +#include "Vector4.hpp" #include +#include +#include #include #include -#include "Vector4.hpp" -#include #include -#include #include diff --git a/kernels/ray_caster_kernel.cl b/kernels/ray_caster_kernel.cl index bfb7286..a2cc7b2 100644 --- a/kernels/ray_caster_kernel.cl +++ b/kernels/ray_caster_kernel.cl @@ -99,12 +99,13 @@ __kernel void raycaster( global int* seed_memory ){ - - int global_id = get_global_id(1) * get_global_size(0) + get_global_id(0); + // Get and set the random seed from seed memory + int global_id = get_global_id(0); int seed = seed_memory[global_id]; int random_number = rand(&seed); seed_memory[global_id] = seed; + size_t id = get_global_id(0); int2 pixel = {id % (*resolution).x, id / (*resolution).x}; float3 ray_dir = projection_matrix[pixel.x + (*resolution).x * pixel.y]; diff --git a/src/Camera.cpp b/src/Camera.cpp index 0710593..9a04e24 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -86,18 +86,14 @@ int Camera::update(double delta_time) { return 1; } -void Camera::look_at_center() { - //std::cout << "X:" << position.x << std::endl; - //std::cout << "Y:" << position.y << std::endl; - //std::cout << "Z:" << position.z << std::endl; +void Camera::update(SfEventPublisher* p, sf::Event e) +{ - //std::cout << "dx:" << direction.x << std::endl; - //std::cout << "dy:" << direction.y << std::endl; +} - direction = CartToNormalizedSphere(sf::Vector3f(75, 75, 75) - position); +void Camera::look_at_center() { - //std::cout << "dx:" << direction.x << std::endl; - //std::cout << "dy:" << direction.y << std::endl; + direction = CartToNormalizedSphere(sf::Vector3f(75, 75, 75) - position); } diff --git a/src/Input.cpp b/src/Input.cpp new file mode 100644 index 0000000..97a0f8d --- /dev/null +++ b/src/Input.cpp @@ -0,0 +1,43 @@ +#include "Input.h" + + +Input::Input() : + keyboard_flags(sf::Keyboard::Key::KeyCount, false), + mouse_flags(sf::Mouse::Button::ButtonCount, false) +{ + +} + +Input::~Input() +{ + +} + +void Input::consume_events(sf::RenderWindow *window) { + + sf::Event e; + while (window->pollEvent(e)) { + event_queue.push_back(e); + } + +} + +void Input::set_flags() { + + for (auto e: event_queue) { + if (e.type == sf::Event::KeyPressed) { + held_keys.push_back(e.key.code); + } + else if (e.type == sf::Event::KeyReleased) { + std::remove(held_keys.begin(), held_keys.end(), e.key.code); + } + } +} + +void Input::dispatch_events() { + + while (event_queue.size() != 0) { + notify(event_queue.front()); + event_queue.pop_front(); + } +} diff --git a/src/Ray.cpp b/src/Ray.cpp index a7ab0b2..a168bc4 100644 --- a/src/Ray.cpp +++ b/src/Ray.cpp @@ -131,11 +131,11 @@ sf::Color Ray::Cast() { switch (voxel_data) { case 5: - return sf::Color(255, 120, 255, alpha); + return sf::Color(255, 120, 255, static_cast(alpha)); case 6: - return sf::Color(150, 80, 220, alpha); + return sf::Color(150, 80, 220, static_cast(alpha)); default: - return sf::Color(150, 80, 220, alpha); + return sf::Color(150, 80, 220, static_cast(alpha)); } dist++; diff --git a/src/Software_Caster.cpp b/src/Software_Caster.cpp index 5117e2f..1ec1c67 100644 --- a/src/Software_Caster.cpp +++ b/src/Software_Caster.cpp @@ -328,7 +328,7 @@ sf::Color Software_Caster::global_light(sf::Color in, sf::Vector3i mask) { sf::Vector3f mask_f(mask); - in.a = in.a + acos( + in.a = in.a + (int)acos( DotProduct( Normalize(lights.at(0).direction_cartesian), Normalize(mask_f) diff --git a/src/main.cpp b/src/main.cpp index 85c4277..6bfc42e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,9 @@ #elif defined _WIN32 #include + +// As if hardware is ever going to move away from 1.2 +#define CL_USE_DEPRECATED_OPENCL_1_2_APIS #include #include @@ -32,6 +35,7 @@ #include "Vector4.hpp" #include #include "Software_Caster.h" +#include "Input.h" const int WINDOW_X = 1920; @@ -79,20 +83,14 @@ int main() { t.create_program(); t.create_buffers(); - // Initialize the raycaster hardware, compat, or software + RayCaster *rc = new Hardware_Caster(); - //RayCaster *rc = new Software_Caster(); + if (rc->init() != 1) { - delete rc; - // rc = new Hardware_Caster_Compat(); - // if (rc->init() != 0) { - // delete rc; - // rc = new Software_Caster(); - // } + abort(); } // Set up the raycaster - std::cout << "map..."; sf::Vector3i map_dim(MAP_X, MAP_Y, MAP_Z); Old_Map* map = new Old_Map(map_dim); @@ -147,8 +145,15 @@ int main() { bool mouse_enabled = true; bool reset = false; + + Input input_handler; + input_handler.subscribe(camera, SfEventPublisher::Event_Class::KeyEvent); + window.setKeyRepeatEnabled(false); + while (window.isOpen()) { + input_handler.consume_events(&window); + input_handler.set_flags(); // Poll for events from the user sf::Event event; while (window.pollEvent(event)) { @@ -156,6 +161,15 @@ int main() { if (event.type == sf::Event::Closed) window.close(); + if (event.type == sf::Event::KeyPressed) { + std::cout << event.key.code << std::endl; + } + if (event.type == sf::Event::KeyReleased) { + std::cout << event.key.code << std::endl; + } + + + if (event.type == sf::Event::KeyPressed) { if (event.key.code == sf::Keyboard::M) { if (mouse_enabled)