I'm about to go to bed so won't be able to reply to any responses until I wake up, but this has been frustrating me for a bit and I don't know what I have done wrond and my C++ debugging skills are still quite poor.
I'm going to comment this code more properly tomorrow as well.
Essentially, we have to make a basic ray-tracer that runs on the CPU as an assignment. We've been told to do it in Java, but I asked if I could do it in C++ instead as I want to learn C++ and got told yes, so I decided to whack the following code together tonight (using Handmade Hero's framebuffer which Casey very kindly let my use). All the relevant stuff is in
https://github.com/Moosichu/RayTracer/blob/master/src/ray_tracer.cpp.
However, when I run my program, nothing is being drawn to the screen

, and I can't work out why.
The reason I think the error is here, is because if I set the ambientFactor color to a value, the entire screen will be filled with that. It's just that no circles are being drawn which is what I want essentially as I have just implement the ambient component of spheres.
Code:
Color traceRay(Ray ray,
Sphere sceneObjects[], std::size_t numObjects,
PointLight lights[], std::size_t numLights,
int recurseDepth) {
LightCollision closestCollision;
closestCollision.position = {600000.0, 60000.0, 60000.0}; //TODO(Tom) Replace with max possible scalar values
closestCollision.normal = {1.0, 0, 0};
closestCollision.ambientFactor = {0, 0, 0};
closestCollision.diffuseFactor = {0, 0, 0};
closestCollision.specularFactor = {0, 0, 0};
//Find the closest position
for(std::size_t i = 0; i < numObjects; i++) {
//TODO(Tom) Have a way of handling type of sceneObject
{
Sphere sphere = sceneObjects[i];
Vector3D sphereToRayOrigin = sphere.position - ray.origin;
scalar a = ray.direction.dot(ray.direction); //a = |ray.direction|^2
scalar b = 2 * ray.direction.dot(sphereToRayOrigin);
scalar c = sphereToRayOrigin.dot(sphereToRayOrigin) - (sphere.radius*sphere.radius);
scalar d;
{
double intermediate = (b*b) - (4*a*c);
if(intermediate < 0) {
continue; //No intersection
}
d = sqrt(intermediate);
}
double s1 = (-b + d)/(2*a);
double s2 = (-b - d)/(2*a);
double s = s1 < s2 ? s1 : s2; //select the closest point intersection
if(s < 0) {
continue;
}
//Work out the position of the collision relateve to the camera's location
Vector3D collisionOffset = ray.direction * s;
if(collisionOffset.square() < closestCollision.position.square()) { //Comparing magnitudes
closestCollision.position = collisionOffset;
//TODO(Tom) Calculate the normal of the collision!
closestCollision.ambientFactor = sphere.ambientFactor;
closestCollision.diffuseFactor = sphere.diffuseFactor;
closestCollision.specularFactor = sphere.specularFactor;
}
}
}
Color finalColor = closestCollision.ambientFactor;
if(recurseDepth > 0) {
Color diffuseComponent;
Color specularComponent;
//check to make sure any diffuse components actually have to be calculated
if (closestCollision.diffuseFactor.red |
closestCollision.diffuseFactor.green |
closestCollision.diffuseFactor.blue) {
//TODO(Tom) recursively calculate diffuse components and add to final color variable
}
//check to make sure any specular components actually have to be calculated
if (closestCollision.specularFactor.red |
closestCollision.specularFactor.green |
closestCollision.specularFactor.blue) {
//TODO(Tom) recursively calculate specular component and add to final color variable
}
}
return finalColor;
}
Sorry about this huge code dump, I'm very tired and something glaringly obvious will probably jump out in the morning, but I also have a huge fear that I will spend hours trying to track down a niggly bug.
I'm guessing the error is somewhere in my collision detection section, but I did already implement this in java and it worked fine and I have just been porting my work there to C++ so there shouldn't be any issues with the basic maths.