diff --git a/2.png b/2.png
index 4ed86d8537c100c777481be7d82f8d453965eb80..a4930f70c5490e930d75e078e8eea0d619046e44 100644
Binary files a/2.png and b/2.png differ
diff --git a/0.png b/Rapport/0.png
similarity index 100%
rename from 0.png
rename to Rapport/0.png
diff --git a/1.png b/Rapport/1.png
similarity index 100%
rename from 1.png
rename to Rapport/1.png
diff --git a/Rapport/2.png b/Rapport/2.png
new file mode 100644
index 0000000000000000000000000000000000000000..4ed86d8537c100c777481be7d82f8d453965eb80
Binary files /dev/null and b/Rapport/2.png differ
diff --git a/main b/main
old mode 100644
new mode 100755
index c248d48d4ff0cc9440be85d18a0ca9445982a5b2..5595c74b405ef063a25f4cc3473dd2b77208437f
Binary files a/main and b/main differ
diff --git a/main.cpp b/main.cpp
index 4b2dd71393fbaab3d4ad90b9efef769bc966087c..ccea6f982cc04d275c7727b271b51ae1a2d07a8a 100644
--- a/main.cpp
+++ b/main.cpp
@@ -150,7 +150,7 @@ int main()
 		Material white(255, 255, 255, 0);
 		Material grey(122, 122, 122, 0);
 		Material black(0, 0, 0, 0);
-		Material mirror(0, 0, 0, 1);
+		Material mirror(255, 255, 255, 0.9);
 
 		int nb_shapes = 7;
 		float width = 100; //x
@@ -168,8 +168,8 @@ int main()
 		shapes[2] = new Quad(white, Vector3f(width/2, height, depth/2), width, 0, depth); //plafond
 		shapes[3] = new Quad(cyan, Vector3f(0, height/2, depth/2), 0, height, depth); //mur droit
 		shapes[4] = new Quad(green, Vector3f(width/2, 0, depth/2), width, 0, depth); //sol
-		shapes[5] = new Quad(red, Vector3f(20, 15, 15), 10, 10, 10); //cube
-		shapes[6] = new Sphere(blue, Vector3f(75, 20, 70), 20); //sphere
+		shapes[5] = new Quad(mirror, Vector3f(15, 25, 20), 10, 10, 10); //cube
+		shapes[6] = new Sphere(mirror, Vector3f(75, 20, 70), 20); //sphere
 
 		Camera camera(Vector3f(width/2, height/2, -50), Vector3f(0, 0, 1)); //on met la caméra un peu en recul
 		Ray3f source(Vector3f(width/2, height-1, depth/3), Vector3f(0, -1, 0)); //lumière au plafond
@@ -187,9 +187,6 @@ int main()
 			std::cout<<"direction "<<shapes[0]->reflect(light).direction()<<std::endl;
 		}*/
 
-
-
-
 		//----------CALCUL ET SAUVEGARDE DE L'IMAGE----------
 		std::cout << "Création de l'image..." << std::endl;
 		std::string filename = "2.png";
@@ -199,6 +196,8 @@ int main()
 		//----------LIBERATION DE LA MEMOIRE----------
 		for (int i=0; i<nb_shapes; i++)
 			delete [] shapes[i];
+
+
 	}
 
 	catch (const char* s)
diff --git a/scene.cpp b/scene.cpp
index f324f8fa7222fca69160cc67a3148c537f10cf0d..f8c584d252f37bad24161708687db13bfbe89b59 100644
--- a/scene.cpp
+++ b/scene.cpp
@@ -2,6 +2,8 @@
 #include <png.h>
 #include <math.h> //fmin
 
+#include <iostream>
+
 
 
 Scene::Scene(Camera camera, Shape* *shapes, Ray3f source) : camera_(camera), shapes_(shapes), source_(source)
@@ -47,11 +49,10 @@ Ray3f Scene::source() const
 	return source_;
 }
 
-
-
+/*
 void Scene::render(int width, int height, int nb_pixel_row, int nb_pixel_col, int nb_shapes, char* filename)
 {
-	/*--------------------------------Copié de la doc de libpng-------------------------------------*/
+	/*--------------------------------Copié de la doc de libpng-------------------------------------*//*
 	FILE *f = fopen(filename, "wb");
 	if (!f) throw "Echec de la création du fichier";
 
@@ -71,7 +72,7 @@ void Scene::render(int width, int height, int nb_pixel_row, int nb_pixel_col, in
     }
 
     png_init_io(png_ptr, f);
-    /*----------------------------------------------------------------------------------------------*/
+    /*----------------------------------------------------------------------------------------------*//*
 
 
     //Set header
@@ -175,10 +176,216 @@ void Scene::render(int width, int height, int nb_pixel_row, int nb_pixel_col, in
 
 	png_write_end(png_ptr, NULL);
 
+	fclose(f);
+}*/
+
+
+void Scene::render(int width, int height, int nb_pixel_row, int nb_pixel_col, int nb_shapes, char* filename)
+{
+	/*--------------------------------Copié de la doc de libpng-------------------------------------*/
+	FILE *f = fopen(filename, "wb");
+	if (!f) throw "Echec de la création du fichier";
+
+	png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (!png_ptr)
+    {
+    	fclose(f);
+    	throw "Echec allocation png_ptr";
+    }
+
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+       fclose(f);
+       png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
+       throw "Echec allocation info_ptr";
+    }
+
+    png_init_io(png_ptr, f);
+    /*----------------------------------------------------------------------------------------------*/
+
+
+    //Set header
+    png_set_IHDR(png_ptr, info_ptr, nb_pixel_row, nb_pixel_col, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+    
+    //Set text
+    png_text title_text;
+	title_text.compression = PNG_TEXT_COMPRESSION_NONE;
+	title_text.text = filename;
+	png_set_text(png_ptr, info_ptr, &title_text, 0);
+
+	png_write_info(png_ptr, info_ptr);
+
+
+	//Mémoire allouée pour une ligne de pixels (rgb => 3 bytes par pixel)
+	png_bytep row = (png_bytep) png_malloc(png_ptr, 3*nb_pixel_row*sizeof(png_byte));
+
+
+	float pw = (float) width / (float) nb_pixel_col; //largeur d'un pixel
+	float ph = (float) height / (float) nb_pixel_row; //hauteur d'un pixel
+	float min_dist;
+	float hit_dist;
+
+	int ref_max=3;
+	Ray3f *ray[ref_max];
+	float shine[ref_max-1];
+	float coef[ref_max-1];
+
+
+	for (int i=nb_pixel_col-1; i>=0; i--) //on remplit l'image par le bas à droite
+	{
+		for (int j=0; j<nb_pixel_row; j++)
+		{
+			min_dist = 1000;
+			Vector3f Pij(j*pw, i*ph, 0); //point de la grille par laquelle on regarde
+			Ray3f camera_to_grid(camera_.position(), Pij-camera_.position());
+			ray[0]=new Ray3f(camera_to_grid);
+
+			nb_reflected(ray, nb_shapes, ref_max, shine);
+			coeff(shine, coef, ref_max);
+
+
+
+			row[3*(nb_pixel_row-1-j)] = 0;
+			row[3*(nb_pixel_row-1-j) + 1] = 0;
+			row[3*(nb_pixel_row-1-j) + 2] = 0;
+
+			for(int r=0;r<ref_max-1;r++)
+			{
+				for (int k=0; k<nb_shapes; k++)
+				{
+					if (shapes_[k]->is_hit(*ray[r]))
+					{
+						Ray3f reflected(shapes_[k]->reflect(*ray[r]));
+						hit_dist = dist(reflected.origin() , camera_.position());
+
+						if ( hit_dist < min_dist ) //on regarde l'objet le plus proche de la caméra
+						{
+							min_dist = hit_dist;
+
+							bool shadow = false;
+							Ray3f reflect_to_source(reflected.origin(), source_.origin()-reflected.origin());
+
+
+							for (int l=0; l<nb_shapes; l++)
+							{
+								if (l != k) //pour éviter que l'objet se cache lui-même
+									if (shapes_[l]->is_hit(reflect_to_source))
+										if (  dist(reflected.origin() , shapes_[l]->reflect(reflect_to_source).origin())
+											< dist(reflected.origin() , source_.origin())  )
+										{
+											shadow = true;
+											break;
+										}
+							}
+
+							//intensité pour harmoniser les ombres selon la distance
+							float intensity = dist(reflected.origin(), source_.origin());
+							intensity = 5000/(intensity*intensity);
+
+							if (shadow)
+							{
+								row[3*(nb_pixel_row-1-j)] = row[3*(nb_pixel_row-1-j)] + coef[r]*fmin(50, 50*intensity);
+								row[3*(nb_pixel_row-1-j) + 1] = row[3*(nb_pixel_row-1-j) + 1] + coef[r]*fmin(50, 50*intensity);
+								row[3*(nb_pixel_row-1-j) + 2] = row[3*(nb_pixel_row-1-j) + 2] + coef[r]*fmin(50, 50*intensity);
+							}
+
+							else
+							{
+								Ray3f source_to_reflect(source_.origin(), reflected.origin()-source_.origin());
+
+								//self_shadow
+								//au lieu de diviser par une constante (2.) diviser par l'angle ?
+								if (  dist(reflect_to_source.origin() , shapes_[k]->reflect(source_to_reflect).origin()) > 0.05  )
+								{
+									row[3*(nb_pixel_row-1-j)] = row[3*(nb_pixel_row-1-j)] + coef[r]*fmin(shapes_[k]->matter().r()/2. * intensity, shapes_[k]->matter().r()/2.);
+									row[3*(nb_pixel_row-1-j) + 1] =row[3*(nb_pixel_row-1-j) + 1] + coef[r]*fmin(shapes_[k]->matter().g()/2. * intensity, shapes_[k]->matter().g()/2.);
+									row[3*(nb_pixel_row-1-j) + 2] =row[3*(nb_pixel_row-1-j) + 2] + coef[r]*fmin(shapes_[k]->matter().b()/2. * intensity, shapes_[k]->matter().b()/2.);
+								}
+
+								else //il faut rajouter la réflexion et l'angle
+								{
+									row[3*(nb_pixel_row-1-j)] = row[3*(nb_pixel_row-1-j)] + coef[r]*fmin(shapes_[k]->matter().r() * intensity, 255.);
+									row[3*(nb_pixel_row-1-j) + 1] = row[3*(nb_pixel_row-1-j) + 1] + coef[r]*fmin(shapes_[k]->matter().g() * intensity, 255.);
+									row[3*(nb_pixel_row-1-j) + 2] = row[3*(nb_pixel_row-1-j) + 2] + coef[r]*fmin(shapes_[k]->matter().b() * intensity, 255.);
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+
+		png_write_row(png_ptr, row);
+	}
+
+	png_write_end(png_ptr, NULL);
+
+	for (int r=0; r<ref_max;r++)
+		delete[] ray[r];
+
+
 	fclose(f);
 }
 
 
+
+int Scene::nb_reflected(Ray3f **ray, int nb_shapes, int ref_max,  float* shine){
+
+	bool vide=false;
+
+	float min_dist;
+	float hit_dist;
+
+	for(int r=0;r<(ref_max-1);r++)
+	{
+		shine[r]=0.0;
+	}
+
+
+	for(int r=0;r<(ref_max-1);r++)
+	{
+		min_dist=1000;
+		for (int k=0; k<nb_shapes; k++)
+		{
+
+			if (shapes_[k]->is_hit(*ray[r]))
+			{
+				Ray3f reflected(shapes_[k]->reflect(*ray[r]));
+				hit_dist = dist(reflected.origin() , camera_.position());
+
+
+				if ( hit_dist < min_dist ) //on regarde l'objet le plus proche de la caméra
+				{
+					min_dist = hit_dist;
+
+					ray[r+1]=new Ray3f(reflected);
+
+					shine[r]=shapes_[k]->matter().shiness();
+	
+				}
+			}
+		}
+	}
+}
+
+
+void Scene::coeff(float* shine, float* coef, int ref_max)
+{
+
+	for(int r=0;r<ref_max;r++)
+	{
+		coef[r]=1;
+		for(int i=0;i<r;i++)
+		{
+			coef[r]=coef[r]*shine[i];
+		}
+		coef[r]=coef[r]*(1-shine[r]);
+	}
+}
+
+
+
 /*std::ostream & operator<<(std::ostream & st, const Scene & s)
 {
 	st << "camera" << std::endl << s.camera() << std::endl;
diff --git a/scene.h b/scene.h
index b8e62d810db0c4eb3a9d41c0918d364d44629da0..a05bc5429c269629460add5403f7278181952a5f 100644
--- a/scene.h
+++ b/scene.h
@@ -33,6 +33,8 @@ class Scene
 		Ray3f source() const;
 
 		void render(int width, int height, int nb_pixel_row, int nb_pixel_col, int nb_shapes, char* filename);
+		int nb_reflected(Ray3f **ray, int nb_shapes, int ref_max, float* shine);
+		void coeff(float* shine, float* coef, int ref_max);
 };