In the middle of a couple of things right now, but decided to focus a

little bit less on the lighting and start laying groundwork for the SVO
The map section was in real need of some love so I deleted a bunch of
stuff and started prototyping the pointer arithmetic that I need to do
master
MitchellHansen 8 years ago
parent 4c31cfaf48
commit de2f0ad6a1

@ -15,7 +15,7 @@ public:
int set_position(sf::Vector3f position); int set_position(sf::Vector3f position);
int add_static_impulse(sf::Vector3f impulse); int add_static_impulse(sf::Vector3f impulse);
int add_relative_impulse(DIRECTION direction); int add_relative_impulse(DIRECTION direction, float speed);
int slew_camera(sf::Vector2f input); int slew_camera(sf::Vector2f input);

@ -8,295 +8,44 @@
#include <cmath> #include <cmath>
#define _USE_MATH_DEFINES #define _USE_MATH_DEFINES
#include <math.h> #include <math.h>
#include <unordered_map>
#include <deque>
class Map {
public:
// In addition to traversing the voxel hierarchy, we must also be able to
// tell which block a given voxel resides in.This is accomplished us -
// ing 32 - bit page headers spread amongst the child descriptors.Page
// headers are placed at every 8 kilobyte boundary, and each contains
// a relative pointer to the block info section.By placing the begin -
// ning of the child descriptor array at such a boundary, we can always
// find a page header by simply clearing the lowest bits of any child
// descriptor pointer.
struct page_header {
int bitmask;
};
struct leaf_node {
long bitmask;
};
short scale;
void generate_octree() {
uint64_t *octree = new uint64_t[200];
long tree_node = 0;
std::vector<long> page_array;
// Page placed every 8 kilobytes
// contains a relative pointer to the block info section
uint32_t page = 255;
// Child pointer points to the first non-leaf child of this node
uint16_t child_pointer = 20;
uint32_t pointer = page | child_pointer;
};
Map(sf::Vector3i dim) {
//generate_octree();
//return;
dimensions = dim;
std::mt19937 gen;
std::uniform_real_distribution<double> dis(-1.0, 1.0);
auto f_rand = std::bind(dis, gen);
list = new char[dim.x * dim.y * dim.z];
height_map = new double[dim.x * dim.y];
for (int i = 0; i < dim.x * dim.y * dim.z; i++) {
list[i] = 0;
}
for (int i = 0; i < dim.x * dim.y; i++) {
height_map[i] = 0;
}
//for (int x = -dim.x / 2; x < dim.x/2; x++) {
// for (int y = -dim.y / 2; y < dim.y/2; y++) {
//
// double height = 20;
// height += std::pow(x / 50.0, 2) - 10 * std::cos(2 * 3.1415926 * x / 50.0);
// height += std::pow(y / 50.0, 2) - 10 * std::cos(2 * 3.1415926 * y / 50.0);
//
// list[(x + dim.x/2) + dim.x * ((y +dim.y/2) + dim.z * (int)height)] = 5;
// }
//}
//int xx = 0;
//int yy = 0;
//for (int x = -dim.x / 2; x < dim.x / 2; x++) {
// for (int y = -dim.y / 2; y < dim.y / 2; y++) {
// double z = 150;
////for (int x = 0; x < dim.x; x++) {
//// for (int y = 0; y < dim.y; y++) {
// double height = 0;
// z += -x*2 * std::sin(std::sqrt(abs(x*2 - y*2 - 47))) -
// (y*2 + 47) * std::sin(std::sqrt(std::abs(y*2 + 47 + x*2 / 2)));
//
// //z += x * std::sin(std::sqrt(std::abs(y - x + 1))) *
// // std::cos(std::sqrt(std::abs(y + x + 1))) +
// // (y + 1) *
// // std::cos(std::sqrt(std::abs(y - x + 1))) *
// // std::sin(std::sqrt(std::abs(y + x + 1)));
//
// // Pathological
// //z += 0.5 +
// // (std::pow(std::sin(std::sqrt(100 * std::pow(x/20, 2) + std::pow(y/20, 2))), 2) - 0.5) /
// // (1 + 0.001 * std::pow(std::pow(x/20, 2) - 2 * x/20 * y/20 + std::pow(y/20, 2), 2));
// // Ackleys
// //z += 20 + M_E -
// // (20 / (std::pow(M_E, 0.2) * std::sqrt((std::pow(x / 16.0, 2) + std::pow(y / 16.0, 2) + 1) / 2))) -
// // std::pow(M_E, 0.5 * std::cos(2 * M_PI * x / 16.0) + cos(2 * M_PI * y / 16.0));
// //
// //z += -20 * std::pow(M_E, -0.2 * sqrt(0.5 * std::pow(x/64.0, 2) + std::pow(y/64.0, 2))) - std::pow(M_E, 0.5 * (cos(2 * M_PI * x/64.0) + (cos(2 * M_PI * y/64.0)))) + 20 + M_E;
//
// //list[x + dim.x * (y + dim.z * (int)height)] = 5;
// double m = 0.2;
// while ((z*m) > 0){
// list[xx + dim.x * (yy + dim.z * (int)(z*m))] = 5;
// z -= 1/m;
// }
// yy++;
// }
// yy = 0;
// xx++;
//}
//
//return;
//int featuresize = 2;
//for (int y = 0; y < dim.y; y += featuresize)
// for (int x = 0; x < dim.x; x += featuresize) {
// double t = dis(gen);
// setSample(x, y, t); //IMPORTANT: frand() is a random function that returns a value between -1 and 1.
// }
//int samplesize = featuresize;
//double scale = 10.0;
//while (samplesize > 1) {
// DiamondSquare(samplesize, scale);
// samplesize /= 2;
// scale /= 2.0;
//}
//size of grid to generate, note this must be a
//value 2^n+1
int DATA_SIZE = dim.x + 1;
//an initial seed value for the corners of the data
double SEED = rand() % 25 + 25;
//seed the data
setSample(0, 0, SEED);
setSample(0, dim.y, SEED);
setSample(dim.x, 0, SEED);
setSample(dim.x, dim.y, SEED);
double h = 30.0;//the range (-h -> +h) for the average offset #include <deque>
//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
setSample(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
setSample(x,y, avg);
//wrap values on the edges, remove
//this and adjust loop condition above
//for non-wrapping values.
if (x == 0) setSample(DATA_SIZE - 1,y, avg);
if (y == 0) setSample(x, DATA_SIZE - 1, avg);
}
}
}
for (int x = 0; x < dim.x; x++) {
for (int y = 0; y < dim.y; y++) {
if (height_map[x + y * dim.x] > 0) {
int z = height_map[x + y * dim.x];
while (z > 0){
list[x + dim.x * (y + dim.z * z)] = 5;
z--;
}
}
}
}
for (int x = 0; x < dim.x / 10; x++) {
for (int y = 0; y < dim.y / 10; y++) {
for (int z = 0; z < dim.z; z++) {
if (rand() % 1000 < 1)
list[x + dim.x * (y + dim.z * z)] = rand() % 6;
}
}
}
#define CHUNK_DIM 32
} struct KeyHasher {
std::size_t operator()(const sf::Vector3i& k) const {
~Map() { return ((std::hash<int>()(k.x)
^ (std::hash<int>()(k.y) << 1)) >> 1)
^ (std::hash<int>()(k.z) << 1);
} }
};
struct Chunk {
Chunk(int type) { voxel_data = new int[CHUNK_DIM * CHUNK_DIM * CHUNK_DIM]; set(type); };
Chunk() { };
void set(int type);
~Chunk() { voxel_data = nullptr; };
int* voxel_data;
};
class Map {
public:
Map(sf::Vector3i dim);
void generate_octree();
void load_unload(sf::Vector3i world_position);
void load_single(sf::Vector3i world_position);
sf::Vector3i getDimensions(); sf::Vector3i getDimensions();
char *list; char *list;
sf::Vector3i dimensions; //sf::Vector3i dimensions;
void setVoxel(sf::Vector3i position, int val){
list[position.x + dimensions.x * (position.y + dimensions.z * position.z)] = val; void setVoxel(sf::Vector3i position, int val);
};
void moveLight(sf::Vector2f in); void moveLight(sf::Vector2f in);
sf::Vector3f global_light; sf::Vector3f global_light;
@ -304,72 +53,21 @@ public:
protected: protected:
private: private:
double* height_map;
double sample(int x, int y) {
return height_map[(x & (dimensions.x - 1)) + (y & (dimensions.y - 1)) * dimensions.x];
}
void setSample(int x, int y, double value) {
height_map[(x & (dimensions.x - 1)) + (y & (dimensions.y - 1)) * dimensions.x] = value;
}
void sampleSquare(int x, int y, int size, double value) {
int hs = size / 2;
// a b
//
// x
//
// c d
double a = sample(x - hs, y - hs); std::unordered_map<sf::Vector3i, Chunk, KeyHasher> chunk_map;
double b = sample(x + hs, y - hs);
double c = sample(x - hs, y + hs);
double d = sample(x + hs, y + hs);
setSample(x, y, ((a + b + c + d) / 4.0) + value);
}
void sampleDiamond(int x, int y, int size, double value) { double* height_map;
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);
setSample(x, y, ((a + b + c + d) / 4.0) + value);
}
void DiamondSquare(int stepsize, double scale) {
std::mt19937 generator;
std::uniform_real_distribution<double> 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) {
sampleSquare(x, y, stepsize, f_rand() * scale);
}
}
for (int y = 0; y < dimensions.y; y += stepsize) { // 2^k
for (int x = 0; x < dimensions.x; x += stepsize) { int chunk_radius = 6;
sampleDiamond(x + halfstep, y, stepsize, f_rand() * scale);
sampleDiamond(x, y + halfstep, stepsize, f_rand() * scale);
}
}
sf::Vector3i world_to_chunk(sf::Vector3i world_coords) {
return sf::Vector3i(
world_coords.x / CHUNK_DIM + 1,
world_coords.y / CHUNK_DIM + 1,
world_coords.z / CHUNK_DIM + 1
);
} }
}; };

@ -22,25 +22,38 @@ float4 cast_light_rays(float3 eye_direction, float3 ray_origin, float4 voxel_col
// which side z, and the x and y position // which side z, and the x and y position
float ambient_constant = 0.5; float ambient_constant = 0.5;
float intensity = 1.2; float intensity = 0;
for (int i = 0; i < *light_count; i++) { for (int i = 0; i < *light_count; i++) {
float distance = sqrt(
pow(lights[10 * i + 4] - ray_origin.x, 2) +
pow(lights[10 * i + 5] - ray_origin.y, 2) +
pow(lights[10 * i + 6] - ray_origin.z, 2));
if (distance > 50)
continue;
float3 light_direction = (lights[10 * i + 7], lights[10 * i + 8], lights[10 * i + 9]); float3 light_direction = (lights[10 * i + 7], lights[10 * i + 8], lights[10 * i + 9]);
float c = 1.0; float c = 10.0;
if (dot(light_direction, voxel_normal) > 0.0) { //if (dot(light_direction, voxel_normal) > 0.0) {
float3 halfwayVector = normalize(light_direction + eye_direction); float3 halfwayVector = normalize(light_direction + eye_direction);
float dot_prod = dot(voxel_normal, halfwayVector); float dot_prod = dot(voxel_normal, halfwayVector);
float specTmp = max((float)dot_prod, 0.0f); float specTmp = max((float)dot_prod, 0.0f);
intensity += pow(specTmp, c); intensity += pow(specTmp, c);
//}
} }
if (get_global_id(0) == 1037760) {
printf("%f", intensity);
voxel_color = (float4)(1.0, 1.0, 1.0, 1.0);
return voxel_color;
} }
//if (get_global_id(0) == 0) voxel_color.w *= intensity;
// printf("%i", *light_count);
voxel_color *= intensity;
voxel_color.w += ambient_constant; voxel_color.w += ambient_constant;
return voxel_color; return voxel_color;
// for every light // for every light
@ -176,8 +189,8 @@ __kernel void min_kern(
float3 vox = convert_float3(voxel); float3 vox = convert_float3(voxel);
float3 norm = normalize(fabs(convert_float3(mask))); float3 norm = normalize(convert_float3(mask) * convert_float3(voxel_step));
float4 color = (float4)(0.25, 0.00, 0.25, 1.00); float4 color = (float4)(0.95, 0.00, 0.25, 1.00);
write_imagef(image, pixel, write_imagef(image, pixel,

@ -25,7 +25,7 @@ int Camera::add_static_impulse(sf::Vector3f impulse) {
return 1; return 1;
} }
int Camera::add_relative_impulse(DIRECTION impulse_direction) { int Camera::add_relative_impulse(DIRECTION impulse_direction, float speed) {
// No sense in doing fancy dot products, adding Pi's will suffice // No sense in doing fancy dot products, adding Pi's will suffice
// Always add PI/2 to X initially to avoid negative case // Always add PI/2 to X initially to avoid negative case
@ -55,6 +55,7 @@ int Camera::add_relative_impulse(DIRECTION impulse_direction) {
} }
movement += SphereToCart(dir); movement += SphereToCart(dir);
movement *= speed;
return 1; return 1;
} }

@ -5,45 +5,67 @@
#include <SFML/System/Vector2.hpp> #include <SFML/System/Vector2.hpp>
#include "util.hpp" #include "util.hpp"
sf::Vector3i Map::getDimensions() { Map::Map(sf::Vector3i position) {
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;
load_unload(position);
} }
int BitCount(unsigned int u) {
unsigned int uCount;
uCount = u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111);
return ((uCount + (uCount >> 3)) & 030707070707) % 63;
}
struct block {
int header = 0;
double* data = new double[1000];
};
void Map::generate_octree() {
int* dataset = new int[32 * 32 * 32];
for (int i = 0; i < 32 * 32 * 32; i++) {
dataset[0] = i;
}
char* arr[8192];
for (int i = 0; i < 8192; i++) {
arr[i] = 0;
}
std::list<int> parent_stack;
int byte_pos = 0;
int levels = log2(32);
unsigned int parent = 0;
for (int i = 0; i < 16; i++) {
parent ^= 1 << i;
}
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};
for (int i = 0; i < levels; i++) {
}
}
@ -58,13 +80,312 @@ void Map::moveLight(sf::Vector2f in) {
//void Map::generate_test() {
//
// //generate_octree();
// //return;
//
// //dimensions = dim;
// //std::mt19937 gen;
// //std::uniform_real_distribution<double> dis(-1.0, 1.0);
// //auto f_rand = std::bind(dis, gen);
//
//
// //list = new char[dim.x * dim.y * dim.z];
//
// //height_map = new double[dim.x * dim.y];
//
// //for (int i = 0; i < dim.x * dim.y * dim.z; i++) {
// // list[i] = 0;
// //}
//
// //for (int i = 0; i < dim.x * dim.y; i++) {
// // height_map[i] = 0;
// //}
//
//
// //for (int x = 50; x < 60; x += 2) {
// // for (int y = 50; y < 60; y += 2) {
// // for (int z = 50; z < 60; z += 2) {
// // list[x + dimensions.x * (y + dimensions.z * z)] = 5;
// // }
// // }
// //}
//
// //list[71 + dimensions.x * (61 + dimensions.z * 51)] = 5;
//
// ////for (int x = -dim.x / 2; x < dim.x/2; x++) {
// //// for (int y = -dim.y / 2; y < dim.y/2; y++) {
// ////
// //// double height = 20;
//
// //// height += std::pow(x / 50.0, 2) - 10 * std::cos(2 * 3.1415926 * x / 50.0);
// //// height += std::pow(y / 50.0, 2) - 10 * std::cos(2 * 3.1415926 * y / 50.0);
// ////
// //// list[(x + dim.x/2) + dim.x * ((y +dim.y/2) + dim.z * (int)height)] = 5;
// //// }
// ////}
//
// ////int xx = 0;
// ////int yy = 0;
// ////for (int x = -dim.x / 2; x < dim.x / 2; x++) {
// //// for (int y = -dim.y / 2; y < dim.y / 2; y++) {
//
// //// double z = 150;
// //////for (int x = 0; x < dim.x; x++) {
// ////// for (int y = 0; y < dim.y; y++) {
// //// double height = 0;
//
// //// z += -x*2 * std::sin(std::sqrt(abs(x*2 - y*2 - 47))) -
// //// (y*2 + 47) * std::sin(std::sqrt(std::abs(y*2 + 47 + x*2 / 2)));
// ////
//
// //// //z += x * std::sin(std::sqrt(std::abs(y - x + 1))) *
// //// // std::cos(std::sqrt(std::abs(y + x + 1))) +
// //// // (y + 1) *
// //// // std::cos(std::sqrt(std::abs(y - x + 1))) *
// //// // std::sin(std::sqrt(std::abs(y + x + 1)));
// ////
// //// // Pathological
// //// //z += 0.5 +
// //// // (std::pow(std::sin(std::sqrt(100 * std::pow(x/20, 2) + std::pow(y/20, 2))), 2) - 0.5) /
// //// // (1 + 0.001 * std::pow(std::pow(x/20, 2) - 2 * x/20 * y/20 + std::pow(y/20, 2), 2));
//
// //// // Ackleys
// //// //z += 20 + M_E -
// //// // (20 / (std::pow(M_E, 0.2) * std::sqrt((std::pow(x / 16.0, 2) + std::pow(y / 16.0, 2) + 1) / 2))) -
// //// // std::pow(M_E, 0.5 * std::cos(2 * M_PI * x / 16.0) + cos(2 * M_PI * y / 16.0));
//
// //// //
// //// //z += -20 * std::pow(M_E, -0.2 * sqrt(0.5 * std::pow(x/64.0, 2) + std::pow(y/64.0, 2))) - std::pow(M_E, 0.5 * (cos(2 * M_PI * x/64.0) + (cos(2 * M_PI * y/64.0)))) + 20 + M_E;
// ////
// //// //list[x + dim.x * (y + dim.z * (int)height)] = 5;
//
// //// double m = 0.2;
// //// while ((z*m) > 0){
// //// list[xx + dim.x * (yy + dim.z * (int)(z*m))] = 5;
// //// z -= 1/m;
// //// }
// //// yy++;
//
// //// }
// //// yy = 0;
// //// xx++;
// ////}
// ////
//
// ////return;
//
//
//
// ////int featuresize = 2;
//
// ////for (int y = 0; y < dim.y; y += featuresize)
// //// for (int x = 0; x < dim.x; x += featuresize) {
// //// double t = dis(gen);
// //// setSample(x, y, t); //IMPORTANT: frand() is a random function that returns a value between -1 and 1.
// //// }
//
// ////int samplesize = featuresize;
//
// ////double scale = 10.0;
//
// ////while (samplesize > 1) {
//
// //// DiamondSquare(samplesize, scale);
//
// //// samplesize /= 2;
// //// scale /= 2.0;
// ////}
//
//
//
//
// ////size of grid to generate, note this must be a
// ////value 2^n+1
// //int DATA_SIZE = dim.x + 1;
// ////an initial seed value for the corners of the data
// //double SEED = rand() % 25 + 25;
//
// ////seed the data
// //setSample(0, 0, SEED);
// //setSample(0, dim.y, SEED);
// //setSample(dim.x, 0, SEED);
// //setSample(dim.x, dim.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
// // setSample(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
// // setSample(x, y, avg);
//
// // //wrap values on the edges, remove
// // //this and adjust loop condition above
// // //for non-wrapping values.
// // if (x == 0) setSample(DATA_SIZE - 1, y, avg);
// // if (y == 0) setSample(x, DATA_SIZE - 1, avg);
// // }
// // }
// //}
//
//
// //for (int x = 0; x < dim.x; x++) {
// // for (int y = 0; y < dim.y; y++) {
//
// // if (height_map[x + y * dim.x] > 0) {
// // int z = height_map[x + y * dim.x];
// // while (z > 0) {
// // list[x + dim.x * (y + dim.z * z)] = 5;
// // z--;
// // }
// // }
//
// // }
// //}
//
//
// //for (int x = 0; x < dim.x / 10; x++) {
// // for (int y = 0; y < dim.y / 10; y++) {
// // for (int z = 0; z < dim.z; z++) {
// // if (rand() % 1000 < 1)
// // list[x + dim.x * (y + dim.z * z)] = rand() % 6;
// // }
// // }
// //}
//
//}
//
void Map::load_unload(sf::Vector3i world_position) {
sf::Vector3i chunk_pos(world_to_chunk(world_position));
//Don't forget the middle chunk
if (chunk_map.find(chunk_pos) == chunk_map.end()) {
chunk_map[chunk_pos] = Chunk(5);
}
for (int x = chunk_pos.x - chunk_radius / 2; x < chunk_pos.x + chunk_radius / 2; x++) {
for (int y = chunk_pos.y - chunk_radius / 2; y < chunk_pos.y + chunk_radius / 2; y++) {
for (int z = chunk_pos.z - chunk_radius / 2; z < chunk_pos.z + chunk_radius / 2; z++) {
if (chunk_map.find(sf::Vector3i(x, y, z)) == chunk_map.end()) {
chunk_map.emplace(sf::Vector3i(x, y, z), Chunk(rand() % 6));
//chunk_map[sf::Vector3i(x, y, z)] = Chunk(rand() % 6);
}
}
}
}
}
void Map::load_single(sf::Vector3i world_position) {
sf::Vector3i chunk_pos(world_to_chunk(world_position));
//Don't forget the middle chunk
if (chunk_map.find(chunk_pos) == chunk_map.end()) {
chunk_map[chunk_pos] = Chunk(0);
}
}
sf::Vector3i Map::getDimensions() {
return sf::Vector3i(0, 0, 0);
}
void Map::setVoxel(sf::Vector3i world_position, int val) {
load_single(world_position);
sf::Vector3i chunk_pos(world_to_chunk(world_position));
sf::Vector3i in_chunk_pos(
world_position.x % CHUNK_DIM,
world_position.y % CHUNK_DIM,
world_position.z % CHUNK_DIM
);
chunk_map.at(chunk_pos).voxel_data[in_chunk_pos.x + CHUNK_DIM * (in_chunk_pos.y + CHUNK_DIM * in_chunk_pos.z)]
= val;
}
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 Chunk::set(int type) {
for (int i = 0; i < CHUNK_DIM * CHUNK_DIM * CHUNK_DIM; i++) {
voxel_data[i] = 0;
}
for (int x = 0; x < CHUNK_DIM; x+=2) {
for (int y = 0; y < CHUNK_DIM; y+=2) {
//list[x + dim.x * (y + dim.z * z)]
voxel_data[x + CHUNK_DIM * (y + CHUNK_DIM * 1)] = type;
}
}
}

@ -34,8 +34,8 @@
#include "Vector4.hpp" #include "Vector4.hpp"
#include <Camera.h> #include <Camera.h>
const int WINDOW_X = 1000; const int WINDOW_X = 1920;
const int WINDOW_Y = 1000; const int WINDOW_Y = 1080;
const int WORK_SIZE = WINDOW_X * WINDOW_Y; const int WORK_SIZE = WINDOW_X * WINDOW_Y;
const int MAP_X = 512; const int MAP_X = 512;
@ -65,297 +65,306 @@ sf::Texture window_texture;
int main() { int main() {
//Map m(sf::Vector3i (50, 50, 50));
//return 1;
sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML");
// Setup CL, instantiate and pass in values to the kernel Map m(sf::Vector3i (50, 50, 50));
CL_Wrapper c; m.generate_octree();
query_platform_devices(); return 1;
c.acquire_platform_and_device();
c.create_shared_context(); //sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML");
c.create_command_queue();
//// Setup CL, instantiate and pass in values to the kernel
if (c.compile_kernel("../kernels/ray_caster_kernel.cl", true, "min_kern") < 0) { //CL_Wrapper c;
std::cin.get(); //query_platform_devices();
return -1; //c.acquire_platform_and_device();
} //c.create_shared_context();
//c.create_command_queue();
std::cout << "map...";
sf::Vector3i map_dim(MAP_X, MAP_Y, MAP_Z); //if (c.compile_kernel("../kernels/ray_caster_kernel.cl", true, "min_kern") < 0) {
Map* map = new Map(map_dim); // std::cin.get();
// return -1;
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); //
//std::cout << "map...";
sf::Vector2i view_res(WINDOW_X, WINDOW_Y); // sf::Vector3i map_dim(MAP_X, MAP_Y, MAP_Z);
c.create_buffer("res_buffer", sizeof(int) * 2, &view_res); // Map* map = new Map(map_dim);
//
//c.create_buffer("map_buffer", sizeof(char) * map_dim.x * map_dim.y * map_dim.z, map->list);
double y_increment_radians = DegreesToRadians(50.0 / view_res.y); //c.create_buffer("dim_buffer", sizeof(int) * 3, &map_dim);
double x_increment_radians = DegreesToRadians(80.0 / view_res.x);
//sf::Vector2i view_res(WINDOW_X, WINDOW_Y);
std::cout << "view matrix..."; //c.create_buffer("res_buffer", sizeof(int) * 2, &view_res);
//
sf::Vector4f* view_matrix = new sf::Vector4f[WINDOW_X * WINDOW_Y * 4];
// double y_increment_radians = DegreesToRadians(50.0 / view_res.y);
for (int y = -view_res.y / 2; y < view_res.y / 2; y++) { // double x_increment_radians = DegreesToRadians(80.0 / view_res.x);
for (int x = -view_res.x / 2; x < view_res.x / 2; x++) {
//std::cout << "view matrix...";
// The base ray direction to slew from //
sf::Vector3f ray(1, 0, 0); //sf::Vector4f* view_matrix = new sf::Vector4f[WINDOW_X * WINDOW_Y * 4];
// Y axis, pitch // for (int y = -view_res.y / 2; y < view_res.y / 2; y++) {
ray = sf::Vector3f( // for (int x = -view_res.x / 2; x < view_res.x / 2; x++) {
ray.z * sin(y_increment_radians * y) + ray.x * cos(y_increment_radians * y),
ray.y, // // The base ray direction to slew from
ray.z * cos(y_increment_radians * y) - ray.x * sin(y_increment_radians * y) // sf::Vector3f ray(1, 0, 0);
);
// // Y axis, pitch
// Z axis, yaw // ray = sf::Vector3f(
ray = sf::Vector3f( // ray.z * sin(y_increment_radians * y) + ray.x * cos(y_increment_radians * y),
ray.x * cos(x_increment_radians * x) - ray.y * sin(x_increment_radians * x), // ray.y,
ray.x * sin(x_increment_radians * x) + ray.y * cos(x_increment_radians * x), // ray.z * cos(y_increment_radians * y) - ray.x * sin(y_increment_radians * y)
ray.z // );
);
int index = (x + view_res.x / 2) + view_res.x * (y + view_res.y / 2); // // Z axis, yaw
ray = Normalize(ray); // ray = sf::Vector3f(
// ray.x * cos(x_increment_radians * x) - ray.y * sin(x_increment_radians * x),
view_matrix[index] = sf::Vector4f( // ray.x * sin(x_increment_radians * x) + ray.y * cos(x_increment_radians * x),
ray.x, // ray.z
ray.y, // );
ray.z, //
0 // 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,
c.create_buffer("view_matrix_buffer", sizeof(float) * 4 * view_res.x * view_res.y, view_matrix); // ray.y,
// ray.z,
Camera camera( // 0
sf::Vector3f(256, 256, 256), // );
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("view_matrix_buffer", sizeof(float) * 4 * view_res.x * view_res.y, view_matrix);
c.create_buffer("cam_pos_buffer", sizeof(float) * 4, (void*)camera.get_position_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
//Camera camera(
int light_count = 2; // sf::Vector3f(70, 60, 50),
c.create_buffer("light_count_buffer", sizeof(int), &light_count); // sf::Vector2f(0.0f, 1.00f)
//);
// {r, g, b, i, x, y, z, x', y', z'} //
sf::Vector3f v = Normalize(sf::Vector3f(1.0, 1.0, 0.0)); //c.create_buffer("cam_dir_buffer", sizeof(float) * 4, (void*)camera.get_direction_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
sf::Vector3f v2 = Normalize(sf::Vector3f(1.1, 0.4, 0.7)); //c.create_buffer("cam_pos_buffer", sizeof(float) * 4, (void*)camera.get_position_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
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}; //int light_count = 2;
c.create_buffer("light_buffer", sizeof(float) * 10 * light_count, light, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR); //c.create_buffer("light_count_buffer", sizeof(int), &light_count);
// The drawing canvas //// {r, g, b, i, x, y, z, x', y', z'}
unsigned char* pixel_array = new sf::Uint8[WINDOW_X * WINDOW_Y * 4]; //sf::Vector3f v = Normalize(sf::Vector3f(1.0, 0.0, 0.0));
//sf::Vector3f v2 = Normalize(sf::Vector3f(1.1, 0.4, 0.7));
for (int i = 0; i < WINDOW_X * WINDOW_Y * 4; i += 4) { //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};
pixel_array[i] = 255; // R? //c.create_buffer("light_buffer", sizeof(float) * 10 * light_count, light, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
pixel_array[i + 1] = 255; // G?
pixel_array[i + 2] = 255; // B? //// The drawing canvas
pixel_array[i + 3] = 100; // A? // unsigned char* pixel_array = new sf::Uint8[WINDOW_X * WINDOW_Y * 4];
}
// for (int i = 0; i < WINDOW_X * WINDOW_Y * 4; i += 4) {
sf::Texture t;
t.create(WINDOW_X, WINDOW_Y); // pixel_array[i] = 255; // R?
t.update(pixel_array); // pixel_array[i + 1] = 255; // G?
// pixel_array[i + 2] = 255; // B?
int error; // pixel_array[i + 3] = 100; // A?
cl_mem image_buff = clCreateFromGLTexture( // }
c.getContext(), CL_MEM_WRITE_ONLY, GL_TEXTURE_2D,
0, t.getNativeHandle(), &error); //sf::Texture t;
// t.create(WINDOW_X, WINDOW_Y);
if (c.assert(error, "clCreateFromGLTexture")) // t.update(pixel_array);
return -1;
// int error;
c.store_buffer(image_buff, "image_buffer"); // cl_mem image_buff = clCreateFromGLTexture(
// c.getContext(), CL_MEM_WRITE_ONLY, GL_TEXTURE_2D,
c.set_kernel_arg("min_kern", 0, "map_buffer"); // 0, t.getNativeHandle(), &error);
c.set_kernel_arg("min_kern", 1, "dim_buffer");
c.set_kernel_arg("min_kern", 2, "res_buffer"); // if (c.assert(error, "clCreateFromGLTexture"))
c.set_kernel_arg("min_kern", 3, "view_matrix_buffer"); // return -1;
c.set_kernel_arg("min_kern", 4, "cam_dir_buffer");
c.set_kernel_arg("min_kern", 5, "cam_pos_buffer"); // c.store_buffer(image_buff, "image_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", 0, "map_buffer");
c.set_kernel_arg("min_kern", 8, "image_buffer"); // c.set_kernel_arg("min_kern", 1, "dim_buffer");
// c.set_kernel_arg("min_kern", 2, "res_buffer");
sf::Sprite s; // c.set_kernel_arg("min_kern", 3, "view_matrix_buffer");
s.setTexture(t); // c.set_kernel_arg("min_kern", 4, "cam_dir_buffer");
s.setPosition(0, 0); // c.set_kernel_arg("min_kern", 5, "cam_pos_buffer");
//c.set_kernel_arg("min_kern", 6, "light_buffer");
// The step size in milliseconds between calls to Update() //c.set_kernel_arg("min_kern", 7, "light_count_buffer");
// Lets set it to 16.6 milliseonds (60FPS) //c.set_kernel_arg("min_kern", 8, "image_buffer");
float step_size = 0.0166f;
//sf::Sprite s;
// Timekeeping values for the loop //s.setTexture(t);
double frame_time = 0.0, //s.setPosition(0, 0);
elapsed_time = 0.0,
delta_time = 0.0, // // The step size in milliseconds between calls to Update()
accumulator_time = 0.0, // // Lets set it to 16.6 milliseonds (60FPS)
current_time = 0.0; // float step_size = 0.0166f;
fps_counter fps; // // Timekeeping values for the loop
// double frame_time = 0.0,
// ============================= RAYCASTER SETUP ================================== // elapsed_time = 0.0,
// delta_time = 0.0,
// Setup the sprite and texture // accumulator_time = 0.0,
window_texture.create(WINDOW_X, WINDOW_Y); // current_time = 0.0;
window_sprite.setPosition(0, 0);
// fps_counter fps;
// State values
//// ============================= RAYCASTER SETUP ==================================
sf::Vector3f cam_vec(0, 0, 0);
//// Setup the sprite and texture
RayCaster ray_caster(map, map_dim, view_res); //window_texture.create(WINDOW_X, WINDOW_Y);
//window_sprite.setPosition(0, 0);
sf::Vector2f *dp = camera.get_direction_pointer();
debug_text cam_text_x(1, 30, &dp->x, "X: "); //// State values
debug_text cam_text_y(2, 30, &dp->y, "Y: ");
//sf::Vector3f cam_vec(0, 0, 0);
sf::Vector3f *mp = camera.get_movement_pointer();
debug_text cam_text_mov_x(4, 30, &mp->x, "X: "); //RayCaster ray_caster(map, map_dim, view_res);
debug_text cam_text_mov_y(5, 30, &mp->y, "Y: ");
debug_text cam_text_mov_z(6, 30, &mp->y, "Z: "); //sf::Vector2f *dp = camera.get_direction_pointer();
//debug_text cam_text_z(3, 30, &p->z); //debug_text cam_text_x(1, 30, &dp->x, "X: ");
//debug_text cam_text_y(2, 30, &dp->y, "Y: ");
debug_text light_x (7, 30, &light[7], "X: ");
debug_text light_y(8, 30, &light[8], "Y: "); //sf::Vector3f *mp = camera.get_movement_pointer();
debug_text light_z(9, 30, &light[9], "Z: "); //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: ");
// Mouse capture ////debug_text cam_text_z(3, 30, &p->z);
sf::Vector2i deltas;
sf::Vector2i fixed(window.getSize()); //debug_text light_x(7, 30, &light[7], "X: ");
bool mouse_enabled = true; //debug_text light_y(8, 30, &light[8], "Y: ");
//debug_text light_z(9, 30, &light[9], "Z: ");
sf::Vector3f cam_mov_vec; //// ===============================================================================
while (window.isOpen()) { //// Mouse capture
//sf::Vector2i deltas;
// Poll for events from the user //sf::Vector2i fixed(window.getSize());
sf::Event event; //bool mouse_enabled = true;
while (window.pollEvent(event)) {
//sf::Vector3f cam_mov_vec;
// If the user tries to exit the application via the GUI
if (event.type == sf::Event::Closed) //while (window.isOpen()) {
window.close();
if (event.type == sf::Event::KeyPressed) { // // Poll for events from the user
if (event.key.code == sf::Keyboard::Space) { // sf::Event event;
if (mouse_enabled) // while (window.pollEvent(event)) {
mouse_enabled = false;
else // // If the user tries to exit the application via the GUI
mouse_enabled = true; // if (event.type == sf::Event::Closed)
} // window.close();
} // if (event.type == sf::Event::KeyPressed) {
} // if (event.key.code == sf::Keyboard::Space) {
// if (mouse_enabled)
cam_vec.x = 0; // mouse_enabled = false;
cam_vec.y = 0; // else
cam_vec.z = 0; // mouse_enabled = true;
// }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) { // }
camera.add_relative_impulse(Camera::DIRECTION::DOWN); // }
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::E)) { // cam_vec.x = 0;
camera.add_relative_impulse(Camera::DIRECTION::UP); // cam_vec.y = 0;
} // cam_vec.z = 0;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
camera.add_relative_impulse(Camera::DIRECTION::FORWARD); // float speed = 1.0f;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { // if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift)) {
camera.add_relative_impulse(Camera::DIRECTION::REARWARD); // speed = 0.2f;
} // }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { // if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) {
camera.add_relative_impulse(Camera::DIRECTION::LEFT); // camera.add_relative_impulse(Camera::DIRECTION::DOWN, speed);
} // }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { // if (sf::Keyboard::isKeyPressed(sf::Keyboard::E)) {
camera.add_relative_impulse(Camera::DIRECTION::RIGHT); // camera.add_relative_impulse(Camera::DIRECTION::UP, speed);
} // }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::T)) { // if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
camera.set_position(sf::Vector3f(50, 50, 50)); // camera.add_relative_impulse(Camera::DIRECTION::FORWARD, speed);
} // }
// if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
camera.add_static_impulse(cam_vec); // camera.add_relative_impulse(Camera::DIRECTION::REARWARD, speed);
// }
if (mouse_enabled) { // if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
deltas = fixed - sf::Mouse::getPosition(); // camera.add_relative_impulse(Camera::DIRECTION::LEFT, speed);
if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) { // }
// if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
// Mouse movement // camera.add_relative_impulse(Camera::DIRECTION::RIGHT, speed);
sf::Mouse::setPosition(fixed); // }
camera.slew_camera(sf::Vector2f( // if (sf::Keyboard::isKeyPressed(sf::Keyboard::T)) {
deltas.y / 300.0f, // camera.set_position(sf::Vector3f(50, 50, 50));
deltas.x / 300.0f // }
));
} // camera.add_static_impulse(cam_vec);
}
// if (mouse_enabled) {
// Time keeping // deltas = fixed - sf::Mouse::getPosition();
elapsed_time = elap_time(); // if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) {
delta_time = elapsed_time - current_time;
current_time = elapsed_time; // // Mouse movement
if (delta_time > 0.2f) // sf::Mouse::setPosition(fixed);
delta_time = 0.2f; // camera.slew_camera(sf::Vector2f(
accumulator_time += delta_time; // deltas.y / 300.0f,
while ((accumulator_time - step_size) >= step_size) { // deltas.x / 300.0f
accumulator_time -= step_size; // ));
// }
// ==== DELTA TIME LOCKED ==== // }
}
// // Time keeping
float l[] = { // elapsed_time = elap_time();
light[9] * sin(delta_time) + light[7] * cos(delta_time), // delta_time = elapsed_time - current_time;
light[8], // current_time = elapsed_time;
light[9] * cos(delta_time) - light[7] * sin(delta_time) // if (delta_time > 0.2f)
}; // delta_time = 0.2f;
// accumulator_time += delta_time;
float l2[] = { // while ((accumulator_time - step_size) >= step_size) {
l[0] * cos(delta_time) - l[2] * sin(delta_time), // accumulator_time -= step_size;
l[0] * sin(delta_time) + l[2] * cos(delta_time),
l[2] // // ==== DELTA TIME LOCKED ====
}; // }
light[7] = l[0]; // float l[] = {
light[8] = l[1]; // light[9] * sin(delta_time / 1) + light[7] * cos(delta_time / 1),
light[9] = l[2]; // light[8],
// light[9] * cos(delta_time / 1) - light[7] * sin(delta_time / 1)
// ==== FPS LOCKED ==== // };
camera.update(delta_time);
// float l2[] = {
// Run the raycast // l[0] * cos(delta_time) - l[2] * sin(delta_time),
c.run_kernel("min_kern", WORK_SIZE); // l[0] * sin(delta_time) + l[2] * cos(delta_time),
// l[2]
// ==== RENDER ==== // };
window.clear(sf::Color::Black); // light[7] = l[0];
// light[8] = l[1];
window.draw(s); // light[9] = l[2];
// Give the frame counter the frame time and draw the average frame time // // ==== FPS LOCKED ====
fps.frame(delta_time); // camera.update(delta_time);
fps.draw(&window);
// // Run the raycast
cam_text_x.draw(&window); // c.run_kernel("min_kern", WORK_SIZE);
cam_text_y.draw(&window); //
// // ==== RENDER ====
cam_text_mov_x.draw(&window);
cam_text_mov_y.draw(&window); // window.clear(sf::Color::Black);
cam_text_mov_z.draw(&window);
// window.draw(s);
light_x.draw(&window);
light_y.draw(&window); // // Give the frame counter the frame time and draw the average frame time
light_z.draw(&window); // fps.frame(delta_time);
// fps.draw(&window);
window.display();
// 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; return 0;
} }

Loading…
Cancel
Save