rendered paste body#include <iostream>
#include <math.h>
#include "tinyptc.h"
#define WIDTH 640
#define HEIGHT 480
#define SIZE WIDTH*HEIGHT
#define WORLDYMIN -1.0f
#define WORLDYMAX 1.0f
#define WORLDXMIN -1.333f
#define WORLDXMAX 1.333f
int pixel[SIZE];
typedef struct {
float x;
float y;
float z;
} float3;
typedef struct {
float3 coordinates;
float radius;
float3 color;
} sphere;
float screentoworld(int smin, int smax, int s, float wmin, float wmax);
float3 iraysphere(float3& s, float& r, float3& p0, float3& p1);
float discriminant(float3& f);
float irayspherelight(float3& s, float& r, float3& p0, float3& p1);
int main(int argc, char * argv[])
{
if (!ptc_open("test", WIDTH, HEIGHT)) {
return 1;
}
int x;
int y;
float3 camera;
camera.x = 0.0f;
camera.y = 0.0f;
camera.z = -10.0f;
sphere s1;
s1.coordinates.x = 0.0f;
s1.coordinates.y = 0.0f;
s1.coordinates.z = 0.0f;
s1.radius = 0.5f;
s1.color.x = 1.0f;
s1.color.y = 1.0f;
s1.color.z = 0.0f;
for (y = 0; y < HEIGHT; y++) {
for (x = 0; x < WIDTH; x++) {
float3 pix;
pix.x = screentoworld(0, WIDTH, x, WORLDXMIN, WORLDXMAX);
pix.y = screentoworld(0, HEIGHT, y, WORLDYMIN, WORLDYMAX);
pix.z = 0;
float hit = discriminant(iraysphere(s1.coordinates, s1.radius, camera, pix));
if(hit >= 0) {
float kd = 0.9f;
float ka = 0.1f;
float f = irayspherelight(s1.coordinates, s1.radius, camera, pix);
float r = (kd * f * s1.color.x) + (ka * s1.color.x);
float g = (kd * f * s1.color.y) + (ka * s1.color.y);
float b = (kd * f * s1.color.z) + (ka * s1.color.z);
pixel[y * WIDTH + x] = ((int)(r * 255.0f) << 16) | ((int)(g * 255.0f) << 8) | (int)(b * 255.0f);
} else {
pixel[y * WIDTH + x] = (0xCC << 16) | (0xCC << 8) | 0xCC;
}
//std::cout << "Hit = " << hit << "\n";
}
ptc_update(pixel);
}
while (true) {
ptc_update(pixel);
}
}
float screentoworld(int smin, int smax, int s, float wmin, float wmax) {
return (((wmax - wmin) * ((float)s / ((float)smax - (float)smin))) + wmin);
}
float3 iraysphere(float3& s, float& r, float3& p0, float3& p1) {
//std::cout << "p0.x = " << p0.x << " p0.y = " << p0.y << " p0.z = " << p0.z << "\n";
//std::cout << "p1.x = " << p1.x << " p1.y = " << p1.y << " p1.z = " << p1.z << "\n";
float dx = p1.x - p0.x;
float dy = p1.y - p0.y;
float dz = p1.z - p0.z;
float3 ret;
ret.x = (dx * dx) + (dy * dy) + (dz * dz);
ret.y = (2 * dx * (p0.x - s.x)) + (2 * dy * (p0.y - s.y)) + (2.0f * dz * (p0.z - s.z));
ret.z = (s.x * s.x) + (s.y * s.y) + (s.z * s.z) +
(p0.x * p0.x) + (p0.y * p0.y) + (p0.z * p0.z) -
(2.0f * ((s.x * p0.x) + (s.y * p0.y) + (s.y * p0.z))) -
(r * r);
return ret;
}
float irayspherelight(float3& s, float& r, float3& p0, float3& p1) {
//std::cout << "p0.x = " << p0.x << " p0.y = " << p0.y << " p0.z = " << p0.z << "\n";
//std::cout << "p1.x = " << p1.x << " p1.y = " << p1.y << " p1.z = " << p1.z << "\n";
float dx = p1.x - p0.x;
float dy = p1.y - p0.y;
float dz = p1.z - p0.z;
float a = (dx * dx) + (dy * dy) + (dz * dz);
float b = (2 * dx * (p0.x - s.x)) + (2 * dy * (p0.y - s.y)) + (2.0f * dz * (p0.z - s.z));
float c = (s.x * s.x) + (s.y * s.y) + (s.z * s.z) +
(p0.x * p0.x) + (p0.y * p0.y) + (p0.z * p0.z) -
(2.0f * ((s.x * p0.x) + (s.y * p0.y) + (s.y * p0.z))) -
(r * r);
float d = ((b * b) - (4.0f * a * c));
float t = ((-b - sqrt(d)) / (2.0f * a));
float x = p0.x + (t * dx);
float y = p0.y + (t * dy);
float z = p0.z + (t * dz);
float3 n;
n.x = ((x - s.x) / r);
n.y = ((y - s.y) / r);
n.z = ((z - s.z) / r);
float3 lprime;
lprime.x = (-1.0f - x);
lprime.y = (1.0f - y);
lprime.z = (0.0f - z);
float3 l;
l.x = (lprime.x / abs(lprime.x));
l.y = (lprime.y / abs(lprime.y));
l.z = (lprime.z / abs(lprime.z));
float factor = ((l.x * n.x) + (l.y * n.y) + (l.z * n.z));
return factor;
}
float discriminant(float3& f) {
return ((f.y * f.y) - (4.0f * f.x * f.z));
}