15 #include "pgFrameStyle.h"
17 #include "pandaNode.h"
18 #include "transparencyAttrib.h"
19 #include "pointerTo.h"
21 #include "textureAttrib.h"
22 #include "renderState.h"
23 #include "shadeModelAttrib.h"
24 #include "colorAttrib.h"
26 #include "geomTristrips.h"
27 #include "geomVertexWriter.h"
36 operator << (ostream &out, PGFrameStyle::Type type) {
38 case PGFrameStyle::T_none:
41 case PGFrameStyle::T_flat:
44 case PGFrameStyle::T_bevel_out:
45 return out <<
"bevel_out";
47 case PGFrameStyle::T_bevel_in:
48 return out <<
"bevel_in";
50 case PGFrameStyle::T_groove:
51 return out <<
"groove";
53 case PGFrameStyle::T_ridge:
54 return out <<
"ridge";
56 case PGFrameStyle::T_texture_border:
57 return out <<
"texture_border";
60 return out <<
"**unknown(" << (int)type <<
")**";
73 LPoint2 center((frame[0] + frame[1]) / 2.0f,
74 (frame[2] + frame[3]) / 2.0f);
76 ((frame[0] - center[0]) * _visible_scale[0] + center[0],
77 (frame[1] - center[0]) * _visible_scale[0] + center[0],
78 (frame[2] - center[1]) * _visible_scale[1] + center[1],
79 (frame[3] - center[1]) * _visible_scale[1] + center[1]);
90 return LVecBase4(scaled_frame[0] + _width[0],
91 scaled_frame[1] - _width[0],
92 scaled_frame[2] + _width[1],
93 scaled_frame[3] - _width[1]);
102 output(ostream &out)
const {
103 out << _type <<
" color = " << _color <<
" width = " << _width;
104 if (_visible_scale !=
LVecBase2(1.0f, 1.0f)) {
127 PN_stdfloat x_scale = x.
length();
130 PN_stdfloat z_scale = z.
length();
132 _width[0] *= x_scale;
133 _width[1] *= z_scale;
144 case T_texture_border:
167 LPoint2 center((frame[0] + frame[1]) / 2.0f,
168 (frame[2] + frame[3]) / 2.0f);
170 ((frame[0] - center[0]) * _visible_scale[0] + center[0],
171 (frame[1] - center[0]) * _visible_scale[0] + center[0],
172 (frame[2] - center[1]) * _visible_scale[1] + center[1],
173 (frame[3] - center[1]) * _visible_scale[1] + center[1]);
180 new_node = generate_flat_geom(scaled_frame);
184 new_node = generate_bevel_geom(scaled_frame,
false);
188 new_node = generate_bevel_geom(scaled_frame,
true);
192 new_node = generate_groove_geom(scaled_frame,
true);
196 new_node = generate_groove_geom(scaled_frame,
false);
199 case T_texture_border:
200 new_node = generate_texture_border_geom(scaled_frame);
207 if (new_node != (
PandaNode *)NULL && _color[3] != 1.0f) {
209 new_node->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
223 generate_flat_geom(const
LVecBase4 &frame) {
226 PN_stdfloat left = frame[0];
227 PN_stdfloat right = frame[1];
228 PN_stdfloat bottom = frame[2];
229 PN_stdfloat top = frame[3];
231 CPT(GeomVertexFormat) format;
233 format = GeomVertexFormat::get_v3t2();
235 format = GeomVertexFormat::get_v3();
239 ("PGFrame", format,
Geom::UH_static);
242 vertex.add_data3(
LPoint3::rfu(left, 0.0f, top));
243 vertex.add_data3(
LPoint3::rfu(left, 0.0f, bottom));
244 vertex.add_data3(
LPoint3::rfu(right, 0.0f, top));
245 vertex.add_data3(
LPoint3::rfu(right, 0.0f, bottom));
251 bottom = uv_range[2];
255 texcoord.add_data2(left, top);
256 texcoord.add_data2(left, bottom);
257 texcoord.add_data2(right, top);
258 texcoord.add_data2(right, bottom);
262 strip->add_next_vertices(4);
263 strip->close_primitive();
267 state = state->set_attrib(TextureAttrib::make(get_texture()));
270 geom->add_primitive(strip);
271 gnode->add_geom(geom, state);
283 generate_bevel_geom(const
LVecBase4 &frame,
bool in) {
343 PN_stdfloat left = frame[0];
344 PN_stdfloat right = frame[1];
345 PN_stdfloat bottom = frame[2];
346 PN_stdfloat top = frame[3];
348 PN_stdfloat cx = (left + right) * 0.5;
349 PN_stdfloat cy = (top + bottom) * 0.5;
351 PN_stdfloat inner_left = min(left + _width[0], cx);
352 PN_stdfloat inner_right = max(right - _width[0], cx);
353 PN_stdfloat inner_bottom = min(bottom + _width[1], cy);
354 PN_stdfloat inner_top = max(top - _width[1], cy);
356 PN_stdfloat left_color_scale = 1.2;
357 PN_stdfloat right_color_scale = 0.8;
358 PN_stdfloat bottom_color_scale = 0.7;
359 PN_stdfloat top_color_scale = 1.3;
362 right_color_scale = 1.2;
363 left_color_scale = 0.8;
364 top_color_scale = 0.7;
365 bottom_color_scale = 1.3;
369 LColor cleft(min(_color[0] * left_color_scale, (PN_stdfloat)1.0),
370 min(_color[1] * left_color_scale, (PN_stdfloat)1.0),
371 min(_color[2] * left_color_scale, (PN_stdfloat)1.0),
374 LColor cright(min(_color[0] * right_color_scale, (PN_stdfloat)1.0),
375 min(_color[1] * right_color_scale, (PN_stdfloat)1.0),
376 min(_color[2] * right_color_scale, (PN_stdfloat)1.0),
379 LColor cbottom(min(_color[0] * bottom_color_scale, (PN_stdfloat)1.0),
380 min(_color[1] * bottom_color_scale, (PN_stdfloat)1.0),
381 min(_color[2] * bottom_color_scale, (PN_stdfloat)1.0),
384 LColor ctop(min(_color[0] * top_color_scale, (PN_stdfloat)1.0),
385 min(_color[1] * top_color_scale, (PN_stdfloat)1.0),
386 min(_color[2] * top_color_scale, (PN_stdfloat)1.0),
389 CPT(GeomVertexFormat) format;
391 format = GeomVertexFormat::get_v3cpt2();
393 format = GeomVertexFormat::get_v3cp();
397 ("PGFrame", format,
Geom::UH_static);
404 vertex.add_data3(
LPoint3::rfu(right, 0.0f, bottom));
405 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, inner_bottom));
406 vertex.add_data3(
LPoint3::rfu(left, 0.0f, bottom));
407 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, inner_bottom));
408 vertex.add_data3(
LPoint3::rfu(left, 0.0f, top));
409 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, inner_top));
410 vertex.add_data3(
LPoint3::rfu(right, 0.0f, top));
411 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, inner_top));
412 color.add_data4(cbottom);
413 color.add_data4(cbottom);
414 color.add_data4(cbottom);
415 color.add_data4(cbottom);
416 color.add_data4(cleft);
417 color.add_data4(cleft);
418 color.add_data4(ctop);
419 color.add_data4(ctop);
421 strip->add_next_vertices(8);
422 strip->close_primitive();
425 vertex.add_data3(
LPoint3::rfu(right, 0.0f, bottom));
426 vertex.add_data3(
LPoint3::rfu(right, 0.0f, top));
427 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, inner_bottom));
428 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, inner_top));
429 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, inner_bottom));
430 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, inner_top));
431 color.add_data4(cright);
432 color.add_data4(cright);
433 color.add_data4(cright);
434 color.add_data4(cright);
435 color.add_data4(_color);
436 color.add_data4(_color);
438 strip->add_next_vertices(6);
439 strip->close_primitive();
440 strip->set_shade_model(
Geom::SM_flat_last_vertex);
444 PN_stdfloat left = uv_range[0];
445 PN_stdfloat right = uv_range[1];
446 PN_stdfloat bottom = uv_range[2];
447 PN_stdfloat top = uv_range[3];
449 PN_stdfloat cx = (left + right) * 0.5;
450 PN_stdfloat cy = (top + bottom) * 0.5;
452 PN_stdfloat inner_left = min(left + _uv_width[0], cx);
453 PN_stdfloat inner_right = max(right - _uv_width[0], cx);
454 PN_stdfloat inner_bottom = min(bottom + _uv_width[1], cy);
455 PN_stdfloat inner_top = max(top - _uv_width[1], cy);
458 texcoord.add_data2(right, bottom);
459 texcoord.add_data2(inner_right, inner_bottom);
460 texcoord.add_data2(left, bottom);
461 texcoord.add_data2(inner_left, inner_bottom);
462 texcoord.add_data2(left, top);
463 texcoord.add_data2(inner_left, inner_top);
464 texcoord.add_data2(right, top);
465 texcoord.add_data2(inner_right, inner_top);
467 texcoord.add_data2(right, bottom);
468 texcoord.add_data2(right, top);
469 texcoord.add_data2(inner_right, inner_bottom);
470 texcoord.add_data2(inner_right, inner_top);
471 texcoord.add_data2(inner_left, inner_bottom);
472 texcoord.add_data2(inner_left, inner_top);
475 geom->add_primitive(strip);
481 state = state->set_attrib(TextureAttrib::make(get_texture()));
483 gnode->add_geom(geom, state);
495 generate_groove_geom(const
LVecBase4 &frame,
bool in) {
596 PN_stdfloat left = frame[0];
597 PN_stdfloat right = frame[1];
598 PN_stdfloat bottom = frame[2];
599 PN_stdfloat top = frame[3];
601 PN_stdfloat cx = (left + right) * 0.5;
602 PN_stdfloat cy = (top + bottom) * 0.5;
604 PN_stdfloat mid_left = min(left + 0.5f * _width[0], cx);
605 PN_stdfloat mid_right = max(right - 0.5f * _width[0], cx);
606 PN_stdfloat mid_bottom = min(bottom + 0.5f * _width[1], cy);
607 PN_stdfloat mid_top = max(top - 0.5f * _width[1], cy);
609 PN_stdfloat inner_left = min(left + _width[0], cx);
610 PN_stdfloat inner_right = max(right - _width[0], cx);
611 PN_stdfloat inner_bottom = min(bottom + _width[1], cy);
612 PN_stdfloat inner_top = max(top - _width[1], cy);
614 PN_stdfloat left_color_scale = 1.2;
615 PN_stdfloat right_color_scale = 0.8f;
616 PN_stdfloat bottom_color_scale = 0.7f;
617 PN_stdfloat top_color_scale = 1.3;
620 right_color_scale = 1.2;
621 left_color_scale = 0.8f;
622 top_color_scale = 0.7f;
623 bottom_color_scale = 1.3;
627 LColor cleft(min(_color[0] * left_color_scale, (PN_stdfloat)1.0),
628 min(_color[1] * left_color_scale, (PN_stdfloat)1.0),
629 min(_color[2] * left_color_scale, (PN_stdfloat)1.0),
632 LColor cright(min(_color[0] * right_color_scale, (PN_stdfloat)1.0),
633 min(_color[1] * right_color_scale, (PN_stdfloat)1.0),
634 min(_color[2] * right_color_scale, (PN_stdfloat)1.0),
637 LColor cbottom(min(_color[0] * bottom_color_scale, (PN_stdfloat)1.0),
638 min(_color[1] * bottom_color_scale, (PN_stdfloat)1.0),
639 min(_color[2] * bottom_color_scale, (PN_stdfloat)1.0),
642 LColor ctop(min(_color[0] * top_color_scale, (PN_stdfloat)1.0),
643 min(_color[1] * top_color_scale, (PN_stdfloat)1.0),
644 min(_color[2] * top_color_scale, (PN_stdfloat)1.0),
647 CPT(GeomVertexFormat) format;
649 format = GeomVertexFormat::get_v3cpt2();
651 format = GeomVertexFormat::get_v3cp();
654 ("PGFrame", format,
Geom::UH_static);
661 vertex.add_data3(
LPoint3::rfu(right, 0.0f, bottom));
662 vertex.add_data3(
LPoint3::rfu(mid_right, 0.0f, mid_bottom));
663 vertex.add_data3(
LPoint3::rfu(left, 0.0f, bottom));
664 vertex.add_data3(
LPoint3::rfu(mid_left, 0.0f, mid_bottom));
665 vertex.add_data3(
LPoint3::rfu(left, 0.0f, top));
666 vertex.add_data3(
LPoint3::rfu(mid_left, 0.0f, mid_top));
667 vertex.add_data3(
LPoint3::rfu(right, 0.0f, top));
668 vertex.add_data3(
LPoint3::rfu(mid_right, 0.0f, mid_top));
669 color.add_data4(cbottom);
670 color.add_data4(cbottom);
671 color.add_data4(cbottom);
672 color.add_data4(cbottom);
673 color.add_data4(cleft);
674 color.add_data4(cleft);
675 color.add_data4(ctop);
676 color.add_data4(ctop);
678 strip->add_next_vertices(8);
679 strip->close_primitive();
682 vertex.add_data3(
LPoint3::rfu(mid_right, 0.0f, mid_bottom));
683 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, inner_bottom));
684 vertex.add_data3(
LPoint3::rfu(mid_left, 0.0f, mid_bottom));
685 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, inner_bottom));
686 vertex.add_data3(
LPoint3::rfu(mid_left, 0.0f, mid_top));
687 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, inner_top));
688 vertex.add_data3(
LPoint3::rfu(mid_right, 0.0f, mid_top));
689 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, inner_top));
690 color.add_data4(ctop);
691 color.add_data4(ctop);
692 color.add_data4(ctop);
693 color.add_data4(ctop);
694 color.add_data4(cright);
695 color.add_data4(cright);
696 color.add_data4(cbottom);
697 color.add_data4(cbottom);
699 strip->add_next_vertices(8);
700 strip->close_primitive();
703 vertex.add_data3(
LPoint3::rfu(right, 0.0f, bottom));
704 vertex.add_data3(
LPoint3::rfu(right, 0.0f, top));
705 vertex.add_data3(
LPoint3::rfu(mid_right, 0.0f, mid_bottom));
706 vertex.add_data3(
LPoint3::rfu(mid_right, 0.0f, mid_top));
707 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, inner_bottom));
708 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, inner_top));
709 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, inner_bottom));
710 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, inner_top));
711 color.add_data4(cright);
712 color.add_data4(cright);
713 color.add_data4(cright);
714 color.add_data4(cright);
715 color.add_data4(cleft);
716 color.add_data4(cleft);
717 color.add_data4(_color);
718 color.add_data4(_color);
720 strip->add_next_vertices(8);
721 strip->close_primitive();
723 strip->set_shade_model(
Geom::SM_flat_last_vertex);
727 PN_stdfloat left = uv_range[0];
728 PN_stdfloat right = uv_range[1];
729 PN_stdfloat bottom = uv_range[2];
730 PN_stdfloat top = uv_range[3];
732 PN_stdfloat cx = (left + right) * 0.5;
733 PN_stdfloat cy = (top + bottom) * 0.5;
735 PN_stdfloat mid_left = min(left + 0.5f * _width[0], cx);
736 PN_stdfloat mid_right = max(right - 0.5f * _width[0], cx);
737 PN_stdfloat mid_bottom = min(bottom + 0.5f * _width[1], cy);
738 PN_stdfloat mid_top = max(top - 0.5f * _width[1], cy);
740 PN_stdfloat inner_left = min(left + _width[0], cx);
741 PN_stdfloat inner_right = max(right - _width[0], cx);
742 PN_stdfloat inner_bottom = min(bottom + _width[1], cy);
743 PN_stdfloat inner_top = max(top - _width[1], cy);
746 texcoord.add_data2(right, bottom);
747 texcoord.add_data2(mid_right, mid_bottom);
748 texcoord.add_data2(left, bottom);
749 texcoord.add_data2(mid_left, mid_bottom);
750 texcoord.add_data2(left, top);
751 texcoord.add_data2(mid_left, mid_top);
752 texcoord.add_data2(right, top);
753 texcoord.add_data2(mid_right, mid_top);
755 texcoord.add_data2(mid_right, mid_bottom);
756 texcoord.add_data2(inner_right, inner_bottom);
757 texcoord.add_data2(mid_left, mid_bottom);
758 texcoord.add_data2(inner_left, inner_bottom);
759 texcoord.add_data2(mid_left, mid_top);
760 texcoord.add_data2(inner_left, inner_top);
761 texcoord.add_data2(mid_right, mid_top);
762 texcoord.add_data2(inner_right, inner_top);
764 texcoord.add_data2(right, bottom);
765 texcoord.add_data2(right, top);
766 texcoord.add_data2(mid_right, mid_bottom);
767 texcoord.add_data2(mid_right, mid_top);
768 texcoord.add_data2(inner_right, inner_bottom);
769 texcoord.add_data2(inner_right, inner_top);
770 texcoord.add_data2(inner_left, inner_bottom);
771 texcoord.add_data2(inner_left, inner_top);
775 geom->add_primitive(strip);
780 state = state->set_attrib(TextureAttrib::make(get_texture()));
782 gnode->add_geom(geom, state);
794 generate_texture_border_geom(const
LVecBase4 &frame) {
824 PN_stdfloat left = frame[0];
825 PN_stdfloat right = frame[1];
826 PN_stdfloat bottom = frame[2];
827 PN_stdfloat top = frame[3];
829 PN_stdfloat cx = (left + right) * 0.5;
830 PN_stdfloat cy = (top + bottom) * 0.5;
832 PN_stdfloat inner_left = min(left + _width[0], cx);
833 PN_stdfloat inner_right = max(right - _width[0], cx);
834 PN_stdfloat inner_bottom = min(bottom + _width[1], cy);
835 PN_stdfloat inner_top = max(top - _width[1], cy);
837 CPT(GeomVertexFormat) format;
839 format = GeomVertexFormat::get_v3t2();
841 format = GeomVertexFormat::get_v3();
845 ("PGFrame", format,
Geom::UH_static);
850 vertex.add_data3(
LPoint3::rfu(left, 0.0f, top));
851 vertex.add_data3(
LPoint3::rfu(left, 0.0f, inner_top));
852 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, top));
853 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, inner_top));
855 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, top));
856 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, inner_top));
857 vertex.add_data3(
LPoint3::rfu(right, 0.0f, top));
858 vertex.add_data3(
LPoint3::rfu(right, 0.0f, inner_top));
860 vertex.add_data3(
LPoint3::rfu(left, 0.0f, inner_bottom));
861 vertex.add_data3(
LPoint3::rfu(left, 0.0f, bottom));
862 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, inner_bottom));
863 vertex.add_data3(
LPoint3::rfu(inner_left, 0.0f, bottom));
865 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, inner_bottom));
866 vertex.add_data3(
LPoint3::rfu(inner_right, 0.0f, bottom));
867 vertex.add_data3(
LPoint3::rfu(right, 0.0f, inner_bottom));
868 vertex.add_data3(
LPoint3::rfu(right, 0.0f, bottom));
872 PN_stdfloat left = uv_range[0];
873 PN_stdfloat right = uv_range[1];
874 PN_stdfloat bottom = uv_range[2];
875 PN_stdfloat top = uv_range[3];
877 PN_stdfloat cx = (left + right) * 0.5;
878 PN_stdfloat cy = (top + bottom) * 0.5;
880 PN_stdfloat inner_left = min(left + _uv_width[0], cx);
881 PN_stdfloat inner_right = max(right - _uv_width[0], cx);
882 PN_stdfloat inner_bottom = min(bottom + _uv_width[1], cy);
883 PN_stdfloat inner_top = max(top - _uv_width[1], cy);
888 texcoord.add_data2(left, top);
889 texcoord.add_data2(left, inner_top);
890 texcoord.add_data2(inner_left, top);
891 texcoord.add_data2(inner_left, inner_top);
893 texcoord.add_data2(inner_right, top);
894 texcoord.add_data2(inner_right, inner_top);
895 texcoord.add_data2(right, top);
896 texcoord.add_data2(right, inner_top);
898 texcoord.add_data2(left, inner_bottom);
899 texcoord.add_data2(left, bottom);
900 texcoord.add_data2(inner_left, inner_bottom);
901 texcoord.add_data2(inner_left, bottom);
903 texcoord.add_data2(inner_right, inner_bottom);
904 texcoord.add_data2(inner_right, bottom);
905 texcoord.add_data2(right, inner_bottom);
906 texcoord.add_data2(right, bottom);
912 strip->add_consecutive_vertices(0, 8);
913 strip->close_primitive();
916 strip->add_vertex(1);
917 strip->add_vertex(8);
918 strip->add_vertex(3);
919 strip->add_vertex(10);
920 strip->add_vertex(5);
921 strip->add_vertex(12);
922 strip->add_vertex(7);
923 strip->add_vertex(14);
924 strip->close_primitive();
927 strip->add_consecutive_vertices(8, 8);
928 strip->close_primitive();
932 state = state->set_attrib(TextureAttrib::make(get_texture()));
936 geom->add_primitive(strip);
937 gnode->add_geom(geom, state);
A basic node of the scene graph or data graph.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
Specifies whether flat shading (per-polygon) or smooth shading (per-vertex) is in effect...
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Defines a series of triangle strips.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
bool has_texture() const
Returns true if a texture has been applied to the frame.
float length() const
Returns the length of the vector, by the Pythagorean theorem.
This is a 4-by-4 transform matrix.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
NodePath generate_into(const NodePath &parent, const LVecBase4 &frame, int sort=0)
Generates geometry representing a frame of the indicated size, and parents it to the indicated node...
A container for geometry primitives.
This is the base class for all two-component vectors and points.
Texture * get_texture() const
Returns the texture that has been applied to the frame, or NULL if no texture has been applied...
const LVecBase2 & get_visible_scale() const
Returns the scale factor on the visible representation of the frame, in the X and Y directions...
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
bool xform(const LMatrix4 &mat)
Applies the indicated transform to the FrameStyle.
This is the base class for all three-component vectors and points.
LVecBase4 get_internal_frame(const LVecBase4 &frame) const
Computes the size of the internal frame, given the indicated external frame, appropriate for this kin...
Indicates what color should be applied to renderable geometry.
LVecBase3f get_row3(int row) const
Retrieves the row column of the matrix as a 3-component vector, ignoring the last column...
This is a two-component point in space.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
A node that holds Geom objects, renderable pieces of geometry.
NodePath attach_new_node(PandaNode *node, int sort=0, Thread *current_thread=Thread::get_current_thread()) const
Attaches a new node, with or without existing parents, to the scene graph below the referenced node o...