00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "pandaFramework.h"
00016 #include "pandaSystem.h"
00017 #include "textNode.h"
00018 #include "configVariableBool.h"
00019 #include "texturePool.h"
00020 #include "multitexReducer.h"
00021 #include "sceneGraphReducer.h"
00022 #include "partGroup.h"
00023 #include "cardMaker.h"
00024 #include "bamCache.h"
00025 #include "virtualFileSystem.h"
00026 #include "panda_getopt.h"
00027 #include "preprocess_argv.h"
00028
00029
00030
00031
00032
00033 #include "checkPandaVersion.h"
00034
00035 PandaFramework framework;
00036
00037 ConfigVariableBool pview_test_hack
00038 ("pview-test-hack", false,
00039 "Enable the '0' key in pview to run whatever hacky test happens to be in "
00040 "there right now.");
00041
00042 bool
00043 output_screenshot(Filename &fn)
00044 {
00045 Thread *current_thread = Thread::get_current_thread();
00046
00047
00048 framework.do_frame(current_thread);
00049 framework.do_frame(current_thread);
00050
00051 WindowFramework *wf = framework.get_window(0);
00052 bool ok = wf->get_graphics_output()->save_screenshot(fn, "from pview");
00053 if (!ok) {
00054 cerr << "Could not generate screenshot " << fn << "\n";
00055 }
00056 return ok;
00057 }
00058
00059 void
00060 event_W(const Event *, void *) {
00061
00062
00063
00064 GraphicsPipe *pipe = (GraphicsPipe *)NULL;
00065 GraphicsStateGuardian *gsg = (GraphicsStateGuardian *)NULL;
00066
00067 if (framework.get_num_windows() > 0) {
00068 WindowFramework *old_window = framework.get_window(0);
00069 GraphicsOutput *win = old_window->get_graphics_output();
00070 pipe = win->get_pipe();
00071
00072 }
00073
00074 WindowFramework *window = framework.open_window(pipe, gsg);
00075 if (window != (WindowFramework *)NULL) {
00076 window->enable_keyboard();
00077 window->setup_trackball();
00078 framework.get_models().instance_to(window->get_render());
00079 }
00080 }
00081
00082 void
00083 event_F(const Event *, void *) {
00084
00085 framework.get_models().flatten_strong();
00086 }
00087
00088 void
00089 event_Enter(const Event *, void *) {
00090
00091
00092
00093 GraphicsPipe *pipe = (GraphicsPipe *)NULL;
00094 GraphicsStateGuardian *gsg = (GraphicsStateGuardian *)NULL;
00095
00096 WindowProperties props;
00097
00098 for (int i = 0; i < framework.get_num_windows(); ++i) {
00099 WindowFramework *old_window = framework.get_window(i);
00100 GraphicsWindow *win = old_window->get_graphics_window();
00101 if (win != (GraphicsWindow *)NULL) {
00102 pipe = win->get_pipe();
00103 gsg = win->get_gsg();
00104 props = win->get_properties();
00105 framework.close_window(old_window);
00106 break;
00107 }
00108 }
00109
00110
00111 props.set_fullscreen(!props.get_fullscreen());
00112 int flags = GraphicsPipe::BF_require_window;
00113
00114 WindowFramework *window = framework.open_window(props, flags, pipe, gsg);
00115 if (window != (WindowFramework *)NULL) {
00116 window->enable_keyboard();
00117 window->setup_trackball();
00118 framework.get_models().instance_to(window->get_render());
00119 }
00120 }
00121
00122 void
00123 event_2(const Event *event, void *) {
00124
00125
00126 EventParameter param = event->get_parameter(0);
00127 WindowFramework *wf;
00128 DCAST_INTO_V(wf, param.get_ptr());
00129
00130 WindowFramework *split = wf->split_window();
00131 if (split != (WindowFramework *)NULL) {
00132 split->enable_keyboard();
00133 split->setup_trackball();
00134 framework.get_models().instance_to(split->get_render());
00135 }
00136 }
00137
00138 void
00139 event_0(const Event *event, void *) {
00140
00141 EventParameter param = event->get_parameter(0);
00142 WindowFramework *wf;
00143 DCAST_INTO_V(wf, param.get_ptr());
00144
00145
00146 GraphicsOutput *win = wf->get_graphics_output();
00147 PT(GraphicsOutput) buffer = win->make_texture_buffer("tex", 256, 256);
00148 cerr << buffer->get_type() << "\n";
00149
00150
00151 DisplayRegion *dr = buffer->make_display_region();
00152 dr->set_camera(NodePath(wf->get_camera(0)));
00153
00154
00155
00156 buffer->set_clear_color(LColor(1, 1, 0, 0));
00157
00158
00159
00160 CardMaker cm("card");
00161 cm.set_frame(0, 1, 0, 1);
00162 NodePath card_np(cm.generate());
00163
00164 card_np.reparent_to(wf->get_render_2d());
00165 card_np.set_texture(buffer->get_texture());
00166 }
00167
00168 void
00169 usage() {
00170 cerr <<
00171 "\n"
00172 "Usage: pview [opts] model [model ...]\n"
00173 " pview -h\n\n";
00174 }
00175
00176 void
00177 help() {
00178 usage();
00179 cerr <<
00180 "pview opens a quick Panda window for viewing one or more models and/or\n"
00181 "animations.\n\n"
00182
00183 "Options:\n\n"
00184
00185 " -a\n"
00186 " Convert and play animations, if loading an external file type\n"
00187 " (like .mb) directly and if the converter supports animations.\n"
00188 " Also implicitly enables the animation controls.\n\n"
00189
00190 " -c\n"
00191 " Automatically center models within the viewing window on startup.\n"
00192 " This can also be achieved with the 'c' hotkey at runtime.\n\n"
00193
00194 " -l\n"
00195 " Open the window before loading any models with the text \"Loading\"\n"
00196 " displayed in the window. The default is not to open the window\n"
00197 " until all models are loaded.\n\n"
00198
00199 " -i\n"
00200 " Ignore bundle/group names. Normally, the <group> name must match\n"
00201 " the <bundle> name, or the animation will not be used.\n\n"
00202
00203 " -s filename\n"
00204 " After displaying the models, immediately take a screenshot and\n"
00205 " exit.\n\n"
00206
00207 " -D\n"
00208 " Delete the model files after loading them (presumably this option\n"
00209 " will only be used when loading a temporary model file).\n\n"
00210
00211 " -V\n"
00212 " Report the current version of Panda, and exit.\n\n"
00213
00214 " -h\n"
00215 " Display this help text.\n\n";
00216 }
00217
00218 void
00219 report_version() {
00220 nout << "\n";
00221 PandaSystem *ps = PandaSystem::get_global_ptr();
00222 ps->write(nout);
00223 nout << "\n";
00224 }
00225
00226 int
00227 main(int argc, char **argv) {
00228 preprocess_argv(argc, argv);
00229 framework.open_framework(argc, argv);
00230 framework.set_window_title("Panda Viewer");
00231
00232 bool anim_controls = false;
00233 bool auto_center = false;
00234 bool show_loading = false;
00235 bool auto_screenshot = false;
00236 int hierarchy_match_flags = PartGroup::HMF_ok_part_extra |
00237 PartGroup::HMF_ok_anim_extra;
00238 Filename screenshotfn;
00239 bool delete_models = false;
00240
00241 extern char *optarg;
00242 extern int optind;
00243 static const char *optflags = "acls:DVhi";
00244 int flag = getopt(argc, argv, optflags);
00245
00246 while (flag != EOF) {
00247 switch (flag) {
00248 case 'a':
00249 anim_controls = true;
00250 PandaFramework::_loader_options.set_flags(PandaFramework::_loader_options.get_flags() | LoaderOptions::LF_convert_anim);
00251 break;
00252
00253 case 'c':
00254 auto_center = true;
00255 break;
00256
00257 case 'l':
00258 show_loading = true;
00259 break;
00260
00261 case 'i':
00262 hierarchy_match_flags |= PartGroup::HMF_ok_wrong_root_name;
00263 break;
00264
00265 case 's':
00266 auto_screenshot = true;
00267 screenshotfn = optarg;
00268 break;
00269
00270 case 'D':
00271 delete_models = true;
00272 break;
00273
00274 case 'V':
00275 report_version();
00276 return 1;
00277
00278 case 'h':
00279 help();
00280 return 1;
00281
00282 case '?':
00283 usage();
00284 return 1;
00285
00286 default:
00287 cerr << "Unhandled switch: " << flag << endl;
00288 break;
00289 }
00290 flag = getopt(argc, argv, optflags);
00291 }
00292 argc -= (optind - 1);
00293 argv += (optind - 1);
00294
00295 WindowFramework *window = framework.open_window();
00296 if (window != (WindowFramework *)NULL) {
00297
00298
00299 NodePath loading_np;
00300
00301 if (show_loading) {
00302
00303 NodePath aspect_2d = window->get_aspect_2d();
00304 PT(TextNode) loading = new TextNode("loading");
00305 loading_np = aspect_2d.attach_new_node(loading);
00306 loading_np.set_scale(0.125f);
00307 loading->set_text_color(1.0f, 1.0f, 1.0f, 1.0f);
00308 loading->set_shadow_color(0.0f, 0.0f, 0.0f, 1.0f);
00309 loading->set_shadow(0.04, 0.04);
00310 loading->set_align(TextNode::A_center);
00311 loading->set_text("Loading...");
00312
00313
00314
00315 Thread *current_thread = Thread::get_current_thread();
00316 framework.do_frame(current_thread);
00317 framework.do_frame(current_thread);
00318 }
00319
00320 window->enable_keyboard();
00321 window->setup_trackball();
00322 framework.get_models().instance_to(window->get_render());
00323 if (argc < 2) {
00324
00325 window->load_default_model(framework.get_models());
00326 } else {
00327 window->load_models(framework.get_models(), argc, argv);
00328
00329 if (delete_models) {
00330 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00331 for (int i = 1; i < argc && argv[i] != (char *)NULL; i++) {
00332 Filename model = Filename::from_os_specific(argv[i]);
00333 if (vfs->exists(model)) {
00334 nout << "Deleting " << model << "\n";
00335 vfs->delete_file(model);
00336 }
00337 }
00338 }
00339 }
00340 window->loop_animations(hierarchy_match_flags);
00341
00342
00343 framework.get_models().prepare_scene(window->get_graphics_output()->get_gsg());
00344
00345 loading_np.remove_node();
00346
00347 if (auto_center) {
00348 window->center_trackball(framework.get_models());
00349 }
00350
00351 if (auto_screenshot) {
00352 return(output_screenshot(screenshotfn) ? 0:1);
00353 }
00354
00355 if (anim_controls) {
00356 window->set_anim_controls(true);
00357 }
00358
00359 framework.enable_default_keys();
00360 framework.define_key("shift-w", "open a new window", event_W, NULL);
00361 framework.define_key("shift-f", "flatten hierarchy", event_F, NULL);
00362 framework.define_key("alt-enter", "toggle between window/fullscreen", event_Enter, NULL);
00363 framework.define_key("2", "split the window", event_2, NULL);
00364 if (pview_test_hack) {
00365 framework.define_key("0", "run quick hacky test", event_0, NULL);
00366 }
00367 framework.main_loop();
00368 framework.report_frame_rate(nout);
00369 }
00370
00371 framework.close_framework();
00372 return (0);
00373 }