Software raycasting now works, but has some major problems / is extremely

slow. Perhaps it will only be useful in debugging the kernel via emulation
master
MitchellHansen 8 years ago
parent b2988f0e13
commit 8c1f18ac70

@ -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) {
int i = 0; for (int i = start_id; i < end_id; i++) {
for (int y = 0; y < viewport_resolution.y; y++) { cast_ray(i);
for (int x = 0; x < viewport_resolution.x; x++) { }
}
int id = i; void Software_Caster::cast_ray(int id)
{
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;
} }

@ -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

Loading…
Cancel
Save