int loop_hook(t_env *e) { t_rgb c; int x; if (e->img.img != NULL) { mlx_destroy_image(e->mlx, e->img.img); e->img.img = NULL; } e->img.img = mlx_new_image(e->mlx, WIN_WIDTH, WIN_HEIGH); x = 0; while (x < WIN_WIDTH) { initray(e, x); raydir(e); dda(e); compute(e); colors(e, &c); drawline(x, e, &c); x++; } get_timeframe(e); move(e); mlx_put_image_to_window(e->mlx, e->win, e->img.img, 0, 0); return (0); }
Scalar RectilinearGrid::exitDistance(Index elem, const Vector &point, const Vector &dir) const { if (elem == InvalidIndex) return false; Vector raydir(dir.normalized()); std::array<Index,3> n = cellCoordinates(elem, m_numDivisions); assert(n[0] < m_numDivisions[0]); assert(n[1] < m_numDivisions[1]); assert(n[2] < m_numDivisions[2]); Scalar exitDist = -1; Scalar t0[3], t1[3]; for (int c=0; c<3; ++c) { Scalar x0 = m_coords[c][n[c]], x1 = m_coords[c][n[c]+1]; t0[c] = (x0-point[c])/raydir[c]; t1[c] = (x1-point[c])/raydir[c]; } for (int c=0; c<3; ++c) { if (t0[c] > 0) { if (exitDist<0 || exitDist>t0[c]) exitDist = t0[c]; } if (t1[c] > 0) { if (exitDist<0 || exitDist>t1[c]) exitDist = t1[c]; } } return exitDist; }
void render(const std::vector<Sphere<T> *> &spheres) { unsigned width = WIDTH, height = HEIGTH, area = WIDTH * HEIGTH; Vec3<T> *image = new Vec3<T>[area], *pixel = image; T invWidth = 1 / T(width), invHeight = 1 / T(height); T fov = 30, aspectratio = width / T(height); T angle = tan(M_PI * 0.5 * fov / T(180)); // Trace rays for (unsigned pix = 0; pix< area; pix++, pixel++){ unsigned x = pix % width, y = pix / width; T xx = (2 * ((x + 0.5) * invWidth) - 1) * angle * aspectratio; T yy = (1 - 2 * ((y + 0.5) * invHeight)) * angle; Vec3<T> raydir(xx, yy, -1); raydir.normalize(); *pixel = trace(Vec3<T>(0), raydir, spheres, 0); } // Save result to a PPM image std::ofstream ofs("./untitled.ppm"); ofs << "P6\n" << width << " " << height << "\n255\n"; for (unsigned i = 0; i < width * height; ++i) { ofs << (unsigned char)(std::min(T(1), image[i].x) * 255) << (unsigned char)(std::min(T(1), image[i].y) * 255) << (unsigned char)(std::min(T(1), image[i].z) * 255); } ofs.close(); delete [] image; }
void traceRays(void *computator, long long startIndex, long long endIndex, float **results) { RayTracerComputator *rt = (RayTracerComputator *)computator; const std::vector<Intersecter *> sceneObjects = rt->GetSceneObjects(); long long width = (long long)rt->GetWidth(); int indicesSize = (int)(endIndex - startIndex + 1); long long index = startIndex; for (int i = 0; index < endIndex; ++i, ++index) { long long x = index % width, y = index / width; FloatType xx = rt->GetRelativeX((int)x); FloatType yy = rt->GetRelativeY((int)y); Vector3 raydir(xx, yy, -1); raydir.normalize(); Vector3 v = trace(Vector3(0), raydir, sceneObjects, 0); FloatType *result = results[i]; result[0] = v.x; result[1] = v.y; result[2] = v.z; } }
void render(const std::vector<Intersecter *> &objects) { unsigned width = 640, height = 480; Vector3 *image = new Vector3[width * height], *pixel = image; FloatType invWidth = 1 / FloatType(width), invHeight = 1 / FloatType(height); FloatType fov = 30, aspectratio = width / FloatType(height); FloatType angle = tan(M_PI * 0.5 * fov / FloatType(180)); // Trace rays for (unsigned y = 0; y < height; ++y) { for (unsigned x = 0; x < width; ++x, ++pixel) { FloatType xx = (2 * ((x + 0.5) * invWidth) - 1) * angle * aspectratio; FloatType yy = (1 - 2 * ((y + 0.5) * invHeight)) * angle; Vector3 raydir(xx, yy, -1); raydir.normalize(); *pixel = trace(Vector3(0), raydir, objects, 0); } } // Save result to a PPM image (keep these flags if you compile under Windows) std::ofstream ofs("./untitled.ppm", std::ios::out | std::ios::binary); ofs << "P6\n" << width << " " << height << "\n255\n"; for (unsigned i = 0; i < width * height; ++i) { ofs << (unsigned char)(std::min(FloatType(1), image[i].x) * 255) << (unsigned char)(std::min(FloatType(1), image[i].y) * 255) << (unsigned char)(std::min(FloatType(1), image[i].z) * 255); } ofs.close(); delete [] image; }
// pick Geometry* Scene::pickRay(float cx, float cy, float cz, float nx, float ny, float nz) { // Attributes to determine which object in the scene is picked Geometry* closepick = NULL; int minT = 1000; // Pack arguments Vector3 raydir(nx, ny, nz); Point3 raysrc(cx, cy, cz); // Iterate over children, perform ray-sphere intersection test // keep minimum t. for (vector<Geometry*>::iterator iter(children.begin()); iter != children.end(); iter++) { Geometry* candidate = *iter; // Construct bounding sphere float sx, sy, sz, r; // sphere properties candidate->getBoundingSphere(sx, sy, sz, r); Point3 spheresrc(sx, sy, sz); if (testRaySphere(raydir, raysrc, spheresrc, r)) { // An intersection! find minimum t int quant; float tval[2]; findRaySphere(raydir, raysrc, spheresrc, r, quant, tval); for (int i = 0; i < quant; i++) { if (tval[i] < minT) { minT = tval[i]; closepick = candidate; } } } } return closepick; }