More tweaking and refactoring

master
MitchellHansen 7 years ago
parent e0cb26a9d1
commit 0b42481020

@ -11,8 +11,6 @@ public:
bool init(std::string root_config_path); bool init(std::string root_config_path);
private: private:

@ -153,7 +153,7 @@ public:
// Queries hardware, creates the command queue and context, and compiles kernel // Queries hardware, creates the command queue and context, and compiles kernel
int init(); bool init();
// Creates a texture to send to the GPU via height and width // Creates a texture to send to the GPU via height and width
// Creates a viewport vector array via vertical and horizontal fov // Creates a viewport vector array via vertical and horizontal fov
@ -164,12 +164,13 @@ public:
bool assign_lights(std::vector<PackedData> *data) ; bool assign_lights(std::vector<PackedData> *data) ;
// We take a ptr to the map and create the map, and map_dimensions buffer for the GPU // We take a ptr to the map and create the map, and map_dimensions buffer for the GPU
bool assign_map(Old_Map *map) ; bool assign_map(std::shared_ptr<Old_Map> map);
bool release_map();
// We take a ptr to the camera and create a camera direction and position buffer // We take a ptr to the camera and create a camera direction and position buffer
bool assign_camera(Camera *camera) ; bool assign_camera(std::shared_ptr<Camera> camera);
bool release_camera();
// TODO: Hoist this to the base class
// Creates 3 buffers relating to the texture atlas: texture_atlas, atlas_dim, and tile_dim // Creates 3 buffers relating to the texture atlas: texture_atlas, atlas_dim, and tile_dim
// With these on the GPU we can texture any quad with an atlas tile // With these on the GPU we can texture any quad with an atlas tile
bool create_texture_atlas(sf::Texture *t, sf::Vector2i tile_dim); bool create_texture_atlas(sf::Texture *t, sf::Vector2i tile_dim);
@ -183,7 +184,10 @@ public:
// Take the viewport sprite and draw it to the screen // Take the viewport sprite and draw it to the screen
void draw(sf::RenderWindow* window) ; void draw(sf::RenderWindow* window) ;
// Load the saved device config from a file
bool load_config(); bool load_config();
// Save the chosen device config to a file
void save_config(); void save_config();
// ================================== DEBUG ======================================= // ================================== DEBUG =======================================
@ -196,17 +200,14 @@ public:
private: private:
// Iterate the devices available and choose the best one // Cycle through the OpenCL devices and store *all* of their data, not super useful
// Also checks for the sharing extension bool query_hardware();
int acquire_platform_and_device();
// Cycle through the OpenCL devices and store only the minimal amount of data that we need
bool aquire_hardware(); bool aquire_hardware();
bool query_hardware(); // Create a shared cl_gl context with respect to the individual platforms implementation of sharing
bool create_shared_context();
// With respect to the individual platforms implementation of sharing
// create a shared cl_gl context
int create_shared_context();
// Using the context and the device create a command queue for them // Using the context and the device create a command queue for them
bool create_command_queue(); bool create_command_queue();
@ -241,18 +242,23 @@ private:
// Run a test kernel that prints out the kernel args // Run a test kernel that prints out the kernel args
void print_kernel_arguments(); void print_kernel_arguments();
// CL error code handler. ImGui overlaps the assert() function annoyingly so I had to rename it // Cl can return 0 or 1 for success, greater or lower for fail. Return true or false based on that requirement
static bool cl_assert(int error_code); static bool cl_assert(int error_code);
// Take an integer error code and return the string of the related CL ENUM
static std::string cl_err_lookup(int error_code); static std::string cl_err_lookup(int error_code);
//static bool vr_assert(int error_code)
// Setters and getters
cl_device_id getDeviceID(); cl_device_id getDeviceID();
cl_platform_id getPlatformID(); cl_platform_id getPlatformID();
cl_context getContext(); cl_context getContext();
cl_kernel getKernel(std::string kernel_name); cl_kernel getKernel(std::string kernel_name);
cl_command_queue getCommandQueue(); cl_command_queue getCommandQueue();
// Our device data // List of queried devices
std::vector<device> device_list;
// Our picked device data
cl_platform_id platform_id; cl_platform_id platform_id;
cl_device_id device_id; cl_device_id device_id;
@ -265,21 +271,22 @@ private:
std::map<std::string, cl_mem> buffer_map; std::map<std::string, cl_mem> buffer_map;
std::unordered_map<std::string, std::pair<sf::Sprite, std::unique_ptr<sf::Texture>>> image_map; std::unordered_map<std::string, std::pair<sf::Sprite, std::unique_ptr<sf::Texture>>> image_map;
// Hardware caster holds and renders its own textures
sf::Sprite viewport_sprite; sf::Sprite viewport_sprite;
sf::Texture viewport_texture; sf::Texture viewport_texture;
Old_Map * map = nullptr;
Camera *camera = nullptr;
// std::vector<LightController::PackedData> *lights;
std::vector<PackedData> *lights;
int light_count = 0;
sf::Uint8 *viewport_image = nullptr; sf::Uint8 *viewport_image = nullptr;
sf::Vector4f *viewport_matrix = nullptr; sf::Vector4f *viewport_matrix = nullptr;
sf::Vector2i viewport_resolution; sf::Vector2i viewport_resolution;
int error = 0; std::shared_ptr<Camera> camera;
std::shared_ptr<Old_Map> map;
std::vector<device> device_list; std::vector<PackedData> *lights;
int light_count = 0;
int error = 0;
}; };

@ -44,6 +44,14 @@ public:
virtual void recieve_event(VrEventPublisher* publisher, std::unique_ptr<vr::Event>(event)) override { virtual void recieve_event(VrEventPublisher* publisher, std::unique_ptr<vr::Event>(event)) override {
if (event.get()->type == vr::Event::Closed) { if (event.get()->type == vr::Event::Closed) {
window_ref->close(); window_ref->close();
} else if (event.get()->type == vr::Event::KeyPressed) {
vr::KeyPressed *key_event = static_cast<vr::KeyPressed*>(event.get());
if (key_event->code == sf::Keyboard::Escape) {
window_ref->close();
}
} }
}; };

@ -8,9 +8,9 @@
#include "LightHandle.h" #include "LightHandle.h"
// Lighting is a bit tricky as we need to // Typical light workflow:
// 1.) Create light prototype with desired values
// 2.) Submit prototype to the LightController
struct LightPrototype { struct LightPrototype {
@ -56,6 +56,7 @@ public:
LightController(std::shared_ptr<Hardware_Caster> raycaster); LightController(std::shared_ptr<Hardware_Caster> raycaster);
~LightController(); ~LightController();
// find a free light 'slot' and create
std::shared_ptr<LightHandle> create_light(LightPrototype light_prototype); std::shared_ptr<LightHandle> create_light(LightPrototype light_prototype);
void remove_light(unsigned int light_index); void remove_light(unsigned int light_index);

@ -2,14 +2,13 @@
#include "Pub_Sub.h" #include "Pub_Sub.h"
Camera::Camera() { Camera::Camera() {}
}
Camera::Camera(sf::Vector3f position, sf::Vector2f direction, sf::RenderWindow* window) : Camera::Camera(sf::Vector3f position, sf::Vector2f direction, sf::RenderWindow* window) :
position(position), direction(direction), window(window) position(position), direction(direction), window(window) {
{
fixed = sf::Vector2i(sf::Vector2i(window->getSize().x/2, window->getSize().y/2)); fixed = sf::Vector2i(sf::Vector2i(window->getSize().x/2, window->getSize().y/2));
} }
Camera::~Camera() { Camera::~Camera() {

@ -4,7 +4,7 @@
Hardware_Caster::Hardware_Caster() {} Hardware_Caster::Hardware_Caster() {}
Hardware_Caster::~Hardware_Caster() {} Hardware_Caster::~Hardware_Caster() {}
int Hardware_Caster::init() { bool Hardware_Caster::init() {
Logger::log("Initializing the Hardware Caster", Logger::LogLevel::INFO); Logger::log("Initializing the Hardware Caster", Logger::LogLevel::INFO);
@ -68,68 +68,99 @@ int Hardware_Caster::init() {
} }
bool Hardware_Caster::assign_map(Old_Map *map) { bool Hardware_Caster::assign_map(std::shared_ptr<Old_Map> map) {
this->map = map; this->map = map;
auto dimensions = map->getDimensions(); auto dimensions = map->getDimensions();
if (!create_buffer("map", sizeof(char) * dimensions.x * dimensions.y * dimensions.z, map->get_voxel_data())) if (!create_buffer("map", sizeof(char) * dimensions.x * dimensions.y * dimensions.z, map->get_voxel_data()))
return false; return false;
if (!create_buffer("map_dimensions", sizeof(int) * 3, &dimensions)) if (!create_buffer("map_dimensions", sizeof(int) * 3, &dimensions))
return false; return false;
return true;
}
bool Hardware_Caster::release_map() {
this->map = nullptr;
if (!release_buffer("map"))
return false;
if (!release_buffer("map_dimensions"))
return false;
return true; return true;
} }
bool Hardware_Caster::assign_camera(Camera *camera) {
bool Hardware_Caster::assign_camera(std::shared_ptr<Camera> camera) {
this->camera = camera; this->camera = camera;
if (!create_buffer("camera_direction", sizeof(float) * 4, (void*)camera->get_direction_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR)) if (!create_buffer("camera_direction", sizeof(float) * 4, (void*)camera->get_direction_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR))
return false; return false;
if (!create_buffer("camera_position", sizeof(float) * 4, (void*)camera->get_position_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR)) if (!create_buffer("camera_position", sizeof(float) * 4, (void*)camera->get_position_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR))
return false; return false;
return true; return true;
} }
bool Hardware_Caster::validate() { bool Hardware_Caster::release_camera() {
Logger::log("Validating OpenCL kernel args", Logger::LogLevel::INFO); this->camera = nullptr;
// Check to make sure everything has been entered; if (!release_buffer("camera_direction"))
if (camera == nullptr || return false;
map == nullptr ||
viewport_image == nullptr ||
viewport_matrix == nullptr) {
Logger::log("Raycaster.validate() failed, camera, map, or viewport not initialized", Logger::LogLevel::WARN); if (!release_buffer("camera_position"))
return false; return false;
} else { return true;
}
// Set all the kernel args
set_kernel_arg("raycaster", 0, "map");
set_kernel_arg("raycaster", 1, "map_dimensions");
set_kernel_arg("raycaster", 2, "viewport_resolution");
set_kernel_arg("raycaster", 3, "viewport_matrix");
set_kernel_arg("raycaster", 4, "camera_direction");
set_kernel_arg("raycaster", 5, "camera_position");
set_kernel_arg("raycaster", 6, "lights");
set_kernel_arg("raycaster", 7, "light_count");
set_kernel_arg("raycaster", 8, "image");
set_kernel_arg("raycaster", 9, "seed");
set_kernel_arg("raycaster", 10, "texture_atlas");
set_kernel_arg("raycaster", 11, "atlas_dim");
set_kernel_arg("raycaster", 12, "tile_dim");
return true; bool Hardware_Caster::validate() {
//print_kernel_arguments();
} Logger::log("Validating OpenCL kernel args", Logger::LogLevel::INFO);
// Check to make sure everything has been entered
if (!camera.get()) {
Logger::log("Raycaster.validate() failed, camera not initialized", Logger::LogLevel::WARN);
return false;
}
if (!map.get()) {
Logger::log("Raycaster.validate() failed, map not initialized", Logger::LogLevel::WARN);
return false;
}
if (!viewport_image) {
Logger::log("Raycaster.validate() failed, viewport_image not initialized", Logger::LogLevel::WARN);
return false;
}
if (!viewport_matrix) {
Logger::log("Raycaster.validate() failed, viewport_matrix not initialized", Logger::LogLevel::WARN);
return false;
}
// Set all the kernel args
set_kernel_arg("raycaster", 0, "map");
set_kernel_arg("raycaster", 1, "map_dimensions");
set_kernel_arg("raycaster", 2, "viewport_resolution");
set_kernel_arg("raycaster", 3, "viewport_matrix");
set_kernel_arg("raycaster", 4, "camera_direction");
set_kernel_arg("raycaster", 5, "camera_position");
set_kernel_arg("raycaster", 6, "lights");
set_kernel_arg("raycaster", 7, "light_count");
set_kernel_arg("raycaster", 8, "image");
set_kernel_arg("raycaster", 9, "seed");
set_kernel_arg("raycaster", 10, "texture_atlas");
set_kernel_arg("raycaster", 11, "atlas_dim");
set_kernel_arg("raycaster", 12, "tile_dim");
return true;
} }
bool Hardware_Caster::create_texture_atlas(sf::Texture *t, sf::Vector2i tile_dim) { bool Hardware_Caster::create_texture_atlas(sf::Texture *t, sf::Vector2i tile_dim) {
@ -500,7 +531,8 @@ bool Hardware_Caster::query_hardware()
return true; return true;
} }
int Hardware_Caster::create_shared_context() { bool Hardware_Caster::create_shared_context()
{
// Hurray for standards! // Hurray for standards!
// Setup the context properties to grab the current GL context // Setup the context properties to grab the current GL context

@ -2,8 +2,10 @@
LightController::LightController(std::shared_ptr<Hardware_Caster> raycaster) : packed_data_array(reserved_count), open_list(reserved_count) { LightController::LightController(std::shared_ptr<Hardware_Caster> raycaster) : packed_data_array(reserved_count), open_list(reserved_count) {
// initialize the open list with numbers 1 -> open_list.size()
std::iota(open_list.begin(), open_list.end(), 0); std::iota(open_list.begin(), open_list.end(), 0);
//
raycaster->assign_lights(&packed_data_array); raycaster->assign_lights(&packed_data_array);
} }

@ -85,13 +85,8 @@ int main() {
srand(time(nullptr)); srand(time(nullptr));
// =============================
Map _map(32); Map _map(32);
//_map.test();
//std::cin.get();
//return 0; //return 0;
// =============================
sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML"); sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML");
window.setMouseCursorVisible(false); window.setMouseCursorVisible(false);
@ -104,24 +99,22 @@ int main() {
// Start up the raycaster // Start up the raycaster
std::shared_ptr<Hardware_Caster> raycaster(new Hardware_Caster()); std::shared_ptr<Hardware_Caster> raycaster(new Hardware_Caster());
if (!raycaster->init())
if (raycaster->init() != 1) {
abort(); abort();
}
// Create and generate the old 3d array style map // Create and generate the old 3d array style map
Old_Map* map = new Old_Map(sf::Vector3i(MAP_X, MAP_Y, MAP_Z)); std::shared_ptr<Old_Map> map(new Old_Map(sf::Vector3i(MAP_X, MAP_Y, MAP_Z)));
map->generate_terrain(); map->generate_terrain();
// Send the data to the GPU // Send the data to the GPU
raycaster->assign_map(map); raycaster->assign_map(map);
// Create a new camera with (starting position, direction) // Create a new camera with (starting position, direction)
Camera *camera = new Camera( std::shared_ptr<Camera> camera(new Camera(
sf::Vector3f(50, 50, 50), sf::Vector3f(50, 50, 50),
sf::Vector2f(1.5f, 0.0f), sf::Vector2f(1.5f, 0.0f),
&window &window
); ));
// *link* the camera to the GPU // *link* the camera to the GPU
raycaster->assign_camera(camera); raycaster->assign_camera(camera);
@ -129,59 +122,65 @@ int main() {
// Generate and send the viewport to the GPU. Also creates the viewport texture // Generate and send the viewport to the GPU. Also creates the viewport texture
raycaster->create_viewport(WINDOW_X, WINDOW_Y, 0.625f * 90.0f, 90.0f); raycaster->create_viewport(WINDOW_X, WINDOW_Y, 0.625f * 90.0f, 90.0f);
float w = 60.0; // Initialize the light controller and link it to the GPU
float h = 90.0;
LightController light_controller(raycaster); LightController light_controller(raycaster);
// Create a light prototype, send it to the controller, and get the handle back
LightPrototype prototype( LightPrototype prototype(
sf::Vector3f(100.0f, 100.0f, 75.0f), sf::Vector3f(100.0f, 100.0f, 75.0f),
sf::Vector3f(-1.0f, -1.0f, -1.5f), sf::Vector3f(-1.0f, -1.0f, -1.5f),
sf::Vector4f(0.4f, 0.4f, 0.4f, 1.0f) sf::Vector4f(0.4f, 0.4f, 0.4f, 1.0f)
); );
std::shared_ptr<LightHandle> light_handle(light_controller.create_light(prototype));
std::shared_ptr<LightHandle> handle(light_controller.create_light(prototype));
// Load in the spritesheet texture // Load in the spritesheet texture
sf::Texture spritesheet; sf::Texture spritesheet;
spritesheet.loadFromFile("../assets/textures/minecraft_tiles.png"); if (!spritesheet.loadFromFile("../assets/textures/minecraft_tiles.png"))
Logger::log("Failed to load spritesheet from file", Logger::LogLevel::WARN);
raycaster->create_texture_atlas(&spritesheet, sf::Vector2i(16, 16)); raycaster->create_texture_atlas(&spritesheet, sf::Vector2i(16, 16));
// Checks to see if proper data was uploaded, then sets the kernel args // Checks to see if proper data was uploaded, then sets the kernel args
// ALL DATA LOADING MUST BE FINISHED // ALL DATA LOADING MUST BE FINISHED
raycaster->validate(); if (!raycaster->validate()) {
abort();
};
// Start up the input handler and link the camera to some of the events
Input input_handler; Input input_handler;
camera->subscribe_to_publisher(&input_handler, vr::Event::EventType::KeyHeld); camera->subscribe_to_publisher(&input_handler, vr::Event::EventType::KeyHeld);
camera->subscribe_to_publisher(&input_handler, vr::Event::EventType::KeyPressed); camera->subscribe_to_publisher(&input_handler, vr::Event::EventType::KeyPressed);
camera->subscribe_to_publisher(&input_handler, vr::Event::EventType::MouseMoved); camera->subscribe_to_publisher(&input_handler, vr::Event::EventType::MouseMoved);
camera->subscribe_to_publisher(&input_handler, vr::Event::EventType::MouseButtonPressed); camera->subscribe_to_publisher(&input_handler, vr::Event::EventType::MouseButtonPressed);
// Start up a window handler which subscribes to input and listens for window closed events
WindowHandler win_hand(&window); WindowHandler win_hand(&window);
win_hand.subscribe_to_publisher(&input_handler, vr::Event::EventType::Closed); win_hand.subscribe_to_publisher(&input_handler, vr::Event::EventType::Closed);
win_hand.subscribe_to_publisher(&input_handler, vr::Event::EventType::KeyPressed);
float step_size = 0.0166f;
double frame_time = 0.0,
elapsed_time = 0.0,
delta_time = 0.0,
accumulator_time = 0.0,
current_time = 0.0;
// The sfml imgui wrapper I'm using requires Update be called with sf::Time // The sfml imgui wrapper I'm using requires Update be called with sf::Time
// Might modify it to also accept seconds // Might modify it to also accept seconds
sf::Clock sf_delta_clock; sf::Clock sf_delta_clock;
fps_counter fps; fps_counter fps;
// vars for us to use with ImGUI
float light_color[4] = { 0, 0, 0, 0 }; float light_color[4] = { 0, 0, 0, 0 };
float light_pos[4] = { 100, 100, 30 }; float light_pos[4] = { 100, 100, 30 };
char screenshot_buf[128]{0}; char screenshot_buf[128]{0};
bool paused = false; bool paused = false;
float camera_speed = 1.0; float camera_speed = 1.0;
// Game loop values
float step_size = 0.0166f;
double frame_time = 0.0,
elapsed_time = 0.0,
delta_time = 0.0,
accumulator_time = 0.0,
current_time = 0.0;
while (window.isOpen()) { while (window.isOpen()) {
// Have the input handler empty the event stack, generate events for held keys, and then dispatch the events to listeners
input_handler.consume_sf_events(&window); input_handler.consume_sf_events(&window);
input_handler.handle_held_keys(); input_handler.handle_held_keys();
input_handler.dispatch_events(); input_handler.dispatch_events();
@ -205,15 +204,18 @@ int main() {
ImGui::SFML::Update(window, sf_delta_clock.restart()); ImGui::SFML::Update(window, sf_delta_clock.restart());
// Pausing stops camera and light updates, as well as raycaster computes
if (!paused) { if (!paused) {
camera->update(delta_time); camera->update(delta_time);
handle->update(delta_time); light_handle->update(delta_time);
// Run the raycast // Run the raycast
raycaster->compute(); if (!raycaster->compute()) {
abort();
};
} }
// Let the raycaster draw it screen buffer
raycaster->draw(&window); raycaster->draw(&window);
// Give the frame counter the frame time and draw the average frame time // Give the frame counter the frame time and draw the average frame time
@ -292,7 +294,7 @@ int main() {
if (ImGui::SliderFloat4("Color", light_color, 0, 1)) { if (ImGui::SliderFloat4("Color", light_color, 0, 1)) {
sf::Vector4f light(light_color[0], light_color[1], light_color[2], light_color[3]); sf::Vector4f light(light_color[0], light_color[1], light_color[2], light_color[3]);
handle->set_rgbi(light); light_handle->set_rgbi(light);
} }
if (ImGui::SliderFloat("Camera Speed", &camera_speed, 0, 4)) { if (ImGui::SliderFloat("Camera Speed", &camera_speed, 0, 4)) {
@ -301,7 +303,7 @@ int main() {
if (ImGui::SliderFloat3("Position", light_pos, 0, MAP_X)) { if (ImGui::SliderFloat3("Position", light_pos, 0, MAP_X)) {
sf::Vector3f light(light_pos[0], light_pos[1], light_pos[2]); sf::Vector3f light(light_pos[0], light_pos[1], light_pos[2]);
handle->set_position(light); light_handle->set_position(light);
} }
if (ImGui::CollapsingHeader("Window options")) if (ImGui::CollapsingHeader("Window options"))
@ -317,7 +319,8 @@ int main() {
ImGui::Render(); ImGui::Render();
// ImGUI messes up somthing in the SFML GL state, so we need a single draw call to right things
// then we can move on to flip the screen buffer via display
window.draw(sf::CircleShape(0)); window.draw(sf::CircleShape(0));
window.display(); window.display();

@ -52,12 +52,10 @@ bool Map::test_oct_arr_traversal(sf::Vector3i dimensions) {
} }
void Map::setVoxel(sf::Vector3i pos, int val) { void Map::setVoxel(sf::Vector3i pos, int val) {
voxel_data[pos.x + OCT_DIM * (pos.y + OCT_DIM * pos.z)] = val; voxel_data[pos.x + OCT_DIM * (pos.y + OCT_DIM * pos.z)] = val;
} }
char Map::getVoxel(sf::Vector3i pos){ char Map::getVoxel(sf::Vector3i pos){
return octree.GetVoxel(pos).found; return octree.GetVoxel(pos).found;
} }

Loading…
Cancel
Save