diff --git a/0.png b/0.png new file mode 100644 index 0000000000000000000000000000000000000000..26fd209a570fcbced0554a97d7aec26ec4372ca4 Binary files /dev/null and b/0.png differ diff --git a/Makefile b/Makefile index 7ba04975e296086144b8661e4f029dfd7bc697b4..399a99583056a9e45eb5e001928ad660afe81251 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ sphere.o: sphere.h scene.o: scene.h main: $(OBJ) - $(CC) -o $@ $^ + $(CC) -o $@ $^ -lpng clean: rm *.o main \ No newline at end of file diff --git a/main b/main index cb553feecb06412446184a6a9ace4846d0a6dbcf..fb5cbdad93febbdd58074c5002cc95defe2432a6 100644 Binary files a/main and b/main differ diff --git a/main.cpp b/main.cpp index 5eb62496578493add945984ae09b34bdd5b0841b..0acd8a920c25614e99b0ea5d24e2a3cb1e8cb4f8 100644 --- a/main.cpp +++ b/main.cpp @@ -144,6 +144,9 @@ int main() Material red(255, 0, 0, 0); Material green(0, 255, 0, 0); Material blue(0, 0, 255, 0); + Material yellow(255, 255, 0, 0); + Material magenta(255, 0, 255, 0); + Material cyan(0, 255, 255, 0); Material white(255, 255, 255, 0); Material grey(122, 122, 122, 0); Material black(0, 0, 0, 0); @@ -159,24 +162,24 @@ int main() | x <----X z*/ Shape *shapes[nb_shapes]; - shapes[0] = new Quad(grey, Vector3f(width/2, height/2, depth), width, height, 0); //mur du fond - shapes[1] = new Quad(grey, Vector3f(width, height/2, depth/2), 0, height, depth); //mur gauche - shapes[2] = new Quad(grey, Vector3f(width/2, height, depth/2), width, 0, depth); //plafond - shapes[3] = new Quad(grey, Vector3f(0, height/2, depth/2), 0, height, depth); //mur droit + shapes[0] = new Quad(yellow, Vector3f(width/2, height/2, depth), width, height, 0); //mur du fond + shapes[1] = new Quad(magenta, Vector3f(width, height/2, depth/2), 0, height, depth); //mur gauche + 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(grey, Vector3f(width/2, 0, depth/2), width, 0, depth); //sol shapes[5] = new Quad(red, Vector3f(width/4, 20, depth-20), 40, 40, 40); //cube shapes[6] = new Sphere(blue, Vector3f(3/4*width, 20, depth/2), 40); //sphere - Camera camera(Vector3f(width/2, height/2, 0), Vector3f(0, 0, 1)); - Ray3f source(Vector3f(width/2, height, depth/2), Vector3f(0, -1, 0)); + Camera camera(Vector3f(width/2, height/2, -1), Vector3f(0, 0, 1)); //on met la caméra un peu en recul + Ray3f source(Vector3f(width/2, height, depth/2), Vector3f(0, -1, 0)); //lumière au plafonc Scene scene(camera, shapes, source); //----------CALCUL ET SAUVEGARDE DE L'IMAGE---------- - std::cout << "Création de l'image..." ; + std::cout << "Création de l'image..." << std::endl; std::string filename = "0.png"; - scene.render(640, 480, filename.c_str()); - std::cout << " image sauvegardée" << std::endl; + scene.render(width, height, 640, 480, nb_shapes, (char *) filename.c_str()); + std::cout << "Image sauvegardée" << std::endl; //----------LIBERATION DE LA MEMOIRE---------- for (int i=0; i<nb_shapes; i++) diff --git a/scene.cpp b/scene.cpp index 1d237fea1c433b0878ca5bee6f36cc02fa05ebf6..f541ab7dbe867e761b401b4ce246de80906e0d10 100644 --- a/scene.cpp +++ b/scene.cpp @@ -1,4 +1,5 @@ #include "scene.h" +#include <png.h> @@ -46,9 +47,74 @@ Ray3f Scene::source() const } -void Scene::render(int width, int height, const char* filename) -{ +void Scene::render(int width, int height, int nb_pixel_row, int nb_pixel_col, int nb_shapes, char* filename) +{ + 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 = width / nb_pixel_row; + float ph = height / nb_pixel_col; + for (int i=0; i<nb_pixel_row; i++) + { + for (int j=0; j<nb_pixel_col; j++) + { + Vector3f Pij(i*pw, j*ph, 0); //point de la grille par laquelle on regarde + Ray3f camera_to_grid(camera_.position(), Pij-camera_.position()); + + row[3*i] = 0; + row[3*i + 1] = 0; + row[3*i + 2] = 0; + + for (int k=0; k<nb_shapes; k++) + { + if (shapes_[k]->is_hit(camera_to_grid)) + { + row[3*i] = shapes_[k]->matter().r(); + row[3*i + 1] = shapes_[k]->matter().g(); + row[3*i + 2] = shapes_[k]->matter().b(); + } + } + } + + png_write_row(png_ptr, row); + } + + png_write_end(png_ptr, NULL); + + fclose(f); } diff --git a/scene.h b/scene.h index 5762f809306aecef958035c0d60502099c6b4273..bc4f16d8e7e07e82f436bdb6380fb8308876c7ac 100644 --- a/scene.h +++ b/scene.h @@ -21,7 +21,7 @@ class Scene Shape* *shapes() const; Ray3f source() const; - void render(int width, int height, const char* filename); + void render(int width, int height, int nb_pixel_row, int nb_pixel_col, int nb_shapes, char* filename); };