00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "lux.h"
00025 #include "api.h"
00026 #include "scene.h"
00027 #include "camera.h"
00028 #include "film.h"
00029 #include "error.h"
00030 #include "luxgui.h"
00031 #include "renderwindow.h"
00032 #include "icons.h"
00033
00034 #include <iostream>
00035 #include <fstream>
00036 #include <sstream>
00037 #include <string>
00038 #include <exception>
00039 #include <boost/program_options.hpp>
00040 #include <boost/thread.hpp>
00041 #include <boost/thread/xtime.hpp>
00042 #include <boost/date_time/posix_time/posix_time.hpp>
00043 #include <boost/filesystem/path.hpp>
00044 #include <boost/filesystem/operations.hpp>
00045 #include <boost/bind.hpp>
00046 #include <zlib.h>
00047
00048
00049
00050 #if defined(WIN32) && !defined(__CYGWIN__)
00051 #include "direct.h"
00052 #include "resource.h"
00053 #define chdir _chdir
00054 #endif
00055
00056
00057 using namespace lux;
00058 namespace po = boost::program_options;
00059 static int threads;
00060 bool parseError;
00061 bool renderingDone;
00062 void AddThread();
00063
00064
00065 Fl_Menu_Item menu_bar[] = {
00066 { "&File", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 11, 0 },
00067 {" &Open scenefile...", FL_CTRL + 'o', (Fl_Callback*) open_cb, 0, 128, FL_NORMAL_LABEL, 0, 11, 0 },
00068 {" &Exit", FL_CTRL + 'q', (Fl_Callback *) exit_cb, 0, 0, FL_NORMAL_LABEL, 0, 11, 0 },
00069 { 0 },
00070 { "&Help", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 11, 0 },
00071 {" &About...", 0, (Fl_Callback *) about_cb, 0, 0, FL_NORMAL_LABEL, 0, 11, 0 },
00072 { 0 },
00073 { 0 }
00074 };
00075
00076 Fl_Menu_Item menu_threads[] = {
00077 { "+ Add Thread", 0, (Fl_Callback *) addthread_cb, 0, 0, FL_NORMAL_LABEL, 0, 11, 0 },
00078 { "- Remove Thread", 0, (Fl_Callback *) removethread_cb, 0, 0, FL_NORMAL_LABEL, 0, 11, 0 },
00079 { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
00080 };
00081
00082 void exit_cb(Fl_Widget *, void *) {
00083 if (fb_update_thread)
00084 fb_update_thread->join();
00085
00086
00087 if(gui_current_scenefile[0]!=0) {
00088 luxExit();
00089
00090 if (engine_thread)
00091 engine_thread->join();
00092
00093 luxError(LUX_NOERROR, LUX_INFO, "Freeing resources.");
00094 luxCleanup();
00095 }
00096
00097 exit(0);
00098 }
00099
00100
00101 Fl_Double_Window * make_MainWindow(int width, int height,
00102 Fl_RGB_Image * rgb_buffer, bool opengl_enabled) {
00103 Fl_Color col_back = fl_rgb_color(212, 208, 200);
00104 Fl_Color col_activeback = fl_rgb_color(255, 170, 20);
00105 Fl_Color col_renderback = fl_rgb_color(128, 128, 128);
00106
00107 Fl_Double_Window * w;
00108 {
00109 Fl_Double_Window * o = new Fl_Double_Window (width, height, "LuxRender");
00110 w = o;
00111 o->callback(exit_cb);
00112 o->color(col_back);
00113 {
00114 Fl_Group * o = new Fl_Group (0, 20, width, height - 20);
00115 o->color(col_back);
00116 o->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE);
00117 {
00118 Fl_Tabs * o = new Fl_Tabs (0, 20, width, height - 20);
00119 o->labelsize(12);
00120 {
00121 RenderWindow* o = new RenderWindow(0, 40, width, height-40, col_back, col_renderback, "Film", opengl_enabled);
00122 renderview = o;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 o->end();
00135 }
00136 {
00137 Fl_Group * o = new Fl_Group (90, 20, width - 90, 20, "toolbar");
00138 o->box(FL_FLAT_BOX);
00139 o->color(col_back);
00140 o->labeltype(FL_NO_LABEL);
00141 {
00142 Fl_Group * o = new Fl_Group (310, 20, 260, 20, "statistics");
00143 o->box(FL_FLAT_BOX);
00144 o->color(col_back);
00145 o->deactivate();
00146 info_statistics_group = o;
00147 o->labeltype(FL_NO_LABEL);
00148 {
00149 Fl_Box * o = new Fl_Box (310, 20, 260, 20);
00150 o->box(FL_THIN_UP_BOX);
00151 o->image(image_clock);
00152 o->deimage(image_clock1);
00153 o->labelsize(11);
00154 o->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00155 }
00156 {
00157 Fl_Group * o = new Fl_Group (330, 20, 240, 20, "");
00158 o->labelsize(11);
00159 o->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE);
00160 info_statistics = o;
00161 o->end();
00162 }
00163 o->end();
00164 }
00165 {
00166 Fl_Group * o = new Fl_Group (90, 20, 85, 20, "geometry");
00167 o->box(FL_FLAT_BOX);
00168 o->color(col_back);
00169 o->labeltype(FL_NO_LABEL);
00170 o->deactivate();
00171 {
00172 Fl_Box * o = new Fl_Box (90, 20, 85, 20);
00173 o->box(FL_THIN_UP_BOX);
00174 o->image(image_geom);
00175 o->deimage(image_geom1);
00176 o->labelsize(11);
00177 o->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00178 }
00179 {
00180 Fl_Group * o = new Fl_Group (108, 20, 65, 20, "(0)");
00181 o->labelsize(11);
00182 o->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00183 o->end();
00184 }
00185 o->end();
00186 }
00187 {
00188 Fl_Group * o = new Fl_Group (570, 20, 230, 20, "render");
00189 o->box(FL_FLAT_BOX);
00190 o->color(col_back);
00191 o->labeltype(FL_NO_LABEL);
00192 o->deactivate();
00193 info_render_group = o;
00194 o->align(FL_ALIGN_CENTER);
00195 {
00196 Fl_Menu_Button * o = new Fl_Menu_Button (570, 20, 170, 20);
00197 o->box(FL_THIN_UP_BOX);
00198 o->down_box(FL_THIN_DOWN_BOX);
00199 o->color(col_activeback);
00200 o->image(image_render);
00201 o->deimage(image_render1);
00202 o->labelsize(11);
00203 o->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00204 o->menu(menu_threads);
00205 }
00206 {
00207 Fl_Group * o = new Fl_Group (590, 20, 65, 20, "(0)");
00208 o->labelsize(11);
00209 o->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00210 info_render = o;
00211 o->end();
00212 info_render = o;
00213 }
00214 o->end();
00215 }
00216 {
00217 Fl_Group * o = new Fl_Group (175, 20, 135, 20, "tonemap");
00218 o->box(FL_FLAT_BOX);
00219 o->color(col_back);
00220 info_tonemap_group = o;
00221 o->deactivate();
00222 o->labeltype(FL_NO_LABEL);
00223 {
00224 Fl_Menu_Button * o = new Fl_Menu_Button (175, 20, 135, 20);
00225 o->box(FL_THIN_UP_BOX);
00226 o->down_box(FL_THIN_DOWN_BOX);
00227 o->color(col_activeback);
00228 o->image(image_tonemap);
00229 o->deimage(image_tonemap1);
00230 o->labelsize(11);
00231 o->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00232 }
00233 {
00234 Fl_Group * o = new Fl_Group (195, 20, 65, 20, "(0)");
00235 o->labelsize(11);
00236 o->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
00237 info_tonemap = o;
00238 o->end();
00239 }
00240 o->end();
00241 }
00242 {
00243 Fl_Group * o = new Fl_Group (width - 60, 20, 69, 20, "buttons");
00244 o->box(FL_FLAT_BOX);
00245 o->color(col_back);
00246 o->labeltype(FL_NO_LABEL);
00247 o->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE);
00248 {
00249 Fl_Button * o = new Fl_Button (width - 20, 20, 20, 20);
00250 o->box(FL_THIN_UP_BOX);
00251 o->down_box(FL_THIN_DOWN_BOX);
00252 o->image(image_stop);
00253 o->deimage(image_stop1);
00254 o->callback((Fl_Callback *) stop_cb);
00255 o->deactivate();
00256 o->color(col_back);
00257 button_pause = o;
00258 }
00259 {
00260 Fl_Button * o = new Fl_Button (width - 40, 20, 20, 20);
00261 o->box(FL_THIN_UP_BOX);
00262 o->down_box(FL_THIN_DOWN_BOX);
00263 o->image(image_rewind);
00264 o->deimage(image_rewind1);
00265 o->callback((Fl_Callback *) restart_cb);
00266 o->deactivate();
00267 o->color(col_back);
00268 button_restart = o;
00269 }
00270 {
00271 Fl_Button * o = new Fl_Button (width - 60, 20, 20, 20);
00272 o->box(FL_THIN_UP_BOX);
00273 o->down_box(FL_THIN_DOWN_BOX);
00274 o->image(image_play);
00275 o->deimage(image_play1);
00276 o->callback((Fl_Callback *) start_cb);
00277 o->deactivate();
00278 o->color(col_back);
00279 button_play = o;
00280 }
00281 o->end();
00282 }
00283 o->end();
00284 }
00285 o->end();
00286 Fl_Group::current ()->resizable(o);
00287 }
00288 {
00289 Fl_Menu_Bar * o = new Fl_Menu_Bar (0, 0, 800, 20);
00290 o->box(FL_THIN_UP_BOX);
00291 o->color(col_back);
00292 o->menu(menu_bar);
00293
00294 }
00295 o->end();
00296 }
00297 return w;
00298 }
00299
00300
00301
00302 void open_cb(Fl_Widget *, void *) {
00303 if (status_render == STATUS_RENDER_NONE) {
00304
00305 Fl_File_Chooser chooser(".",
00306 "LuxRender Scenes (*.lxs)",
00307 Fl_File_Chooser::SINGLE,
00308 "Open Scenefile...");
00309 chooser.preview(0);
00310 chooser.show();
00311
00312
00313 while (chooser.shown()) {
00314 Fl::wait();
00315 }
00316
00317
00318 if (chooser.value() == NULL)
00319 return;
00320
00321
00322 strcpy(gui_current_scenefile, chooser.value());
00323
00324
00325 printf("GUI: Changing working directory to: %s\n", chooser.value());
00326 chdir(chooser.directory());
00327
00328
00329 static char wintxt[512];
00330 sprintf(wintxt, "LuxRender: %s", chooser.value());
00331 window->label(wintxt);
00332
00333
00334 RenderScenefile();
00335 }
00336 }
00337
00338
00339 #include "splash.h"
00340 void about_cb(Fl_Widget *, void *) {
00341 unsigned int about_window_w = 500;
00342 unsigned int about_window_h = 270;
00343 Fl_Window *about_window = new Fl_Double_Window(window->x()+window->w()/2-about_window_w/2,window->y()+window->h()/2-about_window_h/2,about_window_w, about_window_h, "About: LuxRender");
00344 { Fl_Button* o = new Fl_Button(0, 0, 500, 270);
00345 o->image(image_splash);
00346 o->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
00347 }
00348 about_window->end();
00349 about_window->set_modal();
00350 about_window->show();
00351
00352 while(1){
00353 Fl_Widget *o = Fl::readqueue();
00354 if (!o) {
00355 Fl::wait();
00356 Fl::wait(0.1);
00357 }
00358 else break;
00359 }
00360
00361 about_window->hide();
00362 delete about_window;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 void addthread_cb(Fl_Widget *, void *) {
00493 AddThread();
00494 }
00495
00496 ;
00497 void removethread_cb(Fl_Widget *, void *) {
00498 RemoveThread();
00499 }
00500
00501 ;
00502 void start_cb(Fl_Widget *, void *) {
00503 RenderStart();
00504 }
00505
00506 void stop_cb(Fl_Widget *, void *) {
00507 RenderPause();
00508 }
00509
00510 void restart_cb(Fl_Widget *, void *) {
00511 }
00512
00513 void Engine_Thread() {
00514
00515 std::stringstream ss;
00516 ss << "GUI: Parsing scenefile '" << gui_current_scenefile << "'";
00517 luxError(LUX_NOERROR, LUX_INFO, ss.str ().c_str());
00518 ParseFile(gui_current_scenefile);
00519 if (luxStatistics("sceneIsReady") == false)
00520 parseError = true;
00521
00522
00523
00524 luxWait();
00525 renderingDone = true;
00526 luxError(LUX_NOERROR, LUX_INFO, "Rendering done.");
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 }
00539
00540 void merge_FrameBuffer_Thread(bool *threadDone){
00541 luxUpdateFramebuffer();
00542 *threadDone = true;
00543 }
00544
00545
00546 void merge_FrameBuffer(void *) {
00547 if (fb_update_thread)
00548 return;
00549
00550 static char ittxt[256];
00551 sprintf(ittxt, "(1) Tonemapping...");
00552 static const char * txttp = ittxt;
00553 luxError(LUX_NOERROR, LUX_INFO, "GUI: Updating framebuffer...");
00554 info_tonemap_group->activate();
00555 info_tonemap->label(txttp);
00556 Fl::redraw();
00557
00558 bool threadDone = false;
00559 fb_update_thread = new boost::thread(boost::bind(&merge_FrameBuffer_Thread, &threadDone));
00560 while(!threadDone) Fl::wait(0.5);
00561 fb_update_thread->join();
00562 delete fb_update_thread;
00563 fb_update_thread = NULL;
00564 renderview->update_image();
00565
00566 luxError(LUX_NOERROR, LUX_INFO, "GUI: Framebuffer update done.");
00567 sprintf(ittxt, "(1) Idle.");
00568 info_tonemap->label(txttp);
00569 Fl::redraw();
00570
00571
00572
00573 if (!renderingDone)
00574 Fl::repeat_timeout(framebufferUpdate, merge_FrameBuffer);
00575 }
00576
00577 int RenderScenefile() {
00578
00579 unsigned int parsing_window_w = 300;
00580 unsigned int parsing_window_h = 40;
00581 Fl_Window *parsing_window = new Fl_Window(window->x()+window->w()/2-parsing_window_w/2,window->y()+window->h()/2-parsing_window_h/2,parsing_window_w, parsing_window_h, "Processing...");
00582 { Fl_Box *o = new Fl_Box(10, 10, parsing_window_w-20, parsing_window_h-20, "Parsing scene file, please wait...");
00583 o->labelsize(16);
00584 }
00585 parsing_window->end();
00586 parsing_window->set_modal();
00587 parsing_window->show();
00588
00589 fflush(stdout);
00590 parseError = false;
00591 renderingDone = false;
00592
00593 engine_thread = new boost::thread (&Engine_Thread);
00594
00595
00596 while (!luxStatistics("sceneIsReady") && !parseError) {
00597
00598
00599
00600
00601
00602 Fl::wait(0.5);
00603 }
00604
00605 if(parseError) {
00606 std::stringstream ss;
00607 ss<<"Skipping invalid scenefile '"<<gui_current_scenefile<<"'";
00608 luxError(LUX_BADFILE, LUX_SEVERE, ss.str ().c_str());
00609
00610
00611 parsing_window->hide();
00612 delete parsing_window;
00613
00614 message_window("Error","Invalid scenefile!");
00615
00616
00617
00618
00619 exit(1);
00620 }
00621
00622
00623 int threadsToAdd = threads;
00624 while (--threadsToAdd) {
00625 AddThread();
00626 }
00627
00628
00629 parsing_window->hide();
00630 delete parsing_window;
00631
00632 return 0;
00633 }
00634
00635 void setInfo_render() {
00636 static char irtxt[256];
00637
00638 if (status_render == STATUS_RENDER_RENDER) {
00639 sprintf(irtxt, "(%i) Rendering...", gui_nrthreads);
00640 info_render_group->activate();
00641 info_tonemap_group->activate();
00642 button_play->value(1);
00643 button_play->deactivate();
00644 button_pause->activate();
00645 info_statistics_group->activate();
00646 } else if (status_render == STATUS_RENDER_IDLE) {
00647 sprintf(irtxt, "(%i) Idle.", gui_nrthreads);
00648 info_statistics_group->activate();
00649 info_render_group->activate();
00650 button_play->activate();
00651 button_play->value(0);
00652 button_pause->deactivate();
00653 } else {
00654 info_render_group->deactivate();
00655 info_tonemap_group->deactivate();
00656 button_play->deactivate();
00657 button_pause->deactivate();
00658 button_play->value(0);
00659 button_pause->value(0);
00660 info_statistics_group->deactivate();
00661 sprintf(irtxt, "(0)");
00662 }
00663
00664 static const char * txtp = irtxt;
00665 info_render->label(txtp);
00666 Fl::redraw();
00667 }
00668
00669 void RenderStart() {
00670 luxStart();
00671 status_render = STATUS_RENDER_RENDER;
00672 setInfo_render();
00673 }
00674
00675 void RenderPause() {
00676 luxPause();
00677 status_render = STATUS_RENDER_IDLE;
00678 setInfo_render();
00679 }
00680
00681 void AddThread() {
00682 gui_nrthreads++;
00683 setInfo_render();
00684 if (luxAddThread() == 1) {
00685 gui_nrthreads--;
00686 setInfo_render();
00687 }
00688 }
00689 void RemoveThread() {
00690 if (gui_nrthreads > 1) {
00691 gui_nrthreads--;
00692 setInfo_render();
00693 luxRemoveThread();
00694 }
00695 }
00696
00697 void bindFrameBuffer() {
00698 if (GuiSceneReady) {
00699
00700 u_int xRes = (u_int)luxStatistics("filmXres");
00701 u_int yRes = (u_int)luxStatistics("filmYres");
00702 framebufferUpdate = (float)luxStatistics("displayInterval");
00703
00704
00705 uchar * fbP = luxFramebuffer();
00706 rgb_image = new Fl_RGB_Image (fbP, xRes, yRes, 3, 0);
00707
00708
00709 rgb_image->uncache();
00710 renderview->set_image(rgb_image);
00711 Fl::redraw();
00712
00713 Fl::add_timeout(framebufferUpdate, merge_FrameBuffer);
00714 }
00715 }
00716
00717 void update_Statistics(void *) {
00718 int samplessec = Floor2Int(luxStatistics("samplesSec"));
00719 int samplesTotSec = Floor2Int(luxStatistics("samplesTotSec"));
00720 int secelapsed = Floor2Int(luxStatistics("secElapsed"));
00721 double samplespx = luxStatistics("samplesPx");
00722 int efficiency = Floor2Int(luxStatistics("efficiency"));
00723
00724 char t[] = "00:00";
00725 int secs = (secelapsed) % 60;
00726 int mins = (secelapsed / 60) % 60;
00727 int hours = (secelapsed / 3600);
00728 t[4] = (secs % 10) + '0';
00729 t[3] = ((secs / 10) % 10) + '0';
00730 t[1] = (mins % 10) + '0';
00731 t[0] = ((mins / 10) % 10) + '0';
00732
00733 static char istxt[256];
00734 sprintf(istxt, "%i:%s - %i S/s - %i TotS/s - %.2f S/px - %i%% eff", hours, t,
00735 samplessec, samplesTotSec,
00736 samplespx, efficiency);
00737 static const char * txts = istxt;
00738 info_statistics->label(txts);
00739 Fl::redraw();
00740 Fl::repeat_timeout(2.0, update_Statistics);
00741 }
00742
00743 void check_SceneReady(void *) {
00744 if (luxStatistics("sceneIsReady")) {
00745 GuiSceneReady = true;
00746
00747
00748 status_render = STATUS_RENDER_RENDER;
00749 setInfo_render();
00750 Fl::add_timeout(2.0, update_Statistics);
00751 Fl::redraw();
00752
00753 #ifndef __APPLE__
00754 Fl::lock();
00755 #endif
00756
00757
00758
00759
00760 bindFrameBuffer();
00761 } else
00762 Fl::repeat_timeout(0.25, check_SceneReady);
00763 }
00764
00765 void message_window(const char *label, const char *msg){
00766
00767
00768 unsigned int message_window_w = 300;
00769 unsigned int message_window_h = 100;
00770 Fl_Window *message_window = new Fl_Window(window->x()+window->w()/2-message_window_w/2,window->y()+window->h()/2-message_window_h/2,message_window_w, message_window_h, label);
00771 if(msg!=NULL){
00772 Fl_Box *o = new Fl_Box(10, 10, message_window_w-20, message_window_h-10-45, msg);
00773 o->labelsize(16);
00774 }
00775 { Fl_Return_Button *o = new Fl_Return_Button(message_window_w/2-100/2, message_window_h-35, 100, 25, "OK");
00776 o->take_focus();
00777 }
00778 message_window->end();
00779 message_window->set_modal();
00780 message_window->show();
00781 while(Fl::readqueue());
00782 while(1){
00783 Fl_Widget *o = Fl::readqueue();
00784 if (!o) Fl::wait();
00785 else break;
00786 }
00787 message_window->hide();
00788 delete message_window;
00789 }
00790
00791
00792 int main(int ac, char *av[]) {
00793 #ifdef __APPLE__
00794
00795
00796
00797 for(int i = 0; i < ac; ++i)
00798 if (std::string(av[i]).compare(0, 5, "-psn_") == 0)
00799 av[i][0] = '\0';
00800 #endif
00801
00802 bool useServer = false;
00803 GuiSceneReady = false;
00804 framebufferUpdate = 10.0f;
00805 strcpy(gui_current_scenefile, "");
00806 status_render = STATUS_RENDER_NONE;
00807 bool opengl_enabled = true;
00808 engine_thread = NULL;
00809 fb_update_thread = NULL;
00810
00811
00812 luxInit();
00813
00814 try
00815 {
00816
00817
00818 po::options_description generic ("Generic options");
00819 generic.add_options ()
00820 ("version,v", "Print version string")
00821 ("help", "Produce help message")
00822 ("debug,d", "Enable debug mode")
00823 ;
00824
00825
00826
00827
00828 po::options_description config ("Configuration");
00829 config.add_options ()
00830 ("threads,t", po::value < int >(), "Specify the number of threads that Lux will run in parallel.")
00831 ("useserver,u", po::value< std::vector<std::string> >()->composing(), "Specify the adress of a rendering server to use.")
00832 ("serverinterval,i", po::value < int >(), "Specify the number of seconds between requests to rendering servers.")
00833 ;
00834
00835
00836
00837 po::options_description hidden ("Hidden options");
00838 hidden.add_options ()
00839 ("input-file", po::value < vector < string > >(), "input file");
00840
00841 #ifdef LUX_USE_OPENGL
00842 generic.add_options ()
00843 ("noopengl", "Disable OpenGL to display the image");
00844 #else
00845 hidden.add_options ()
00846 ("noopengl", "Disable OpenGL to display the image");
00847 #endif // LUX_USE_OPENGL
00848
00849 po::options_description cmdline_options;
00850 cmdline_options.add (generic).add (config).add (hidden);
00851
00852 po::options_description config_file_options;
00853 config_file_options.add (config).add (hidden);
00854
00855 po::options_description visible ("Allowed options");
00856 visible.add (generic).add (config);
00857
00858 po::positional_options_description p;
00859
00860 p.add ("input-file", -1);
00861
00862 po::variables_map vm;
00863 store (po::command_line_parser (ac, av).
00864 options (cmdline_options).positional (p).run (), vm);
00865
00866 std::ifstream ifs ("luxrender.cfg");
00867 store (parse_config_file (ifs, config_file_options), vm);
00868 notify (vm);
00869
00870 if (vm.count ("help"))
00871 {
00872 std::cout << "Usage: luxrender [options] file...\n";
00873 std::cout << visible << "\n";
00874 return 0;
00875 }
00876
00877 if (vm.count ("version"))
00878 {
00879 std::
00880 cout << "Lux version " << LUX_VERSION_STRING << " of " << __DATE__ <<
00881 " at " << __TIME__ << std::endl;
00882 return 0;
00883 }
00884
00885 if (vm.count ("threads"))
00886 {
00887 threads = vm["threads"].as < int >();
00888 }
00889 else
00890 {
00891 threads = 1;;
00892 }
00893
00894 if (vm.count("debug")) {
00895 luxError(LUX_NOERROR, LUX_INFO, "Debug mode enabled");
00896 luxEnableDebugMode();
00897 }
00898
00899 int serverInterval;
00900 if (vm.count("serverinterval")) {
00901 serverInterval = vm["serverinterval"].as<int>();
00902 luxSetNetworkServerUpdateInterval(serverInterval);
00903 } else
00904 serverInterval = luxGetNetworkServerUpdateInterval();
00905
00906 if (vm.count("useserver")) {
00907 std::stringstream ss;
00908
00909 std::vector<std::string> names = vm["useserver"].as<std::vector<std::string> >();
00910
00911 for (std::vector<std::string>::iterator i = names.begin(); i < names.end(); i++) {
00912 ss.str("");
00913 ss << "Connecting to server '" << (*i) << "'";
00914 luxError(LUX_NOERROR, LUX_INFO, ss.str().c_str());
00915
00916
00917 luxAddServer((*i).c_str());
00918 }
00919
00920 useServer = true;
00921
00922 ss.str("");
00923 ss << "Server requests interval: " << serverInterval << " secs";
00924 luxError(LUX_NOERROR, LUX_INFO, ss.str().c_str());
00925 }
00926
00927 if (vm.count ("noopengl"))
00928 {
00929 opengl_enabled = false;
00930 }
00931 else
00932 {
00933 #ifdef LUX_USE_OPENGL
00934 opengl_enabled = true;
00935 #else
00936 opengl_enabled = false;
00937 luxError(LUX_NOERROR, LUX_INFO, "GUI: OpenGL support was not compiled in - will not be used.");
00938 #endif // LUX_USE_OPENGL
00939 }
00940
00941 if (vm.count ("input-file"))
00942 {
00943 const std::vector < std::string > &v = vm["input-file"].as < vector < string > >();
00944 if (v.size() > 1)
00945 {
00946 luxError (LUX_SYSTEM, LUX_SEVERE,
00947 "More than one file passed on command line : rendering the first one.");
00948 }
00949
00950
00951 boost::filesystem::path fullPath (boost::filesystem::initial_path ());
00952 fullPath =
00953 boost::filesystem::system_complete (boost::filesystem::
00954 path (v[0], boost::filesystem::native));
00955 if(!boost::filesystem::exists(fullPath))
00956 {
00957 std::stringstream ss;
00958 ss<<"Unable to open scenefile '"<<fullPath.string()<<"'";
00959 luxError(LUX_NOFILE, LUX_SEVERE, ss.str ().c_str());
00960 }
00961 else
00962 {
00963 strcpy (gui_current_scenefile, fullPath.leaf ().c_str ());
00964 chdir (fullPath.branch_path ().string ().c_str ());
00965 }
00966 }
00967
00968
00969 int width = 800;
00970 int height = 600;
00971 window = make_MainWindow(width, height, rgb_image, opengl_enabled);
00972 setInfo_render();
00973 #if defined(WIN32) && !defined(__CYGWIN__)
00974
00975 window->icon((char *)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON1)));
00976 #elif !defined(__APPLE__) && !defined(__CYGWIN__)
00977
00978 fl_open_display();
00979 Pixmap icon_pixmap=XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display), (char*)lux_icon_bitmap, 32, 32);
00980 window->icon((char *)icon_pixmap);
00981 #endif
00982
00983 Fl::foreground(0,0,0);
00984 Fl::background(200,200,200);
00985 Fl::background2(255,255,255);
00986
00987 window->show(1,av);
00988 #if !defined(WIN32) && !defined(__APPLE__)
00989
00990 XWMHints *hints = XGetWMHints(fl_display, fl_xid(window));
00991 hints->icon_mask = XCreateBitmapFromData(fl_display, fl_xid(window), (char*)lux_icon_mask, 32, 32);
00992 hints->flags |= IconMaskHint;
00993 XSetWMHints(fl_display, fl_xid(window), hints);
00994 XFree(hints);
00995 #endif
00996
00997 if(gui_current_scenefile[0]!=0)
00998 RenderScenefile();
00999
01000
01001 Fl::add_timeout(0.25, check_SceneReady);
01002
01003
01004 Fl::run ();
01005 }
01006 catch (std::exception & e)
01007 {
01008 std::cout << e.what () << std::endl; return 1;
01009 }
01010
01011
01012 return 0;
01013 }