Camera::Camera(EngineParams& params) : KernelObject(params) { fprintf(stderr, "Initializing <Camera>.\n"); fprintf(stderr, "Loading '*/camera.xml'.\n"); std::fstream stream; pugi::xml_document doc; GetData("camera.xml", stream); fprintf(stderr, "Parsing camera parameters..."); ParseXML(doc, stream); fprintf(stderr, " done.\n"); pugi::xml_node node = doc.child("camera"); Vector cameraPos = parseVector(node.child("position")); Vector cameraTarget = parseVector(node.child("target")); Vector dir = normalize(cameraTarget - cameraPos); node = node.child("misc"); float FOV = (PI / 180.0f) * node.attribute("fov").as_float(); node = node.parent(); node = node.child("focal"); /* Depth-of-field params. */ float focalSpread = node.attribute("spread").as_float(); float focalLength = node.attribute("length").as_float(); fprintf(stderr, "Camera position = (%.2f, %.2f, %.2f).\n", cameraPos.x, cameraPos.y, cameraPos.z); fprintf(stderr, "Camera target = (%.2f, %.2f, %.2f).\n", cameraTarget.x, cameraTarget.y, cameraTarget.z); fprintf(stderr, "Field of view = %.2f radians.\n", FOV); fprintf(stderr, "Focal length = %.2f.\n", focalLength); fprintf(stderr, "Focal spread = %.2f.\n", focalSpread); Vector normal, tangent; Basis(dir, &normal, &tangent); Vector focalPlane[4]; float z = 1.0f / tan(FOV * 0.5f); focalPlane[0] = normalize(Vector(-1.0f, +1.0f, z)); focalPlane[1] = normalize(Vector(+1.0f, +1.0f, z)); focalPlane[2] = normalize(Vector(+1.0f, -1.0f, z)); focalPlane[3] = normalize(Vector(-1.0f, -1.0f, z)); for (size_t t = 0; t < 4; ++t) { /* Transform the focal plane to camera space (= "rotate" it) */ focalPlane[t] = Transform(focalPlane[t], tangent, normal, dir); focalPlane[t] = focalPlane[t] * focalLength + cameraPos; } this->buffer = CreateBuffer(params.context, CL_MEM_READ_ONLY, sizeof(cl_data), nullptr); cl_data data; for (size_t t = 0; t < 4; ++t) focalPlane[t].CL(&data.p[t]); cameraPos.CL(&data.pos); normal.CL(&data.up); tangent.CL(&data.left); data.spread = focalSpread; WriteToBuffer(params.queue, this->buffer, CL_TRUE, 0, sizeof(cl_data), &data); fprintf(stderr, "Initialization complete.\n\n"); stream.close(); }