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