58 #include "rock_floor.rgb_src.c"
63 #include "shuttle_controls.bam_src.c"
65 using std::istringstream;
66 using std::ostringstream;
70 static const int override_priority = 100;
72 PT(
TextFont) WindowFramework::_shuttle_controls_font =
nullptr;
80 _panda_framework(panda_framework)
82 _got_keyboard =
false;
83 _got_trackball =
false;
85 _anim_controls_enabled =
false;
87 _wireframe_enabled =
false;
88 _wireframe_filled =
false;
89 _texture_enabled =
true;
90 _two_sided_enabled =
false;
91 _one_sided_reverse_enabled =
false;
92 _lighting_enabled =
false;
93 _perpixel_enabled =
false;
94 _background_type = BT_default;
102 _panda_framework(copy._panda_framework),
103 _window(copy._window),
104 _display_region_3d(display_region)
106 _got_keyboard =
false;
107 _got_trackball =
false;
109 _anim_controls_enabled =
false;
111 _wireframe_enabled =
false;
112 _texture_enabled =
true;
113 _two_sided_enabled =
false;
114 _one_sided_reverse_enabled =
false;
115 _lighting_enabled =
false;
116 _perpixel_enabled =
false;
117 _background_type = BT_default;
122 _display_region_3d->set_camera(camera_np);
141 nassertr(_window ==
nullptr, _window);
143 static int next_window_index = 1;
144 ostringstream stream;
145 stream <<
"window" << next_window_index;
147 string name = stream.str();
152 props, flags, gsg,
nullptr);
153 if (winout !=
nullptr) {
163 _window->set_clear_depth_active(
false);
164 _window->set_clear_stencil_active(
false);
168 _display_region_3d->set_camera(camera_np);
172 if (show_frame_rate_meter) {
174 _frame_rate_meter->setup_window(_window);
176 if (show_scene_graph_analyzer_meter) {
178 _scene_graph_analyzer_meter->setup_window(_window);
189 void WindowFramework::
199 _got_keyboard =
false;
200 _got_trackball =
false;
203 _wireframe_enabled =
false;
204 _texture_enabled =
true;
205 _two_sided_enabled =
false;
206 _one_sided_reverse_enabled =
false;
207 _lighting_enabled =
false;
208 _perpixel_enabled =
false;
210 if (_frame_rate_meter !=
nullptr) {
211 _frame_rate_meter->clear_window();
212 _frame_rate_meter =
nullptr;
214 if (_scene_graph_analyzer_meter !=
nullptr) {
215 _scene_graph_analyzer_meter->clear_window();
216 _scene_graph_analyzer_meter =
nullptr;
229 return _camera_group;
241 _render.
node()->
set_attrib(ShadeModelAttrib::make(ShadeModelAttrib::M_smooth));
268 PN_stdfloat l, r, b, t;
269 _display_region_3d->get_dimensions(l, r, b, t);
270 _display_region_2d = _window->make_mono_display_region(l, r, b, t);
271 _display_region_2d->set_sort(10);
279 static const PN_stdfloat left = -1.0f;
280 static const PN_stdfloat right = 1.0f;
281 static const PN_stdfloat bottom = -1.0f;
282 static const PN_stdfloat top = 1.0f;
284 lens->set_film_offset((right + left) * 0.5, (top + bottom) * 0.5);
285 lens->set_near_far(-1000, 1000);
287 camera->set_lens(lens);
288 _display_region_2d->set_camera(camera_np);
307 if (mouse_node->
is_of_type(MouseWatcher::get_class_type())) {
311 PN_stdfloat this_aspect_ratio = aspect_ratio;
312 if (this_aspect_ratio == 0.0f) {
314 this_aspect_ratio = 1.0f;
316 if (_window->has_size()) {
317 int x_size = _window->get_sbs_left_x_size();
318 int y_size = _window->get_sbs_left_y_size();
320 this_aspect_ratio = (PN_stdfloat)x_size / (PN_stdfloat)y_size;
325 _aspect_2d.
set_scale(1.0f / this_aspect_ratio, 1.0f, 1.0f);
341 _pixel_2d.set_pos(-1, 0, 1);
343 if (_window->has_size()) {
344 int x_size = _window->get_sbs_left_x_size();
345 int y_size = _window->get_sbs_left_y_size();
347 _pixel_2d.set_sx(2.0f / (
float)x_size);
349 _pixel_2d.set_sy(1.0f);
351 _pixel_2d.set_sz(2.0f / (
float)y_size);
378 if (_window->get_side_by_side_stereo()) {
383 mw->set_display_region(_window->get_overlay_display_region());
386 _mouse = mouse.attach_new_node(mw);
397 return _button_thrower;
410 if (_window->is_of_type(GraphicsWindow::get_class_type()) &&
423 bt->set_modifier_buttons(mods);
424 _button_thrower = mouse.attach_new_node(bt);
427 _got_keyboard =
true;
435 if (_got_trackball) {
439 if (_window->is_of_type(GraphicsWindow::get_class_type()) &&
445 _trackball->set_pos(LVector3::forward() * 50.0);
446 mouse.attach_new_node(_trackball);
449 tball2cam->set_node(camera.
node());
450 _trackball->add_child(tball2cam);
453 _got_trackball =
true;
462 if (_trackball ==
nullptr) {
468 nassertv(volume !=
nullptr);
469 nassertv(volume->is_of_type(GeometricBoundingVolume::get_class_type()));
472 if (
object.has_parent()) {
473 CPT(
TransformState) net_transform =
object.get_parent().get_net_transform();
475 new_gbv->xform(net_transform->get_mat());
480 if (gbv->is_infinite()) {
481 framework_cat.warning()
482 <<
"Infinite bounding volume for " <<
object <<
"\n";
486 if (gbv->is_empty()) {
487 framework_cat.warning()
488 <<
"Empty bounding volume for " <<
object <<
"\n";
495 if (!sphere->extend_by(gbv)) {
496 framework_cat.warning()
497 <<
"Cannot determine bounding volume of " <<
object <<
"\n";
501 LPoint3 center = sphere->get_center();
502 PN_stdfloat radius = sphere->get_radius();
504 PN_stdfloat distance = 50.0f;
509 Lens *lens =
nullptr;
510 if (!_cameras.empty()) {
511 Cameras::const_iterator ci;
512 for (ci = _cameras.begin();
513 ci != _cameras.end() && lens ==
nullptr;
515 lens = (*ci)->get_lens();
519 if (lens !=
nullptr) {
520 LVecBase2 fov = lens->
get_fov();
521 distance = radius / ctan(deg_2_rad(std::min(fov[0], fov[1]) / 2.0f));
524 PN_stdfloat ideal_far_plane = distance + radius * 1.5;
528 PN_stdfloat ideal_near_plane = distance - radius;
532 _trackball->set_origin(center);
533 _trackball->set_pos(LVector3::forward() * distance);
537 _trackball->set_forward_scale(distance * 0.006);
551 for (
int i = first_arg; i < argc && argv[i] !=
nullptr; i++) {
569 for (fi = files.begin(); fi != files.end(); ++fi) {
586 framework_cat.info() <<
"Loading " << filename <<
"\n";
595 bool is_image =
false;
598 if (extension ==
"pz" || extension ==
"gz") {
605 if (!extension.empty()) {
609 if (model_type ==
nullptr) {
622 options.set_flags(options.get_flags() | LoaderOptions::LF_search);
624 options.set_flags(options.get_flags() & ~LoaderOptions::LF_search);
630 node = load_image_as_model(filename);
632 node = loader.load_sync(filename, options);
637 if (node ==
nullptr && !is_image && model_type ==
nullptr) {
642 if (node ==
nullptr) {
643 nout <<
"Unable to load " << filename <<
"\n";
657 CPT(
RenderState) state = RenderState::make_empty();
659 state = state->add_attrib(ColorAttrib::make_flat(LColor(0.5, 0.5, 1.0, 1.0)));
663 string rock_floor_string((
const char *)rock_floor, rock_floor_len);
664 istringstream rock_floor_strm(rock_floor_string);
666 if (rock_floor_pnm.
read(rock_floor_strm,
"rock-floor.rgb")) {
668 tex->set_name(
"rock-floor.rgb");
669 tex->load(rock_floor_pnm);
670 tex->set_minfilter(SamplerState::FT_linear);
671 tex->set_magfilter(SamplerState::FT_linear);
672 state = state->add_attrib(TextureAttrib::make(tex));
684 vertex.
add_data3(LVertex::rfu(0.0, 0.0, 0.0));
685 vertex.
add_data3(LVertex::rfu(1.0, 0.0, 0.0));
686 vertex.
add_data3(LVertex::rfu(0.0, 0.0, 1.0));
697 tri->add_consecutive_vertices(0, 3);
698 tri->close_primitive();
701 geom->add_primitive(tri);
730 double r = (double)rand() / (double)RAND_MAX;
744 if (_anim_controls_enabled) {
745 destroy_anim_controls();
760 create_anim_controls();
778 _anim_controls_enabled = enable;
779 if (_anim_controls_enabled) {
780 create_anim_controls();
783 destroy_anim_controls();
795 PN_stdfloat this_aspect_ratio = aspect_ratio;
797 int x_size = 0, y_size = 0;
798 if (_window->has_size()) {
799 x_size = _window->get_sbs_left_x_size();
800 y_size = _window->get_sbs_left_y_size();
803 if (this_aspect_ratio == 0.0f) {
805 this_aspect_ratio = 1.0f;
807 this_aspect_ratio = (float)x_size / (
float)y_size;
812 _aspect_2d.
set_scale(1.0f / this_aspect_ratio, 1.0f, 1.0f);
818 _pixel_2d.set_sx(2.0f / (
float)x_size);
820 _pixel_2d.set_sy(1.0f);
822 _pixel_2d.set_sz(2.0f / (
float)y_size);
826 Cameras::iterator ci;
827 for (ci = _cameras.begin(); ci != _cameras.end(); ++ci) {
828 Lens *lens = (*ci)->get_lens();
829 if (lens !=
nullptr) {
849 if (split_type == ST_default) {
853 if (_display_region_3d->get_pixel_width() >
854 _display_region_3d->get_pixel_height()) {
855 split_type = ST_horizontal;
857 split_type = ST_vertical;
861 PN_stdfloat left, right, bottom, top;
862 _display_region_3d->get_dimensions(left, right, bottom, top);
863 new_region = _display_region_3d->
get_window()->make_display_region();
865 if (split_type == ST_vertical) {
866 _display_region_3d->set_dimensions(left, right, bottom, (top + bottom) / 2.0f);
867 if (_display_region_2d !=
nullptr) {
868 _display_region_2d->set_dimensions(left, right, bottom, (top + bottom) / 2.0f);
871 new_region->
set_dimensions(left, right, (top + bottom) / 2.0f, top);
874 _display_region_3d->set_dimensions(left, (left + right) / 2.0f, bottom, top);
875 if (_display_region_2d !=
nullptr) {
876 _display_region_2d->set_dimensions(left, (left + right) / 2.0f, bottom, top);
879 new_region->
set_dimensions((left + right) / 2.0f, right, bottom, top);
883 _panda_framework->_windows.push_back(wf);
893 if (enable == _wireframe_enabled && filled == _wireframe_filled) {
899 if (!_two_sided_enabled) {
905 render.set_attrib(RenderModeAttrib::make(
906 RenderModeAttrib::M_filled_wireframe,
907 1.4f,
false, LColor(1, 1, 1, .5f)),
911 render.
set_color_scale(LColor(0.7f, 0.7f, 0.7f, 1), override_priority);
919 if (_one_sided_reverse_enabled) {
920 CPT(
RenderAttrib) attrib = CullFaceAttrib::make_reverse();
926 _wireframe_enabled = enable;
927 _wireframe_filled = filled;
935 if (enable == _texture_enabled) {
947 _texture_enabled = enable;
955 if (enable == _two_sided_enabled) {
964 if (!_wireframe_enabled) {
969 _two_sided_enabled = enable;
970 _one_sided_reverse_enabled =
false;
979 if (enable == _one_sided_reverse_enabled) {
985 if (!_wireframe_enabled) {
987 CPT(
RenderAttrib) attrib = CullFaceAttrib::make_reverse();
994 _two_sided_enabled =
false;
995 _one_sided_reverse_enabled = enable;
1003 if (enable == _lighting_enabled) {
1019 _lighting_enabled = enable;
1027 if (enable == _perpixel_enabled) {
1034 render.set_shader_auto();
1036 render.set_shader_off();
1039 _perpixel_enabled = enable;
1049 _background_type = type;
1051 if (_display_region_3d ==
nullptr) {
1055 switch (_background_type) {
1060 _display_region_3d->set_clear_color_active(
true);
1061 _display_region_3d->set_clear_depth_active(
true);
1062 _display_region_3d->set_clear_stencil_active(
true);
1063 _display_region_3d->set_clear_color(_window->get_clear_color());
1064 _display_region_3d->set_clear_depth(_window->get_clear_depth());
1065 _display_region_3d->set_clear_stencil(_window->get_clear_stencil());
1069 _display_region_3d->set_clear_color_active(
true);
1070 _display_region_3d->set_clear_depth_active(
true);
1071 _display_region_3d->set_clear_stencil_active(
true);
1072 _display_region_3d->set_clear_color(LColor(0.0f, 0.0f, 0.0f, 0.0f));
1073 _display_region_3d->set_clear_depth(1.0f);
1074 _display_region_3d->set_clear_stencil(0);
1078 _display_region_3d->set_clear_color_active(
true);
1079 _display_region_3d->set_clear_depth_active(
true);
1080 _display_region_3d->set_clear_stencil_active(
true);
1081 _display_region_3d->set_clear_color(LColor(0.3, 0.3, 0.3, 0.0f));
1082 _display_region_3d->set_clear_depth(1.0f);
1083 _display_region_3d->set_clear_stencil(0);
1087 _display_region_3d->set_clear_color_active(
true);
1088 _display_region_3d->set_clear_depth_active(
true);
1089 _display_region_3d->set_clear_stencil_active(
true);
1090 _display_region_3d->set_clear_color(LColor(1.0f, 1.0f, 1.0f, 0.0f));
1091 _display_region_3d->set_clear_depth(1.0f);
1092 _display_region_3d->set_clear_stencil(0);
1096 _display_region_3d->set_clear_color_active(
false);
1097 _display_region_3d->set_clear_depth_active(
false);
1098 _display_region_3d->set_clear_stencil_active(
false);
1108 if (_shuttle_controls_font ==
nullptr) {
1111 string shuttle_controls_string((
const char *)shuttle_controls, shuttle_controls_len);
1112 istringstream in(shuttle_controls_string);
1114 if (bam_file.
open_read(in,
"shuttle_controls font stream")) {
1115 PT(
PandaNode) node = bam_file.read_node();
1116 if (node !=
nullptr) {
1122 return _shuttle_controls_font;
1133 _cameras.push_back(camera);
1137 if (aspect_ratio != 0.0) {
1144 if (_window->has_size()) {
1145 int x_size = _window->get_sbs_left_x_size();
1146 int y_size = _window->get_sbs_left_y_size();
1148 lens->set_film_size(x_size, y_size);
1153 camera->set_lens(lens);
1161 void WindowFramework::
1171 alight->
set_color(LColor(0.2, 0.2, 0.2, 1.0f));
1173 dlight->
set_color(LColor(0.8f, 0.8f, 0.8f, 1.0f));
1187 load_image_as_model(
const Filename &filename) {
1189 if (tex ==
nullptr) {
1194 tex->set_minfilter(SamplerState::FT_linear_mipmap_linear);
1195 tex->set_magfilter(SamplerState::FT_linear);
1196 tex->set_wrap_u(SamplerState::WM_clamp);
1197 tex->set_wrap_v(SamplerState::WM_clamp);
1198 tex->set_wrap_w(SamplerState::WM_clamp);
1201 bool has_alpha =
true;
1202 LVecBase2 tex_scale = tex->get_tex_scale();
1206 int x_size = tex->get_orig_file_x_size();
1207 int y_size = tex->get_orig_file_y_size();
1210 PN_stdfloat left,right,top,bottom;
1211 static const PN_stdfloat scale = 10.0;
1212 if (x_size > y_size) {
1215 top = (scale * y_size) / x_size;
1216 bottom = -(scale * y_size) / x_size;
1217 }
else if (y_size != 0) {
1218 left = -(scale * x_size) / y_size;
1219 right = (scale * x_size) / y_size;
1223 framework_cat.warning()
1224 <<
"Texture size is 0 0: " << *tex <<
"\n";
1233 card_node->set_attrib(TextureAttrib::make(tex));
1235 card_node->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
1239 if (tex->get_texture_type() == Texture::TT_3d_texture ||
1240 tex->get_texture_type() == Texture::TT_cube_map) {
1252 vformat = GeomVertexFormat::register_format
1254 (InternalName::get_vertex(), 3,
1255 GeomEnums::NT_stdfloat, GeomEnums::C_point,
1256 InternalName::get_texcoord(), 3,
1257 GeomEnums::NT_stdfloat, GeomEnums::C_texcoord));
1261 (
"card", vformat, Geom::UH_static);
1267 vertex.
add_data3(LVertex::rfu(left, 0.02, top));
1268 vertex.
add_data3(LVertex::rfu(left, 0.02, bottom));
1269 vertex.
add_data3(LVertex::rfu(right, 0.02, top));
1270 vertex.
add_data3(LVertex::rfu(right, 0.02, bottom));
1274 texcoord.
add_data2(tex_scale[0], tex_scale[1]);
1289 texcoord.
add_data3(-1.0f, -1.0f, -1.0f);
1302 strip->add_consecutive_vertices(0, 4);
1303 strip->close_primitive();
1307 strip->add_vertex(7);
1308 strip->add_vertex(0);
1309 strip->add_vertex(4);
1310 strip->add_vertex(3);
1311 strip->close_primitive();
1313 strip->add_vertex(1);
1314 strip->add_vertex(6);
1315 strip->add_vertex(2);
1316 strip->add_vertex(5);
1317 strip->close_primitive();
1319 strip->add_vertex(5);
1320 strip->add_vertex(4);
1321 strip->add_vertex(2);
1322 strip->add_vertex(3);
1323 strip->add_vertex(1);
1324 strip->add_vertex(0);
1325 strip->add_vertex(6);
1326 strip->add_vertex(7);
1327 strip->add_vertex(5);
1328 strip->add_vertex(4);
1329 strip->close_primitive();
1333 geom->add_primitive(strip);
1335 card_node->add_geom(geom);
1344 void WindowFramework::
1345 create_anim_controls() {
1346 destroy_anim_controls();
1350 style.
set_type(PGFrameStyle::T_flat);
1352 group->set_frame(-1.0f, 1.0f, 0.0f, 0.2);
1353 group->set_frame_style(0, style);
1354 group->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
1355 group->set_active(
true);
1358 _anim_controls_group.set_pos(0.0f, 0.0f, -0.9f);
1362 label->set_align(TextNode::A_center);
1363 label->set_text(
"No animation.");
1365 tnp.set_pos(0.0f, 0.0f, 0.07f);
1372 nassertv(control !=
nullptr);
1382 label->set_align(TextNode::A_center);
1383 label->set_text(text.str());
1385 tnp.set_pos(0.0f, 0.0f, 0.07f);
1392 label->set_align(TextNode::A_left);
1395 tnp.set_pos(-0.95f, 0.0f, 0.15f);
1399 _anim_slider->setup_slider(
false, 1.9f, 0.1f, 0.005f);
1400 _anim_slider->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
1401 _anim_slider->get_thumb_button()->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
1403 _anim_slider->set_range(0.0f, (PN_stdfloat)(control->
get_num_frames() - 1));
1404 _anim_slider->set_scroll_size(0.0f);
1405 _anim_slider->set_page_size(1.0f);
1407 snp.set_pos(0.0f, 0.0f, 0.06f);
1409 _frame_number =
new TextNode(
"frame_number");
1410 _frame_number->set_text_color(0.0f, 0.0f, 0.0f, 1.0f);
1411 _frame_number->set_align(TextNode::A_center);
1412 _frame_number->set_text(format_string(control->
get_frame()));
1415 fnp.set_pos(0.0f, 0.0f, -0.01f);
1417 _play_rate_slider =
new PGSliderBar(
"play_rate_slider");
1418 _play_rate_slider->setup_slider(
false, 0.4, 0.05f, 0.005f);
1419 _play_rate_slider->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
1420 _play_rate_slider->get_thumb_button()->set_suppress_flags(MouseWatcherRegion::SF_mouse_button);
1423 pnp.set_pos(0.75f, 0.0f, 0.15f);
1427 setup_shuttle_button(
"9", 0, st_back_button);
1428 setup_shuttle_button(
";", 1, st_pause_button);
1429 setup_shuttle_button(
"4", 2, st_play_button);
1430 setup_shuttle_button(
":", 3, st_forward_button);
1432 _update_anim_controls_task =
new GenericAsyncTask(
"controls", st_update_anim_controls, (
void *)
this);
1439 void WindowFramework::
1440 destroy_anim_controls() {
1441 if (!_anim_controls_group.
is_empty()) {
1445 if (_update_anim_controls_task !=
nullptr) {
1447 _update_anim_controls_task.clear();
1455 void WindowFramework::
1456 update_anim_controls() {
1458 nassertv(control !=
nullptr);
1460 if (_anim_slider !=
nullptr) {
1461 if (_anim_slider->is_button_down()) {
1462 control->
pose((
int)(_anim_slider->get_value() + 0.5));
1464 _anim_slider->set_value((PN_stdfloat)control->
get_frame());
1468 if (_frame_number !=
nullptr) {
1469 _frame_number->set_text(format_string(control->
get_frame()));
1479 void WindowFramework::
1480 setup_shuttle_button(
const string &label,
int index,
1481 EventHandler::EventCallbackFunction *func) {
1483 button->set_frame(-0.05f, 0.05f, 0.0f, 0.07f);
1485 PN_stdfloat bevel = 0.005f;
1488 style.
set_color(0.8f, 0.8f, 0.8f, 1.0f);
1491 style.
set_type(PGFrameStyle::T_bevel_out);
1492 button->set_frame_style(PGButton::S_ready, style);
1494 style.
set_type(PGFrameStyle::T_bevel_in);
1495 button->set_frame_style(PGButton::S_depressed, style);
1497 style.
set_color(0.9f, 0.9f, 0.9f, 1.0f);
1498 style.
set_type(PGFrameStyle::T_bevel_out);
1499 button->set_frame_style(PGButton::S_rollover, style);
1503 tn->set_align(TextNode::A_center);
1505 tn->set_text(label);
1506 tn->set_text_color(0.0f, 0.0f, 0.0f, 1.0f);
1507 LMatrix4 xform = LMatrix4::scale_mat(0.07f);
1508 xform.set_row(3, LVecBase3(0.0f, 0.0f, 0.016f));
1509 tn->set_transform(xform);
1511 button->get_state_def(PGButton::S_ready).attach_new_node(tn);
1512 button->get_state_def(PGButton::S_depressed).attach_new_node(tn);
1513 button->get_state_def(PGButton::S_rollover).attach_new_node(tn);
1517 np.set_pos(0.1f * index - 0.15f, 0.0f, 0.12);
1525 void WindowFramework::
1528 nassertv(control !=
nullptr);
1535 void WindowFramework::
1538 nassertv(control !=
nullptr);
1545 void WindowFramework::
1548 nassertv(control !=
nullptr);
1549 control->
loop(
false);
1555 void WindowFramework::
1558 nassertv(control !=
nullptr);
1566 AsyncTask::DoneStatus WindowFramework::
1569 self->update_anim_controls();
1570 return AsyncTask::DS_cont;
1577 void WindowFramework::
1578 st_back_button(
const Event *,
void *data) {
1580 self->back_button();
1586 void WindowFramework::
1587 st_pause_button(
const Event *,
void *data) {
1589 self->pause_button();
1595 void WindowFramework::
1596 st_play_button(
const Event *,
void *data) {
1598 self->play_button();
1604 void WindowFramework::
1605 st_forward_button(
const Event *,
void *data) {
1607 self->forward_button();