* mcgarvey@eng.utah.edu
*/
-#include <stdio.h>
+#define _POSIX_C_SOURCE 2
+#include <errno.h>
+#include <unistd.h>
-#include "pixmap.h"
+#include "raster.h"
#include "scene.h"
/*
- * Read a scene file, construct the scene object, draw the scene to a pixmap,
- * and export the pixmap in PPM and BMP formats.
+ * Load a scene from a file.
*/
-int main(int argc, char* argv[])
+static int load(scene_t** scene, const char* filename)
+{
+ FILE* file = fopen(filename, "r");
+ if (file == NULL) {
+ fprintf(stderr, "Cannot read %s: %s\n", filename, strerror(errno));
+ return -1;
+ }
+
+ *scene = scene_alloc(file);
+ if (*scene == NULL) {
+ fclose(file);
+ return -1;
+ }
+
+ fclose(file);
+ return 0;
+}
+
+/*
+ * Load a scene from standard input.
+ */
+static int load_from_stdin(scene_t** scene)
{
- scene_t* scene = scene_alloc("scene.u2d");
- if (scene == NULL) {
- fprintf(stderr, "An error prevented the scene from loading. Aborting!\n");
- return 1;
+ *scene = scene_alloc(stdin);
+ if (*scene == NULL) {
+ return -1;
}
+ return 0;
+}
+
+/*
+ * Load a scene file, render it, and export it.
+ */
+static void draw(const char* filename)
+{
+ scene_t* scene;
+ TRY_DO("Loading %s", load(&scene, filename), filename);
- pixmap_t* raster = scene_render(scene);
+ raster_t* raster = scene_render(scene);
scene_destroy(scene);
+ raster_printstats(raster);
- pixmap_export_ppm(raster, "scene.ppm");
- pixmap_export_bmp(raster, "scene.bmp");
+ char* u3d = mem_strdup(filename);
+ strcut(u3d, '.');
+#if EXPORT_PPM
+ char* ppm = mem_strcat(u3d, ".ppm");
+ TRY_DO("Exporting to %s", raster_export_ppm(raster, ppm), ppm);
+ mem_free(ppm);
+#endif
+#if EXPORT_BMP
+ char* bmp = mem_strcat(u3d, ".bmp");
+ TRY_DO("Exporting to %s", raster_export_bmp(raster, bmp), bmp);
+ mem_free(bmp);
+#endif
- pixmap_destroy(raster);
+ mem_free(u3d);
+ raster_destroy(raster);
+}
-#ifndef NDEBUG
+/*
+ * Render a scene that is read from standard input, and export to BMP.
+ */
+static void draw_from_stdin(const char* filename)
+{
+ scene_t* scene;
+ TRY_DO("Loading from stdin", load_from_stdin(&scene));
+
+ raster_t* raster = scene_render(scene);
+ scene_destroy(scene);
+ raster_printstats(raster);
+
+ TRY_DO("Exporting to %s", raster_export_bmp(raster, filename), filename);
+
+ raster_destroy(raster);
+}
+
+/*
+ * Render one or more scenes from 3D scene files.
+ */
+int main(int argc, char* argv[])
+{
+ int out = 0;
+ int c;
+ while ((c = getopt(argc, argv, "o:")) != -1) {
+ switch (c) {
+ case 'o':
+ ++out;
+ draw_from_stdin(optarg);
+ }
+ }
+
+ if (out == 0 && argc <= 1) {
+ draw("scene.u3d");
+ }
+ else {
+ for (int i = optind; i < argc; ++i) {
+ draw(argv[i]);
+ }
+ }
+
+#if !NDEBUG
int _blocks = mem_blocks();
if (_blocks != 0) {
fprintf(stderr, " *** Leaked %d blocks of memory! ***\n", _blocks);
- return 1;
+ return EXIT_FAILURE;
}
#endif
- return 0;
+ return EXIT_SUCCESS;
}