diff --git a/include/Camera.h b/include/Camera.h index e9d6f92..56548a2 100644 --- a/include/Camera.h +++ b/include/Camera.h @@ -31,8 +31,8 @@ public: private: - float friction_coefficient = 0.1; - float default_impulse = 1.0; + float friction_coefficient = 0.1f; + float default_impulse = 1.0f; // 3D vector sf::Vector3f movement; diff --git a/include/Old_map.h b/include/Old_map.h new file mode 100644 index 0000000..bbb9069 --- /dev/null +++ b/include/Old_map.h @@ -0,0 +1,42 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include + +#define _USE_MATH_DEFINES +#include + +#include + +class Old_Map { +public: + + Old_Map(sf::Vector3i dim); + ~Old_Map(); + + void generate_terrain(); + + sf::Vector3i getDimensions(); + char* get_voxel_data(); + +protected: + +private: + + double* height_map; + char *voxel_data; + sf::Vector3i dimensions; + + void set_voxel(sf::Vector3i position, int val); + double sample(int x, int y); + void set_sample(int x, int y, double value); + void sample_square(int x, int y, int size, double value); + void sample_diamond(int x, int y, int size, double value); + void diamond_square(int stepsize, double scale); + + +}; diff --git a/include/Renderer.h b/include/Renderer.h index a81cedb..cda2007 100644 --- a/include/Renderer.h +++ b/include/Renderer.h @@ -36,7 +36,7 @@ public: private: CL_Wrapper *cl; - bool sharing_supported = False; + bool sharing_supported = false; sf::Uint8 *drawing_surface; sf::RenderWindow* window; diff --git a/include/util.hpp b/include/util.hpp index 532ff14..10ff55d 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -64,7 +64,7 @@ public: else { t.setFont(f); t.setCharacterSize(20); - t.setPosition(20, slot * pixel_spacing); + t.setPosition(static_cast(20), static_cast(slot * pixel_spacing)); } } @@ -140,11 +140,11 @@ inline float AngleBetweenVectors(sf::Vector3f a, sf::Vector3f b){ } inline float DegreesToRadians(float in) { - return in * PI / 180.0f; + return static_cast(in * PI / 180.0f); } inline float RadiansToDegrees(float in) { - return in * 180.0f / PI; + return static_cast(in * 180.0f / PI); } inline std::string read_file(std::string file_name){ diff --git a/kernels/ray_caster_kernel.cl b/kernels/ray_caster_kernel.cl index a8f7a91..1309fb5 100644 --- a/kernels/ray_caster_kernel.cl +++ b/kernels/ray_caster_kernel.cl @@ -16,7 +16,13 @@ float4 white_light(float4 input, float3 light, int3 mask) { // 0 1 2 3 4 5 6 7 8 9 // {r, g, b, i, x, y, z, x', y', z'} -float4 cast_light_rays(float3 eye_direction, float3 ray_origin, float4 voxel_color, float3 voxel_normal, global float* lights, global int* light_count) { +float4 cast_light_rays( + float3 eye_direction, + float3 ray_origin, + float4 voxel_color, + float3 voxel_normal, + global float* lights, + global int* light_count) { // set the ray origin to be where the initial ray intersected the voxel // which side z, and the x and y position @@ -183,10 +189,10 @@ __kernel void min_kern( write_imagef(image, pixel, (float4)(.25, .00, .25, 1.00)); return; case 5: - { + //write_imagef(image, pixel, (float4)(.00, .00, + 0.5, 1.00)); - //write_imagef(image, pixel, white_light((float4)(.35, .00, ((1.0 - 0) / (128 - 0) * (voxel.z - 128)) + 1, 0.2), (float3)(lights[7], lights[8], lights[9]), mask)); - + write_imagef(image, pixel, white_light((float4)(.35, .00, ((1.0 - 0) / (128 - 0) * (voxel.z - 128)) + 1, 0.2), (float3)(lights[7], lights[8], lights[9]), mask)); + return; float3 vox = convert_float3(voxel); float3 norm = normalize(convert_float3(mask) * convert_float3(voxel_step)); @@ -204,13 +210,13 @@ __kernel void min_kern( )); return; - } + case 6: write_imagef(image, pixel, (float4)(.30, .80, .10, 1.00)); return; default: - write_imagef(image, pixel, (float4)(.30, .80, .10, 1.00)); - return; + //write_imagef(image, pixel, (float4)(.30, .10, .10, 1.00)); + continue; } } diff --git a/notes/notes.cpp b/notes/notes.cpp new file mode 100644 index 0000000..66c224d --- /dev/null +++ b/notes/notes.cpp @@ -0,0 +1,32 @@ +// TODO + +/* + +OpenCL: + - Add phong lighting / fix the current implementation + - Switch to switch lighting models + - Separate out into a part of the rendering module + +Map: + - Reimplement the old map, put it into an old_map structure + - Implement the new octree structure + - storing the pre-octree volumetric data + - determining when to load volumetric data into the in-memory structure + - building the octree from that raw volumetric data + - combining with other octree nodes to allow streaming of leafs + - passing that data into the renderer + - renderer needs to then traverse the octree + - Terrain generation for real this time + - Loader of 3rd party voxel data + +Renderer: + - Determine when to switch between the cpu and gpu rendering + - call to the map to make sure that the gpu/cpu has an up to date copy + of the volumetric data + + + + + +*/ + diff --git a/src/Camera.cpp b/src/Camera.cpp index f95dc32..55a7379 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -34,22 +34,22 @@ int Camera::add_relative_impulse(DIRECTION impulse_direction, float speed) { switch (impulse_direction) { case DIRECTION::UP: - dir = sf::Vector2f(direction.y, direction.x + PI); + dir = sf::Vector2f(direction.y, direction.x + PI_F); break; case DIRECTION::DOWN: dir = sf::Vector2f(direction.y, direction.x); break; case DIRECTION::LEFT: - dir = sf::Vector2f(direction.y + PI + PI / 2, PI / 2); + dir = sf::Vector2f(direction.y + PI_F + PI_F / 2, PI_F / 2); break; case DIRECTION::RIGHT: - dir = sf::Vector2f(direction.y + PI / 2, PI / 2); + dir = sf::Vector2f(direction.y + PI_F / 2, PI_F / 2); break; case DIRECTION::FORWARD: - dir = sf::Vector2f(direction.y, direction.x + PI / 2); + dir = sf::Vector2f(direction.y, direction.x + PI_F / 2); break; case DIRECTION::REARWARD: - dir = sf::Vector2f(direction.y + PI, (direction.x * -1) + PI / 2 ); + dir = sf::Vector2f(direction.y + PI_F, (direction.x * -1) + PI_F / 2 ); break; } @@ -58,7 +58,7 @@ int Camera::add_relative_impulse(DIRECTION impulse_direction, float speed) { movement *= speed; return 1; -} +} int Camera::slew_camera(sf::Vector2f input) { direction -= input; diff --git a/src/Map.cpp b/src/Map.cpp index 5ab2be8..eb3e8a7 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -27,30 +27,30 @@ struct block { void Map::generate_octree() { - char* arr[8192]; - for (int i = 0; i < 8192; i++) { - arr[i] = 0; - } + char* arr[8192]; + for (int i = 0; i < 8192; i++) { + arr[i] = 0; + } int* dataset = new int[32 * 32 * 32]; for (int i = 0; i < 32 * 32 * 32; i++) { dataset[0] = i; } - int level = log2(32); + int level = static_cast(log2(32)); - leaf top_node; - top_node.level = level; + leaf top_node; + top_node.level = level; - for (int i = 0; i < 16 * 16 * 16; i++){ - for (int i = 0; i < 8 * 8 * 8; i++){ - for (int i = 0; i < 4 * 4 * 4; i++){ - for (int i = 0; i < 2 * 2 * 2; i++){ + for (int i = 0; i < 16 * 16 * 16; i++) { + for (int i = 0; i < 8 * 8 * 8; i++) { + for (int i = 0; i < 4 * 4 * 4; i++) { + for (int i = 0; i < 2 * 2 * 2; i++) { - } - } - } - } + } + } + } + } @@ -67,13 +67,13 @@ void Map::generate_octree() { unsigned int leafmask = 255; unsigned int validmask = leafmask << 8; - + parent &= validmask; parent &= leafmask; std::cout << BitCount(parent & leafmask); - unsigned int children[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + unsigned int children[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; } diff --git a/src/Old_map.cpp b/src/Old_map.cpp new file mode 100644 index 0000000..11898ea --- /dev/null +++ b/src/Old_map.cpp @@ -0,0 +1,225 @@ +#pragma once +#include +#include +#include +#include "util.hpp" +#include + +Old_Map::Old_Map(sf::Vector3i dim) { + dimensions = dim; +} + + +Old_Map::~Old_Map() { +} + +void Old_Map::generate_terrain() { + std::mt19937 gen; + std::uniform_real_distribution dis(-1.0, 1.0); + auto f_rand = std::bind(dis, gen); + + voxel_data = new char[dimensions.x * dimensions.y * dimensions.z]; + height_map = new double[dimensions.x * dimensions.y]; + + for (int i = 0; i < dimensions.x * dimensions.y * dimensions.z; i++) { + voxel_data[i] = 0; + } + + for (int i = 0; i < dimensions.x * dimensions.y; i++) { + height_map[i] = 0; + } + + //size of grid to generate, note this must be a + //value 2^n+1 + int DATA_SIZE = dimensions.x + 1; + //an initial seed value for the corners of the data + double SEED = rand() % 25 + 25; + + //seed the data + set_sample(0, 0, SEED); + set_sample(0, dimensions.y, SEED); + set_sample(dimensions.x, 0, SEED); + set_sample(dimensions.x, dimensions.y, SEED); + + double h = 30.0;//the range (-h -> +h) for the average offset + //for the new value in range of h + //side length is distance of a single square side + //or distance of diagonal in diamond + for (int sideLength = DATA_SIZE - 1; + //side length must be >= 2 so we always have + //a new value (if its 1 we overwrite existing values + //on the last iteration) + sideLength >= 2; + //each iteration we are looking at smaller squares + //diamonds, and we decrease the variation of the offset + sideLength /= 2, h /= 2.0) { + //half the length of the side of a square + //or distance from diamond center to one corner + //(just to make calcs below a little clearer) + int halfSide = sideLength / 2; + + //generate the new square values + for (int x = 0; x < DATA_SIZE - 1; x += sideLength) { + for (int y = 0; y < DATA_SIZE - 1; y += sideLength) { + //x, y is upper left corner of square + //calculate average of existing corners + double avg = sample(x, y) + //top left + sample(x + sideLength, y) +//top right + sample(x, y + sideLength) + //lower left + sample(x + sideLength, y + sideLength);//lower right + avg /= 4.0; + + //center is average plus random offset + set_sample(x + halfSide, y + halfSide, + //We calculate random value in range of 2h + //and then subtract h so the end value is + //in the range (-h, +h) + avg + (f_rand() * 2 * h) - h); + } + } + + //generate the diamond values + //since the diamonds are staggered we only move x + //by half side + //NOTE: if the data shouldn't wrap then x < DATA_SIZE + //to generate the far edge values + for (int x = 0; x < DATA_SIZE - 1; x += halfSide) { + //and y is x offset by half a side, but moved by + //the full side length + //NOTE: if the data shouldn't wrap then y < DATA_SIZE + //to generate the far edge values + for (int y = (x + halfSide) % sideLength; y < DATA_SIZE - 1; y += sideLength) { + //x, y is center of diamond + //note we must use mod and add DATA_SIZE for subtraction + //so that we can wrap around the array to find the corners + double avg = + sample((x - halfSide + DATA_SIZE) % DATA_SIZE, y) + //left of center + sample((x + halfSide) % DATA_SIZE, y) + //right of center + sample(x, (y + halfSide) % DATA_SIZE) + //below center + sample(x, (y - halfSide + DATA_SIZE) % DATA_SIZE); //above center + avg /= 4.0; + + //new value = average plus random offset + //We calculate random value in range of 2h + //and then subtract h so the end value is + //in the range (-h, +h) + avg = avg + (f_rand() * 2 * h) - h; + //update value for center of diamond + set_sample(x, y, avg); + + //wrap values on the edges, remove + //this and adjust loop condition above + //for non-wrapping values. + if (x == 0) set_sample(DATA_SIZE - 1, y, avg); + if (y == 0) set_sample(x, DATA_SIZE - 1, avg); + } + } + } + + + for (int x = 0; x < dimensions.x; x++) { + for (int y = 0; y < dimensions.y; y++) { + + if (height_map[x + y * dimensions.x] > 0) { + + int z = static_cast(height_map[x + y * dimensions.x]); + + while (z > 0) { + voxel_data[x + dimensions.x * (y + dimensions.z * z)] = 5; + z--; + } + } + + } + } + + + for (int x = 0; x < dimensions.x / 10; x++) { + for (int y = 0; y < dimensions.y / 10; y++) { + for (int z = 0; z < dimensions.z; z++) { + if (rand() % 1000 < 1) + voxel_data[x + dimensions.x * (y + dimensions.z * z)] = rand() % 6; + } + } + } + +} + + +void Old_Map::set_voxel(sf::Vector3i position, int val) { + voxel_data[position.x + dimensions.x * (position.y + dimensions.z * position.z)] = val; +} + +sf::Vector3i Old_Map::getDimensions() { + return dimensions; +} + +char* Old_Map::get_voxel_data() { + return voxel_data; +} + +double Old_Map::sample(int x, int y) { + return height_map[(x & (dimensions.x - 1)) + (y & (dimensions.y - 1)) * dimensions.x]; +} + +void Old_Map::set_sample(int x, int y, double value) { + height_map[(x & (dimensions.x - 1)) + (y & (dimensions.y - 1)) * dimensions.x] = value; +} + +void Old_Map::sample_square(int x, int y, int size, double value) { + int hs = size / 2; + + // a b + // + // x + // + // c d + + double a = sample(x - hs, y - hs); + double b = sample(x + hs, y - hs); + double c = sample(x - hs, y + hs); + double d = sample(x + hs, y + hs); + + set_sample(x, y, ((a + b + c + d) / 4.0) + value); + +} + +void Old_Map::sample_diamond(int x, int y, int size, double value) { + int hs = size / 2; + + // c + // + //a x b + // + // d + + double a = sample(x - hs, y); + double b = sample(x + hs, y); + double c = sample(x, y - hs); + double d = sample(x, y + hs); + + set_sample(x, y, ((a + b + c + d) / 4.0) + value); +} + +void Old_Map::diamond_square(int stepsize, double scale) { + + std::mt19937 generator; + std::uniform_real_distribution uniform_distribution(-1.0, 1.0); + auto f_rand = std::bind(uniform_distribution, std::ref(generator)); + + int halfstep = stepsize / 2; + + for (int y = halfstep; y < dimensions.y + halfstep; y += stepsize) { + for (int x = halfstep; x < dimensions.x + halfstep; x += stepsize) { + sample_square(x, y, stepsize, f_rand() * scale); + } + } + + for (int y = 0; y < dimensions.y; y += stepsize) { + for (int x = 0; x < dimensions.x; x += stepsize) { + sample_diamond(x + halfstep, y, stepsize, f_rand() * scale); + sample_diamond(x, y + halfstep, stepsize, f_rand() * scale); + } + } + +} \ No newline at end of file diff --git a/src/Ray.cpp b/src/Ray.cpp index e0894e8..70d62b4 100644 --- a/src/Ray.cpp +++ b/src/Ray.cpp @@ -30,9 +30,9 @@ sf::Color Ray::Cast() { // Setup the voxel coords from the camera origin voxel = sf::Vector3( - floorf(origin.x), - floorf(origin.y), - floorf(origin.z) + static_cast(floorf(origin.x)), + static_cast(floorf(origin.y)), + static_cast(floorf(origin.z)) ); // Delta T is the units a ray must travel along an axis in order to @@ -113,18 +113,18 @@ sf::Color Ray::Cast() { if (face == 0) { alpha = AngleBetweenVectors(sf::Vector3f(1, 0, 0), map->global_light); - alpha = fmod(alpha, 0.785) * 2; + alpha = static_cast(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; + alpha = static_cast(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 = static_cast(fmod(alpha, 0.785) * 2); } alpha *= 162; diff --git a/src/main.cpp b/src/main.cpp index 6e3f52c..d1050ef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,3 @@ -#include -#include -#include -#include -#include - #ifdef linux #include #include @@ -25,7 +19,14 @@ #include #endif -#include "Map.h" + +#include +#include +#include +#include +#include + +#include "Old_Map.h" #include "Curses.h" #include "util.hpp" #include "RayCaster.h" @@ -52,7 +53,7 @@ float elap_time(){ std::chrono::time_point now = std::chrono::system_clock::now(); std::chrono::duration elapsed_time = now - start; - return elapsed_time.count(); + return static_cast(elapsed_time.count()); } sf::Sprite window_sprite; @@ -64,299 +65,296 @@ sf::Texture window_texture; int main() { + sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML"); + CL_Wrapper c; - //Map m(sf::Vector3i (50, 50, 50)); - //m.generate_octree(); - return 1; - - //sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML"); - - //if (c.compile_kernel("../kernels/ray_caster_kernel.cl", true, "min_kern") < 0) { - // std::cin.get(); - // return -1; - //} - // - //std::cout << "map..."; - // sf::Vector3i map_dim(MAP_X, MAP_Y, MAP_Z); - // Map* map = new Map(map_dim); - // - //c.create_buffer("map_buffer", sizeof(char) * map_dim.x * map_dim.y * map_dim.z, map->list); - //c.create_buffer("dim_buffer", sizeof(int) * 3, &map_dim); - - //sf::Vector2i view_res(WINDOW_X, WINDOW_Y); - //c.create_buffer("res_buffer", sizeof(int) * 2, &view_res); - // - - // double y_increment_radians = DegreesToRadians(50.0 / view_res.y); - // double x_increment_radians = DegreesToRadians(80.0 / view_res.x); - - //std::cout << "view matrix..."; - // - //sf::Vector4f* view_matrix = new sf::Vector4f[WINDOW_X * WINDOW_Y * 4]; - - // for (int y = -view_res.y / 2; y < view_res.y / 2; y++) { - // for (int x = -view_res.x / 2; x < view_res.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 + view_res.x / 2) + view_res.x * (y + view_res.y / 2); - // ray = Normalize(ray); - - // view_matrix[index] = sf::Vector4f( - // ray.x, - // ray.y, - // ray.z, - // 0 - // ); - // } - // } - - //c.create_buffer("view_matrix_buffer", sizeof(float) * 4 * view_res.x * view_res.y, view_matrix); - - //Camera camera( - // sf::Vector3f(70, 60, 50), - // sf::Vector2f(0.0f, 1.00f) - //); - // - //c.create_buffer("cam_dir_buffer", sizeof(float) * 4, (void*)camera.get_direction_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR); - //c.create_buffer("cam_pos_buffer", sizeof(float) * 4, (void*)camera.get_position_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR); - // - //int light_count = 2; - //c.create_buffer("light_count_buffer", sizeof(int), &light_count); - - //// {r, g, b, i, x, y, z, x', y', z'} - //sf::Vector3f v = Normalize(sf::Vector3f(1.0, 0.0, 0.0)); - //sf::Vector3f v2 = Normalize(sf::Vector3f(1.1, 0.4, 0.7)); - //float light[] = { 0.4, 0.8, 0.1, 1, 50, 50, 50, v.x, v.y, v.z, - // 0.4, 0.8, 0.1, 1, 50, 50, 50, v2.x, v2.y, v2.z}; - //c.create_buffer("light_buffer", sizeof(float) * 10 * light_count, light, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR); - - //// The drawing canvas - // unsigned char* pixel_array = new sf::Uint8[WINDOW_X * WINDOW_Y * 4]; - - // for (int i = 0; i < WINDOW_X * WINDOW_Y * 4; i += 4) { - - // pixel_array[i] = 255; // R? - // pixel_array[i + 1] = 255; // G? - // pixel_array[i + 2] = 255; // B? - // pixel_array[i + 3] = 100; // A? - // } - - //sf::Texture t; - // t.create(WINDOW_X, WINDOW_Y); - // t.update(pixel_array); - - // int error; - // cl_mem image_buff = clCreateFromGLTexture( - // c.getContext(), CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, - // 0, t.getNativeHandle(), &error); - - // if (c.assert(error, "clCreateFromGLTexture")) - // return -1; - - // c.store_buffer(image_buff, "image_buffer"); - - // c.set_kernel_arg("min_kern", 0, "map_buffer"); - // c.set_kernel_arg("min_kern", 1, "dim_buffer"); - // c.set_kernel_arg("min_kern", 2, "res_buffer"); - // c.set_kernel_arg("min_kern", 3, "view_matrix_buffer"); - // c.set_kernel_arg("min_kern", 4, "cam_dir_buffer"); - // c.set_kernel_arg("min_kern", 5, "cam_pos_buffer"); - //c.set_kernel_arg("min_kern", 6, "light_buffer"); - //c.set_kernel_arg("min_kern", 7, "light_count_buffer"); - //c.set_kernel_arg("min_kern", 8, "image_buffer"); - - //sf::Sprite s; - //s.setTexture(t); - //s.setPosition(0, 0); - - // // 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::Vector3f cam_vec(0, 0, 0); + if (c.compile_kernel("../kernels/ray_caster_kernel.cl", true, "min_kern") < 0) { + std::cin.get(); + return -1; + } + + std::cout << "map..."; + sf::Vector3i map_dim(MAP_X, MAP_Y, MAP_Z); + Old_Map* map = new Old_Map(map_dim); + map->generate_terrain(); + + c.create_buffer("map_buffer", sizeof(char) * map_dim.x * map_dim.y * map_dim.z, map->get_voxel_data()); + c.create_buffer("dim_buffer", sizeof(int) * 3, &map_dim); + + sf::Vector2i view_res(WINDOW_X, WINDOW_Y); + c.create_buffer("res_buffer", sizeof(int) * 2, &view_res); + + + double y_increment_radians = DegreesToRadians(50.0f / view_res.y); + double x_increment_radians = DegreesToRadians(80.0f / view_res.x); + + std::cout << "view matrix..."; + + sf::Vector4f* view_matrix = new sf::Vector4f[WINDOW_X * WINDOW_Y * 4]; + + for (int y = -view_res.y / 2; y < view_res.y / 2; y++) { + for (int x = -view_res.x / 2; x < view_res.x / 2; x++) { + + // The base ray direction to slew from + sf::Vector3f ray(1, 0, 0); + + // Y axis, pitch + ray = sf::Vector3f( + static_cast(ray.z * sin(y_increment_radians * y) + ray.x * cos(y_increment_radians * y)), + static_cast(ray.y), + static_cast(ray.z * cos(y_increment_radians * y) - ray.x * sin(y_increment_radians * y)) + ); + + + // Z axis, yaw + ray = sf::Vector3f( + static_cast(ray.x * cos(x_increment_radians * x) - ray.y * sin(x_increment_radians * x)), + static_cast(ray.x * sin(x_increment_radians * x) + ray.y * cos(x_increment_radians * x)), + static_cast(ray.z) + ); + + int index = (x + view_res.x / 2) + view_res.x * (y + view_res.y / 2); + ray = Normalize(ray); + + view_matrix[index] = sf::Vector4f( + ray.x, + ray.y, + ray.z, + 0 + ); + } + } + + c.create_buffer("view_matrix_buffer", sizeof(float) * 4 * view_res.x * view_res.y, view_matrix); + + Camera camera( + sf::Vector3f(70, 60, 50), + sf::Vector2f(0.0f, 1.00f) + ); + + c.create_buffer("cam_dir_buffer", sizeof(float) * 4, (void*)camera.get_direction_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR); + c.create_buffer("cam_pos_buffer", sizeof(float) * 4, (void*)camera.get_position_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR); + + int light_count = 2; + c.create_buffer("light_count_buffer", sizeof(int), &light_count); + + // {r, g, b, i, x, y, z, x', y', z'} + sf::Vector3f v = Normalize(sf::Vector3f(1.0f, 0.0f, 0.0f)); + sf::Vector3f v2 = Normalize(sf::Vector3f(1.1f, 0.4f, 0.7f)); + float light[] = { 0.4f, 0.8f, 0.1f, 1.0f, 50.0f, 50.0f, 50.0f, v.x, v.y, v.z, + 0.4f, 0.8f, 0.1f, 1.0f, 50.0f, 50.0f, 50.0f, v2.x, v2.y, v2.z}; + c.create_buffer("light_buffer", sizeof(float) * 10 * light_count, light, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR); + + // The drawing canvas + unsigned char* pixel_array = new sf::Uint8[WINDOW_X * WINDOW_Y * 4]; + + for (int i = 0; i < WINDOW_X * WINDOW_Y * 4; i += 4) { + + pixel_array[i] = 255; // R? + pixel_array[i + 1] = 255; // G? + pixel_array[i + 2] = 255; // B? + pixel_array[i + 3] = 100; // A? + } + + sf::Texture t; + t.create(WINDOW_X, WINDOW_Y); + t.update(pixel_array); + + int error; + cl_mem image_buff = clCreateFromGLTexture( + c.getContext(), CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, + 0, t.getNativeHandle(), &error); + + if (c.assert(error, "clCreateFromGLTexture")) + return -1; + + c.store_buffer(image_buff, "image_buffer"); + + c.set_kernel_arg("min_kern", 0, "map_buffer"); + c.set_kernel_arg("min_kern", 1, "dim_buffer"); + c.set_kernel_arg("min_kern", 2, "res_buffer"); + c.set_kernel_arg("min_kern", 3, "view_matrix_buffer"); + c.set_kernel_arg("min_kern", 4, "cam_dir_buffer"); + c.set_kernel_arg("min_kern", 5, "cam_pos_buffer"); + c.set_kernel_arg("min_kern", 6, "light_buffer"); + c.set_kernel_arg("min_kern", 7, "light_count_buffer"); + c.set_kernel_arg("min_kern", 8, "image_buffer"); + + sf::Sprite s; + s.setTexture(t); + s.setPosition(0, 0); + + // 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::Vector3f cam_vec(0, 0, 0); //RayCaster ray_caster(map, map_dim, view_res); - //sf::Vector2f *dp = camera.get_direction_pointer(); - //debug_text cam_text_x(1, 30, &dp->x, "X: "); - //debug_text cam_text_y(2, 30, &dp->y, "Y: "); - - //sf::Vector3f *mp = camera.get_movement_pointer(); - //debug_text cam_text_mov_x(4, 30, &mp->x, "X: "); - //debug_text cam_text_mov_y(5, 30, &mp->y, "Y: "); - //debug_text cam_text_mov_z(6, 30, &mp->y, "Z: "); - ////debug_text cam_text_z(3, 30, &p->z); - - //debug_text light_x(7, 30, &light[7], "X: "); - //debug_text light_y(8, 30, &light[8], "Y: "); - //debug_text light_z(9, 30, &light[9], "Z: "); - //// =============================================================================== - - //// Mouse capture - //sf::Vector2i deltas; - //sf::Vector2i fixed(window.getSize()); - //bool mouse_enabled = true; - - //sf::Vector3f cam_mov_vec; - - //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(); - // if (event.type == sf::Event::KeyPressed) { - // if (event.key.code == sf::Keyboard::Space) { - // if (mouse_enabled) - // mouse_enabled = false; - // else - // mouse_enabled = true; - // } - // } - // } - - // cam_vec.x = 0; - // cam_vec.y = 0; - // cam_vec.z = 0; - - // float speed = 1.0f; - - // if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift)) { - // speed = 0.2f; - // } - // if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) { - // camera.add_relative_impulse(Camera::DIRECTION::DOWN, speed); - // } - // if (sf::Keyboard::isKeyPressed(sf::Keyboard::E)) { - // camera.add_relative_impulse(Camera::DIRECTION::UP, speed); - // } - // if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { - // camera.add_relative_impulse(Camera::DIRECTION::FORWARD, speed); - // } - // if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { - // camera.add_relative_impulse(Camera::DIRECTION::REARWARD, speed); - // } - // if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { - // camera.add_relative_impulse(Camera::DIRECTION::LEFT, speed); - // } - // if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { - // camera.add_relative_impulse(Camera::DIRECTION::RIGHT, speed); - // } - // if (sf::Keyboard::isKeyPressed(sf::Keyboard::T)) { - // camera.set_position(sf::Vector3f(50, 50, 50)); - // } - - // camera.add_static_impulse(cam_vec); - - // if (mouse_enabled) { - // deltas = fixed - sf::Mouse::getPosition(); - // if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) { - - // // Mouse movement - // sf::Mouse::setPosition(fixed); - // camera.slew_camera(sf::Vector2f( - // deltas.y / 300.0f, - // deltas.x / 300.0f - // )); - // } - // } - - // // 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; - - // // ==== DELTA TIME LOCKED ==== - // } - - // float l[] = { - // light[9] * sin(delta_time / 1) + light[7] * cos(delta_time / 1), - // light[8], - // light[9] * cos(delta_time / 1) - light[7] * sin(delta_time / 1) - // }; - - // float l2[] = { - // l[0] * cos(delta_time) - l[2] * sin(delta_time), - // l[0] * sin(delta_time) + l[2] * cos(delta_time), - // l[2] - // }; - - // light[7] = l[0]; - // light[8] = l[1]; - // light[9] = l[2]; - - // // ==== FPS LOCKED ==== - // camera.update(delta_time); - - // // Run the raycast - // c.run_kernel("min_kern", WORK_SIZE); - // - // // ==== RENDER ==== - - // window.clear(sf::Color::Black); - - // window.draw(s); - - // // Give the frame counter the frame time and draw the average frame time - // fps.frame(delta_time); - // fps.draw(&window); - - // cam_text_x.draw(&window); - // cam_text_y.draw(&window); - - // cam_text_mov_x.draw(&window); - // cam_text_mov_y.draw(&window); - // cam_text_mov_z.draw(&window); - - // light_x.draw(&window); - // light_y.draw(&window); - // light_z.draw(&window); - // - // window.display(); - - //} + sf::Vector2f *dp = camera.get_direction_pointer(); + debug_text cam_text_x(1, 30, &dp->x, "X: "); + debug_text cam_text_y(2, 30, &dp->y, "Y: "); + + sf::Vector3f *mp = camera.get_movement_pointer(); + debug_text cam_text_mov_x(4, 30, &mp->x, "X: "); + debug_text cam_text_mov_y(5, 30, &mp->y, "Y: "); + debug_text cam_text_mov_z(6, 30, &mp->y, "Z: "); + //debug_text cam_text_z(3, 30, &p->z); + + debug_text light_x(7, 30, &light[7], "X: "); + debug_text light_y(8, 30, &light[8], "Y: "); + debug_text light_z(9, 30, &light[9], "Z: "); + // =============================================================================== + + // Mouse capture + sf::Vector2i deltas; + sf::Vector2i fixed(window.getSize()); + bool mouse_enabled = true; + + sf::Vector3f cam_mov_vec; + + 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(); + if (event.type == sf::Event::KeyPressed) { + if (event.key.code == sf::Keyboard::Space) { + if (mouse_enabled) + mouse_enabled = false; + else + mouse_enabled = true; + } + } + } + + cam_vec.x = 0; + cam_vec.y = 0; + cam_vec.z = 0; + + float speed = 1.0f; + + if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift)) { + speed = 0.2f; + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) { + camera.add_relative_impulse(Camera::DIRECTION::DOWN, speed); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::E)) { + camera.add_relative_impulse(Camera::DIRECTION::UP, speed); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { + camera.add_relative_impulse(Camera::DIRECTION::FORWARD, speed); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { + camera.add_relative_impulse(Camera::DIRECTION::REARWARD, speed); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { + camera.add_relative_impulse(Camera::DIRECTION::LEFT, speed); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { + camera.add_relative_impulse(Camera::DIRECTION::RIGHT, speed); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::T)) { + camera.set_position(sf::Vector3f(50, 50, 50)); + } + + camera.add_static_impulse(cam_vec); + + if (mouse_enabled) { + deltas = fixed - sf::Mouse::getPosition(); + if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) { + + // Mouse movement + sf::Mouse::setPosition(fixed); + camera.slew_camera(sf::Vector2f( + deltas.y / 300.0f, + deltas.x / 300.0f + )); + } + } + + // 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; + + // ==== DELTA TIME LOCKED ==== + } + + float l[] = { + static_cast(light[9] * sin(delta_time / 1) + light[7] * cos(delta_time / 1)), + static_cast(light[8]), + static_cast(light[9] * cos(delta_time / 1) - light[7] * sin(delta_time / 1)) + }; + + float l2[] = { + static_cast(l[0] * cos(delta_time) - l[2] * sin(delta_time)), + static_cast(l[0] * sin(delta_time) + l[2] * cos(delta_time)), + static_cast(l[2]) + }; + + light[7] = l[0]; + light[8] = l[1]; + light[9] = l[2]; + + // ==== FPS LOCKED ==== + camera.update(delta_time); + + // Run the raycast + c.run_kernel("min_kern", WORK_SIZE); + + // ==== RENDER ==== + + window.clear(sf::Color::Black); + + window.draw(s); + + // Give the frame counter the frame time and draw the average frame time + fps.frame(delta_time); + fps.draw(&window); + + cam_text_x.draw(&window); + cam_text_y.draw(&window); + + cam_text_mov_x.draw(&window); + cam_text_mov_y.draw(&window); + cam_text_mov_z.draw(&window); + + light_x.draw(&window); + light_y.draw(&window); + light_z.draw(&window); + + window.display(); + + } return 0; }