#include <iostream>
-#include <stdio.h>
+#include <cstdio>
+#include <cfloat>
using namespace std;
+#include "Indice1D.h"
#include "Indice2D.h"
#include "IndiceTools.h"
+#include "ColorTools.h"
#include "cudaTools.h"
#include "Device.h"
#include "RayTracingDevice.h"
-#include "RayTracingMath.h"
-__global__
-void rayTracing(uchar4* ptrDevPixels, int w, int h, DomaineMath domaineMath, float t)
+#if CURRENT_MEMORY_MODEL == MEMORY_MODEL_CONSTANT
+// Les spheres dans la constant memory.
+__constant__ Sphere CONST_SPHERES[NB_SPHERES];
+
+ConstantMemoryLink constantMemorySpheresLink()
+ {
+ float* ptrDevTabData;
+ size_t sizeAll = NB_SPHERES * sizeof(Sphere);
+ HANDLE_ERROR(cudaGetSymbolAddress((void**)&ptrDevTabData, CONST_SPHERES));
+ ConstantMemoryLink cmLink =
+ {
+ (void**)ptrDevTabData, NB_SPHERES, sizeAll
+ };
+ return cmLink;
+ }
+#endif
+
+#if CURRENT_MEMORY_MODEL == MEMORY_MODEL_GLOBAL or CURRENT_MEMORY_MODEL == MEMORY_MODEL_SHARED
+ __global__
+ void rayTracing(uchar4* ptrDevPixels, const Sphere* ptrDevSpheres, int w, int h, float t)
+#elif CURRENT_MEMORY_MODEL == MEMORY_MODEL_CONSTANT
+ __global__
+ void rayTracing(uchar4* ptrDevPixels, int w, int h, float t)
+#endif
{
+
const int TID = Indice2D::tid();
const int NB_THREAD = Indice2D::nbThread();
const int WH = w * h;
- RayTracingMath rayTracing; // TODO: prendre
+#if CURRENT_MEMORY_MODEL == MEMORY_MODEL_SHARED
+ __shared__ Sphere tabSpheresSM[NB_SPHERES];
- uchar4 color;
- color.w = 255; // Par défaut, l'image est opaque.
+ // Copy the global memory to shared memory.
+ const int NB_THREAD_LOCAL = Indice1D::nbThreadBlock();
+ const int TID_LOCAL = Indice1D::tidLocal();
+ int sLocal = TID_LOCAL;
+ while (sLocal < NB_SPHERES)
+ {
+ tabSpheresSM[sLocal] = ptrDevSpheres[sLocal];
+ sLocal += NB_THREAD_LOCAL;
+ }
- double x, y;
- int pixelI, pixelJ;
+ __syncthreads();
+#endif
int s = TID;
while (s < WH)
{
- IndiceTools::toIJ(s, w, &pixelI, &pixelJ); // update (pixelI, pixelJ)
+ const float2 pixel = IndiceTools::toPixelFloat(s, w);
+
+ // Les données de la sphère sélectionnée.
+ float selectedSphereDistance = FLT_MAX;
+ float brightness = 0;
+ float hue = 0;
+
+ // Sélectionne la sphère la plus proche, il peut ne pas y avoir de sphère trouvée.
+ for (int i = 0; i < NB_SPHERES; ++i)
+ {
+#if CURRENT_MEMORY_MODEL == MEMORY_MODEL_GLOBAL
+ const Sphere& sphere = ptrDevSpheres[i];
+#elif CURRENT_MEMORY_MODEL == MEMORY_MODEL_CONSTANT
+ const Sphere& sphere = CONST_SPHERES[i];
+#elif CURRENT_MEMORY_MODEL == MEMORY_MODEL_SHARED
+ const Sphere& sphere = tabSpheresSM[i];
+#endif
+
+ const float hSquare = sphere.hSquare(pixel);
+
+ if (sphere.isBelow(hSquare))
+ {
+ const float dz = sphere.dz(hSquare);
+ const float sphereDistance = sphere.distance(dz);
- // (i,j) domaine écran.
- // (x,y) domaine math.
- // domaineMath.toXY(pixelI, pixelJ, &x, &y); // (i,j) -> (x,y).
+ if (sphereDistance < selectedSphereDistance)
+ {
+ selectedSphereDistance = sphereDistance;
+ brightness = sphere.brightness(dz);
+ hue = sphere.hue(t);
+ }
+ }
+ }
- // newtonMath.colorXY(&color, x, y);
+ // Si une sphère a pu être trouvée.
+ if (selectedSphereDistance != FLT_MAX)
+ {
+ ColorTools::HSB_TO_RVB(hue, 1, brightness, &ptrDevPixels[s]);
+ }
- ptrDevPixels[s] = color;
+ ptrDevPixels[s].w = 255;
s += NB_THREAD;
}