diff --git a/.gitignore b/.gitignore index a3748b9..fffacb7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.xcodeproj old +gloss +.*.d diff --git a/Color.h b/Color.h index f8770cb..6e46e19 100644 --- a/Color.h +++ b/Color.h @@ -5,8 +5,8 @@ typedef struct { float red, green, blue; } Color; -Color makeColorWhite(); -Color makeColorBlack(); +Color makeColorWhite(void); +Color makeColorBlack(void); Color makeColorLightness(const float l); Color makeColor(const float red, const float green, const float blue); diff --git a/Container.h b/Container.h index 1b3f5b1..3aac467 100644 --- a/Container.h +++ b/Container.h @@ -37,6 +37,7 @@ type * lowercaseType##ContainerAddValue(type##Container *container, const type v assert(0); \ } \ } \ +__attribute__((noreturn)) \ void lowercaseType##ContainerAddValues(type##Container *container, const type##Container values) { \ /* TODO: Actually implement. */ \ assert(0); \ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0cfa48b --- /dev/null +++ b/Makefile @@ -0,0 +1,84 @@ +.SUFFIXES: + +CC := $(CROSS_COMPILE)gcc + +FAST := -flto -fwhole-program \ + -msse4.2 -ftree-vectorize \ + -mtune=corei7 -march=corei7 \ + -ffast-math + +EXTRA_DEFS := -D_FILE_OFFSET_BITS=64 +CFLAGS := -g -pipe -O2 -Wall \ + $(FAST) \ + -Wsign-compare -Wcast-align \ + -Wstrict-prototypes \ + -Wmissing-prototypes \ + -Wmissing-declarations \ + -Wmissing-noreturn \ + -finline-functions \ + -Wmissing-format-attribute \ + -Wno-cast-align \ + -I. -I/usr/include/SDL \ + -std=gnu99 \ + $(EXTRA_DEFS) + +GLOSS_BIN := gloss +GLOSS_LIBS := -lSDL -lm +GLOSS_OBJ = \ + Box.o \ + Color.o \ + Intersection.o \ + main.o \ + Material.o \ + MaterialContainer.o \ + Matrix.o \ + Photon.o \ + PhotonContainer.o \ + PhotonEndPoint.o \ + PhotonEndPointContainer.o \ + Plane.o \ + randf.o \ + Ray.o \ + Scene.o \ + SceneObjectBox.o \ + SceneObject.o \ + SceneObjectContainer.o \ + SceneObjectPlane.o \ + SceneObjectSphere.o \ + SceneObjectUnitPlane.o \ + Sphere.o \ + Vector.o + +ALL_BIN := $(GLOSS_BIN) +ALL_OBJ := $(GLOSS_OBJ) +ALL_DEP := $(patsubst %.o, .%.d, $(ALL_OBJ)) +ALL_TARGETS := $(ALL_BIN) + +TARGET: all + +.PHONY: all clean + +all: $(ALL_BIN) + +ifeq ($(filter clean, $(MAKECMDGOALS)),clean) +CLEAN_DEP := clean +else +CLEAN_DEP := +endif + +%.o %.d: %.c $(CLEAN_DEP) $(CONFIG_MAK) Makefile + @echo " [C] $<" + @$(CC) $(CFLAGS) -MMD -MF $(patsubst %.o, .%.d, $@) \ + -MT $(patsubst .%.d, %.o, $@) \ + -c -o $(patsubst .%.d, %.o, $@) $< + +$(GLOSS_BIN): $(GLOSS_OBJ) + @echo " [LINK] $@" + @$(CC) $(CFLAGS) -o $@ $(GLOSS_OBJ) $(GLOSS_LIBS) + +clean: + rm -f $(ALL_TARGETS) $(ALL_OBJ) $(ALL_DEP) + +ifneq ($(MAKECMDGOALS),clean) +-include $(ALL_DEP) +endif diff --git a/Matrix.c b/Matrix.c index e64f459..ca13c32 100644 --- a/Matrix.c +++ b/Matrix.c @@ -1,38 +1,41 @@ #include "Matrix.h" #include +__attribute__((const)) Matrix makeMatrixZero() { - return (Matrix) { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 - }; + return (Matrix) {{ + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }}; } +__attribute__((const)) Matrix makeMatrixIdentity() { - return (Matrix) { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - }; + return (Matrix) {{ + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1} + }}; } +__attribute__((const)) Matrix makeMatrixTranslation(const Vector v) { - return (Matrix) { - 1, 0, 0, v.x, - 0, 1, 0, v.y, - 0, 0, 1, v.z, - 0, 0, 0, 1 - }; + return (Matrix) {{ + {1, 0, 0, v.x}, + {0, 1, 0, v.y}, + {0, 0, 1, v.z}, + {0, 0, 0, 1}, + }}; } +__attribute__((const)) Matrix makeMatrixAxisAngle(const Vector axis, const float angle) { - float length = vLength(axis); if(length < 0.0005){ @@ -59,29 +62,31 @@ Matrix makeMatrixAxisAngle(const Vector axis, const float angle) { return matrix; } +__attribute__((const)) bool mEqual(const Matrix a, const Matrix b) { - for (int i=0; i<4; i++) for (int j=0; j<4; j++) if (a.values[i][j] + vEpsilon < b.values[i][j] || b.values[i][j] + vEpsilon < a.values[i][j]) return false; - + return true; } -Matrix mMul(const Matrix a, const Matrix b) { +__attribute__((pure)) +Matrix mMul(const Matrix *a, const Matrix *b) { Matrix matrix = makeMatrixZero(); for (int i=0; i<4; i++) for (int j=0; j<4; j++) for (int k=0; k<4; k++) - matrix.values[i][j] += a.values[i][k] * b.values[k][j]; + matrix.values[i][j] += a->values[i][k] * b->values[k][j]; return matrix; } -Vector mvMul(const Matrix matrix, const Vector vector) { +__attribute__((pure)) +Vector mvMul(const Matrix *matrix, const Vector *vector) { Vector newVector = mvMulDir(matrix, vector); @@ -89,33 +94,37 @@ Vector mvMul(const Matrix matrix, const Vector vector) { float* newVectorValues = (float*)&newVector.x; for (int i=0; i<3; i++) - newVectorValues[i] += matrix.values[i][3]; + newVectorValues[i] += matrix->values[i][3]; return newVector; } -Vector mvMulDir(const Matrix matrix, const Vector vector) { +__attribute__((pure)) +Vector mvMulDir(const Matrix *matrix, const Vector *vector) { Vector newVector = makeVector(0, 0, 0); // Access x,y,z as an array. - float* vectorValues = (float*)&vector.x; + float* vectorValues = (float*)&vector->x; float* newVectorValues = (float*)&newVector.x; for (int i=0; i<3; i++) for (int j=0; j<3; j++) - newVectorValues[i] += matrix.values[i][j] * vectorValues[j]; + newVectorValues[i] += matrix->values[i][j] * vectorValues[j]; return newVector; } -Ray mrMul(const Matrix matrix, const Ray ray) { +__attribute__((pure)) +Ray mrMul(const Matrix *matrix, const Ray *ray) { - return makeRay(mvMul(matrix, ray.origin), vNormalized(mvMulDir(matrix, ray.direction))); + return makeRay(mvMul(matrix, &ray->origin), + vNormalized(mvMulDir(matrix, &ray->direction))); } -Matrix mInversed(const Matrix matrix) { - float* m = (float*)&matrix.values[0][0]; +__attribute__((pure)) +Matrix mInversed(const Matrix *matrix) { + float* m = (float*)&matrix->values[0][0]; Matrix returnValue; float* out = &returnValue.values[0][0]; @@ -289,6 +298,3 @@ Matrix mInversed(const Matrix matrix) { return returnValue; } - - - diff --git a/Matrix.h b/Matrix.h index 6cf8c0d..eb982c0 100644 --- a/Matrix.h +++ b/Matrix.h @@ -8,20 +8,31 @@ typedef struct { float values[4][4]; } Matrix; -Matrix makeMatrixZero(); -Matrix makeMatrixIdentity(); +__attribute__((const)) +Matrix makeMatrixZero(void); +__attribute__((const)) +Matrix makeMatrixIdentity(void); +__attribute__((const)) Matrix makeMatrixTranslation(const Vector v); +__attribute__((const)) Matrix makeMatrixAxisAngle(const Vector axis, const float angle); +__attribute__((const)) bool mEqual(const Matrix a, const Matrix b); -Matrix mMul(const Matrix a, const Matrix b); +__attribute__((pure)) +Matrix mMul(const Matrix *a, const Matrix *b); -Vector mvMul (const Matrix Matrix, const Vector Vector); -Vector mvMulDir(const Matrix Matrix, const Vector Vector); +__attribute__((pure)) +Vector mvMul (const Matrix *Matrix, const Vector *Vector); -Ray mrMul(const Matrix matrix, const Ray ray); +__attribute__((pure)) +Vector mvMulDir(const Matrix *Matrix, const Vector *Vector); -Matrix mInversed(); +__attribute__((pure)) +Ray mrMul(const Matrix *matrix, const Ray *ray); + +__attribute__((pure)) +Matrix mInversed(const Matrix *); #endif // MATRIX_H diff --git a/Scene.c b/Scene.c index 3c1ac3e..2c7b88b 100644 --- a/Scene.c +++ b/Scene.c @@ -2,7 +2,7 @@ #include "Matrix.h" #include "Color.h" #include "Intersection.h" -#include "PhotonEndpoint.h" +#include "PhotonEndPoint.h" #include "PhotonEndPointContainer.h" #include "PhotonContainer.h" #include "pi.h" @@ -28,8 +28,10 @@ Color sceneTraceRayAtPixel(const Scene *scene, const int currentPixel, const int float maxX = tanf(cameraFov/360.0*PI); float x = ((((currentPixel % width) + randf()) / width ) * 2 - 1) * maxX; float y = -((((currentPixel / width) + randf()) / height) * 2 - 1) * maxX / cameraAspectRatio; + Matrix m = mInversed(&scene->cameraOrientation); + Ray r = makeRay(makeVectorOrigo(), vNormalized(makeVector(x, y, 1))); - return sceneTraceRay(scene, mrMul(mInversed(scene->cameraOrientation), makeRay(makeVectorOrigo(), vNormalized(makeVector(x, y, 1)))), numCameraRayBounces); + return sceneTraceRay(scene, mrMul(&m, &r), numCameraRayBounces); } void sceneGeneratePhotons(Scene *scene, const int lightRayBounces, const int numPhotonsPerLightSource) { @@ -187,14 +189,20 @@ void buildCornellBox(Scene *scene) { // Boxes + Matrix a, b; + a = makeMatrixAxisAngle(makeVector(0, 1, 0), .3); + b = makeMatrixTranslation(makeVector(-.3, -.3, .3)); sceneObjectContainerAddValue(&scene->objects, makeSceneObjectBox( makeVector(.3, .7, .3), - mMul(makeMatrixAxisAngle(makeVector(0, 1, 0), .3), makeMatrixTranslation(makeVector(-.3, -.3, .3))), + mMul(&a, &b), whiteMaterial )); + + a = makeMatrixAxisAngle(makeVector(0, 1, 0), -.3); + b = makeMatrixTranslation(makeVector(.3, -.75, -.3)); sceneObjectContainerAddValue(&scene->objects, makeSceneObjectBox( makeVector(.3, .3, .3), - mMul(makeMatrixAxisAngle(makeVector(0, 1, 0), -.3), makeMatrixTranslation(makeVector(.3, -.75, -.3))), + mMul(&a, &b), whiteMaterial )); @@ -256,7 +264,8 @@ void buildCornellBox(Scene *scene) { -void buildSpherePhotonSpawnTest(Scene *scene) { +__attribute__((unused)) +static void buildSpherePhotonSpawnTest(Scene *scene) { // Camera scene->cameraOrientation = makeMatrixTranslation(makeVector(0, 0, 3.8)); diff --git a/Scene.h b/Scene.h index 0a7aec7..cab7367 100644 --- a/Scene.h +++ b/Scene.h @@ -21,7 +21,7 @@ typedef struct { } Scene; -Scene makeScene(); +Scene makeScene(void); Color sceneTraceRayAtPixel(const Scene *scene, const int currentPixel, const int width, const int height, const int numCameraRayBounces); void sceneGeneratePhotons(Scene *scene, const int lightRayBounces, const int numPhotonsPerLightSource); diff --git a/SceneObjectBox.c b/SceneObjectBox.c index ceedbca..c437e02 100644 --- a/SceneObjectBox.c +++ b/SceneObjectBox.c @@ -2,24 +2,25 @@ #include "randf.h" #include -const SceneObjectVTable sceneObjectBoxVTable = (SceneObjectVTable) { +const SceneObjectVTable sceneObjectBoxVTable = { &sceneObjectBoxIntersectRay, &sceneObjectBoxEmitPhotons }; SceneObject makeSceneObjectBox (const Vector size, const Matrix transform, const Material *material) { - return (SceneObject) {&sceneObjectBoxVTable, material, transform, mInversed(transform), {.box = makeBox(size)}}; + return (SceneObject) {&sceneObjectBoxVTable, material, transform, mInversed(&transform), {.box = makeBox(size)}}; } Intersection sceneObjectBoxIntersectRay(const SceneObject object, const Ray ray) { - Intersection intersection = bIntersect(object.box, mrMul(object.inversedTransform, ray)); + Intersection intersection = bIntersect(object.box, + mrMul(&object.inversedTransform, &ray)); if (intersection.hitType) { - intersection.normal = mvMulDir(object.transform, intersection.normal ); - intersection.position = mvMul (object.transform, intersection.position); + intersection.normal = mvMulDir(&object.transform, &intersection.normal ); + intersection.position = mvMul (&object.transform, &intersection.position); intersection.material = object.material; if (intersection.material->isPerfectBlack) { diff --git a/SceneObjectPlane.c b/SceneObjectPlane.c index f98dcbc..e2a494f 100644 --- a/SceneObjectPlane.c +++ b/SceneObjectPlane.c @@ -1,23 +1,24 @@ #include "SceneObjectPlane.h" -const SceneObjectVTable sceneObjectPlaneVTable = (SceneObjectVTable) { +const SceneObjectVTable sceneObjectPlaneVTable = { &sceneObjectPlaneIntersectRay, &sceneObjectPlaneEmitPhotons }; SceneObject makeSceneObjectPlane (const Plane plane, const Matrix transform, const Material *material) { - return (SceneObject) {&sceneObjectPlaneVTable, material, transform, mInversed(transform), {.plane = plane}}; + return (SceneObject) {&sceneObjectPlaneVTable, material, transform, mInversed(&transform), {.plane = plane}}; } Intersection sceneObjectPlaneIntersectRay(const SceneObject object, const Ray ray) { - Intersection intersection = pIntersect(object.plane, mrMul(object.inversedTransform, ray)); + Intersection intersection = pIntersect(object.plane, + mrMul(&object.inversedTransform, &ray)); if (intersection.hitType) { - intersection.normal = mvMulDir(object.transform, intersection.normal ); - intersection.position = mvMul (object.transform, intersection.position); + intersection.normal = mvMulDir(&object.transform, &intersection.normal ); + intersection.position = mvMul (&object.transform, &intersection.position); intersection.material = object.material; if (intersection.material->isPerfectBlack) { diff --git a/SceneObjectSphere.c b/SceneObjectSphere.c index da129a4..ab7357d 100644 --- a/SceneObjectSphere.c +++ b/SceneObjectSphere.c @@ -4,24 +4,25 @@ #include "pi.h" #include -const SceneObjectVTable sceneObjectSphereVTable = (SceneObjectVTable) { +const SceneObjectVTable sceneObjectSphereVTable = { &sceneObjectSphereIntersectRay, &sceneObjectSphereEmitPhotons }; SceneObject makeSceneObjectSphere (const Sphere sphere, const Matrix transform, const Material *material) { - return (SceneObject) {&sceneObjectSphereVTable, material, transform, mInversed(transform), {.sphere = sphere}}; + return (SceneObject) {&sceneObjectSphereVTable, material, transform, mInversed(&transform), {.sphere = sphere}}; } Intersection sceneObjectSphereIntersectRay(const SceneObject object, const Ray ray) { - Intersection intersection = sIntersect(object.sphere, mrMul(object.inversedTransform, ray)); + Intersection intersection = sIntersect(object.sphere, + mrMul(&object.inversedTransform, &ray)); if (intersection.hitType) { - intersection.normal = mvMulDir(object.transform, intersection.normal ); - intersection.position = mvMul (object.transform, intersection.position); + intersection.normal = mvMulDir(&object.transform, &intersection.normal ); + intersection.position = mvMul (&object.transform, &intersection.position); intersection.material = object.material; if (intersection.material->isPerfectBlack) { @@ -91,7 +92,10 @@ bool sceneObjectSphereEmitPhotons(const SceneObject object, const int numPhotons Vector position = vAdd(object.sphere.position, vsMul(normal, 1+vEpsilon)); - photonContainerAddValue(photons, makePhoton(mrMul(object.transform, makeRay(position, normal)), csMul(object.material->radience, 1.0 / numPhotons))); + Ray r = makeRay(position, normal); + photonContainerAddValue(photons, + makePhoton(mrMul(&object.transform, &r), + csMul(object.material->radience, 1.0 / numPhotons))); } } @@ -108,7 +112,10 @@ bool sceneObjectSphereEmitPhotons(const SceneObject object, const int numPhotons Vector position = vAdd(object.sphere.position, vsMul(normal, 1+vEpsilon)); - photonContainerAddValue(photons, makePhoton(mrMul(object.transform, makeRay(position, normal)), csMul(object.material->radience, 1.0 / numPhotons))); + Ray r = makeRay(position, normal); + photonContainerAddValue(photons, + makePhoton(mrMul(&object.transform, &r), + csMul(object.material->radience, 1.0 / numPhotons))); } return true; diff --git a/SceneObjectUnitPlane.c b/SceneObjectUnitPlane.c index 8c60cfd..c564e65 100644 --- a/SceneObjectUnitPlane.c +++ b/SceneObjectUnitPlane.c @@ -2,19 +2,20 @@ #include "randf.h" #include -const SceneObjectVTable sceneObjectUnitPlaneVTable = (SceneObjectVTable) { +const SceneObjectVTable sceneObjectUnitPlaneVTable = { &sceneObjectUnitPlaneIntersectRay, &sceneObjectUnitPlaneEmitPhotons }; SceneObject makeSceneObjectUnitPlane (const Plane plane, const Matrix transform, const Material *material) { - return (SceneObject) {&sceneObjectUnitPlaneVTable, material, transform, mInversed(transform), {.plane = plane}}; + return (SceneObject) {&sceneObjectUnitPlaneVTable, material, transform, mInversed(&transform), {.plane = plane}}; } Intersection sceneObjectUnitPlaneIntersectRay(const SceneObject object, const Ray ray) { - Intersection intersection = pIntersect(object.plane, mrMul(object.inversedTransform, ray)); + Intersection intersection = pIntersect(object.plane, + mrMul(&object.inversedTransform, &ray)); if (intersection.hitType) { @@ -31,8 +32,8 @@ Intersection sceneObjectUnitPlaneIntersectRay(const SceneObject object, const Ra return intersection; } - intersection.normal = mvMulDir(object.transform, intersection.normal ); - intersection.position = mvMul (object.transform, intersection.position); + intersection.normal = mvMulDir(&object.transform, &intersection.normal ); + intersection.position = mvMul (&object.transform, &intersection.position); intersection.material = object.material; if (intersection.material->isPerfectBlack) { diff --git a/Vector.h b/Vector.h index fb28bf9..31af432 100644 --- a/Vector.h +++ b/Vector.h @@ -10,7 +10,7 @@ typedef struct { } Vector; Vector makeVector(const float x, const float y, const float z); -Vector makeVectorOrigo(); +Vector makeVectorOrigo(void); bool vEqual(const Vector a, const Vector b); diff --git a/randf.h b/randf.h index 6b44ca1..d081372 100644 --- a/randf.h +++ b/randf.h @@ -1,6 +1,6 @@ #ifndef _randf_ #define _randf_ -float randf(); +float randf(void); -#endif \ No newline at end of file +#endif