#include #include #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)); }