Added a quick printout of the hardware info. Running into a problem choosing between platforms, going to abstract CL out into it's own class and hide all that logic
This commit is contained in:
374
src/Curses.cpp
374
src/Curses.cpp
@@ -1,187 +1,187 @@
|
||||
#pragma once
|
||||
#include "Curses.h"
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
Curses::Curses(sf::Vector2i tile_size_, sf::Vector2i grid_dimensions_) :
|
||||
window(sf::VideoMode(tile_size_.x * grid_dimensions_.x, tile_size_.y * grid_dimensions_.y), "SimpleFML Curses"),
|
||||
grid_dimensions(grid_dimensions_),
|
||||
tile_pixel_dimensions(tile_size_){
|
||||
|
||||
font.loadFromFile("unifont.ttf");
|
||||
|
||||
for (int y = 0; y < grid_dimensions_.y; y++) {
|
||||
for (int x = 0 ; x < grid_dimensions_.x; x++) {
|
||||
tiles.emplace_back(Tile(sf::Vector2i(x, y)));
|
||||
|
||||
// L'\u0020' = space char
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set screen values to increasing unicode chars
|
||||
/*wchar_t char_ind = L'\u0041';
|
||||
for (int i = 0; i < tiles.size(); i++) {
|
||||
tiles.at(i).push_clear(char_ind++, sf::Color::White, sf::Color::Black);
|
||||
}*/
|
||||
}
|
||||
|
||||
Curses::~Curses() {
|
||||
}
|
||||
|
||||
void Curses::Update(double delta_time_) {
|
||||
|
||||
for (Tile &tile : tiles) {
|
||||
tile.inc_index();
|
||||
}
|
||||
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event)) {
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
|
||||
void Curses::Render() {
|
||||
window.clear();
|
||||
|
||||
sf::Texture font_texture = font.getTexture(tile_pixel_dimensions.x);
|
||||
|
||||
// Draw text and backfills
|
||||
sf::VertexArray backfill_v_arr(sf::Quads, grid_dimensions.x * grid_dimensions.y * 4);
|
||||
sf::VertexArray font_v_arr(sf::Quads, grid_dimensions.x * grid_dimensions.y * 4);
|
||||
|
||||
int tile_index = 0;
|
||||
|
||||
for (int i = 0; i < backfill_v_arr.getVertexCount(); i += 4) {
|
||||
|
||||
Tile* tile = &tiles.at(tile_index);
|
||||
sf::Glyph glyph = font.getGlyph(tile->current_unicode_value(), tile_pixel_dimensions.x, false);
|
||||
|
||||
// Backfill the tile with the specified backfill color
|
||||
backfill_v_arr[i + 0].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y);
|
||||
backfill_v_arr[i + 1].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x + tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y);
|
||||
backfill_v_arr[i + 2].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x + tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y + tile_pixel_dimensions.y);
|
||||
backfill_v_arr[i + 3].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y + tile_pixel_dimensions.y);
|
||||
|
||||
backfill_v_arr[i + 0].color = tile->current_backfill_color();
|
||||
backfill_v_arr[i + 1].color = tile->current_backfill_color();
|
||||
backfill_v_arr[i + 2].color = tile->current_backfill_color();
|
||||
backfill_v_arr[i + 3].color = tile->current_backfill_color();
|
||||
|
||||
// Draw the font with the correct size, texture location, window location, and color
|
||||
font_v_arr[i + 0].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y);
|
||||
font_v_arr[i + 1].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x + glyph.textureRect.width, tile->getPosition().y * tile_pixel_dimensions.y);
|
||||
font_v_arr[i + 2].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x + glyph.textureRect.width, tile->getPosition().y * tile_pixel_dimensions.y + glyph.textureRect.height);
|
||||
font_v_arr[i + 3].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y + glyph.textureRect.height);
|
||||
|
||||
// Make the letter appear in the center of the tile by applying an offset
|
||||
sf::Vector2f position_offset = sf::Vector2f(tile_pixel_dimensions.x / 4, tile_pixel_dimensions.y / 4);
|
||||
font_v_arr[i + 0].position += position_offset;
|
||||
font_v_arr[i + 1].position += position_offset;
|
||||
font_v_arr[i + 2].position += position_offset;
|
||||
font_v_arr[i + 3].position += position_offset;
|
||||
|
||||
font_v_arr[i + 0].texCoords = sf::Vector2f(glyph.textureRect.left, glyph.textureRect.top);
|
||||
font_v_arr[i + 1].texCoords = sf::Vector2f(glyph.textureRect.width + glyph.textureRect.left, glyph.textureRect.top);
|
||||
font_v_arr[i + 2].texCoords = sf::Vector2f(glyph.textureRect.width + glyph.textureRect.left, glyph.textureRect.top + glyph.textureRect.height);
|
||||
font_v_arr[i + 3].texCoords = sf::Vector2f(glyph.textureRect.left, glyph.textureRect.top + glyph.textureRect.height);
|
||||
|
||||
font_v_arr[i + 0].color = tile->current_font_color();
|
||||
font_v_arr[i + 1].color = tile->current_font_color();
|
||||
font_v_arr[i + 2].color = tile->current_font_color();
|
||||
font_v_arr[i + 3].color = tile->current_font_color();
|
||||
|
||||
tile_index++;
|
||||
}
|
||||
|
||||
window.draw(backfill_v_arr);
|
||||
window.draw(font_v_arr, &font_texture);
|
||||
|
||||
window.display();
|
||||
}
|
||||
|
||||
void Curses::setTile(Tile tile_) {
|
||||
tiles.at(multi_to_linear(tile_.getPosition())) = tile_;
|
||||
}
|
||||
|
||||
void Curses::setTiles(std::vector<Tile> tiles_) {
|
||||
for (Tile tile: tiles_) {
|
||||
tiles.at(multi_to_linear(tile.getPosition())) = tile;
|
||||
}
|
||||
}
|
||||
|
||||
void Curses::Clear() {
|
||||
for (Tile &tile : tiles) {
|
||||
tile.clear();
|
||||
}
|
||||
}
|
||||
|
||||
Curses::Tile* Curses::getTile(sf::Vector2i position_) {
|
||||
return &tiles.at(multi_to_linear(position_));
|
||||
}
|
||||
|
||||
std::vector<Curses::Tile*> Curses::getTiles(sf::Vector2i start_, sf::Vector2i end_) {
|
||||
std::vector<Curses::Tile*> ret;
|
||||
for (int i = multi_to_linear(start_); i < multi_to_linear(end_); i++) {
|
||||
ret.push_back(&tiles.at(i));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Curses::setScroll(int ratio_, sf::Vector2i start_, std::list<Slot> scroll_text_) {
|
||||
// Scrolling and it's scroll ratio is faux implemented by
|
||||
// essentially stacking values and repeating them to slow the scroll down
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < scroll_text_.size(); i++) {
|
||||
append_slots(start_, scroll_text_);
|
||||
scroll_text_.push_back(scroll_text_.front());
|
||||
scroll_text_.pop_front();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Curses::set_tile_ratio(int ratio_, sf::Vector2i tile_position_) {
|
||||
getTile(tile_position_)->set_ratio(ratio_);
|
||||
}
|
||||
|
||||
void Curses::append_slots(sf::Vector2i start_, std::list<Slot> values_)
|
||||
{
|
||||
std::vector<Tile*> tiles = getTiles(start_,
|
||||
sf::Vector2i((values_.size() + start_.x) % grid_dimensions.x,
|
||||
(values_.size() + start_.x) / grid_dimensions.x + start_.y));
|
||||
|
||||
if (tiles.size() != values_.size()) {
|
||||
std::cout << "Values did not match up to slots when appending\n";
|
||||
return;
|
||||
}
|
||||
|
||||
std::list<Slot>::iterator beg_slot_it = values_.begin();
|
||||
std::list<Slot>::iterator end_slot_it = values_.end();
|
||||
std::list<Slot>::iterator slot_it;
|
||||
|
||||
std::vector<Tile*>::iterator beg_tile_it = tiles.begin();
|
||||
std::vector<Tile*>::iterator end_tile_it = tiles.end();
|
||||
std::vector<Tile*>::iterator tile_it;
|
||||
|
||||
for (slot_it = beg_slot_it, tile_it = beg_tile_it;
|
||||
(slot_it != end_slot_it) && (tile_it != end_tile_it);
|
||||
++slot_it, ++tile_it) {
|
||||
|
||||
Tile* t = *tile_it;
|
||||
t->push_back(*slot_it);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sf::Vector2i Curses::linear_to_multi(int position_) const {
|
||||
return sf::Vector2i(position_ % grid_dimensions.x, position_ / grid_dimensions.x);
|
||||
}
|
||||
int Curses::multi_to_linear(sf::Vector2i position_) const {
|
||||
return position_.y * grid_dimensions.x + position_.x;
|
||||
}
|
||||
#pragma once
|
||||
#include "Curses.h"
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
Curses::Curses(sf::Vector2i tile_size_, sf::Vector2i grid_dimensions_) :
|
||||
window(sf::VideoMode(tile_size_.x * grid_dimensions_.x, tile_size_.y * grid_dimensions_.y), "SimpleFML Curses"),
|
||||
grid_dimensions(grid_dimensions_),
|
||||
tile_pixel_dimensions(tile_size_){
|
||||
|
||||
font.loadFromFile("unifont.ttf");
|
||||
|
||||
for (int y = 0; y < grid_dimensions_.y; y++) {
|
||||
for (int x = 0 ; x < grid_dimensions_.x; x++) {
|
||||
tiles.emplace_back(Tile(sf::Vector2i(x, y)));
|
||||
|
||||
// L'\u0020' = space char
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set screen values to increasing unicode chars
|
||||
/*wchar_t char_ind = L'\u0041';
|
||||
for (int i = 0; i < tiles.size(); i++) {
|
||||
tiles.at(i).push_clear(char_ind++, sf::Color::White, sf::Color::Black);
|
||||
}*/
|
||||
}
|
||||
|
||||
Curses::~Curses() {
|
||||
}
|
||||
|
||||
void Curses::Update(double delta_time_) {
|
||||
|
||||
for (Tile &tile : tiles) {
|
||||
tile.inc_index();
|
||||
}
|
||||
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event)) {
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
|
||||
void Curses::Render() {
|
||||
window.clear();
|
||||
|
||||
sf::Texture font_texture = font.getTexture(tile_pixel_dimensions.x);
|
||||
|
||||
// Draw text and backfills
|
||||
sf::VertexArray backfill_v_arr(sf::Quads, grid_dimensions.x * grid_dimensions.y * 4);
|
||||
sf::VertexArray font_v_arr(sf::Quads, grid_dimensions.x * grid_dimensions.y * 4);
|
||||
|
||||
int tile_index = 0;
|
||||
|
||||
for (int i = 0; i < backfill_v_arr.getVertexCount(); i += 4) {
|
||||
|
||||
Tile* tile = &tiles.at(tile_index);
|
||||
sf::Glyph glyph = font.getGlyph(tile->current_unicode_value(), tile_pixel_dimensions.x, false);
|
||||
|
||||
// Backfill the tile with the specified backfill color
|
||||
backfill_v_arr[i + 0].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y);
|
||||
backfill_v_arr[i + 1].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x + tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y);
|
||||
backfill_v_arr[i + 2].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x + tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y + tile_pixel_dimensions.y);
|
||||
backfill_v_arr[i + 3].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y + tile_pixel_dimensions.y);
|
||||
|
||||
backfill_v_arr[i + 0].color = tile->current_backfill_color();
|
||||
backfill_v_arr[i + 1].color = tile->current_backfill_color();
|
||||
backfill_v_arr[i + 2].color = tile->current_backfill_color();
|
||||
backfill_v_arr[i + 3].color = tile->current_backfill_color();
|
||||
|
||||
// Draw the font with the correct size, texture location, window location, and color
|
||||
font_v_arr[i + 0].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y);
|
||||
font_v_arr[i + 1].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x + glyph.textureRect.width, tile->getPosition().y * tile_pixel_dimensions.y);
|
||||
font_v_arr[i + 2].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x + glyph.textureRect.width, tile->getPosition().y * tile_pixel_dimensions.y + glyph.textureRect.height);
|
||||
font_v_arr[i + 3].position = sf::Vector2f(tile->getPosition().x * tile_pixel_dimensions.x, tile->getPosition().y * tile_pixel_dimensions.y + glyph.textureRect.height);
|
||||
|
||||
// Make the letter appear in the center of the tile by applying an offset
|
||||
sf::Vector2f position_offset = sf::Vector2f(tile_pixel_dimensions.x / 4, tile_pixel_dimensions.y / 4);
|
||||
font_v_arr[i + 0].position += position_offset;
|
||||
font_v_arr[i + 1].position += position_offset;
|
||||
font_v_arr[i + 2].position += position_offset;
|
||||
font_v_arr[i + 3].position += position_offset;
|
||||
|
||||
font_v_arr[i + 0].texCoords = sf::Vector2f(glyph.textureRect.left, glyph.textureRect.top);
|
||||
font_v_arr[i + 1].texCoords = sf::Vector2f(glyph.textureRect.width + glyph.textureRect.left, glyph.textureRect.top);
|
||||
font_v_arr[i + 2].texCoords = sf::Vector2f(glyph.textureRect.width + glyph.textureRect.left, glyph.textureRect.top + glyph.textureRect.height);
|
||||
font_v_arr[i + 3].texCoords = sf::Vector2f(glyph.textureRect.left, glyph.textureRect.top + glyph.textureRect.height);
|
||||
|
||||
font_v_arr[i + 0].color = tile->current_font_color();
|
||||
font_v_arr[i + 1].color = tile->current_font_color();
|
||||
font_v_arr[i + 2].color = tile->current_font_color();
|
||||
font_v_arr[i + 3].color = tile->current_font_color();
|
||||
|
||||
tile_index++;
|
||||
}
|
||||
|
||||
window.draw(backfill_v_arr);
|
||||
window.draw(font_v_arr, &font_texture);
|
||||
|
||||
window.display();
|
||||
}
|
||||
|
||||
void Curses::setTile(Tile tile_) {
|
||||
tiles.at(multi_to_linear(tile_.getPosition())) = tile_;
|
||||
}
|
||||
|
||||
void Curses::setTiles(std::vector<Tile> tiles_) {
|
||||
for (Tile tile: tiles_) {
|
||||
tiles.at(multi_to_linear(tile.getPosition())) = tile;
|
||||
}
|
||||
}
|
||||
|
||||
void Curses::Clear() {
|
||||
for (Tile &tile : tiles) {
|
||||
tile.clear();
|
||||
}
|
||||
}
|
||||
|
||||
Curses::Tile* Curses::getTile(sf::Vector2i position_) {
|
||||
return &tiles.at(multi_to_linear(position_));
|
||||
}
|
||||
|
||||
std::vector<Curses::Tile*> Curses::getTiles(sf::Vector2i start_, sf::Vector2i end_) {
|
||||
std::vector<Curses::Tile*> ret;
|
||||
for (int i = multi_to_linear(start_); i < multi_to_linear(end_); i++) {
|
||||
ret.push_back(&tiles.at(i));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Curses::setScroll(int ratio_, sf::Vector2i start_, std::list<Slot> scroll_text_) {
|
||||
// Scrolling and it's scroll ratio is faux implemented by
|
||||
// essentially stacking values and repeating them to slow the scroll down
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < scroll_text_.size(); i++) {
|
||||
append_slots(start_, scroll_text_);
|
||||
scroll_text_.push_back(scroll_text_.front());
|
||||
scroll_text_.pop_front();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Curses::set_tile_ratio(int ratio_, sf::Vector2i tile_position_) {
|
||||
getTile(tile_position_)->set_ratio(ratio_);
|
||||
}
|
||||
|
||||
void Curses::append_slots(sf::Vector2i start_, std::list<Slot> values_)
|
||||
{
|
||||
std::vector<Tile*> tiles = getTiles(start_,
|
||||
sf::Vector2i((values_.size() + start_.x) % grid_dimensions.x,
|
||||
(values_.size() + start_.x) / grid_dimensions.x + start_.y));
|
||||
|
||||
if (tiles.size() != values_.size()) {
|
||||
std::cout << "Values did not match up to slots when appending\n";
|
||||
return;
|
||||
}
|
||||
|
||||
std::list<Slot>::iterator beg_slot_it = values_.begin();
|
||||
std::list<Slot>::iterator end_slot_it = values_.end();
|
||||
std::list<Slot>::iterator slot_it;
|
||||
|
||||
std::vector<Tile*>::iterator beg_tile_it = tiles.begin();
|
||||
std::vector<Tile*>::iterator end_tile_it = tiles.end();
|
||||
std::vector<Tile*>::iterator tile_it;
|
||||
|
||||
for (slot_it = beg_slot_it, tile_it = beg_tile_it;
|
||||
(slot_it != end_slot_it) && (tile_it != end_tile_it);
|
||||
++slot_it, ++tile_it) {
|
||||
|
||||
Tile* t = *tile_it;
|
||||
t->push_back(*slot_it);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sf::Vector2i Curses::linear_to_multi(int position_) const {
|
||||
return sf::Vector2i(position_ % grid_dimensions.x, position_ / grid_dimensions.x);
|
||||
}
|
||||
int Curses::multi_to_linear(sf::Vector2i position_) const {
|
||||
return position_.y * grid_dimensions.x + position_.x;
|
||||
}
|
||||
|
||||
146
src/Map.cpp
146
src/Map.cpp
@@ -1,73 +1,73 @@
|
||||
#pragma once
|
||||
#include "Map.h"
|
||||
#include <iostream>
|
||||
#include <SFML/System/Vector3.hpp>
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include "util.hpp"
|
||||
|
||||
sf::Vector3i Map::getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
void Map::moveLight(sf::Vector2f in) {
|
||||
|
||||
sf::Vector3f light_spherical = CartToSphere(global_light);
|
||||
|
||||
light_spherical.y += in.y;
|
||||
light_spherical.x += in.x;
|
||||
|
||||
global_light = SphereToCart(light_spherical);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//void Map::GenerateFloor(){
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include "Map.h"
|
||||
#include <iostream>
|
||||
#include <SFML/System/Vector3.hpp>
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include "util.hpp"
|
||||
|
||||
sf::Vector3i Map::getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
void Map::moveLight(sf::Vector2f in) {
|
||||
|
||||
sf::Vector3f light_spherical = CartToSphere(global_light);
|
||||
|
||||
light_spherical.y += in.y;
|
||||
light_spherical.x += in.x;
|
||||
|
||||
global_light = SphereToCart(light_spherical);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//void Map::GenerateFloor(){
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
318
src/Ray.cpp
318
src/Ray.cpp
@@ -1,159 +1,159 @@
|
||||
#pragma once
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <iostream>
|
||||
#include "Map.h"
|
||||
#include <Ray.h>
|
||||
#include "util.hpp"
|
||||
|
||||
Ray::Ray(
|
||||
Map *map,
|
||||
sf::Vector2<int> resolution,
|
||||
sf::Vector2<int> pixel,
|
||||
sf::Vector3<float> camera_position,
|
||||
sf::Vector3<float> ray_direction) {
|
||||
|
||||
this->pixel = pixel;
|
||||
this->map = map;
|
||||
origin = camera_position;
|
||||
direction = ray_direction;
|
||||
dimensions = map->getDimensions();
|
||||
}
|
||||
|
||||
sf::Color Ray::Cast() {
|
||||
|
||||
// Setup the voxel step based on what direction the ray is pointing
|
||||
sf::Vector3<int> voxel_step(1, 1, 1);
|
||||
voxel_step.x *= (direction.x > 0) - (direction.x < 0);
|
||||
voxel_step.y *= (direction.y > 0) - (direction.y < 0);
|
||||
voxel_step.z *= (direction.z > 0) - (direction.z < 0);
|
||||
|
||||
// Setup the voxel coords from the camera origin
|
||||
voxel = sf::Vector3<int>(
|
||||
floorf(origin.x),
|
||||
floorf(origin.y),
|
||||
floorf(origin.z)
|
||||
);
|
||||
|
||||
// Delta T is the units a ray must travel along an axis in order to
|
||||
// traverse an integer split
|
||||
delta_t = sf::Vector3<float>(
|
||||
fabsf(1.0f / direction.x),
|
||||
fabsf(1.0f / direction.y),
|
||||
fabsf(1.0f / direction.z)
|
||||
);
|
||||
|
||||
// Intersection T is the collection of the next intersection points
|
||||
// for all 3 axis XYZ.
|
||||
intersection_t = sf::Vector3<float>(
|
||||
delta_t.x,
|
||||
delta_t.y,
|
||||
delta_t.z
|
||||
);
|
||||
|
||||
|
||||
int dist = 0;
|
||||
int face = -1;
|
||||
// X:0, Y:1, Z:2
|
||||
|
||||
// Andrew Woo's raycasting algo
|
||||
do {
|
||||
if ((intersection_t.x) < (intersection_t.y)) {
|
||||
if ((intersection_t.x) < (intersection_t.z)) {
|
||||
|
||||
face = 0;
|
||||
voxel.x += voxel_step.x;
|
||||
intersection_t.x = intersection_t.x + delta_t.x;
|
||||
} else {
|
||||
|
||||
face = 2;
|
||||
voxel.z += voxel_step.z;
|
||||
intersection_t.z = intersection_t.z + delta_t.z;
|
||||
}
|
||||
} else {
|
||||
if ((intersection_t.y) < (intersection_t.z)) {
|
||||
|
||||
face = 1;
|
||||
voxel.y += voxel_step.y;
|
||||
intersection_t.y = intersection_t.y + delta_t.y;
|
||||
} else {
|
||||
|
||||
face = 2;
|
||||
voxel.z += voxel_step.z;
|
||||
intersection_t.z = intersection_t.z + delta_t.z;
|
||||
}
|
||||
}
|
||||
|
||||
// If the ray went out of bounds
|
||||
if (voxel.z >= dimensions.z) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
if (voxel.x >= dimensions.x) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
if (voxel.y >= dimensions.x) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
|
||||
if (voxel.x < 0) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
if (voxel.y < 0) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
if (voxel.z < 0) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
|
||||
// If we hit a voxel
|
||||
int index = voxel.x + dimensions.x * (voxel.y + dimensions.z * voxel.z);
|
||||
int voxel_data = map->list[index];
|
||||
|
||||
float alpha = 0;
|
||||
if (face == 0) {
|
||||
|
||||
alpha = AngleBetweenVectors(sf::Vector3f(1, 0, 0), map->global_light);
|
||||
alpha = fmod(alpha, 0.785) * 2;
|
||||
|
||||
} else if (face == 1) {
|
||||
|
||||
alpha = AngleBetweenVectors(sf::Vector3f(0, 1, 0), map->global_light);
|
||||
alpha = fmod(alpha, 0.785) * 2;
|
||||
|
||||
} else if (face == 2){
|
||||
|
||||
//alpha = 1.57 / 2;
|
||||
alpha = AngleBetweenVectors(sf::Vector3f(0, 0, 1), map->global_light);
|
||||
alpha = fmod(alpha, 0.785) * 2;
|
||||
}
|
||||
|
||||
alpha *= 162;
|
||||
|
||||
switch (voxel_data) {
|
||||
case 1:
|
||||
// AngleBew0 - 1.57 * 162 = 0 - 255
|
||||
|
||||
return sf::Color(255, 0, 0, alpha);
|
||||
case 2:
|
||||
return sf::Color(255, 10, 0, alpha);
|
||||
case 3:
|
||||
return sf::Color(255, 0, 255, alpha);
|
||||
case 4:
|
||||
return sf::Color(80, 0, 150, alpha);
|
||||
case 5:
|
||||
return sf::Color(255, 120, 255, alpha);
|
||||
case 6:
|
||||
return sf::Color(150, 80, 220, alpha);
|
||||
}
|
||||
|
||||
dist++;
|
||||
|
||||
|
||||
} while (dist < 200);
|
||||
|
||||
// Ray timeout color
|
||||
return sf::Color::Cyan;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <iostream>
|
||||
#include "Map.h"
|
||||
#include <Ray.h>
|
||||
#include "util.hpp"
|
||||
|
||||
Ray::Ray(
|
||||
Map *map,
|
||||
sf::Vector2<int> resolution,
|
||||
sf::Vector2<int> pixel,
|
||||
sf::Vector3<float> camera_position,
|
||||
sf::Vector3<float> ray_direction) {
|
||||
|
||||
this->pixel = pixel;
|
||||
this->map = map;
|
||||
origin = camera_position;
|
||||
direction = ray_direction;
|
||||
dimensions = map->getDimensions();
|
||||
}
|
||||
|
||||
sf::Color Ray::Cast() {
|
||||
|
||||
// Setup the voxel step based on what direction the ray is pointing
|
||||
sf::Vector3<int> voxel_step(1, 1, 1);
|
||||
voxel_step.x *= (direction.x > 0) - (direction.x < 0);
|
||||
voxel_step.y *= (direction.y > 0) - (direction.y < 0);
|
||||
voxel_step.z *= (direction.z > 0) - (direction.z < 0);
|
||||
|
||||
// Setup the voxel coords from the camera origin
|
||||
voxel = sf::Vector3<int>(
|
||||
floorf(origin.x),
|
||||
floorf(origin.y),
|
||||
floorf(origin.z)
|
||||
);
|
||||
|
||||
// Delta T is the units a ray must travel along an axis in order to
|
||||
// traverse an integer split
|
||||
delta_t = sf::Vector3<float>(
|
||||
fabsf(1.0f / direction.x),
|
||||
fabsf(1.0f / direction.y),
|
||||
fabsf(1.0f / direction.z)
|
||||
);
|
||||
|
||||
// Intersection T is the collection of the next intersection points
|
||||
// for all 3 axis XYZ.
|
||||
intersection_t = sf::Vector3<float>(
|
||||
delta_t.x,
|
||||
delta_t.y,
|
||||
delta_t.z
|
||||
);
|
||||
|
||||
|
||||
int dist = 0;
|
||||
int face = -1;
|
||||
// X:0, Y:1, Z:2
|
||||
|
||||
// Andrew Woo's raycasting algo
|
||||
do {
|
||||
if ((intersection_t.x) < (intersection_t.y)) {
|
||||
if ((intersection_t.x) < (intersection_t.z)) {
|
||||
|
||||
face = 0;
|
||||
voxel.x += voxel_step.x;
|
||||
intersection_t.x = intersection_t.x + delta_t.x;
|
||||
} else {
|
||||
|
||||
face = 2;
|
||||
voxel.z += voxel_step.z;
|
||||
intersection_t.z = intersection_t.z + delta_t.z;
|
||||
}
|
||||
} else {
|
||||
if ((intersection_t.y) < (intersection_t.z)) {
|
||||
|
||||
face = 1;
|
||||
voxel.y += voxel_step.y;
|
||||
intersection_t.y = intersection_t.y + delta_t.y;
|
||||
} else {
|
||||
|
||||
face = 2;
|
||||
voxel.z += voxel_step.z;
|
||||
intersection_t.z = intersection_t.z + delta_t.z;
|
||||
}
|
||||
}
|
||||
|
||||
// If the ray went out of bounds
|
||||
if (voxel.z >= dimensions.z) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
if (voxel.x >= dimensions.x) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
if (voxel.y >= dimensions.x) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
|
||||
if (voxel.x < 0) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
if (voxel.y < 0) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
if (voxel.z < 0) {
|
||||
return sf::Color(172, 245, 251, 200);
|
||||
}
|
||||
|
||||
// If we hit a voxel
|
||||
int index = voxel.x + dimensions.x * (voxel.y + dimensions.z * voxel.z);
|
||||
int voxel_data = map->list[index];
|
||||
|
||||
float alpha = 0;
|
||||
if (face == 0) {
|
||||
|
||||
alpha = AngleBetweenVectors(sf::Vector3f(1, 0, 0), map->global_light);
|
||||
alpha = fmod(alpha, 0.785) * 2;
|
||||
|
||||
} else if (face == 1) {
|
||||
|
||||
alpha = AngleBetweenVectors(sf::Vector3f(0, 1, 0), map->global_light);
|
||||
alpha = fmod(alpha, 0.785) * 2;
|
||||
|
||||
} else if (face == 2){
|
||||
|
||||
//alpha = 1.57 / 2;
|
||||
alpha = AngleBetweenVectors(sf::Vector3f(0, 0, 1), map->global_light);
|
||||
alpha = fmod(alpha, 0.785) * 2;
|
||||
}
|
||||
|
||||
alpha *= 162;
|
||||
|
||||
switch (voxel_data) {
|
||||
case 1:
|
||||
// AngleBew0 - 1.57 * 162 = 0 - 255
|
||||
|
||||
return sf::Color(255, 0, 0, alpha);
|
||||
case 2:
|
||||
return sf::Color(255, 10, 0, alpha);
|
||||
case 3:
|
||||
return sf::Color(255, 0, 255, alpha);
|
||||
case 4:
|
||||
return sf::Color(80, 0, 150, alpha);
|
||||
case 5:
|
||||
return sf::Color(255, 120, 255, alpha);
|
||||
case 6:
|
||||
return sf::Color(150, 80, 220, alpha);
|
||||
}
|
||||
|
||||
dist++;
|
||||
|
||||
|
||||
} while (dist < 200);
|
||||
|
||||
// Ray timeout color
|
||||
return sf::Color::Cyan;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,110 +1,110 @@
|
||||
#include "RayCaster.h"
|
||||
#include <util.hpp>
|
||||
#include <Ray.h>
|
||||
|
||||
|
||||
RayCaster::RayCaster(
|
||||
Map *map,
|
||||
sf::Vector3<int> map_dimensions,
|
||||
sf::Vector2<int> viewport_resolution ) {
|
||||
|
||||
// Override values
|
||||
//this.map_dimensions = new Vector3<int> (50, 50, 50);
|
||||
//this.resolution = new Vector2<int> (200, 200);
|
||||
//this.camera_direction = new Vector3<float> (1f, 0f, .8f);
|
||||
//this.camera_position = new Vector3<float> (1, 10, 10);
|
||||
|
||||
this->map_dimensions = map_dimensions;
|
||||
this->map = map;
|
||||
|
||||
resolution = viewport_resolution;
|
||||
image = new sf::Color[resolution.x * resolution.y];
|
||||
|
||||
|
||||
// Calculate the view plane vectors
|
||||
// Because casting to individual pixels causes barrel distortion,
|
||||
// Get the radian increments
|
||||
// Set the camera origin
|
||||
// Rotate the ray by the specified pixel * increment
|
||||
|
||||
double y_increment_radians = DegreesToRadians(50.0 / resolution.y);
|
||||
double x_increment_radians = DegreesToRadians(80.0 / resolution.x);
|
||||
|
||||
view_plane_vectors = new sf::Vector3f[resolution.x * resolution.y];
|
||||
for (int y = -resolution.y / 2 ; y < resolution.y / 2; y++) {
|
||||
for (int x = -resolution.x / 2; x < resolution.x / 2; x++) {
|
||||
|
||||
// The base ray direction to slew from
|
||||
sf::Vector3f ray(1, 0, 0);
|
||||
|
||||
// Y axis, pitch
|
||||
ray = sf::Vector3f(
|
||||
ray.z * sin(y_increment_radians * y) + ray.x * cos(y_increment_radians * y),
|
||||
ray.y,
|
||||
ray.z * cos(y_increment_radians * y) - ray.x * sin(y_increment_radians * y)
|
||||
);
|
||||
|
||||
// Z axis, yaw
|
||||
ray = sf::Vector3f(
|
||||
ray.x * cos(x_increment_radians * x) - ray.y * sin(x_increment_radians * x),
|
||||
ray.x * sin(x_increment_radians * x) + ray.y * cos(x_increment_radians * x),
|
||||
ray.z
|
||||
);
|
||||
|
||||
int index = (x + resolution.x / 2) + resolution.x * (y + resolution.y / 2);
|
||||
view_plane_vectors[index] = Normalize(ray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RayCaster::~RayCaster() {
|
||||
delete image;
|
||||
delete view_plane_vectors;
|
||||
}
|
||||
|
||||
sf::Color* RayCaster::CastRays(sf::Vector3<float> camera_direction, sf::Vector3<float> camera_position) {
|
||||
|
||||
// Setup the camera for this cast
|
||||
this->camera_direction = camera_direction;
|
||||
camera_direction_cartesian = Normalize(SphereToCart(camera_direction));
|
||||
this->camera_position = camera_position;
|
||||
|
||||
// Start the loop at the top left, scan right and work down
|
||||
for (int y = 0; y < resolution.y; y++) {
|
||||
for (int x = 0; x < resolution.x; x++) {
|
||||
|
||||
// Get the ray at the base direction
|
||||
sf::Vector3f ray = view_plane_vectors[x + resolution.x * y];
|
||||
|
||||
// Rotate it to the correct pitch and yaw
|
||||
|
||||
// Y axis, pitch
|
||||
ray = sf::Vector3f(
|
||||
ray.z * sin(camera_direction.y) + ray.x * cos(camera_direction.y),
|
||||
ray.y,
|
||||
ray.z * cos(camera_direction.y) - ray.x * sin(camera_direction.y)
|
||||
);
|
||||
|
||||
// Z axis, yaw
|
||||
ray = sf::Vector3f(
|
||||
ray.x * cos(camera_direction.z) - ray.y * sin(camera_direction.z),
|
||||
ray.x * sin(camera_direction.z) + ray.y * cos(camera_direction.z),
|
||||
ray.z
|
||||
);
|
||||
|
||||
|
||||
// Setup the ray
|
||||
Ray r(map, resolution, sf::Vector2i(x, y), camera_position, ray);
|
||||
|
||||
// Cast it and assign its return value
|
||||
image[x + resolution.x * y] = r.Cast();
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void RayCaster::moveCamera(sf::Vector2f v) {
|
||||
camera_direction.y += v.x;
|
||||
camera_direction.z += v.y;
|
||||
}
|
||||
#include "RayCaster.h"
|
||||
#include <util.hpp>
|
||||
#include <Ray.h>
|
||||
|
||||
|
||||
RayCaster::RayCaster(
|
||||
Map *map,
|
||||
sf::Vector3<int> map_dimensions,
|
||||
sf::Vector2<int> viewport_resolution ) {
|
||||
|
||||
// Override values
|
||||
//this.map_dimensions = new Vector3<int> (50, 50, 50);
|
||||
//this.resolution = new Vector2<int> (200, 200);
|
||||
//this.camera_direction = new Vector3<float> (1f, 0f, .8f);
|
||||
//this.camera_position = new Vector3<float> (1, 10, 10);
|
||||
|
||||
this->map_dimensions = map_dimensions;
|
||||
this->map = map;
|
||||
|
||||
resolution = viewport_resolution;
|
||||
image = new sf::Color[resolution.x * resolution.y];
|
||||
|
||||
|
||||
// Calculate the view plane vectors
|
||||
// Because casting to individual pixels causes barrel distortion,
|
||||
// Get the radian increments
|
||||
// Set the camera origin
|
||||
// Rotate the ray by the specified pixel * increment
|
||||
|
||||
double y_increment_radians = DegreesToRadians(50.0 / resolution.y);
|
||||
double x_increment_radians = DegreesToRadians(80.0 / resolution.x);
|
||||
|
||||
view_plane_vectors = new sf::Vector3f[resolution.x * resolution.y];
|
||||
for (int y = -resolution.y / 2 ; y < resolution.y / 2; y++) {
|
||||
for (int x = -resolution.x / 2; x < resolution.x / 2; x++) {
|
||||
|
||||
// The base ray direction to slew from
|
||||
sf::Vector3f ray(1, 0, 0);
|
||||
|
||||
// Y axis, pitch
|
||||
ray = sf::Vector3f(
|
||||
ray.z * sin(y_increment_radians * y) + ray.x * cos(y_increment_radians * y),
|
||||
ray.y,
|
||||
ray.z * cos(y_increment_radians * y) - ray.x * sin(y_increment_radians * y)
|
||||
);
|
||||
|
||||
// Z axis, yaw
|
||||
ray = sf::Vector3f(
|
||||
ray.x * cos(x_increment_radians * x) - ray.y * sin(x_increment_radians * x),
|
||||
ray.x * sin(x_increment_radians * x) + ray.y * cos(x_increment_radians * x),
|
||||
ray.z
|
||||
);
|
||||
|
||||
int index = (x + resolution.x / 2) + resolution.x * (y + resolution.y / 2);
|
||||
view_plane_vectors[index] = Normalize(ray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RayCaster::~RayCaster() {
|
||||
delete image;
|
||||
delete view_plane_vectors;
|
||||
}
|
||||
|
||||
sf::Color* RayCaster::CastRays(sf::Vector3<float> camera_direction, sf::Vector3<float> camera_position) {
|
||||
|
||||
// Setup the camera for this cast
|
||||
this->camera_direction = camera_direction;
|
||||
camera_direction_cartesian = Normalize(SphereToCart(camera_direction));
|
||||
this->camera_position = camera_position;
|
||||
|
||||
// Start the loop at the top left, scan right and work down
|
||||
for (int y = 0; y < resolution.y; y++) {
|
||||
for (int x = 0; x < resolution.x; x++) {
|
||||
|
||||
// Get the ray at the base direction
|
||||
sf::Vector3f ray = view_plane_vectors[x + resolution.x * y];
|
||||
|
||||
// Rotate it to the correct pitch and yaw
|
||||
|
||||
// Y axis, pitch
|
||||
ray = sf::Vector3f(
|
||||
ray.z * sin(camera_direction.y) + ray.x * cos(camera_direction.y),
|
||||
ray.y,
|
||||
ray.z * cos(camera_direction.y) - ray.x * sin(camera_direction.y)
|
||||
);
|
||||
|
||||
// Z axis, yaw
|
||||
ray = sf::Vector3f(
|
||||
ray.x * cos(camera_direction.z) - ray.y * sin(camera_direction.z),
|
||||
ray.x * sin(camera_direction.z) + ray.y * cos(camera_direction.z),
|
||||
ray.z
|
||||
);
|
||||
|
||||
|
||||
// Setup the ray
|
||||
Ray r(map, resolution, sf::Vector2i(x, y), camera_position, ray);
|
||||
|
||||
// Cast it and assign its return value
|
||||
image[x + resolution.x * y] = r.Cast();
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void RayCaster::moveCamera(sf::Vector2f v) {
|
||||
camera_direction.y += v.x;
|
||||
camera_direction.z += v.y;
|
||||
}
|
||||
|
||||
@@ -1,95 +1,121 @@
|
||||
#ifdef linux
|
||||
|
||||
#elif defined _WIN32
|
||||
|
||||
#elif defined TARGET_OS_MAC
|
||||
# include <GL/glew.h>
|
||||
# include <OpenGL/OpenGL.h>
|
||||
# include <OpenCL/opencl.h>
|
||||
#endif
|
||||
|
||||
|
||||
int IsExtensionSupported(
|
||||
const char* support_str,
|
||||
const char* ext_string,
|
||||
size_t ext_buffer_size) {
|
||||
|
||||
size_t offset = 0;
|
||||
|
||||
const char* space_substr = strnstr(ext_string + offset, " ", ext_buffer_size - offset);
|
||||
|
||||
size_t space_pos = space_substr ? space_substr - ext_string : 0;
|
||||
|
||||
while (space_pos < ext_buffer_size) {
|
||||
|
||||
if( strncmp(support_str, ext_string + offset, space_pos) == 0 ) {
|
||||
// Device supports requested extension!
|
||||
printf("Info: Found extension support ‘%s’!\n", support_str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Keep searching -- skip to next token string
|
||||
offset = space_pos + 1;
|
||||
space_substr = strnstr(ext_string + offset, " ", ext_buffer_size - offset);
|
||||
space_pos = space_substr ? space_substr - ext_string : 0;
|
||||
}
|
||||
|
||||
printf("Warning: Extension not supported ‘%s’!\n", support_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_for_gl_cl_sharing() {
|
||||
|
||||
|
||||
int err = 0;
|
||||
#if defined (__APPLE__) || defined(MACOSX)
|
||||
static const char *CL_GL_SHARING_EXT = "cl_APPLE_gl_sharing";
|
||||
#else
|
||||
static const char* CL_GL_SHARING_EXT = "cl_khr_gl_sharing";
|
||||
#endif
|
||||
|
||||
cl_uint num_devices, i;
|
||||
clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
|
||||
|
||||
cl_device_id *devices = (cl_device_id *) calloc(sizeof(cl_device_id), num_devices);
|
||||
clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
|
||||
|
||||
// Get string containing supported device extensions
|
||||
size_t ext_size = 1024;
|
||||
char *ext_string = (char *) malloc(ext_size);
|
||||
err = clGetDeviceInfo(devices[0], CL_DEVICE_EXTENSIONS, ext_size, ext_string, &ext_size);
|
||||
|
||||
free(devices);
|
||||
|
||||
// Search for GL support in extension string (space delimited)
|
||||
int supported = IsExtensionSupported(CL_GL_SHARING_EXT, ext_string, ext_size);
|
||||
if (supported) {
|
||||
// Device supports context sharing with OpenGL
|
||||
printf("Found GL Sharing Support!\n");
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int query_platform_devices() {
|
||||
// From stackoverflow, gets and lists the compute devices
|
||||
cl_uint num_devices, i;
|
||||
clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
|
||||
|
||||
cl_device_id *devices = (cl_device_id *) calloc(sizeof(cl_device_id), num_devices);
|
||||
clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
|
||||
|
||||
char buf[128];
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
clGetDeviceInfo(devices[i], CL_DEVICE_NAME, 128, buf, NULL);
|
||||
fprintf(stdout, "Device %s supports ", buf);
|
||||
|
||||
clGetDeviceInfo(devices[i], CL_DEVICE_VERSION, 128, buf, NULL);
|
||||
fprintf(stdout, "%s\n", buf);
|
||||
}
|
||||
|
||||
free(devices);
|
||||
|
||||
return 1;
|
||||
#pragma once
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <CL/cl_ext.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#ifdef linux
|
||||
|
||||
#elif defined _WIN32
|
||||
|
||||
#elif defined TARGET_OS_MAC
|
||||
# include <GL/glew.h>
|
||||
# include <OpenGL/OpenGL.h>
|
||||
# include <OpenCL/opencl.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef TARGET_OS_MAC
|
||||
int IsExtensionSupported(
|
||||
const char* support_str,
|
||||
const char* ext_string,
|
||||
size_t ext_buffer_size) {
|
||||
|
||||
size_t offset = 0;
|
||||
|
||||
const char* space_substr = strnstr(ext_string + offset, " ", ext_buffer_size - offset);
|
||||
|
||||
size_t space_pos = space_substr ? space_substr - ext_string : 0;
|
||||
|
||||
while (space_pos < ext_buffer_size) {
|
||||
|
||||
if( strncmp(support_str, ext_string + offset, space_pos) == 0 ) {
|
||||
// Device supports requested extension!
|
||||
printf("Info: Found extension support ‘%s’!\n", support_str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Keep searching -- skip to next token string
|
||||
offset = space_pos + 1;
|
||||
space_substr = strnstr(ext_string + offset, " ", ext_buffer_size - offset);
|
||||
space_pos = space_substr ? space_substr - ext_string : 0;
|
||||
}
|
||||
|
||||
std::cout << "Warning: Extension not supported " << support_str << std::endl;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline int test_for_gl_cl_sharing() {
|
||||
|
||||
|
||||
int err = 0;
|
||||
|
||||
#if defined (__APPLE__) || defined(MACOSX)
|
||||
static const char *CL_GL_SHARING_EXT = "cl_APPLE_gl_sharing";
|
||||
#else
|
||||
static const char* CL_GL_SHARING_EXT = "cl_khr_gl_sharing";
|
||||
#endif
|
||||
|
||||
cl_uint num_devices;
|
||||
clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
|
||||
|
||||
cl_device_id *devices = (cl_device_id *) calloc(sizeof(cl_device_id), num_devices);
|
||||
clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
|
||||
|
||||
// Get string containing supported device extensions
|
||||
size_t ext_size = 1024;
|
||||
char *ext_string = (char *) malloc(ext_size);
|
||||
err = clGetDeviceInfo(devices[0], CL_DEVICE_EXTENSIONS, ext_size, ext_string, &ext_size);
|
||||
|
||||
free(devices);
|
||||
|
||||
// Search for GL support in extension string (space delimited)
|
||||
//int supported = IsExtensionSupported(CL_GL_SHARING_EXT, ext_string, ext_size);
|
||||
int supported = 0;
|
||||
if (supported) {
|
||||
// Device supports context sharing with OpenGL
|
||||
printf("Found GL Sharing Support!\n");
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
inline int query_platform_devices() {
|
||||
|
||||
int error = 0;
|
||||
// Get the number of platforms
|
||||
cl_uint platform_count = 0;
|
||||
clGetPlatformIDs(0, nullptr, &platform_count);
|
||||
|
||||
// Fetch the platforms
|
||||
std::vector<cl_platform_id> platformIds(platform_count);
|
||||
clGetPlatformIDs(platform_count, platformIds.data(), nullptr);
|
||||
|
||||
|
||||
for (unsigned int q = 0; q < platform_count; q++) {
|
||||
|
||||
// From stackoverflow, gets and lists the compute devices
|
||||
cl_uint num_devices, i;
|
||||
error = clGetDeviceIDs(platformIds[q], CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
|
||||
|
||||
cl_device_id *devices = (cl_device_id *)calloc(sizeof(cl_device_id), num_devices);
|
||||
error = clGetDeviceIDs(platformIds[q], CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
|
||||
|
||||
char buf[128];
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
clGetDeviceInfo(devices[i], CL_DEVICE_NAME, 128, buf, NULL);
|
||||
fprintf(stdout, "Device %s supports ", buf);
|
||||
|
||||
clGetDeviceInfo(devices[i], CL_DEVICE_VERSION, 128, buf, NULL);
|
||||
fprintf(stdout, "%s\n", buf);
|
||||
}
|
||||
|
||||
free(devices);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Created by Mitchell Hansen on 8/7/16.
|
||||
//
|
||||
|
||||
#include "Vector3.h"
|
||||
//
|
||||
// Created by Mitchell Hansen on 8/7/16.
|
||||
//
|
||||
|
||||
#include "Vector3.h"
|
||||
|
||||
879
src/main.cpp
879
src/main.cpp
@@ -1,415 +1,464 @@
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <GL/glew.h>
|
||||
|
||||
#ifdef linux
|
||||
#include <CL/cl.h>
|
||||
#include <CL/opencl.h>
|
||||
|
||||
#elif defined _WIN32
|
||||
#include <CL/cl.h>
|
||||
#include <CL/opencl.h>
|
||||
#include <windows.h>
|
||||
|
||||
#elif defined TARGET_OS_MAC
|
||||
# include <OpenGL/OpenGL.h>
|
||||
# include <OpenCL/opencl.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include "Map.h"
|
||||
#include "Curses.h"
|
||||
#include "util.hpp"
|
||||
#include "RayCaster.h"
|
||||
|
||||
|
||||
|
||||
const int WINDOW_X = 150;
|
||||
const int WINDOW_Y = 150;
|
||||
|
||||
std::string read_file(std::string file_name){
|
||||
std::ifstream input_file(file_name);
|
||||
|
||||
if (!input_file.is_open()){
|
||||
std::cout << file_name << " could not be opened" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::stringstream buf;
|
||||
buf << input_file.rdbuf();
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
char buffer[256];
|
||||
char *val = getcwd(buffer, sizeof(buffer));
|
||||
if (val) {
|
||||
std::cout << buffer << std::endl;
|
||||
}
|
||||
// ===================================================================== //
|
||||
// ==== Opencl setup
|
||||
|
||||
int error = 0;
|
||||
|
||||
// Get the number of platforms
|
||||
cl_uint platformIdCount = 0;
|
||||
clGetPlatformIDs(0, nullptr, &platformIdCount);
|
||||
|
||||
// Fetch the platforms
|
||||
std::vector<cl_platform_id> platformIds (platformIdCount);
|
||||
clGetPlatformIDs(platformIdCount, platformIds.data(), nullptr);
|
||||
|
||||
|
||||
// get the number of devices, fetch them, choose the first one
|
||||
cl_uint deviceIdCount = 0;
|
||||
std::vector<cl_device_id> deviceIds;
|
||||
// Try to get a GPU first
|
||||
error = clGetDeviceIDs (platformIds [0], CL_DEVICE_TYPE_GPU, 0, nullptr,
|
||||
&deviceIdCount);
|
||||
|
||||
if (deviceIdCount == 0) {
|
||||
std::cout << "couldn't aquire a GPU, falling back to CPU" << std::endl;
|
||||
error = clGetDeviceIDs(platformIds[0], CL_DEVICE_TYPE_CPU, 0, nullptr, &deviceIdCount);
|
||||
deviceIds.resize(deviceIdCount);
|
||||
error = clGetDeviceIDs(platformIds[0], CL_DEVICE_TYPE_CPU, deviceIdCount, deviceIds.data(), NULL);
|
||||
} else {
|
||||
std::cout << "aquired GPU cl target" << std::endl;
|
||||
deviceIds.resize(deviceIdCount);
|
||||
clGetDeviceIDs (platformIds[0], CL_DEVICE_TYPE_GPU, deviceIdCount, deviceIds.data (), nullptr);
|
||||
}
|
||||
|
||||
if (error != 0){
|
||||
std::cout << "Err: clGetDeviceIDs returned: " << error << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
// Hurray for standards!
|
||||
// Setup the context properties to grab the current GL context
|
||||
#ifdef linux
|
||||
cl_context_properties context_properties[] = {
|
||||
CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(),
|
||||
CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(),
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties) platform,
|
||||
0
|
||||
};
|
||||
|
||||
#elif defined _WIN32
|
||||
cl_context_properties context_properties[] = {
|
||||
CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(),
|
||||
CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(),
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties) platform,
|
||||
0
|
||||
};
|
||||
|
||||
#elif defined TARGET_OS_MAC
|
||||
CGLContextObj glContext = CGLGetCurrentContext();
|
||||
CGLShareGroupObj shareGroup = CGLGetShareGroup(glContext);
|
||||
cl_context_properties context_properties[] = {
|
||||
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
|
||||
(cl_context_properties)shareGroup,
|
||||
0
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// Create our shared context
|
||||
auto context = clCreateContext(
|
||||
context_properties,
|
||||
deviceIdCount,
|
||||
deviceIds.data(),
|
||||
nullptr, nullptr,
|
||||
&error
|
||||
);
|
||||
|
||||
if (error != 0){
|
||||
std::cout << "Err: clCreateContext returned: " << error << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
// And the cl command queue
|
||||
auto commandQueue = clCreateCommandQueue(context, deviceIds[0], 0, &error);
|
||||
|
||||
if (error != 0){
|
||||
std::cout << "Err: clCreateCommandQueue returned: " << error << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
// At this point the shared GL/CL context is up and running
|
||||
// ====================================================================== //
|
||||
// ========== Kernel setup & compilation
|
||||
|
||||
// Load in the kernel, and c stringify it
|
||||
std::string kernel_source;
|
||||
kernel_source = read_file("../kernels/kernel.txt");
|
||||
const char* kernel_source_c_str = kernel_source.c_str();
|
||||
size_t kernel_source_size = strlen(kernel_source_c_str);
|
||||
|
||||
|
||||
// Load the source into CL's data structure
|
||||
cl_program kernel_program = clCreateProgramWithSource(
|
||||
context, 1,
|
||||
&kernel_source_c_str,
|
||||
&kernel_source_size, &error
|
||||
);
|
||||
|
||||
if (error != 0){
|
||||
std::cout << "Err: clCreateProgramWithSource returned: " << error << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
// Try and build the program
|
||||
error = clBuildProgram(kernel_program, 1, &deviceIds[0], NULL, NULL, NULL);
|
||||
|
||||
// Check to see if it errored out
|
||||
if (error == CL_BUILD_PROGRAM_FAILURE){
|
||||
|
||||
// Get the size of the queued log
|
||||
size_t log_size;
|
||||
clGetProgramBuildInfo(kernel_program, deviceIds[0], CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
|
||||
char *log = new char[log_size];
|
||||
|
||||
// Grab the log
|
||||
clGetProgramBuildInfo(kernel_program, deviceIds[0], CL_PROGRAM_BUILD_LOG, log_size, log, NULL);
|
||||
|
||||
|
||||
std::cout << "Err: clBuildProgram returned: " << error << std::endl;
|
||||
std::cout << log << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
// Done initializing the kernel
|
||||
cl_kernel finished_kernel = clCreateKernel(kernel_program, "kernel_name", &error);
|
||||
|
||||
if (error != 0){
|
||||
std::cout << "Err: clCreateKernel returned: " << error << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
float elap_time(){
|
||||
static std::chrono::time_point<std::chrono::system_clock> start;
|
||||
static bool started = false;
|
||||
|
||||
if (!started){
|
||||
start = std::chrono::system_clock::now();
|
||||
started = true;
|
||||
}
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
|
||||
std::chrono::duration<double> elapsed_time = now - start;
|
||||
return elapsed_time.count();
|
||||
}
|
||||
|
||||
sf::Sprite window_sprite;
|
||||
sf::Texture window_texture;
|
||||
|
||||
// Y: -1.57 is straight up
|
||||
// Y: 1.57 is straight down
|
||||
|
||||
void test_ray_reflection(){
|
||||
|
||||
sf::Vector3f r(0.588, -0.78, -0.196);
|
||||
sf::Vector3f i(0, 0.928, 0.37);
|
||||
|
||||
// is this needed? free spin but bounded 0 < z < pi
|
||||
if (i.z > PI)
|
||||
i.z -= PI;
|
||||
else if (i.z < 0)
|
||||
i.z += PI;
|
||||
|
||||
std::cout << AngleBetweenVectors(r, i);
|
||||
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main0() {
|
||||
|
||||
// Initialize the render window
|
||||
Curses curse(sf::Vector2i(5, 5), sf::Vector2i(WINDOW_X, WINDOW_Y));
|
||||
sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML");
|
||||
|
||||
|
||||
|
||||
// The step size in milliseconds between calls to Update()
|
||||
// Lets set it to 16.6 milliseonds (60FPS)
|
||||
float step_size = 0.0166f;
|
||||
|
||||
// Timekeeping values for the loop
|
||||
double frame_time = 0.0,
|
||||
elapsed_time = 0.0,
|
||||
delta_time = 0.0,
|
||||
accumulator_time = 0.0,
|
||||
current_time = 0.0;
|
||||
|
||||
fps_counter fps;
|
||||
|
||||
// ============================= RAYCASTER SETUP ==================================
|
||||
|
||||
// Setup the sprite and texture
|
||||
window_texture.create(WINDOW_X, WINDOW_Y);
|
||||
window_sprite.setPosition(0, 0);
|
||||
|
||||
// State values
|
||||
sf::Vector3i map_dim(100, 100, 100);
|
||||
sf::Vector2i view_res(WINDOW_X, WINDOW_Y);
|
||||
sf::Vector3f cam_dir(1.0f, 0.0f, 1.57f);
|
||||
sf::Vector3f cam_pos(50, 50, 50);
|
||||
sf::Vector3f cam_vec(0, 0, 0);
|
||||
Map* map = new Map(map_dim);
|
||||
RayCaster ray_caster(map, map_dim, view_res);
|
||||
|
||||
|
||||
// ===============================================================================
|
||||
|
||||
// Mouse capture
|
||||
sf::Vector2i deltas;
|
||||
sf::Vector2i fixed(window.getSize());
|
||||
bool mouse_enabled = true;
|
||||
|
||||
while (window.isOpen()) {
|
||||
|
||||
// Poll for events from the user
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event)) {
|
||||
|
||||
// If the user tries to exit the application via the GUI
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
}
|
||||
|
||||
cam_vec.x = 0;
|
||||
cam_vec.y = 0;
|
||||
cam_vec.z = 0;
|
||||
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) {
|
||||
cam_vec.z = 1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::E)) {
|
||||
cam_vec.z = -1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
|
||||
cam_vec.y = 1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
|
||||
cam_vec.y = -1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
|
||||
cam_vec.x = 1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
|
||||
cam_vec.x = -1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
|
||||
cam_dir.z = -0.1f;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
|
||||
cam_vec.z = +0.1f;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
|
||||
cam_vec.y = +0.1f;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
|
||||
cam_vec.y = -0.1f;
|
||||
}
|
||||
|
||||
deltas = fixed - sf::Mouse::getPosition();
|
||||
if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) {
|
||||
|
||||
// Mouse movement
|
||||
sf::Mouse::setPosition(fixed);
|
||||
cam_dir.y -= deltas.y / 300.0f;
|
||||
cam_dir.z -= deltas.x / 300.0f;
|
||||
}
|
||||
|
||||
cam_pos.x += cam_vec.x / 1.0;
|
||||
cam_pos.y += cam_vec.y / 1.0;
|
||||
cam_pos.z += cam_vec.z / 1.0;
|
||||
|
||||
// if (cam_vec.x > 0.0f)
|
||||
// cam_vec.x -= 0.1;
|
||||
// else if (cam_vec.x < 0.0f)
|
||||
// cam_vec.x += 0.1;
|
||||
//
|
||||
// if (cam_vec.y > 0.0f)
|
||||
// cam_vec.y -= 0.1;
|
||||
// else if (cam_vec.y < 0.0f)
|
||||
// cam_vec.y += 0.1;
|
||||
//
|
||||
// if (cam_vec.z > 0.0f)
|
||||
// cam_vec.z -= 0.1;
|
||||
// else if (cam_vec.z < 0.0f)
|
||||
// cam_vec.z += 0.1;
|
||||
|
||||
std::cout << cam_vec.x << " : " << cam_vec.y << " : " << cam_vec.z << std::endl;
|
||||
|
||||
|
||||
// Time keeping
|
||||
elapsed_time = elap_time();
|
||||
delta_time = elapsed_time - current_time;
|
||||
current_time = elapsed_time;
|
||||
if (delta_time > 0.2f)
|
||||
delta_time = 0.2f;
|
||||
accumulator_time += delta_time;
|
||||
while ((accumulator_time - step_size) >= step_size) {
|
||||
accumulator_time -= step_size;
|
||||
|
||||
|
||||
// Update cycle
|
||||
curse.Update(delta_time);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Fps cycle
|
||||
// map->moveLight(sf::Vector2f(0.3, 0));
|
||||
|
||||
window.clear(sf::Color::Black);
|
||||
|
||||
// Cast the rays and get the image
|
||||
sf::Color* pixel_colors = ray_caster.CastRays(cam_dir, cam_pos);
|
||||
|
||||
for (int i = 0; i < WINDOW_X * WINDOW_Y; i++) {
|
||||
|
||||
Curses::Tile t(sf::Vector2i(i % WINDOW_X, i / WINDOW_X));
|
||||
Curses::Slot s(L'\u0045', pixel_colors[i], sf::Color::Black);
|
||||
t.push_back(s);
|
||||
curse.setTile(t);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Cast it to an array of Uint8's
|
||||
auto out = (sf::Uint8*)pixel_colors;
|
||||
|
||||
window_texture.update(out);
|
||||
window_sprite.setTexture(window_texture);
|
||||
window.draw(window_sprite);
|
||||
|
||||
|
||||
curse.Render();
|
||||
|
||||
// Give the frame counter the frame time and draw the average frame time
|
||||
fps.frame(delta_time);
|
||||
fps.draw(&window);
|
||||
|
||||
window.display();
|
||||
|
||||
|
||||
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <GL/glew.h>
|
||||
|
||||
#ifdef linux
|
||||
#include <CL/cl.h>
|
||||
#include <CL/opencl.h>
|
||||
|
||||
#elif defined _WIN32
|
||||
#include <CL/cl_gl.h>
|
||||
#include <CL/cl.h>
|
||||
#include <CL/opencl.h>
|
||||
#include <windows.h>
|
||||
|
||||
#elif defined TARGET_OS_MAC
|
||||
# include <OpenGL/OpenGL.h>
|
||||
# include <OpenCL/opencl.h>
|
||||
|
||||
#endif
|
||||
#include "TestPlatform.cpp"
|
||||
#include "Map.h"
|
||||
#include "Curses.h"
|
||||
#include "util.hpp"
|
||||
#include "RayCaster.h"
|
||||
|
||||
|
||||
const int WINDOW_X = 150;
|
||||
const int WINDOW_Y = 150;
|
||||
|
||||
std::string read_file(std::string file_name){
|
||||
std::ifstream input_file(file_name);
|
||||
|
||||
if (!input_file.is_open()){
|
||||
std::cout << file_name << " could not be opened" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::stringstream buf;
|
||||
buf << input_file.rdbuf();
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
|
||||
int error = 0;
|
||||
|
||||
// ===================================================================== //
|
||||
// ==== Opencl setup
|
||||
|
||||
// Get the number of platforms
|
||||
cl_uint platform_count = 0;
|
||||
clGetPlatformIDs(0, nullptr, &platform_count);
|
||||
|
||||
// Fetch the platforms
|
||||
std::vector<cl_platform_id> platformIds(platform_count);
|
||||
clGetPlatformIDs(platform_count, platformIds.data(), nullptr);
|
||||
|
||||
|
||||
|
||||
// Print out this machines info
|
||||
|
||||
std::cout << "============ Hardware info =================" << std::endl;
|
||||
|
||||
for (unsigned int i = 0; i < platform_count; i++) {
|
||||
|
||||
std::cout << "--Platform: " << i << std::endl;
|
||||
|
||||
char platform[128];
|
||||
char version[128];
|
||||
|
||||
clGetPlatformInfo(platformIds[i], CL_PLATFORM_NAME, 128, platform, NULL);
|
||||
clGetPlatformInfo(platformIds[i], CL_PLATFORM_VERSION, 128, version, NULL);
|
||||
|
||||
std::cout << platform << "\n";
|
||||
std::cout << version << "\n\n";
|
||||
|
||||
// get the number of devices, fetch them, choose the first one
|
||||
cl_uint deviceIdCount = 0;
|
||||
error = clGetDeviceIDs(platformIds[i], CL_DEVICE_TYPE_ALL, 0, nullptr, &deviceIdCount);
|
||||
|
||||
std::vector<cl_device_id> deviceIds(deviceIdCount);
|
||||
|
||||
for (int q = 0; q < deviceIdCount; q++) {
|
||||
|
||||
std::cout << "++++Device " << q << std::endl;
|
||||
error = clGetDeviceIDs(platformIds[i], CL_DEVICE_TYPE_ALL, deviceIdCount, deviceIds.data(), NULL);
|
||||
|
||||
clGetDeviceInfo(deviceIds[q], CL_DEVICE_NAME, 128, platform, NULL);
|
||||
clGetDeviceInfo(deviceIds[q], CL_DEVICE_VERSION, 128, version, NULL);
|
||||
|
||||
std::cout << platform << "\n";
|
||||
std::cout << version << "\n\n";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "============================================" << std::endl;
|
||||
|
||||
cl_uint deviceIdCount = 0;
|
||||
std::vector<cl_device_id> deviceIds;
|
||||
|
||||
// Try to get a GPU first
|
||||
error = clGetDeviceIDs(platformIds[1], CL_DEVICE_TYPE_GPU, 0, nullptr,
|
||||
&deviceIdCount);
|
||||
|
||||
|
||||
if (deviceIdCount == 0) {
|
||||
std::cout << "couldn't acquire a GPU, falling back to CPU" << std::endl;
|
||||
error = clGetDeviceIDs(platformIds[1], CL_DEVICE_TYPE_CPU, 0, nullptr, &deviceIdCount);
|
||||
deviceIds.resize(deviceIdCount);
|
||||
error = clGetDeviceIDs(platformIds[1], CL_DEVICE_TYPE_CPU, deviceIdCount, deviceIds.data(), NULL);
|
||||
} else {
|
||||
std::cout << "acquired GPU cl target" << std::endl;
|
||||
deviceIds.resize(deviceIdCount);
|
||||
clGetDeviceIDs (platformIds[1], CL_DEVICE_TYPE_GPU, deviceIdCount, deviceIds.data (), nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (error != 0){
|
||||
std::cout << "Err: clGetDeviceIDs returned: " << error << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
// Hurray for standards!
|
||||
// Setup the context properties to grab the current GL context
|
||||
#ifdef linux
|
||||
cl_context_properties context_properties[] = {
|
||||
CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(),
|
||||
CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(),
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties) platform,
|
||||
0
|
||||
};
|
||||
|
||||
#elif defined _WIN32
|
||||
//cl_context_properties context_properties[] = {
|
||||
// CL_CONTEXT_PLATFORM, (cl_context_properties) platformIds[0],
|
||||
// CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(),
|
||||
// CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(),
|
||||
// 0
|
||||
//};
|
||||
HGLRC hGLRC = wglGetCurrentContext();
|
||||
HDC hDC = wglGetCurrentDC();
|
||||
cl_context_properties context_properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platformIds[1], CL_GL_CONTEXT_KHR, (cl_context_properties)hGLRC, CL_WGL_HDC_KHR, (cl_context_properties)hDC, 0 };
|
||||
|
||||
|
||||
#elif defined TARGET_OS_MAC
|
||||
CGLContextObj glContext = CGLGetCurrentContext();
|
||||
CGLShareGroupObj shareGroup = CGLGetShareGroup(glContext);
|
||||
cl_context_properties context_properties[] = {
|
||||
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
|
||||
(cl_context_properties)shareGroup,
|
||||
0
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// Create our shared context
|
||||
auto context = clCreateContext(
|
||||
context_properties,
|
||||
1,
|
||||
&deviceIds[0],
|
||||
nullptr, nullptr,
|
||||
&error
|
||||
);
|
||||
|
||||
|
||||
//cl_device_id devices[32];
|
||||
//size_t size;
|
||||
//clGetGLContextInfoKHR(context_properties, CL_DEVICES_FOR_GL_CONTEXT_KHR,
|
||||
// 32 * sizeof(cl_device_id), devices, &size);
|
||||
|
||||
if (error != 0){
|
||||
std::cout << "Err: clCreateContext returned: " << error << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
// And the cl command queue
|
||||
auto commandQueue = clCreateCommandQueue(context, deviceIds[0], 0, &error);
|
||||
|
||||
if (error != 0){
|
||||
std::cout << "Err: clCreateCommandQueue returned: " << error << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
// At this point the shared GL/CL context is up and running
|
||||
// ====================================================================== //
|
||||
// ========== Kernel setup & compilation
|
||||
|
||||
// Load in the kernel, and c stringify it
|
||||
std::string kernel_source;
|
||||
kernel_source = read_file("../kernels/kernel.txt");
|
||||
const char* kernel_source_c_str = kernel_source.c_str();
|
||||
size_t kernel_source_size = strlen(kernel_source_c_str);
|
||||
|
||||
|
||||
// Load the source into CL's data structure
|
||||
cl_program kernel_program = clCreateProgramWithSource(
|
||||
context, 1,
|
||||
&kernel_source_c_str,
|
||||
&kernel_source_size, &error
|
||||
);
|
||||
|
||||
if (error != 0){
|
||||
std::cout << "Err: clCreateProgramWithSource returned: " << error << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
// Try and build the program
|
||||
error = clBuildProgram(kernel_program, 1, &deviceIds[0], NULL, NULL, NULL);
|
||||
|
||||
// Check to see if it errored out
|
||||
if (error == CL_BUILD_PROGRAM_FAILURE){
|
||||
|
||||
// Get the size of the queued log
|
||||
size_t log_size;
|
||||
clGetProgramBuildInfo(kernel_program, deviceIds[0], CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
|
||||
char *log = new char[log_size];
|
||||
|
||||
// Grab the log
|
||||
clGetProgramBuildInfo(kernel_program, deviceIds[0], CL_PROGRAM_BUILD_LOG, log_size, log, NULL);
|
||||
|
||||
|
||||
std::cout << "Err: clBuildProgram returned: " << error << std::endl;
|
||||
std::cout << log << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
// Done initializing the kernel
|
||||
cl_kernel finished_kernel = clCreateKernel(kernel_program, "kernel_name", &error);
|
||||
|
||||
if (error != 0){
|
||||
std::cout << "Err: clCreateKernel returned: " << error << std::endl;
|
||||
return error;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
float elap_time(){
|
||||
static std::chrono::time_point<std::chrono::system_clock> start;
|
||||
static bool started = false;
|
||||
|
||||
if (!started){
|
||||
start = std::chrono::system_clock::now();
|
||||
started = true;
|
||||
}
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
|
||||
std::chrono::duration<double> elapsed_time = now - start;
|
||||
return elapsed_time.count();
|
||||
}
|
||||
|
||||
sf::Sprite window_sprite;
|
||||
sf::Texture window_texture;
|
||||
|
||||
// Y: -1.57 is straight up
|
||||
// Y: 1.57 is straight down
|
||||
|
||||
void test_ray_reflection(){
|
||||
|
||||
sf::Vector3f r(0.588, -0.78, -0.196);
|
||||
sf::Vector3f i(0, 0.928, 0.37);
|
||||
|
||||
// is this needed? free spin but bounded 0 < z < pi
|
||||
if (i.z > PI)
|
||||
i.z -= PI;
|
||||
else if (i.z < 0)
|
||||
i.z += PI;
|
||||
|
||||
std::cout << AngleBetweenVectors(r, i);
|
||||
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main0() {
|
||||
|
||||
// Initialize the render window
|
||||
Curses curse(sf::Vector2i(5, 5), sf::Vector2i(WINDOW_X, WINDOW_Y));
|
||||
sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML");
|
||||
|
||||
|
||||
|
||||
// The step size in milliseconds between calls to Update()
|
||||
// Lets set it to 16.6 milliseonds (60FPS)
|
||||
float step_size = 0.0166f;
|
||||
|
||||
// Timekeeping values for the loop
|
||||
double frame_time = 0.0,
|
||||
elapsed_time = 0.0,
|
||||
delta_time = 0.0,
|
||||
accumulator_time = 0.0,
|
||||
current_time = 0.0;
|
||||
|
||||
fps_counter fps;
|
||||
|
||||
// ============================= RAYCASTER SETUP ==================================
|
||||
|
||||
// Setup the sprite and texture
|
||||
window_texture.create(WINDOW_X, WINDOW_Y);
|
||||
window_sprite.setPosition(0, 0);
|
||||
|
||||
// State values
|
||||
sf::Vector3i map_dim(100, 100, 100);
|
||||
sf::Vector2i view_res(WINDOW_X, WINDOW_Y);
|
||||
sf::Vector3f cam_dir(1.0f, 0.0f, 1.57f);
|
||||
sf::Vector3f cam_pos(50, 50, 50);
|
||||
sf::Vector3f cam_vec(0, 0, 0);
|
||||
Map* map = new Map(map_dim);
|
||||
RayCaster ray_caster(map, map_dim, view_res);
|
||||
|
||||
|
||||
// ===============================================================================
|
||||
|
||||
// Mouse capture
|
||||
sf::Vector2i deltas;
|
||||
sf::Vector2i fixed(window.getSize());
|
||||
bool mouse_enabled = true;
|
||||
|
||||
while (window.isOpen()) {
|
||||
|
||||
// Poll for events from the user
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event)) {
|
||||
|
||||
// If the user tries to exit the application via the GUI
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
}
|
||||
|
||||
cam_vec.x = 0;
|
||||
cam_vec.y = 0;
|
||||
cam_vec.z = 0;
|
||||
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) {
|
||||
cam_vec.z = 1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::E)) {
|
||||
cam_vec.z = -1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
|
||||
cam_vec.y = 1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
|
||||
cam_vec.y = -1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
|
||||
cam_vec.x = 1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
|
||||
cam_vec.x = -1;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
|
||||
cam_dir.z = -0.1f;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
|
||||
cam_vec.z = +0.1f;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
|
||||
cam_vec.y = +0.1f;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
|
||||
cam_vec.y = -0.1f;
|
||||
}
|
||||
|
||||
deltas = fixed - sf::Mouse::getPosition();
|
||||
if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) {
|
||||
|
||||
// Mouse movement
|
||||
sf::Mouse::setPosition(fixed);
|
||||
cam_dir.y -= deltas.y / 300.0f;
|
||||
cam_dir.z -= deltas.x / 300.0f;
|
||||
}
|
||||
|
||||
cam_pos.x += cam_vec.x / 1.0;
|
||||
cam_pos.y += cam_vec.y / 1.0;
|
||||
cam_pos.z += cam_vec.z / 1.0;
|
||||
|
||||
// if (cam_vec.x > 0.0f)
|
||||
// cam_vec.x -= 0.1;
|
||||
// else if (cam_vec.x < 0.0f)
|
||||
// cam_vec.x += 0.1;
|
||||
//
|
||||
// if (cam_vec.y > 0.0f)
|
||||
// cam_vec.y -= 0.1;
|
||||
// else if (cam_vec.y < 0.0f)
|
||||
// cam_vec.y += 0.1;
|
||||
//
|
||||
// if (cam_vec.z > 0.0f)
|
||||
// cam_vec.z -= 0.1;
|
||||
// else if (cam_vec.z < 0.0f)
|
||||
// cam_vec.z += 0.1;
|
||||
|
||||
std::cout << cam_vec.x << " : " << cam_vec.y << " : " << cam_vec.z << std::endl;
|
||||
|
||||
|
||||
// Time keeping
|
||||
elapsed_time = elap_time();
|
||||
delta_time = elapsed_time - current_time;
|
||||
current_time = elapsed_time;
|
||||
if (delta_time > 0.2f)
|
||||
delta_time = 0.2f;
|
||||
accumulator_time += delta_time;
|
||||
while ((accumulator_time - step_size) >= step_size) {
|
||||
accumulator_time -= step_size;
|
||||
|
||||
|
||||
// Update cycle
|
||||
curse.Update(delta_time);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Fps cycle
|
||||
// map->moveLight(sf::Vector2f(0.3, 0));
|
||||
|
||||
window.clear(sf::Color::Black);
|
||||
|
||||
// Cast the rays and get the image
|
||||
sf::Color* pixel_colors = ray_caster.CastRays(cam_dir, cam_pos);
|
||||
|
||||
for (int i = 0; i < WINDOW_X * WINDOW_Y; i++) {
|
||||
|
||||
Curses::Tile t(sf::Vector2i(i % WINDOW_X, i / WINDOW_X));
|
||||
Curses::Slot s(L'\u0045', pixel_colors[i], sf::Color::Black);
|
||||
t.push_back(s);
|
||||
curse.setTile(t);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Cast it to an array of Uint8's
|
||||
auto out = (sf::Uint8*)pixel_colors;
|
||||
|
||||
window_texture.update(out);
|
||||
window_sprite.setTexture(window_texture);
|
||||
window.draw(window_sprite);
|
||||
|
||||
|
||||
curse.Render();
|
||||
|
||||
// Give the frame counter the frame time and draw the average frame time
|
||||
fps.frame(delta_time);
|
||||
fps.draw(&window);
|
||||
|
||||
window.display();
|
||||
|
||||
|
||||
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user