Software raycasting now works, but has some major problems / is extremely
slow. Perhaps it will only be useful in debugging the kernel via emulation
This commit is contained in:
@@ -40,6 +40,7 @@ protected:
|
|||||||
Old_Map * map = nullptr;
|
Old_Map * map = nullptr;
|
||||||
Camera *camera = nullptr;
|
Camera *camera = nullptr;
|
||||||
std::vector<Light> lights;
|
std::vector<Light> lights;
|
||||||
|
int light_count = 0;
|
||||||
sf::Uint8 *viewport_image = nullptr;
|
sf::Uint8 *viewport_image = nullptr;
|
||||||
sf::Vector4f *viewport_matrix = nullptr;
|
sf::Vector4f *viewport_matrix = nullptr;
|
||||||
sf::Vector2i viewport_resolution;
|
sf::Vector2i viewport_resolution;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "RayCaster.h"
|
#include "RayCaster.h"
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
class Software_Caster : public RayCaster
|
class Software_Caster : public RayCaster
|
||||||
{
|
{
|
||||||
@@ -26,6 +27,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void cast_rays();
|
void cast_viewport();
|
||||||
|
void cast_thread(int start_id, int end_id);
|
||||||
|
void cast_ray(int id);
|
||||||
|
void blit_pixel(sf::Color color, sf::Vector2i position, sf::Vector3i mask);
|
||||||
|
sf::Color global_light(sf::Color in, sf::Vector3i mask);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,14 +10,13 @@ const double PI = 3.141592653589793238463;
|
|||||||
const float PI_F = 3.14159265358979f;
|
const float PI_F = 3.14159265358979f;
|
||||||
|
|
||||||
struct Light {
|
struct Light {
|
||||||
|
#pragma pack(1)
|
||||||
sf::Vector4f rgbi;
|
sf::Vector4f rgbi;
|
||||||
|
|
||||||
// I believe that Vector3's get padded to Vector4's. Give them a non-garbage value
|
// I believe that Vector3's get padded to Vector4's. Give them a non-garbage value
|
||||||
sf::Vector3f position;
|
sf::Vector3f position;
|
||||||
const float padding_1 = -1;
|
|
||||||
|
|
||||||
sf::Vector3f direction_cartesian;
|
sf::Vector3f direction_cartesian;
|
||||||
const float padding_2 = -2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fps_counter {
|
struct fps_counter {
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ __kernel void raycaster(
|
|||||||
case 5:
|
case 5:
|
||||||
|
|
||||||
//write_imagef(image, pixel, (float4)(.00, .00, + 0.5, 1.00));
|
//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)(.40, .00, ((1.0 - 0) / (128 - 0) * (voxel.z - 128)) + 1, 0.2), (float3)(lights[7], lights[8], lights[9]), mask));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float3 vox = convert_float3(voxel);
|
float3 vox = convert_float3(voxel);
|
||||||
|
|||||||
@@ -170,11 +170,13 @@ void Hardware_Caster::create_viewport(int width, int height, float v_fov, float
|
|||||||
|
|
||||||
void Hardware_Caster::assign_lights(std::vector<Light> lights) {
|
void Hardware_Caster::assign_lights(std::vector<Light> lights) {
|
||||||
|
|
||||||
|
std::cout << sizeof(Light);
|
||||||
|
|
||||||
this->lights = std::vector<Light>(lights);
|
this->lights = std::vector<Light>(lights);
|
||||||
|
|
||||||
int light_count = lights.size();
|
light_count = lights.size();
|
||||||
|
|
||||||
create_buffer("lights", sizeof(float) * 12 * light_count, lights.data(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
|
create_buffer("lights", sizeof(float) * 10 * light_count, this->lights.data(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
|
||||||
|
|
||||||
create_buffer("light_count", sizeof(int), &light_count);
|
create_buffer("light_count", sizeof(int), &light_count);
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ Old_Map::~Old_Map() {
|
|||||||
void Old_Map::generate_terrain() {
|
void Old_Map::generate_terrain() {
|
||||||
std::mt19937 gen;
|
std::mt19937 gen;
|
||||||
std::uniform_real_distribution<double> dis(-1.0, 1.0);
|
std::uniform_real_distribution<double> dis(-1.0, 1.0);
|
||||||
auto f_rand = std::bind(dis, gen);
|
auto f_rand = std::bind(dis, std::ref(gen));
|
||||||
|
|
||||||
voxel_data = new char[dimensions.x * dimensions.y * dimensions.z];
|
voxel_data = new char[dimensions.x * dimensions.y * dimensions.z];
|
||||||
height_map = new double[dimensions.x * dimensions.y];
|
height_map = new double[dimensions.x * dimensions.y];
|
||||||
@@ -34,7 +34,8 @@ void Old_Map::generate_terrain() {
|
|||||||
//value 2^n+1
|
//value 2^n+1
|
||||||
int DATA_SIZE = dimensions.x + 1;
|
int DATA_SIZE = dimensions.x + 1;
|
||||||
//an initial seed value for the corners of the data
|
//an initial seed value for the corners of the data
|
||||||
double SEED = rand() % 25 + 25;
|
//srand(f_rand());
|
||||||
|
double SEED = rand() % 25 + 55;
|
||||||
|
|
||||||
//seed the data
|
//seed the data
|
||||||
set_sample(0, 0, SEED);
|
set_sample(0, 0, SEED);
|
||||||
|
|||||||
@@ -19,19 +19,19 @@ int Software_Caster::init()
|
|||||||
void Software_Caster::create_viewport(int width, int height, float v_fov, float h_fov)
|
void Software_Caster::create_viewport(int width, int height, float v_fov, float h_fov)
|
||||||
{
|
{
|
||||||
// CL needs the screen resolution
|
// CL needs the screen resolution
|
||||||
sf::Vector2i view_res(width, height);
|
viewport_resolution = sf::Vector2i(width, height);
|
||||||
|
|
||||||
// And an array of vectors describing the way the "lens" of our
|
// And an array of vectors describing the way the "lens" of our
|
||||||
// camera works
|
// camera works
|
||||||
// This could be modified to make some odd looking camera lenses
|
// This could be modified to make some odd looking camera lenses
|
||||||
|
|
||||||
double y_increment_radians = DegreesToRadians(v_fov / view_res.y);
|
double y_increment_radians = DegreesToRadians(v_fov / viewport_resolution.y);
|
||||||
double x_increment_radians = DegreesToRadians(h_fov / view_res.x);
|
double x_increment_radians = DegreesToRadians(h_fov / viewport_resolution.x);
|
||||||
|
|
||||||
viewport_matrix = new sf::Vector4f[width * height * 4];
|
viewport_matrix = new sf::Vector4f[width * height * 4];
|
||||||
|
|
||||||
for (int y = -view_res.y / 2; y < view_res.y / 2; y++) {
|
for (int y = -viewport_resolution.y / 2; y < viewport_resolution.y / 2; y++) {
|
||||||
for (int x = -view_res.x / 2; x < view_res.x / 2; x++) {
|
for (int x = -viewport_resolution.x / 2; x < viewport_resolution.x / 2; x++) {
|
||||||
|
|
||||||
// The base ray direction to slew from
|
// The base ray direction to slew from
|
||||||
sf::Vector3f ray(1, 0, 0);
|
sf::Vector3f ray(1, 0, 0);
|
||||||
@@ -51,7 +51,7 @@ void Software_Caster::create_viewport(int width, int height, float v_fov, float
|
|||||||
static_cast<float>(ray.z)
|
static_cast<float>(ray.z)
|
||||||
);
|
);
|
||||||
|
|
||||||
int index = (x + view_res.x / 2) + view_res.x * (y + view_res.y / 2);
|
int index = (x + viewport_resolution.x / 2) + viewport_resolution.x * (y + viewport_resolution.y / 2);
|
||||||
ray = Normalize(ray);
|
ray = Normalize(ray);
|
||||||
|
|
||||||
viewport_matrix[index] = sf::Vector4f(
|
viewport_matrix[index] = sf::Vector4f(
|
||||||
@@ -71,7 +71,7 @@ void Software_Caster::create_viewport(int width, int height, float v_fov, float
|
|||||||
viewport_image[i] = 255; // R
|
viewport_image[i] = 255; // R
|
||||||
viewport_image[i + 1] = 255; // G
|
viewport_image[i + 1] = 255; // G
|
||||||
viewport_image[i + 2] = 255; // B
|
viewport_image[i + 2] = 255; // B
|
||||||
viewport_image[i + 3] = 100; // A
|
viewport_image[i + 3] = 255; // A
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interop lets us keep a reference to it as a texture
|
// Interop lets us keep a reference to it as a texture
|
||||||
@@ -109,7 +109,7 @@ void Software_Caster::validate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Software_Caster::compute() {
|
void Software_Caster::compute() {
|
||||||
cast_rays();
|
cast_viewport();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Software_Caster::draw(sf::RenderWindow * window) {
|
void Software_Caster::draw(sf::RenderWindow * window) {
|
||||||
@@ -117,14 +117,31 @@ void Software_Caster::draw(sf::RenderWindow * window) {
|
|||||||
window->draw(viewport_sprite);
|
window->draw(viewport_sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Software_Caster::cast_rays()
|
void Software_Caster::cast_viewport() {
|
||||||
|
|
||||||
|
std::vector<std::thread*> threads;
|
||||||
|
for (int i = 0; i < 13; i++) {
|
||||||
|
int s = viewport_resolution.x * ((viewport_resolution.y / 13) * i);
|
||||||
|
int e = viewport_resolution.x * ((viewport_resolution.y / 13) * (i + 1));
|
||||||
|
threads.push_back(new std::thread(&Software_Caster::cast_thread, this, s, e));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i : threads) {
|
||||||
|
i->join();
|
||||||
|
delete i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Software_Caster::cast_thread(int start_id, int end_id) {
|
||||||
|
|
||||||
|
for (int i = start_id; i < end_id; i++) {
|
||||||
|
cast_ray(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Software_Caster::cast_ray(int id)
|
||||||
{
|
{
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (int y = 0; y < viewport_resolution.y; y++) {
|
|
||||||
for (int x = 0; x < viewport_resolution.x; x++) {
|
|
||||||
|
|
||||||
int id = i;
|
|
||||||
sf::Vector2i pixel = { id % viewport_resolution.x, id / viewport_resolution.x };
|
sf::Vector2i pixel = { id % viewport_resolution.x, id / viewport_resolution.x };
|
||||||
|
|
||||||
// 4f 3f ??
|
// 4f 3f ??
|
||||||
@@ -251,11 +268,11 @@ void Software_Caster::cast_rays()
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (overshoot.x == 0 || overshoot.y == 0 || overshoot.z == 0 || undershoot.x == 0 || undershoot.y == 0) {
|
if (overshoot.x == 0 || overshoot.y == 0 || overshoot.z == 0 || undershoot.x == 0 || undershoot.y == 0) {
|
||||||
viewport_image[x + viewport_resolution.x * y] = (255, 0, 255, 255);
|
blit_pixel(sf::Color::Yellow, sf::Vector2i{ pixel.x,pixel.y }, mask);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (undershoot.z == 0) {
|
if (undershoot.z == 0) {
|
||||||
viewport_image[x + viewport_resolution.x * y] = (255, 0, 255, 255);
|
blit_pixel(sf::Color::Yellow, sf::Vector2i{ pixel.x,pixel.y }, mask);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,34 +284,57 @@ void Software_Caster::cast_rays()
|
|||||||
|
|
||||||
if (voxel_data != 0) {
|
if (voxel_data != 0) {
|
||||||
switch (voxel_data) {
|
switch (voxel_data) {
|
||||||
case 255:
|
case 1:
|
||||||
viewport_image[x + viewport_resolution.x * y] = (255, 0, 255, 255);
|
blit_pixel(sf::Color::Green, sf::Vector2i{ pixel.x,pixel.y }, mask);
|
||||||
return;
|
return;
|
||||||
case 2:
|
case 2:
|
||||||
viewport_image[x + viewport_resolution.x * y] = (255, 0, 255, 255);
|
blit_pixel(sf::Color::Green, sf::Vector2i{ pixel.x,pixel.y }, mask);
|
||||||
return;
|
return;
|
||||||
case 3:
|
case 3:
|
||||||
viewport_image[x + viewport_resolution.x * y] = (255, 0, 255, 255);
|
blit_pixel(sf::Color::Green, sf::Vector2i{ pixel.x,pixel.y }, mask);
|
||||||
return;
|
return;
|
||||||
case 4:
|
case 4:
|
||||||
viewport_image[x + viewport_resolution.x * y] = (255, 0, 255, 255);
|
blit_pixel(sf::Color::Green, sf::Vector2i{ pixel.x,pixel.y }, mask);
|
||||||
return;
|
return;
|
||||||
case 5:
|
case 5:
|
||||||
viewport_image[x + viewport_resolution.x * y] = (0, 255, 255, 255);
|
blit_pixel(sf::Color(30, 10, 200, 100), sf::Vector2i{ pixel.x,pixel.y }, mask);
|
||||||
|
return;
|
||||||
case 6:
|
case 6:
|
||||||
viewport_image[x + viewport_resolution.x * y] = (255, 0, 255, 255);
|
blit_pixel(sf::Color::Green, sf::Vector2i{ pixel.x,pixel.y }, mask);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
//write_imagef(image, pixel, (float4)(.30, .2550, .2550, 255.00));
|
//write_imagef(image, pixel, (float4)(.30, .2550, .2550, 255.00));
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dist++;
|
dist++;
|
||||||
} while (dist < max_dist);
|
} while (dist < max_dist);
|
||||||
|
|
||||||
viewport_image[x + viewport_resolution.x * y] = (255, 0, 0, 255);
|
blit_pixel(sf::Color::Red, sf::Vector2i{ pixel.x,pixel.y }, mask);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Software_Caster::blit_pixel(sf::Color color, sf::Vector2i position, sf::Vector3i mask) {
|
||||||
|
|
||||||
|
sf::Color t = global_light(color, mask);
|
||||||
|
viewport_image[(position.x + viewport_resolution.x * position.y) * 4 + 0] = t.r;
|
||||||
|
viewport_image[(position.x + viewport_resolution.x * position.y) * 4 + 1] = t.g;
|
||||||
|
viewport_image[(position.x + viewport_resolution.x * position.y) * 4 + 2] = t.b;
|
||||||
|
viewport_image[(position.x + viewport_resolution.x * position.y) * 4 + 3] = t.a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::Color Software_Caster::global_light(sf::Color in, sf::Vector3i mask) {
|
||||||
|
|
||||||
|
sf::Vector3f mask_f(mask);
|
||||||
|
|
||||||
|
in.a = in.a + acos(
|
||||||
|
DotProduct(
|
||||||
|
Normalize(lights.at(0).direction_cartesian),
|
||||||
|
Normalize(mask_f)
|
||||||
|
)
|
||||||
|
)/ 2;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
|
||||||
}
|
}
|
||||||
21
src/main.cpp
21
src/main.cpp
@@ -31,6 +31,7 @@
|
|||||||
#include "Hardware_Caster.h"
|
#include "Hardware_Caster.h"
|
||||||
#include "Vector4.hpp"
|
#include "Vector4.hpp"
|
||||||
#include <Camera.h>
|
#include <Camera.h>
|
||||||
|
#include "Software_Caster.h"
|
||||||
|
|
||||||
const int WINDOW_X = 1920;
|
const int WINDOW_X = 1920;
|
||||||
const int WINDOW_Y = 1080;
|
const int WINDOW_Y = 1080;
|
||||||
@@ -67,6 +68,7 @@ int main() {
|
|||||||
|
|
||||||
// Initialize the raycaster hardware, compat, or software
|
// Initialize the raycaster hardware, compat, or software
|
||||||
RayCaster *rc = new Hardware_Caster();
|
RayCaster *rc = new Hardware_Caster();
|
||||||
|
//RayCaster *rc = new Software_Caster();
|
||||||
if (rc->init() != 1) {
|
if (rc->init() != 1) {
|
||||||
delete rc;
|
delete rc;
|
||||||
// rc = new Hardware_Caster_Compat();
|
// rc = new Hardware_Caster_Compat();
|
||||||
@@ -95,8 +97,8 @@ int main() {
|
|||||||
rc->create_viewport(WINDOW_X, WINDOW_Y, 50.0f, 80.0f);
|
rc->create_viewport(WINDOW_X, WINDOW_Y, 50.0f, 80.0f);
|
||||||
|
|
||||||
Light l;
|
Light l;
|
||||||
l.direction_cartesian = sf::Vector3f(1.0f, 1.0f, 0.0f);
|
l.direction_cartesian = sf::Vector3f(1.5f, 1.2f, 0.5f);
|
||||||
l.position = sf::Vector3f(10.0f, 10.0f, 10.0f);
|
l.position = sf::Vector3f(100.0f, 100.0f, 100.0f);
|
||||||
l.rgbi = sf::Vector4f(0.3f, 0.4f, 0.3f, 1.0f);
|
l.rgbi = sf::Vector4f(0.3f, 0.4f, 0.3f, 1.0f);
|
||||||
|
|
||||||
rc->assign_lights(std::vector<Light>{l});
|
rc->assign_lights(std::vector<Light>{l});
|
||||||
@@ -125,7 +127,9 @@ int main() {
|
|||||||
// Mouse capture
|
// Mouse capture
|
||||||
sf::Vector2i deltas;
|
sf::Vector2i deltas;
|
||||||
sf::Vector2i fixed(window.getSize());
|
sf::Vector2i fixed(window.getSize());
|
||||||
|
sf::Vector2i prev_pos;
|
||||||
bool mouse_enabled = true;
|
bool mouse_enabled = true;
|
||||||
|
bool reset = false;
|
||||||
|
|
||||||
while (window.isOpen()) {
|
while (window.isOpen()) {
|
||||||
|
|
||||||
@@ -142,6 +146,8 @@ int main() {
|
|||||||
mouse_enabled = false;
|
mouse_enabled = false;
|
||||||
else
|
else
|
||||||
mouse_enabled = true;
|
mouse_enabled = true;
|
||||||
|
} if (event.key.code == sf::Keyboard::R) {
|
||||||
|
reset = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,11 +180,18 @@ int main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mouse_enabled) {
|
if (mouse_enabled) {
|
||||||
deltas = fixed - sf::Mouse::getPosition();
|
if (reset) {
|
||||||
|
reset = false;
|
||||||
|
sf::Mouse::setPosition(sf::Vector2i(2560/2, 1080/2));
|
||||||
|
prev_pos = sf::Vector2i(2560 / 2, 1080 / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
deltas = prev_pos - sf::Mouse::getPosition();
|
||||||
if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) {
|
if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) {
|
||||||
|
|
||||||
// Mouse movement
|
// Mouse movement
|
||||||
sf::Mouse::setPosition(fixed);
|
//sf::Mouse::setPosition(fixed);
|
||||||
|
prev_pos = sf::Mouse::getPosition();
|
||||||
camera->slew_camera(sf::Vector2f(
|
camera->slew_camera(sf::Vector2f(
|
||||||
deltas.y / 300.0f,
|
deltas.y / 300.0f,
|
||||||
deltas.x / 300.0f
|
deltas.x / 300.0f
|
||||||
|
|||||||
Reference in New Issue
Block a user