Mercurial > octave-nkf
comparison src/gl-render.cc @ 12358:a076a3d89fce release-3-4-x
opengl_renderer::draw_axes: simplify with subfunctions
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 01 Feb 2011 04:39:21 -0500 |
parents | 23385f2c90b7 |
children | 2ad37783bf01 |
comparison
equal
deleted
inserted
replaced
12357:8fab4aca41fd | 12358:a076a3d89fce |
---|---|
619 | 619 |
620 draw (props.get_all_children ()); | 620 draw (props.get_all_children ()); |
621 } | 621 } |
622 | 622 |
623 void | 623 void |
624 opengl_renderer::render_grid (std::string& gridstyle, Matrix& ticks, | 624 opengl_renderer::render_grid (const std::string& gridstyle, |
625 double lim1, double lim2, | 625 const Matrix& ticks, double lim1, double lim2, |
626 double p1, double p1N, double p2, double p2N, | 626 double p1, double p1N, double p2, double p2N, |
627 int xyz, bool is_3D) | 627 int xyz, bool is_3D) |
628 { | 628 { |
629 set_linestyle (gridstyle, true); | 629 set_linestyle (gridstyle, true); |
630 glBegin (GL_LINES); | 630 glBegin (GL_LINES); |
665 glEnd (); | 665 glEnd (); |
666 set_linestyle ("-", true); | 666 set_linestyle ("-", true); |
667 } | 667 } |
668 | 668 |
669 void | 669 void |
670 opengl_renderer::render_tickmarks(Matrix& ticks, double lim1, double lim2, | 670 opengl_renderer::render_tickmarks (const Matrix& ticks, |
671 double p1, double p1N, double p2, double p2N, | 671 double lim1, double lim2, |
672 double dx, double dy, double dz, | 672 double p1, double p1N, |
673 int xyz, bool doubleside) | 673 double p2, double p2N, |
674 double dx, double dy, double dz, | |
675 int xyz, bool doubleside) | |
674 { | 676 { |
675 glBegin (GL_LINES); | 677 glBegin (GL_LINES); |
678 | |
676 for (int i = 0; i < ticks.numel (); i++) | 679 for (int i = 0; i < ticks.numel (); i++) |
677 { | 680 { |
678 double val = ticks(i); | 681 double val = ticks(i); |
679 | 682 |
680 if (lim1 <= val && val <= lim2) | 683 if (lim1 <= val && val <= lim2) |
709 glVertex3d (p1N-dx, p2N-dy, val); | 712 glVertex3d (p1N-dx, p2N-dy, val); |
710 } | 713 } |
711 } | 714 } |
712 } | 715 } |
713 } | 716 } |
717 | |
714 glEnd (); | 718 glEnd (); |
715 } | 719 } |
716 | 720 |
717 void | 721 void |
718 opengl_renderer::render_ticktexts(Matrix& ticks, string_vector& ticklabels, | 722 opengl_renderer::render_ticktexts (const Matrix& ticks, |
719 double lim1, double lim2, | 723 const string_vector& ticklabels, |
720 double p1, double p2, | 724 double lim1, double lim2, |
721 int xyz, int ha, int va, | 725 double p1, double p2, |
722 int& wmax, int& hmax) | 726 int xyz, int ha, int va, |
727 int& wmax, int& hmax) | |
723 { | 728 { |
724 int n = std::min (ticklabels.numel (), ticks.numel ()); | 729 int n = std::min (ticklabels.numel (), ticks.numel ()); |
725 | 730 |
726 for (int i = 0; i < n; i++) | 731 for (int i = 0; i < n; i++) |
727 { | 732 { |
750 } | 755 } |
751 } | 756 } |
752 } | 757 } |
753 | 758 |
754 void | 759 void |
755 opengl_renderer::draw_axes (const axes::properties& props) | 760 opengl_renderer::setup_opengl_transformation (const axes::properties& props) |
756 { | 761 { |
757 // setup OpenGL transformation | 762 // setup OpenGL transformation |
758 | 763 |
759 Matrix x_zlim = props.get_transform_zlim (); | 764 Matrix x_zlim = props.get_transform_zlim (); |
765 | |
766 xZ1 = x_zlim(0)-(x_zlim(1)-x_zlim(0))/2; | |
767 xZ2 = x_zlim(1)+(x_zlim(1)-x_zlim(0))/2; | |
768 | |
760 Matrix x_mat1 = props.get_opengl_matrix_1 (); | 769 Matrix x_mat1 = props.get_opengl_matrix_1 (); |
761 Matrix x_mat2 = props.get_opengl_matrix_2 (); | 770 Matrix x_mat2 = props.get_opengl_matrix_2 (); |
762 | |
763 xZ1 = x_zlim(0)-(x_zlim(1)-x_zlim(0))/2; | |
764 xZ2 = x_zlim(1)+(x_zlim(1)-x_zlim(0))/2; | |
765 | 771 |
766 #if defined (HAVE_FRAMEWORK_OPENGL) | 772 #if defined (HAVE_FRAMEWORK_OPENGL) |
767 GLint vw[4]; | 773 GLint vw[4]; |
768 #else | 774 #else |
769 int vw[4]; | 775 int vw[4]; |
784 glClear (GL_DEPTH_BUFFER_BIT); | 790 glClear (GL_DEPTH_BUFFER_BIT); |
785 | 791 |
786 // store axes transformation data | 792 // store axes transformation data |
787 | 793 |
788 xform = props.get_transform (); | 794 xform = props.get_transform (); |
789 | 795 } |
790 // draw axes object | 796 |
791 | 797 void |
792 GLboolean antialias; | 798 opengl_renderer::draw_axes_planes (bool visible, const Matrix& axe_color, |
793 glGetBooleanv (GL_LINE_SMOOTH, &antialias); | 799 const Matrix& xlim, const Matrix& ylim, |
794 glDisable (GL_LINE_SMOOTH); | 800 const Matrix& zlim, double x_plane, |
795 | 801 double y_plane, double z_plane) |
796 Matrix xlim = xform.xscale (props.get_xlim ().matrix_value ()); | 802 { |
797 Matrix ylim = xform.yscale (props.get_ylim ().matrix_value ()); | 803 // Axes planes |
798 Matrix zlim = xform.zscale (props.get_zlim ().matrix_value ()); | 804 |
799 double x_min = xlim(0), x_max = xlim(1); | 805 if (axe_color.numel () > 0 && visible) |
800 double y_min = ylim(0), y_max = ylim(1); | 806 { |
801 double z_min = zlim(0), z_max = zlim(1); | 807 set_color (axe_color); |
802 | 808 set_polygon_offset (true, 2.5); |
803 double xd = (props.xdir_is ("normal") ? 1 : -1); | 809 |
804 double yd = (props.ydir_is ("normal") ? 1 : -1); | 810 glBegin (GL_QUADS); |
805 double zd = (props.zdir_is ("normal") ? 1 : -1); | 811 |
812 double x_min = xlim(0); | |
813 double x_max = xlim(1); | |
814 | |
815 double y_min = ylim(0); | |
816 double y_max = ylim(1); | |
817 | |
818 double z_min = zlim(0); | |
819 double z_max = zlim(1); | |
820 | |
821 // X plane | |
822 glVertex3d (x_plane, y_min, z_min); | |
823 glVertex3d (x_plane, y_max, z_min); | |
824 glVertex3d (x_plane, y_max, z_max); | |
825 glVertex3d (x_plane, y_min, z_max); | |
826 | |
827 // Y plane | |
828 glVertex3d (x_min, y_plane, z_min); | |
829 glVertex3d (x_max, y_plane, z_min); | |
830 glVertex3d (x_max, y_plane, z_max); | |
831 glVertex3d (x_min, y_plane, z_max); | |
832 | |
833 // Z plane | |
834 glVertex3d (x_min, y_min, z_plane); | |
835 glVertex3d (x_max, y_min, z_plane); | |
836 glVertex3d (x_max, y_max, z_plane); | |
837 glVertex3d (x_min, y_max, z_plane); | |
838 | |
839 glEnd (); | |
840 | |
841 set_polygon_offset (false); | |
842 } | |
843 } | |
844 | |
845 void | |
846 opengl_renderer::draw_axes_boxes (const axes::properties& props, | |
847 bool visible, bool box, bool xySym, | |
848 double xPlane, double yPlane, double zPlane, | |
849 double xPlaneN, double yPlaneN, double zPlaneN, | |
850 double xpTick, double ypTick, double zpTick, | |
851 double xpTickN, double ypTickN, double zpTickN) | |
852 { | |
853 // Axes box | |
854 | |
855 set_linestyle ("-", true); | |
856 set_linewidth (props.get_linewidth ()); | |
857 | |
858 if (visible) | |
859 { | |
860 glBegin (GL_LINES); | |
861 | |
862 // X box | |
863 set_color (props.get_xcolor_rgb ()); | |
864 glVertex3d (xPlaneN, ypTick, zpTick); | |
865 glVertex3d (xPlane, ypTick, zpTick); | |
866 | |
867 if (box) | |
868 { | |
869 glVertex3d (xPlaneN, ypTickN, zpTick); | |
870 glVertex3d (xPlane, ypTickN, zpTick); | |
871 glVertex3d (xPlaneN, ypTickN, zpTickN); | |
872 glVertex3d (xPlane, ypTickN, zpTickN); | |
873 glVertex3d (xPlaneN, ypTick, zpTickN); | |
874 glVertex3d (xPlane, ypTick, zpTickN); | |
875 } | |
876 | |
877 // Y box | |
878 set_color (props.get_ycolor_rgb ()); | |
879 glVertex3d (xpTick, yPlaneN, zpTick); | |
880 glVertex3d (xpTick, yPlane, zpTick); | |
881 | |
882 if (box) | |
883 { | |
884 glVertex3d (xpTickN, yPlaneN, zpTick); | |
885 glVertex3d (xpTickN, yPlane, zpTick); | |
886 glVertex3d (xpTickN, yPlaneN, zpTickN); | |
887 glVertex3d (xpTickN, yPlane, zpTickN); | |
888 glVertex3d (xpTick, yPlaneN, zpTickN); | |
889 glVertex3d (xpTick, yPlane, zpTickN); | |
890 } | |
891 | |
892 // Z box | |
893 set_color (props.get_zcolor_rgb ()); | |
894 | |
895 if (xySym) | |
896 { | |
897 glVertex3d (xPlaneN, yPlane, zPlaneN); | |
898 glVertex3d (xPlaneN, yPlane, zPlane); | |
899 } | |
900 else | |
901 { | |
902 glVertex3d (xPlane, yPlaneN, zPlaneN); | |
903 glVertex3d (xPlane, yPlaneN, zPlane); | |
904 } | |
905 | |
906 if (box) | |
907 { | |
908 glVertex3d (xPlane, yPlane, zPlaneN); | |
909 glVertex3d (xPlane, yPlane, zPlane); | |
910 | |
911 if (xySym) | |
912 { | |
913 glVertex3d (xPlane, yPlaneN, zPlaneN); | |
914 glVertex3d (xPlane, yPlaneN, zPlane); | |
915 } | |
916 else | |
917 { | |
918 glVertex3d (xPlaneN, yPlane, zPlaneN); | |
919 glVertex3d (xPlaneN, yPlane, zPlane); | |
920 } | |
921 | |
922 glVertex3d (xPlaneN, yPlaneN, zPlaneN); | |
923 glVertex3d (xPlaneN, yPlaneN, zPlane); | |
924 } | |
925 | |
926 glEnd (); | |
927 } | |
928 } | |
929 | |
930 void | |
931 opengl_renderer::draw_axes_x_grid (const axes::properties& props, | |
932 bool visible, bool box, | |
933 const std::string& gridstyle, | |
934 const std::string& minorgridstyle, | |
935 bool nearhoriz, double tickdir, | |
936 bool xyzSym, bool layer2Dtop, | |
937 bool x2Dtop, int xstate, | |
938 double x_min, double x_max, | |
939 double xticklen, double xtickoffset, | |
940 double fy, double yPlane, double yPlaneN, | |
941 double ypTick, double ypTickN, | |
942 double fz, int zstate, double zPlane, | |
943 double zPlaneN, double zpTick, | |
944 double zpTickN) | |
945 { | |
946 // X grid | |
947 | |
948 if (visible && xstate != AXE_DEPTH_DIR) | |
949 { | |
950 bool do_xgrid = (props.is_xgrid () && (gridstyle != "none")); | |
951 bool do_xminorgrid = (props.is_xminorgrid () && (minorgridstyle != "none")); | |
952 bool do_xminortick = props.is_xminortick (); | |
953 Matrix xticks = xform.xscale (props.get_xtick ().matrix_value ()); | |
954 Matrix xmticks = xform.xscale (props.get_xmtick ().matrix_value ()); | |
955 string_vector xticklabels = props.get_xticklabel ().all_strings (); | |
956 int wmax = 0, hmax = 0; | |
957 bool tick_along_z = nearhoriz || xisinf (fy); | |
958 | |
959 set_color (props.get_xcolor_rgb ()); | |
960 | |
961 // grid lines | |
962 if (do_xgrid) | |
963 render_grid (gridstyle, xticks, x_min, x_max, | |
964 yPlane, yPlaneN, layer2Dtop ? zPlaneN : zPlane, | |
965 zPlaneN, 0, (zstate != AXE_DEPTH_DIR)); | |
966 | |
967 // tick marks | |
968 if (tick_along_z) | |
969 { | |
970 render_tickmarks (xticks, x_min, x_max, ypTick, ypTick, | |
971 zpTick, zpTickN, 0., 0., | |
972 signum(zpTick-zpTickN)*fz*xticklen*tickdir, | |
973 0, (box && xstate != AXE_ANY_DIR)); | |
974 } | |
975 else | |
976 { | |
977 render_tickmarks (xticks, x_min, x_max, ypTick, ypTickN, | |
978 zpTick, zpTick, 0., | |
979 signum(ypTick-ypTickN)*fy*xticklen*tickdir, | |
980 0., 0, (box && xstate != AXE_ANY_DIR)); | |
981 } | |
982 | |
983 // tick texts | |
984 if (xticklabels.numel () > 0) | |
985 { | |
986 int halign = (xstate == AXE_HORZ_DIR ? 1 : (xyzSym ? 0 : 2)); | |
987 int valign = (xstate == AXE_VERT_DIR ? 1 : (x2Dtop ? 0 : 2)); | |
988 | |
989 if (tick_along_z) | |
990 render_ticktexts (xticks, xticklabels, x_min, x_max, ypTick, | |
991 zpTick+signum(zpTick-zpTickN)*fz*xtickoffset, | |
992 0, halign, valign, wmax, hmax); | |
993 else | |
994 render_ticktexts (xticks, xticklabels, x_min, x_max, | |
995 ypTick+signum(ypTick-ypTickN)*fy*xtickoffset, | |
996 zpTick, 0, halign, valign, wmax, hmax); | |
997 } | |
998 | |
999 // minor grid lines | |
1000 if (do_xminorgrid) | |
1001 render_grid (minorgridstyle, xmticks, x_min, x_max, | |
1002 yPlane, yPlaneN, layer2Dtop ? zPlaneN : zPlane, | |
1003 zPlaneN, 0, (zstate != AXE_DEPTH_DIR)); | |
1004 | |
1005 // minor tick marks | |
1006 if (do_xminortick) | |
1007 { | |
1008 if (tick_along_z) | |
1009 render_tickmarks (xmticks, x_min, x_max, ypTick, ypTick, | |
1010 zpTick, zpTickN, 0., 0., | |
1011 signum(zpTick-zpTickN)*fz*xticklen/2*tickdir, | |
1012 0, (box && xstate != AXE_ANY_DIR)); | |
1013 else | |
1014 render_tickmarks (xmticks, x_min, x_max, ypTick, ypTickN, | |
1015 zpTick, zpTick, 0., | |
1016 signum(ypTick-ypTickN)*fy*xticklen/2*tickdir, | |
1017 0., 0, (box && xstate != AXE_ANY_DIR)); | |
1018 } | |
1019 | |
1020 text::properties& xlabel_props = | |
1021 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_xlabel ()).get_properties ()); | |
1022 | |
1023 xlabel_props.set_visible ("on"); | |
1024 | |
1025 if (! xlabel_props.get_string ().empty ()) | |
1026 { | |
1027 if (xlabel_props.horizontalalignmentmode_is ("auto")) | |
1028 { | |
1029 xlabel_props.set_horizontalalignment | |
1030 (xstate > AXE_DEPTH_DIR | |
1031 ? "center" : (xyzSym ? "left" : "right")); | |
1032 | |
1033 xlabel_props.set_horizontalalignmentmode ("auto"); | |
1034 } | |
1035 | |
1036 if (xlabel_props.verticalalignmentmode_is ("auto")) | |
1037 { | |
1038 xlabel_props.set_verticalalignment | |
1039 (xstate == AXE_VERT_DIR || x2Dtop ? "bottom" : "top"); | |
1040 | |
1041 xlabel_props.set_verticalalignmentmode ("auto"); | |
1042 } | |
1043 | |
1044 if (xlabel_props.positionmode_is ("auto") | |
1045 || xlabel_props.rotationmode_is ("auto")) | |
1046 { | |
1047 double angle = 0; | |
1048 ColumnVector p | |
1049 = graphics_xform::xform_vector ((x_min+x_max)/2, | |
1050 ypTick, zpTick); | |
1051 | |
1052 if (tick_along_z) | |
1053 p(2) += (signum(zpTick-zpTickN)*fz*xtickoffset); | |
1054 else | |
1055 p(1) += (signum(ypTick-ypTickN)*fy*xtickoffset); | |
1056 | |
1057 p = xform.transform (p(0), p(1), p(2), false); | |
1058 | |
1059 switch (xstate) | |
1060 { | |
1061 case AXE_ANY_DIR: | |
1062 p(0) += (xyzSym ? wmax : -wmax); | |
1063 p(1) += hmax; | |
1064 break; | |
1065 | |
1066 case AXE_VERT_DIR: | |
1067 p(0) -= wmax; | |
1068 angle = 90; | |
1069 break; | |
1070 | |
1071 case AXE_HORZ_DIR: | |
1072 p(1) += (x2Dtop ? -hmax : hmax); | |
1073 break; | |
1074 } | |
1075 | |
1076 if (xlabel_props.positionmode_is ("auto")) | |
1077 { | |
1078 p = xform.untransform (p(0), p(1), p(2), true); | |
1079 xlabel_props.set_position (p.extract_n (0, 3).transpose ()); | |
1080 xlabel_props.set_positionmode ("auto"); | |
1081 } | |
1082 | |
1083 if (xlabel_props.rotationmode_is ("auto")) | |
1084 { | |
1085 xlabel_props.set_rotation (angle); | |
1086 xlabel_props.set_rotationmode ("auto"); | |
1087 } | |
1088 } | |
1089 } | |
1090 } | |
1091 else | |
1092 gh_manager::get_object (props.get_xlabel ()).set ("visible", "off"); | |
1093 } | |
1094 | |
1095 void | |
1096 opengl_renderer::draw_axes_y_grid (const axes::properties& props, | |
1097 bool visible, bool box, | |
1098 const std::string& gridstyle, | |
1099 const std::string& minorgridstyle, | |
1100 bool nearhoriz, double tickdir, | |
1101 bool xyzSym, bool layer2Dtop, | |
1102 bool y2Dright, int ystate, | |
1103 double y_min, double y_max, | |
1104 double yticklen, double ytickoffset, | |
1105 double fx, double xPlane, double xPlaneN, | |
1106 double xpTick, double xpTickN, | |
1107 double fz, int zstate, double zPlane, | |
1108 double zPlaneN, double zpTick, | |
1109 double zpTickN) | |
1110 { | |
1111 // Y grid | |
1112 | |
1113 if (ystate != AXE_DEPTH_DIR && visible) | |
1114 { | |
1115 bool do_ygrid = (props.is_ygrid () && (gridstyle != "none")); | |
1116 bool do_yminorgrid = (props.is_yminorgrid () && (minorgridstyle != "none")); | |
1117 bool do_yminortick = props.is_yminortick (); | |
1118 Matrix yticks = xform.yscale (props.get_ytick ().matrix_value ()); | |
1119 Matrix ymticks = xform.yscale (props.get_ymtick ().matrix_value ()); | |
1120 string_vector yticklabels = props.get_yticklabel ().all_strings (); | |
1121 int wmax = 0, hmax = 0; | |
1122 bool tick_along_z = nearhoriz || xisinf (fx); | |
1123 | |
1124 set_color (props.get_ycolor_rgb ()); | |
1125 | |
1126 // grid lines | |
1127 if (do_ygrid) | |
1128 render_grid (gridstyle, yticks, y_min, y_max, | |
1129 xPlane, xPlaneN, layer2Dtop ? zPlaneN : zPlane, | |
1130 zPlaneN, 1, (zstate != AXE_DEPTH_DIR)); | |
1131 | |
1132 // tick marks | |
1133 if (tick_along_z) | |
1134 render_tickmarks (yticks, y_min, y_max, xpTick, xpTick, | |
1135 zpTick, zpTickN, 0., 0., | |
1136 signum(zpTick-zpTickN)*fz*yticklen*tickdir, | |
1137 1, (box && ystate != AXE_ANY_DIR)); | |
1138 else | |
1139 render_tickmarks (yticks, y_min, y_max, xpTick, xpTickN, | |
1140 zpTick, zpTick, | |
1141 signum(xPlaneN-xPlane)*fx*yticklen*tickdir, | |
1142 0., 0., 1, (box && ystate != AXE_ANY_DIR)); | |
1143 | |
1144 // tick texts | |
1145 if (yticklabels.numel () > 0) | |
1146 { | |
1147 int halign = (ystate == AXE_HORZ_DIR | |
1148 ? 1 : (!xyzSym || y2Dright ? 0 : 2)); | |
1149 int valign = (ystate == AXE_VERT_DIR ? 1 : 2); | |
1150 | |
1151 if (tick_along_z) | |
1152 render_ticktexts (yticks, yticklabels, y_min, y_max, xpTick, | |
1153 zpTick+signum(zpTick-zpTickN)*fz*ytickoffset, | |
1154 1, halign, valign, wmax, hmax); | |
1155 else | |
1156 render_ticktexts (yticks, yticklabels, y_min, y_max, | |
1157 xpTick+signum(xpTick-xpTickN)*fx*ytickoffset, | |
1158 zpTick, 1, halign, valign, wmax, hmax); | |
1159 } | |
1160 | |
1161 // minor grid lines | |
1162 if (do_yminorgrid) | |
1163 render_grid (minorgridstyle, ymticks, y_min, y_max, | |
1164 xPlane, xPlaneN, layer2Dtop ? zPlaneN : zPlane, | |
1165 zPlaneN, 1, (zstate != AXE_DEPTH_DIR)); | |
1166 | |
1167 // minor tick marks | |
1168 if (do_yminortick) | |
1169 { | |
1170 if (tick_along_z) | |
1171 render_tickmarks (ymticks, y_min, y_max, xpTick, xpTick, | |
1172 zpTick, zpTickN, 0., 0., | |
1173 signum(zpTick-zpTickN)*fz*yticklen/2*tickdir, | |
1174 1, (box && ystate != AXE_ANY_DIR)); | |
1175 else | |
1176 render_tickmarks (ymticks, y_min, y_max, xpTick, xpTickN, | |
1177 zpTick, zpTick, | |
1178 signum(xpTick-xpTickN)*fx*yticklen/2*tickdir, | |
1179 0., 0., 1, (box && ystate != AXE_ANY_DIR)); | |
1180 } | |
1181 | |
1182 text::properties& ylabel_props = | |
1183 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_ylabel ()).get_properties ()); | |
1184 | |
1185 ylabel_props.set_visible ("on"); | |
1186 | |
1187 if (! ylabel_props.get_string ().empty ()) | |
1188 { | |
1189 if (ylabel_props.horizontalalignmentmode_is ("auto")) | |
1190 { | |
1191 ylabel_props.set_horizontalalignment | |
1192 (ystate > AXE_DEPTH_DIR | |
1193 ? "center" : (!xyzSym ? "left" : "right")); | |
1194 | |
1195 ylabel_props.set_horizontalalignmentmode ("auto"); | |
1196 } | |
1197 | |
1198 if (ylabel_props.verticalalignmentmode_is ("auto")) | |
1199 { | |
1200 ylabel_props.set_verticalalignment | |
1201 (ystate == AXE_VERT_DIR && !y2Dright ? "bottom" : "top"); | |
1202 | |
1203 ylabel_props.set_verticalalignmentmode ("auto"); | |
1204 } | |
1205 | |
1206 if (ylabel_props.positionmode_is ("auto") | |
1207 || ylabel_props.rotationmode_is ("auto")) | |
1208 { | |
1209 double angle = 0; | |
1210 ColumnVector p = graphics_xform::xform_vector (xpTick, (y_min+y_max)/2, zpTick); | |
1211 | |
1212 if (tick_along_z) | |
1213 p(2) += (signum(zpTick-zpTickN)*fz*ytickoffset); | |
1214 else | |
1215 p(0) += (signum(xpTick-xpTickN)*fx*ytickoffset); | |
1216 | |
1217 p = xform.transform (p(0), p(1), p(2), false); | |
1218 | |
1219 switch (ystate) | |
1220 { | |
1221 case AXE_ANY_DIR: | |
1222 p(0) += (!xyzSym ? wmax : -wmax); | |
1223 p(1) += hmax; | |
1224 break; | |
1225 | |
1226 case AXE_VERT_DIR: | |
1227 p(0) += (y2Dright ? wmax : -wmax); | |
1228 angle = 90; | |
1229 break; | |
1230 | |
1231 case AXE_HORZ_DIR: | |
1232 p(1) += hmax; | |
1233 break; | |
1234 } | |
1235 | |
1236 if (ylabel_props.positionmode_is ("auto")) | |
1237 { | |
1238 p = xform.untransform (p(0), p(1), p(2), true); | |
1239 ylabel_props.set_position (p.extract_n (0, 3).transpose ()); | |
1240 ylabel_props.set_positionmode ("auto"); | |
1241 } | |
1242 | |
1243 if (ylabel_props.rotationmode_is ("auto")) | |
1244 { | |
1245 ylabel_props.set_rotation (angle); | |
1246 ylabel_props.set_rotationmode ("auto"); | |
1247 } | |
1248 } | |
1249 } | |
1250 } | |
1251 else | |
1252 gh_manager::get_object (props.get_ylabel ()).set ("visible", "off"); | |
1253 } | |
1254 | |
1255 void | |
1256 opengl_renderer::draw_axes_z_grid (const axes::properties& props, | |
1257 bool visible, bool box, | |
1258 const std::string& gridstyle, | |
1259 const std::string& minorgridstyle, | |
1260 double tickdir, bool xySym, bool zSign, | |
1261 int zstate, double z_min, double z_max, | |
1262 double zticklen, double ztickoffset, | |
1263 double fx, double xPlane, double xPlaneN, | |
1264 double fy, double yPlane, double yPlaneN) | |
1265 { | |
1266 // Z Grid | |
1267 | |
1268 if (zstate != AXE_DEPTH_DIR && visible) | |
1269 { | |
1270 bool do_zgrid = (props.is_zgrid () && (gridstyle != "none")); | |
1271 bool do_zminorgrid = (props.is_zminorgrid () && (minorgridstyle != "none")); | |
1272 bool do_zminortick = props.is_zminortick (); | |
1273 Matrix zticks = xform.zscale (props.get_ztick ().matrix_value ()); | |
1274 Matrix zmticks = xform.zscale (props.get_zmtick ().matrix_value ()); | |
1275 string_vector zticklabels = props.get_zticklabel ().all_strings (); | |
1276 int wmax = 0, hmax = 0; | |
1277 | |
1278 set_color (props.get_zcolor_rgb ()); | |
1279 | |
1280 // grid lines | |
1281 if (do_zgrid) | |
1282 render_grid (gridstyle, zticks, z_min, z_max, | |
1283 xPlane, xPlaneN, yPlane, yPlaneN, 2, true); | |
1284 | |
1285 // tick marks | |
1286 if (xySym) | |
1287 { | |
1288 if (xisinf (fy)) | |
1289 render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlane, | |
1290 yPlane, yPlane, | |
1291 signum(xPlaneN-xPlane)*fx*zticklen*tickdir, | |
1292 0., 0., 2, (box && zstate != AXE_ANY_DIR)); | |
1293 else | |
1294 render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlaneN, | |
1295 yPlane, yPlane, 0., | |
1296 signum(yPlane-yPlaneN)*fy*zticklen*tickdir, | |
1297 0., 2, false); | |
1298 } | |
1299 else | |
1300 { | |
1301 if (xisinf (fx)) | |
1302 render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlane, | |
1303 yPlaneN, yPlane, 0., | |
1304 signum(yPlaneN-yPlane)*fy*zticklen*tickdir, | |
1305 0., 2, (box && zstate != AXE_ANY_DIR)); | |
1306 else | |
1307 render_tickmarks (zticks, z_min, z_max, xPlane, xPlane, | |
1308 yPlaneN, yPlane, | |
1309 signum(xPlane-xPlaneN)*fx*zticklen*tickdir, | |
1310 0., 0., 2, false); | |
1311 } | |
1312 | |
1313 // FIXME: tick texts | |
1314 if (zticklabels.numel () > 0) | |
1315 { | |
1316 int halign = 2; | |
1317 int valign = (zstate == AXE_VERT_DIR ? 1 : (zSign ? 3 : 2)); | |
1318 | |
1319 if (xySym) | |
1320 { | |
1321 if (xisinf (fy)) | |
1322 render_ticktexts (zticks, zticklabels, z_min, z_max, | |
1323 xPlaneN+signum(xPlaneN-xPlane)*fx*ztickoffset, | |
1324 yPlane, 2, halign, valign, wmax, hmax); | |
1325 else | |
1326 render_ticktexts (zticks, zticklabels, z_min, z_max, xPlaneN, | |
1327 yPlane+signum(yPlane-yPlaneN)*fy*ztickoffset, | |
1328 2, halign, valign, wmax, hmax); | |
1329 } | |
1330 else | |
1331 { | |
1332 if (xisinf (fx)) | |
1333 render_ticktexts (zticks, zticklabels, z_min, z_max, xPlane, | |
1334 yPlaneN+signum(yPlaneN-yPlane)*fy*ztickoffset, | |
1335 2, halign, valign, wmax, hmax); | |
1336 else | |
1337 render_ticktexts (zticks, zticklabels, z_min, z_max, | |
1338 xPlane+signum(xPlane-xPlaneN)*fx*ztickoffset, | |
1339 yPlaneN, 2, halign, valign, wmax, hmax); | |
1340 } | |
1341 } | |
1342 | |
1343 // minor grid lines | |
1344 if (do_zminorgrid) | |
1345 render_grid (minorgridstyle, zmticks, z_min, z_max, | |
1346 xPlane, xPlaneN, yPlane, yPlaneN, 2, true); | |
1347 | |
1348 // minor tick marks | |
1349 if (do_zminortick) | |
1350 { | |
1351 if (xySym) | |
1352 { | |
1353 if (xisinf (fy)) | |
1354 render_tickmarks (zmticks, z_min, z_max, xPlaneN, xPlane, | |
1355 yPlane, yPlane, | |
1356 signum(xPlaneN-xPlane)*fx*zticklen/2*tickdir, | |
1357 0., 0., 2, (box && zstate != AXE_ANY_DIR)); | |
1358 else | |
1359 render_tickmarks (zmticks, z_min, z_max, xPlaneN, xPlaneN, | |
1360 yPlane, yPlane, 0., | |
1361 signum(yPlane-yPlaneN)*fy*zticklen/2*tickdir, | |
1362 0., 2, false); | |
1363 } | |
1364 else | |
1365 { | |
1366 if (xisinf (fx)) | |
1367 render_tickmarks (zmticks, z_min, z_max, xPlane, xPlane, | |
1368 yPlaneN, yPlane, 0., | |
1369 signum(yPlaneN-yPlane)*fy*zticklen/2*tickdir, | |
1370 0., 2, (box && zstate != AXE_ANY_DIR)); | |
1371 else | |
1372 render_tickmarks (zmticks, z_min, z_max, xPlane, xPlane, | |
1373 yPlaneN, yPlaneN, | |
1374 signum(xPlane-xPlaneN)*fx*zticklen/2*tickdir, | |
1375 0., 0., 2, false); | |
1376 } | |
1377 } | |
1378 | |
1379 text::properties& zlabel_props = | |
1380 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_zlabel ()).get_properties ()); | |
1381 | |
1382 zlabel_props.set_visible ("on"); | |
1383 | |
1384 if (! zlabel_props.get_string ().empty ()) | |
1385 { | |
1386 bool camAuto = props.cameraupvectormode_is ("auto"); | |
1387 | |
1388 if (zlabel_props.horizontalalignmentmode_is ("auto")) | |
1389 { | |
1390 zlabel_props.set_horizontalalignment | |
1391 ((zstate > AXE_DEPTH_DIR || camAuto) ? "center" : "right"); | |
1392 | |
1393 zlabel_props.set_horizontalalignmentmode ("auto"); | |
1394 } | |
1395 | |
1396 if (zlabel_props.verticalalignmentmode_is ("auto")) | |
1397 { | |
1398 zlabel_props.set_verticalalignment | |
1399 (zstate == AXE_VERT_DIR | |
1400 ? "bottom" : ((zSign || camAuto) ? "bottom" : "top")); | |
1401 | |
1402 zlabel_props.set_verticalalignmentmode ("auto"); | |
1403 } | |
1404 | |
1405 if (zlabel_props.positionmode_is ("auto") | |
1406 || zlabel_props.rotationmode_is ("auto")) | |
1407 { | |
1408 double angle = 0; | |
1409 ColumnVector p; | |
1410 | |
1411 if (xySym) | |
1412 { | |
1413 p = graphics_xform::xform_vector (xPlaneN, yPlane, | |
1414 (z_min+z_max)/2); | |
1415 if (xisinf (fy)) | |
1416 p(0) += (signum(xPlaneN-xPlane)*fx*ztickoffset); | |
1417 else | |
1418 p(1) += (signum(yPlane-yPlaneN)*fy*ztickoffset); | |
1419 } | |
1420 else | |
1421 { | |
1422 p = graphics_xform::xform_vector (xPlane, yPlaneN, | |
1423 (z_min+z_max)/2); | |
1424 if (xisinf (fx)) | |
1425 p(1) += (signum(yPlaneN-yPlane)*fy*ztickoffset); | |
1426 else | |
1427 p(0) += (signum(xPlane-xPlaneN)*fx*ztickoffset); | |
1428 } | |
1429 | |
1430 p = xform.transform (p(0), p(1), p(2), false); | |
1431 | |
1432 switch (zstate) | |
1433 { | |
1434 case AXE_ANY_DIR: | |
1435 if (camAuto) | |
1436 { | |
1437 p(0) -= wmax; | |
1438 angle = 90; | |
1439 } | |
1440 | |
1441 // FIXME -- what's the correct offset? | |
1442 // | |
1443 // p[0] += (!xySym ? wmax : -wmax); | |
1444 // p[1] += (zSign ? hmax : -hmax); | |
1445 | |
1446 break; | |
1447 | |
1448 case AXE_VERT_DIR: | |
1449 p(0) -= wmax; | |
1450 angle = 90; | |
1451 break; | |
1452 | |
1453 case AXE_HORZ_DIR: | |
1454 p(1) += hmax; | |
1455 break; | |
1456 } | |
1457 | |
1458 if (zlabel_props.positionmode_is ("auto")) | |
1459 { | |
1460 p = xform.untransform (p(0), p(1), p(2), true); | |
1461 zlabel_props.set_position (p.extract_n (0, 3).transpose ()); | |
1462 zlabel_props.set_positionmode ("auto"); | |
1463 } | |
1464 | |
1465 if (zlabel_props.rotationmode_is ("auto")) | |
1466 { | |
1467 zlabel_props.set_rotation (angle); | |
1468 zlabel_props.set_rotationmode ("auto"); | |
1469 } | |
1470 } | |
1471 } | |
1472 } | |
1473 else | |
1474 gh_manager::get_object (props.get_zlabel ()).set ("visible", "off"); | |
1475 } | |
1476 | |
1477 void | |
1478 opengl_renderer::draw_axes_title (const axes::properties& props, | |
1479 double x_min, double x_max, | |
1480 double y_min, double y_max, | |
1481 double z_min, double z_max) | |
1482 { | |
1483 // Title | |
806 | 1484 |
807 ColumnVector bbox(4); | 1485 ColumnVector bbox(4); |
808 bbox(0) = octave_Inf; | 1486 bbox(0) = octave_Inf; |
809 bbox(1) = octave_Inf; | 1487 bbox(1) = octave_Inf; |
810 bbox(2) = -octave_Inf; | 1488 bbox(2) = -octave_Inf; |
811 bbox(3) = -octave_Inf; | 1489 bbox(3) = -octave_Inf; |
812 for (int i = 0; i <= 1; i++) | 1490 for (int i = 0; i <= 1; i++) |
813 for (int j = 0; j <= 1; j++) | 1491 for (int j = 0; j <= 1; j++) |
814 for (int k = 0; k <= 1; k++) | 1492 for (int k = 0; k <= 1; k++) |
815 { | 1493 { |
816 ColumnVector p = xform.transform (i ? x_max : x_min, j ? y_max : y_min, | 1494 ColumnVector p = xform.transform (i ? x_max : x_min, |
1495 j ? y_max : y_min, | |
817 k ? z_max : z_min, false); | 1496 k ? z_max : z_min, false); |
818 bbox(0) = std::min (bbox(0), p(0)); | 1497 bbox(0) = std::min (bbox(0), p(0)); |
819 bbox(1) = std::min (bbox(1), p(1)); | 1498 bbox(1) = std::min (bbox(1), p(1)); |
820 bbox(2) = std::max (bbox(2), p(0)); | 1499 bbox(2) = std::max (bbox(2), p(0)); |
821 bbox(3) = std::max (bbox(3), p(1)); | 1500 bbox(3) = std::max (bbox(3), p(1)); |
822 } | 1501 } |
1502 | |
823 bbox(2) = bbox(2)-bbox(0); | 1503 bbox(2) = bbox(2)-bbox(0); |
824 bbox(3) = bbox(3)-bbox(1); | 1504 bbox(3) = bbox(3)-bbox(1); |
1505 | |
1506 Matrix x_zlim = props.get_transform_zlim (); | |
1507 | |
1508 text::properties& title_props = | |
1509 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_title ()).get_properties ()); | |
1510 | |
1511 if (! title_props.get_string ().empty () | |
1512 && title_props.positionmode_is ("auto")) | |
1513 { | |
1514 ColumnVector p = xform.untransform (bbox(0)+bbox(2)/2, (bbox(1)-10), | |
1515 (x_zlim(0)+x_zlim(1))/2, true); | |
1516 | |
1517 title_props.set_position (p.extract_n(0, 3).transpose ()); | |
1518 title_props.set_positionmode ("auto"); | |
1519 } | |
1520 | |
1521 set_clipbox (x_min, x_max, y_min, y_max, z_min, z_max); | |
1522 } | |
1523 | |
1524 void | |
1525 opengl_renderer::draw_axes_children (const axes::properties& props) | |
1526 { | |
1527 // Children | |
1528 | |
1529 GLboolean antialias; | |
1530 glGetBooleanv (GL_LINE_SMOOTH, &antialias); | |
1531 | |
1532 if (antialias == GL_TRUE) | |
1533 glEnable (GL_LINE_SMOOTH); | |
1534 else | |
1535 glDisable (GL_LINE_SMOOTH); | |
1536 | |
1537 Matrix children = props.get_all_children (); | |
1538 std::list<graphics_object> obj_list; | |
1539 std::list<graphics_object>::iterator it; | |
1540 | |
1541 // 1st pass: draw light objects | |
1542 | |
1543 // Start with the last element of the array of child objects to | |
1544 // display them in the oder they were added to the array. | |
1545 | |
1546 for (octave_idx_type i = children.numel () - 1; i >= 0; i--) | |
1547 { | |
1548 graphics_object go = gh_manager::get_object (children (i)); | |
1549 | |
1550 if (go.get_properties ().is_visible ()) | |
1551 { | |
1552 if (go.isa ("light")) | |
1553 draw (go); | |
1554 else | |
1555 obj_list.push_back (go); | |
1556 } | |
1557 } | |
1558 | |
1559 // 2nd pass: draw other objects (with units set to "data") | |
1560 | |
1561 it = obj_list.begin (); | |
1562 while (it != obj_list.end ()) | |
1563 { | |
1564 graphics_object go = (*it); | |
1565 | |
1566 // FIXME: check whether object has "units" property and it is set | |
1567 // to "data" | |
1568 if (! go.isa ("text") || go.get ("units").string_value () == "data") | |
1569 { | |
1570 set_clipping (go.get_properties ().is_clipping ()); | |
1571 draw (go); | |
1572 | |
1573 it = obj_list.erase (it); | |
1574 } | |
1575 else | |
1576 it++; | |
1577 } | |
1578 | |
1579 // 3rd pass: draw remaining objects | |
1580 | |
1581 glDisable (GL_DEPTH_TEST); | |
1582 | |
1583 for (it = obj_list.begin (); it != obj_list.end (); it++) | |
1584 { | |
1585 graphics_object go = (*it); | |
1586 | |
1587 set_clipping (go.get_properties ().is_clipping ()); | |
1588 draw (go); | |
1589 } | |
1590 | |
1591 glEnable (GL_DEPTH_TEST); | |
1592 | |
1593 set_clipping (false); | |
1594 | |
1595 // FIXME: finalize rendering (transparency processing) | |
1596 // FIXME: draw zoom box, if needed | |
1597 } | |
1598 | |
1599 void | |
1600 opengl_renderer::draw_axes (const axes::properties& props) | |
1601 { | |
1602 setup_opengl_transformation (props); | |
1603 | |
1604 // draw axes object | |
1605 | |
1606 const Matrix xlim = xform.xscale (props.get_xlim ().matrix_value ()); | |
1607 const Matrix ylim = xform.yscale (props.get_ylim ().matrix_value ()); | |
1608 const Matrix zlim = xform.zscale (props.get_zlim ().matrix_value ()); | |
1609 | |
1610 double x_min = xlim(0), x_max = xlim(1); | |
1611 double y_min = ylim(0), y_max = ylim(1); | |
1612 double z_min = zlim(0), z_max = zlim(1); | |
1613 | |
1614 double xd = (props.xdir_is ("normal") ? 1 : -1); | |
1615 double yd = (props.ydir_is ("normal") ? 1 : -1); | |
1616 double zd = (props.zdir_is ("normal") ? 1 : -1); | |
825 | 1617 |
826 ColumnVector p1, p2, xv (3), yv (3), zv (3); | 1618 ColumnVector p1, p2, xv (3), yv (3), zv (3); |
827 int xstate, ystate, zstate; | 1619 int xstate, ystate, zstate; |
828 | 1620 |
829 xstate = ystate = zstate = AXE_ANY_DIR; | 1621 xstate = ystate = zstate = AXE_ANY_DIR; |
974 | 1766 |
975 Matrix axe_color = props.get_color_rgb (); | 1767 Matrix axe_color = props.get_color_rgb (); |
976 bool visible = props.is_visible (); | 1768 bool visible = props.is_visible (); |
977 bool box = props.is_box (); | 1769 bool box = props.is_box (); |
978 | 1770 |
979 // Axes planes | 1771 draw_axes_planes (visible, axe_color, xlim, ylim, zlim, |
980 | 1772 xPlane, yPlane, zPlane); |
981 if (axe_color.numel () > 0 && visible) | 1773 |
982 { | 1774 draw_axes_boxes (props, visible, box, xySym, xPlane, yPlane, zPlane, |
983 set_color (axe_color); | 1775 xPlaneN, yPlaneN, zPlaneN, xpTick, ypTick, zpTick, |
984 set_polygon_offset (true, 2.5); | 1776 xpTickN, ypTickN, zpTickN); |
985 | 1777 |
986 glBegin (GL_QUADS); | |
987 | |
988 // X plane | |
989 glVertex3d (xPlane, y_min, z_min); | |
990 glVertex3d (xPlane, y_max, z_min); | |
991 glVertex3d (xPlane, y_max, z_max); | |
992 glVertex3d (xPlane, y_min, z_max); | |
993 | |
994 // Y plane | |
995 glVertex3d (x_min, yPlane, z_min); | |
996 glVertex3d (x_max, yPlane, z_min); | |
997 glVertex3d (x_max, yPlane, z_max); | |
998 glVertex3d (x_min, yPlane, z_max); | |
999 | |
1000 // Z plane | |
1001 glVertex3d (x_min, y_min, zPlane); | |
1002 glVertex3d (x_max, y_min, zPlane); | |
1003 glVertex3d (x_max, y_max, zPlane); | |
1004 glVertex3d (x_min, y_max, zPlane); | |
1005 | |
1006 glEnd (); | |
1007 | |
1008 set_polygon_offset (false); | |
1009 } | |
1010 | |
1011 // Axes box | |
1012 | |
1013 set_linestyle ("-", true); | |
1014 set_linewidth (props.get_linewidth ()); | |
1015 | |
1016 if (visible) | |
1017 { | |
1018 glBegin (GL_LINES); | |
1019 | |
1020 // X box | |
1021 set_color (props.get_xcolor_rgb ()); | |
1022 glVertex3d (xPlaneN, ypTick, zpTick); | |
1023 glVertex3d (xPlane, ypTick, zpTick); | |
1024 if (box) | |
1025 { | |
1026 glVertex3d (xPlaneN, ypTickN, zpTick); | |
1027 glVertex3d (xPlane, ypTickN, zpTick); | |
1028 glVertex3d (xPlaneN, ypTickN, zpTickN); | |
1029 glVertex3d (xPlane, ypTickN, zpTickN); | |
1030 glVertex3d (xPlaneN, ypTick, zpTickN); | |
1031 glVertex3d (xPlane, ypTick, zpTickN); | |
1032 } | |
1033 | |
1034 // Y box | |
1035 set_color (props.get_ycolor_rgb ()); | |
1036 glVertex3d (xpTick, yPlaneN, zpTick); | |
1037 glVertex3d (xpTick, yPlane, zpTick); | |
1038 if (box) | |
1039 { | |
1040 glVertex3d (xpTickN, yPlaneN, zpTick); | |
1041 glVertex3d (xpTickN, yPlane, zpTick); | |
1042 glVertex3d (xpTickN, yPlaneN, zpTickN); | |
1043 glVertex3d (xpTickN, yPlane, zpTickN); | |
1044 glVertex3d (xpTick, yPlaneN, zpTickN); | |
1045 glVertex3d (xpTick, yPlane, zpTickN); | |
1046 } | |
1047 | |
1048 // Z box | |
1049 set_color (props.get_zcolor_rgb ()); | |
1050 if (xySym) | |
1051 { | |
1052 glVertex3d (xPlaneN, yPlane, zPlaneN); | |
1053 glVertex3d (xPlaneN, yPlane, zPlane); | |
1054 } | |
1055 else | |
1056 { | |
1057 glVertex3d (xPlane, yPlaneN, zPlaneN); | |
1058 glVertex3d (xPlane, yPlaneN, zPlane); | |
1059 } | |
1060 if (box) | |
1061 { | |
1062 glVertex3d (xPlane, yPlane, zPlaneN); | |
1063 glVertex3d (xPlane, yPlane, zPlane); | |
1064 if (xySym) | |
1065 { | |
1066 glVertex3d (xPlane, yPlaneN, zPlaneN); | |
1067 glVertex3d (xPlane, yPlaneN, zPlane); | |
1068 } | |
1069 else | |
1070 { | |
1071 glVertex3d (xPlaneN, yPlane, zPlaneN); | |
1072 glVertex3d (xPlaneN, yPlane, zPlane); | |
1073 } | |
1074 glVertex3d (xPlaneN, yPlaneN, zPlaneN); | |
1075 glVertex3d (xPlaneN, yPlaneN, zPlane); | |
1076 } | |
1077 | |
1078 glEnd (); | |
1079 } | |
1080 | 1778 |
1081 std::string gridstyle = props.get_gridlinestyle (); | 1779 std::string gridstyle = props.get_gridlinestyle (); |
1082 std::string minorgridstyle = props.get_minorgridlinestyle (); | 1780 std::string minorgridstyle = props.get_minorgridlinestyle (); |
1083 | 1781 |
1084 set_font (props); | 1782 set_font (props); |
1085 | 1783 |
1086 // X grid | 1784 draw_axes_x_grid (props, visible, box, gridstyle, minorgridstyle, |
1087 | 1785 nearhoriz, tickdir, xyzSym, layer2Dtop, x2Dtop, |
1088 if (visible && xstate != AXE_DEPTH_DIR) | 1786 xstate, xlim(0), xlim(1), xticklen, xtickoffset, |
1089 { | 1787 fy, yPlane, yPlaneN, ypTick, ypTickN, |
1090 bool do_xgrid = (props.is_xgrid () && (gridstyle != "none")); | 1788 fz, zstate, zPlane, zPlaneN, zpTick, zpTickN); |
1091 bool do_xminorgrid = (props.is_xminorgrid () && (minorgridstyle != "none")); | 1789 |
1092 bool do_xminortick = props.is_xminortick (); | 1790 draw_axes_y_grid (props, visible, box, gridstyle, minorgridstyle, |
1093 Matrix xticks = xform.xscale (props.get_xtick ().matrix_value ()); | 1791 nearhoriz, tickdir, xyzSym, layer2Dtop, y2Dright, |
1094 Matrix xmticks = xform.xscale (props.get_xmtick ().matrix_value ()); | 1792 ystate, ylim(0), ylim(1), yticklen, ytickoffset, |
1095 string_vector xticklabels = props.get_xticklabel ().all_strings (); | 1793 fx, xPlane, xPlaneN, xpTick, xpTickN, |
1096 int wmax = 0, hmax = 0; | 1794 fz, zstate, zPlane, zPlaneN, zpTick, zpTickN); |
1097 bool tick_along_z = nearhoriz || xisinf (fy); | 1795 |
1098 | 1796 draw_axes_z_grid (props, visible, box, gridstyle, minorgridstyle, |
1099 set_color (props.get_xcolor_rgb ()); | 1797 tickdir, xySym, zSign, zstate, zlim(0), zlim(1), |
1100 | 1798 zticklen, ztickoffset, fx, xPlane, xPlaneN, |
1101 // grid lines | 1799 fy, yPlane, yPlaneN); |
1102 if (do_xgrid) | |
1103 render_grid (gridstyle, xticks, x_min, x_max, | |
1104 yPlane, yPlaneN, layer2Dtop ? zPlaneN : zPlane, zPlaneN, | |
1105 0, (zstate != AXE_DEPTH_DIR)); | |
1106 | |
1107 // tick marks | |
1108 if (tick_along_z) | |
1109 { | |
1110 render_tickmarks (xticks, x_min, x_max, ypTick, ypTick, zpTick, zpTickN, | |
1111 0., 0., signum(zpTick-zpTickN)*fz*xticklen*tickdir, | |
1112 0, (box && xstate != AXE_ANY_DIR)); | |
1113 } | |
1114 else | |
1115 { | |
1116 render_tickmarks (xticks, x_min, x_max, ypTick, ypTickN, zpTick, zpTick, | |
1117 0., signum(ypTick-ypTickN)*fy*xticklen*tickdir, 0., | |
1118 0, (box && xstate != AXE_ANY_DIR)); | |
1119 } | |
1120 | |
1121 // tick texts | |
1122 if (xticklabels.numel () > 0) | |
1123 { | |
1124 int halign = (xstate == AXE_HORZ_DIR ? 1 : (xyzSym ? 0 : 2)); | |
1125 int valign = (xstate == AXE_VERT_DIR ? 1 : (x2Dtop ? 0 : 2)); | |
1126 | |
1127 if (tick_along_z) | |
1128 { | |
1129 render_ticktexts (xticks, xticklabels, x_min, x_max, | |
1130 ypTick, zpTick+signum(zpTick-zpTickN)*fz*xtickoffset, | |
1131 0, halign, valign, wmax, hmax); | |
1132 } | |
1133 else | |
1134 { | |
1135 render_ticktexts (xticks, xticklabels, x_min, x_max, | |
1136 ypTick+signum(ypTick-ypTickN)*fy*xtickoffset, zpTick, | |
1137 0, halign, valign, wmax, hmax); | |
1138 } | |
1139 } | |
1140 | |
1141 // minor grid lines | |
1142 if (do_xminorgrid) | |
1143 render_grid (minorgridstyle, xmticks, x_min, x_max, | |
1144 yPlane, yPlaneN, layer2Dtop ? zPlaneN : zPlane, zPlaneN, | |
1145 0, (zstate != AXE_DEPTH_DIR)); | |
1146 | |
1147 // minor tick marks | |
1148 if (do_xminortick) | |
1149 { | |
1150 if (tick_along_z) | |
1151 { | |
1152 render_tickmarks (xmticks, x_min, x_max, ypTick, ypTick, zpTick, zpTickN, | |
1153 0., 0., signum(zpTick-zpTickN)*fz*xticklen/2*tickdir, | |
1154 0, (box && xstate != AXE_ANY_DIR)); | |
1155 } | |
1156 else | |
1157 { | |
1158 render_tickmarks (xmticks, x_min, x_max, ypTick, ypTickN, zpTick, zpTick, | |
1159 0., signum(ypTick-ypTickN)*fy*xticklen/2*tickdir, 0., | |
1160 0, (box && xstate != AXE_ANY_DIR)); | |
1161 } | |
1162 } | |
1163 | |
1164 text::properties& xlabel_props = | |
1165 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_xlabel ()).get_properties ()); | |
1166 | |
1167 xlabel_props.set_visible ("on"); | |
1168 | |
1169 if (! xlabel_props.get_string ().empty ()) | |
1170 { | |
1171 if (xlabel_props.horizontalalignmentmode_is("auto")) | |
1172 { | |
1173 xlabel_props.set_horizontalalignment (xstate > AXE_DEPTH_DIR ? "center" : (xyzSym ? "left" : "right")); | |
1174 xlabel_props.set_horizontalalignmentmode("auto"); | |
1175 } | |
1176 if (xlabel_props.verticalalignmentmode_is("auto")) | |
1177 { | |
1178 xlabel_props.set_verticalalignment (xstate == AXE_VERT_DIR || x2Dtop ? "bottom" : "top"); | |
1179 xlabel_props.set_verticalalignmentmode("auto"); | |
1180 } | |
1181 | |
1182 if (xlabel_props.positionmode_is("auto") || xlabel_props.rotationmode_is("auto")) | |
1183 { | |
1184 double angle = 0; | |
1185 ColumnVector p = graphics_xform::xform_vector ((x_min+x_max)/2, ypTick, zpTick); | |
1186 | |
1187 if (tick_along_z) | |
1188 p(2) += (signum(zpTick-zpTickN)*fz*xtickoffset); | |
1189 else | |
1190 p(1) += (signum(ypTick-ypTickN)*fy*xtickoffset); | |
1191 p = xform.transform (p(0), p(1), p(2), false); | |
1192 switch (xstate) | |
1193 { | |
1194 case AXE_ANY_DIR: | |
1195 p(0) += (xyzSym ? wmax : -wmax); | |
1196 p(1) += hmax; | |
1197 break; | |
1198 case AXE_VERT_DIR: | |
1199 p(0) -= wmax; | |
1200 angle = 90; | |
1201 break; | |
1202 case AXE_HORZ_DIR: | |
1203 p(1) += (x2Dtop ? -hmax : hmax); | |
1204 break; | |
1205 } | |
1206 if (xlabel_props.positionmode_is("auto")) | |
1207 { | |
1208 p = xform.untransform (p(0), p(1), p(2), true); | |
1209 xlabel_props.set_position (p.extract_n (0, 3).transpose ()); | |
1210 xlabel_props.set_positionmode ("auto"); | |
1211 } | |
1212 if (xlabel_props.rotationmode_is("auto")) | |
1213 { | |
1214 xlabel_props.set_rotation (angle); | |
1215 xlabel_props.set_rotationmode ("auto"); | |
1216 } | |
1217 } | |
1218 } | |
1219 } | |
1220 else | |
1221 { | |
1222 gh_manager::get_object (props.get_xlabel ()).set ("visible", "off"); | |
1223 } | |
1224 | |
1225 // Y grid | |
1226 | |
1227 if (ystate != AXE_DEPTH_DIR && visible) | |
1228 { | |
1229 bool do_ygrid = (props.is_ygrid () && (gridstyle != "none")); | |
1230 bool do_yminorgrid = (props.is_yminorgrid () && (minorgridstyle != "none")); | |
1231 bool do_yminortick = props.is_yminortick (); | |
1232 Matrix yticks = xform.yscale (props.get_ytick ().matrix_value ()); | |
1233 Matrix ymticks = xform.yscale (props.get_ymtick ().matrix_value ()); | |
1234 string_vector yticklabels = props.get_yticklabel ().all_strings (); | |
1235 int wmax = 0, hmax = 0; | |
1236 bool tick_along_z = nearhoriz || xisinf (fx); | |
1237 | |
1238 set_color (props.get_ycolor_rgb ()); | |
1239 | |
1240 // grid lines | |
1241 if (do_ygrid) | |
1242 render_grid (gridstyle, yticks, y_min, y_max, | |
1243 xPlane, xPlaneN, layer2Dtop ? zPlaneN : zPlane, zPlaneN, | |
1244 1, (zstate != AXE_DEPTH_DIR)); | |
1245 | |
1246 // tick marks | |
1247 if (tick_along_z) | |
1248 { | |
1249 render_tickmarks (yticks, y_min, y_max, xpTick, xpTick, zpTick, zpTickN, | |
1250 0., 0., signum(zpTick-zpTickN)*fz*yticklen*tickdir, | |
1251 1, (box && ystate != AXE_ANY_DIR)); | |
1252 } | |
1253 else | |
1254 { | |
1255 render_tickmarks (yticks, y_min, y_max, xpTick, xpTickN, zpTick, zpTick, | |
1256 signum(xPlaneN-xPlane)*fx*yticklen*tickdir, 0., 0., | |
1257 1, (box && ystate != AXE_ANY_DIR)); | |
1258 } | |
1259 | |
1260 // tick texts | |
1261 if (yticklabels.numel () > 0) | |
1262 { | |
1263 int halign = (ystate == AXE_HORZ_DIR ? 1 : (!xyzSym || y2Dright ? 0 : 2)); | |
1264 int valign = (ystate == AXE_VERT_DIR ? 1 : 2); | |
1265 | |
1266 if (tick_along_z) | |
1267 { | |
1268 render_ticktexts (yticks, yticklabels, y_min, y_max, | |
1269 xpTick, zpTick+signum(zpTick-zpTickN)*fz*ytickoffset, | |
1270 1, halign, valign, wmax, hmax); | |
1271 } | |
1272 else | |
1273 { | |
1274 render_ticktexts (yticks, yticklabels, y_min, y_max, | |
1275 xpTick+signum(xpTick-xpTickN)*fx*ytickoffset, zpTick, | |
1276 1, halign, valign, wmax, hmax); | |
1277 } | |
1278 } | |
1279 | |
1280 // minor grid lines | |
1281 if (do_yminorgrid) | |
1282 render_grid (minorgridstyle, ymticks, y_min, y_max, | |
1283 xPlane, xPlaneN, layer2Dtop ? zPlaneN : zPlane, zPlaneN, | |
1284 1, (zstate != AXE_DEPTH_DIR)); | |
1285 | |
1286 // minor tick marks | |
1287 if (do_yminortick) | |
1288 { | |
1289 if (tick_along_z) | |
1290 { | |
1291 render_tickmarks (ymticks, y_min, y_max, xpTick, xpTick, zpTick, zpTickN, | |
1292 0., 0., signum(zpTick-zpTickN)*fz*yticklen/2*tickdir, | |
1293 1, (box && ystate != AXE_ANY_DIR)); | |
1294 } | |
1295 else | |
1296 { | |
1297 render_tickmarks (ymticks, y_min, y_max, xpTick, xpTickN, zpTick, zpTick, | |
1298 signum(xpTick-xpTickN)*fx*yticklen/2*tickdir, 0., 0., | |
1299 1, (box && ystate != AXE_ANY_DIR)); | |
1300 } | |
1301 } | |
1302 | |
1303 text::properties& ylabel_props = | |
1304 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_ylabel ()).get_properties ()); | |
1305 | |
1306 ylabel_props.set_visible ("on"); | |
1307 | |
1308 if (! ylabel_props.get_string ().empty ()) | |
1309 { | |
1310 if (ylabel_props.horizontalalignmentmode_is("auto")) | |
1311 { | |
1312 ylabel_props.set_horizontalalignment (ystate > AXE_DEPTH_DIR ? "center" : (!xyzSym ? "left" : "right")); | |
1313 ylabel_props.set_horizontalalignmentmode("auto"); | |
1314 } | |
1315 if (ylabel_props.verticalalignmentmode_is("auto")) | |
1316 { | |
1317 ylabel_props.set_verticalalignment (ystate == AXE_VERT_DIR && !y2Dright ? "bottom" : "top"); | |
1318 ylabel_props.set_verticalalignmentmode("auto"); | |
1319 } | |
1320 | |
1321 if (ylabel_props.positionmode_is("auto") || ylabel_props.rotationmode_is("auto")) | |
1322 { | |
1323 double angle = 0; | |
1324 ColumnVector p = graphics_xform::xform_vector (xpTick, (y_min+y_max)/2, zpTick); | |
1325 | |
1326 if (tick_along_z) | |
1327 p(2) += (signum(zpTick-zpTickN)*fz*ytickoffset); | |
1328 else | |
1329 p(0) += (signum(xpTick-xpTickN)*fx*ytickoffset); | |
1330 p = xform.transform (p(0), p(1), p(2), false); | |
1331 switch (ystate) | |
1332 { | |
1333 case AXE_ANY_DIR: | |
1334 p(0) += (!xyzSym ? wmax : -wmax); | |
1335 p(1) += hmax; | |
1336 break; | |
1337 case AXE_VERT_DIR: | |
1338 p(0) += (y2Dright ? wmax : -wmax); | |
1339 angle = 90; | |
1340 break; | |
1341 case AXE_HORZ_DIR: | |
1342 p(1) += hmax; | |
1343 break; | |
1344 } | |
1345 if (ylabel_props.positionmode_is("auto")) | |
1346 { | |
1347 p = xform.untransform (p(0), p(1), p(2), true); | |
1348 ylabel_props.set_position (p.extract_n (0, 3).transpose ()); | |
1349 ylabel_props.set_positionmode ("auto"); | |
1350 } | |
1351 if (ylabel_props.rotationmode_is("auto")) | |
1352 { | |
1353 ylabel_props.set_rotation (angle); | |
1354 ylabel_props.set_rotationmode ("auto"); | |
1355 } | |
1356 } | |
1357 } | |
1358 } | |
1359 else | |
1360 { | |
1361 gh_manager::get_object (props.get_ylabel ()).set ("visible", "off"); | |
1362 } | |
1363 | |
1364 // Z Grid | |
1365 | |
1366 if (zstate != AXE_DEPTH_DIR && visible) | |
1367 { | |
1368 bool do_zgrid = (props.is_zgrid () && (gridstyle != "none")); | |
1369 bool do_zminorgrid = (props.is_zminorgrid () && (minorgridstyle != "none")); | |
1370 bool do_zminortick = props.is_zminortick (); | |
1371 Matrix zticks = xform.zscale (props.get_ztick ().matrix_value ()); | |
1372 Matrix zmticks = xform.zscale (props.get_zmtick ().matrix_value ()); | |
1373 string_vector zticklabels = props.get_zticklabel ().all_strings (); | |
1374 int wmax = 0, hmax = 0; | |
1375 | |
1376 set_color (props.get_zcolor_rgb ()); | |
1377 | |
1378 // grid lines | |
1379 if (do_zgrid) | |
1380 render_grid (gridstyle, zticks, z_min, z_max, | |
1381 xPlane, xPlaneN, yPlane, yPlaneN, 2, true); | |
1382 | |
1383 // tick marks | |
1384 if (xySym) | |
1385 { | |
1386 if (xisinf (fy)) | |
1387 { | |
1388 render_tickmarks( zticks, z_min, z_max, xPlaneN, xPlane, yPlane, yPlane, | |
1389 signum(xPlaneN-xPlane)*fx*zticklen*tickdir, 0., 0., | |
1390 2, (box && zstate != AXE_ANY_DIR)); | |
1391 } | |
1392 else | |
1393 { | |
1394 render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlaneN, yPlane, yPlane, | |
1395 0., signum(yPlane-yPlaneN)*fy*zticklen*tickdir, 0., | |
1396 2, false); | |
1397 } | |
1398 } | |
1399 else | |
1400 { | |
1401 if (xisinf (fx)) | |
1402 { | |
1403 render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlane, yPlaneN, yPlane, | |
1404 0., signum(yPlaneN-yPlane)*fy*zticklen*tickdir, 0., | |
1405 2, (box && zstate != AXE_ANY_DIR)); | |
1406 } | |
1407 else | |
1408 { | |
1409 render_tickmarks (zticks, z_min, z_max, xPlane, xPlane, yPlaneN, yPlane, | |
1410 signum(xPlane-xPlaneN)*fx*zticklen*tickdir, 0., 0., | |
1411 2, false); | |
1412 } | |
1413 } | |
1414 | |
1415 // FIXME: tick texts | |
1416 if (zticklabels.numel () > 0) | |
1417 { | |
1418 int halign = 2; | |
1419 int valign = (zstate == AXE_VERT_DIR ? 1 : (zSign ? 3 : 2)); | |
1420 | |
1421 if (xySym) | |
1422 { | |
1423 if (xisinf (fy)) | |
1424 { | |
1425 render_ticktexts (zticks, zticklabels, z_min, z_max, | |
1426 xPlaneN+signum(xPlaneN-xPlane)*fx*ztickoffset, yPlane, | |
1427 2, halign, valign, wmax, hmax); | |
1428 } | |
1429 else | |
1430 { | |
1431 render_ticktexts (zticks, zticklabels, z_min, z_max, | |
1432 xPlaneN, yPlane+signum(yPlane-yPlaneN)*fy*ztickoffset, | |
1433 2, halign, valign, wmax, hmax); | |
1434 } | |
1435 } | |
1436 else | |
1437 { | |
1438 if (xisinf (fx)) | |
1439 { | |
1440 render_ticktexts (zticks, zticklabels, z_min, z_max, | |
1441 xPlane, yPlaneN+signum(yPlaneN-yPlane)*fy*ztickoffset, | |
1442 2, halign, valign, wmax, hmax); | |
1443 } | |
1444 else | |
1445 { | |
1446 render_ticktexts (zticks, zticklabels, z_min, z_max, | |
1447 xPlane+signum(xPlane-xPlaneN)*fx*ztickoffset, yPlaneN, | |
1448 2, halign, valign, wmax, hmax); | |
1449 } | |
1450 } | |
1451 } | |
1452 | |
1453 // minor grid lines | |
1454 if (do_zminorgrid) | |
1455 render_grid (minorgridstyle, zmticks, z_min, z_max, | |
1456 xPlane, xPlaneN, yPlane, yPlaneN, 2, true); | |
1457 | |
1458 // minor tick marks | |
1459 if (do_zminortick) | |
1460 { | |
1461 if (xySym) | |
1462 { | |
1463 if (xisinf (fy)) | |
1464 { | |
1465 render_tickmarks( zmticks, z_min, z_max, xPlaneN, xPlane, yPlane, yPlane, | |
1466 signum(xPlaneN-xPlane)*fx*zticklen/2*tickdir, 0., 0., | |
1467 2, (box && zstate != AXE_ANY_DIR)); | |
1468 } | |
1469 else | |
1470 { | |
1471 render_tickmarks (zmticks, z_min, z_max, xPlaneN, xPlaneN, yPlane, yPlane, | |
1472 0., signum(yPlane-yPlaneN)*fy*zticklen/2*tickdir, 0., | |
1473 2, false); | |
1474 } | |
1475 } | |
1476 else | |
1477 { | |
1478 if (xisinf (fx)) | |
1479 { | |
1480 render_tickmarks (zmticks, z_min, z_max, xPlane, xPlane, yPlaneN, yPlane, | |
1481 0., signum(yPlaneN-yPlane)*fy*zticklen/2*tickdir, 0., | |
1482 2, (box && zstate != AXE_ANY_DIR)); | |
1483 } | |
1484 else | |
1485 { | |
1486 render_tickmarks (zmticks, z_min, z_max, xPlane, xPlane, yPlaneN, yPlaneN, | |
1487 signum(xPlane-xPlaneN)*fx*zticklen/2*tickdir, 0., 0., | |
1488 2, false); | |
1489 } | |
1490 } | |
1491 } | |
1492 | |
1493 text::properties& zlabel_props = | |
1494 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_zlabel ()).get_properties ()); | |
1495 | |
1496 zlabel_props.set_visible ("on"); | |
1497 | |
1498 if (! zlabel_props.get_string ().empty ()) | |
1499 { | |
1500 bool camAuto = props.cameraupvectormode_is ("auto"); | |
1501 | |
1502 if (zlabel_props.horizontalalignmentmode_is("auto")) | |
1503 { | |
1504 zlabel_props.set_horizontalalignment ((zstate > AXE_DEPTH_DIR || camAuto) ? "center" : "right"); | |
1505 zlabel_props.set_horizontalalignmentmode("auto"); | |
1506 } | |
1507 if (zlabel_props.verticalalignmentmode_is("auto")) | |
1508 { | |
1509 zlabel_props.set_verticalalignment(zstate == AXE_VERT_DIR ? "bottom" : ((zSign || camAuto) ? "bottom" : "top")); | |
1510 zlabel_props.set_verticalalignmentmode("auto"); | |
1511 } | |
1512 | |
1513 if (zlabel_props.positionmode_is("auto") || zlabel_props.rotationmode_is("auto")) | |
1514 { | |
1515 double angle = 0; | |
1516 ColumnVector p; | |
1517 | |
1518 if (xySym) | |
1519 { | |
1520 p = graphics_xform::xform_vector (xPlaneN, yPlane, (z_min+z_max)/2); | |
1521 if (xisinf (fy)) | |
1522 p(0) += (signum(xPlaneN-xPlane)*fx*ztickoffset); | |
1523 else | |
1524 p(1) += (signum(yPlane-yPlaneN)*fy*ztickoffset); | |
1525 } | |
1526 else | |
1527 { | |
1528 p = graphics_xform::xform_vector (xPlane, yPlaneN, (z_min+z_max)/2); | |
1529 if (xisinf (fx)) | |
1530 p(1) += (signum(yPlaneN-yPlane)*fy*ztickoffset); | |
1531 else | |
1532 p(0) += (signum(xPlane-xPlaneN)*fx*ztickoffset); | |
1533 } | |
1534 p = xform.transform (p(0), p(1), p(2), false); | |
1535 switch (zstate) | |
1536 { | |
1537 case AXE_ANY_DIR: | |
1538 if (camAuto) | |
1539 { | |
1540 p(0) -= wmax; | |
1541 angle = 90; | |
1542 } | |
1543 /* FIXME: what's the correct offset? | |
1544 p[0] += (!xySym ? wmax : -wmax); | |
1545 p[1] += (zSign ? hmax : -hmax); | |
1546 */ | |
1547 break; | |
1548 case AXE_VERT_DIR: | |
1549 p(0) -= wmax; | |
1550 angle = 90; | |
1551 break; | |
1552 case AXE_HORZ_DIR: | |
1553 p(1) += hmax; | |
1554 break; | |
1555 } | |
1556 if (zlabel_props.positionmode_is("auto")) | |
1557 { | |
1558 p = xform.untransform (p(0), p(1), p(2), true); | |
1559 zlabel_props.set_position (p.extract_n (0, 3).transpose ()); | |
1560 zlabel_props.set_positionmode ("auto"); | |
1561 } | |
1562 if (zlabel_props.rotationmode_is("auto")) | |
1563 { | |
1564 zlabel_props.set_rotation (angle); | |
1565 zlabel_props.set_rotationmode ("auto"); | |
1566 } | |
1567 } | |
1568 } | |
1569 } | |
1570 else | |
1571 { | |
1572 gh_manager::get_object (props.get_zlabel ()).set ("visible", "off"); | |
1573 } | |
1574 | 1800 |
1575 set_linestyle ("-"); | 1801 set_linestyle ("-"); |
1576 | 1802 |
1577 // Title | 1803 draw_axes_title (props, xlim(0), xlim(1), ylim(0), ylim(1), |
1578 | 1804 zlim(0), zlim(1)); |
1579 text::properties& title_props = | 1805 |
1580 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_title ()).get_properties ()); | 1806 draw_axes_children (props); |
1581 | |
1582 if (! title_props.get_string ().empty () && title_props.positionmode_is("auto")) | |
1583 { | |
1584 ColumnVector p = xform.untransform (bbox(0)+bbox(2)/2, (bbox(1)-10), | |
1585 (x_zlim(0)+x_zlim(1))/2, true); | |
1586 title_props.set_position (p.extract_n(0, 3).transpose ()); | |
1587 title_props.set_positionmode ("auto"); | |
1588 } | |
1589 | |
1590 set_clipbox (x_min, x_max, y_min, y_max, z_min, z_max); | |
1591 | |
1592 // Children | |
1593 | |
1594 if (antialias == GL_TRUE) | |
1595 glEnable (GL_LINE_SMOOTH); | |
1596 | |
1597 Matrix children = props.get_all_children (); | |
1598 std::list<graphics_object> obj_list; | |
1599 std::list<graphics_object>::iterator it; | |
1600 | |
1601 // 1st pass: draw light objects | |
1602 | |
1603 // Start with the last element of the array of child objects to | |
1604 // display them in the oder they were added to the array. | |
1605 | |
1606 for (octave_idx_type i = children.numel () - 1; i >= 0; i--) | |
1607 { | |
1608 graphics_object go = gh_manager::get_object (children (i)); | |
1609 | |
1610 if (go.get_properties ().is_visible ()) | |
1611 { | |
1612 if (go.isa ("light")) | |
1613 draw (go); | |
1614 else | |
1615 obj_list.push_back (go); | |
1616 } | |
1617 } | |
1618 | |
1619 // 2nd pass: draw other objects (with units set to "data") | |
1620 | |
1621 it = obj_list.begin (); | |
1622 while (it != obj_list.end ()) | |
1623 { | |
1624 graphics_object go = (*it); | |
1625 | |
1626 // FIXME: check whether object has "units" property and it is set to "data" | |
1627 if (! go.isa ("text") || go.get ("units").string_value () == "data") | |
1628 { | |
1629 set_clipping (go.get_properties ().is_clipping ()); | |
1630 draw (go); | |
1631 | |
1632 it = obj_list.erase (it); | |
1633 } | |
1634 else | |
1635 it++; | |
1636 } | |
1637 | |
1638 // 3rd pass: draw remaining objects | |
1639 | |
1640 glDisable (GL_DEPTH_TEST); | |
1641 for (it = obj_list.begin (); it != obj_list.end (); it++) | |
1642 { | |
1643 graphics_object go = (*it); | |
1644 | |
1645 set_clipping (go.get_properties ().is_clipping ()); | |
1646 draw (go); | |
1647 } | |
1648 glEnable (GL_DEPTH_TEST); | |
1649 | |
1650 set_clipping (false); | |
1651 // FIXME: finalize rendering (transparency processing) | |
1652 // FIXME: draw zoom box, if needed | |
1653 } | 1807 } |
1654 | 1808 |
1655 void | 1809 void |
1656 opengl_renderer::draw_line (const line::properties& props) | 1810 opengl_renderer::draw_line (const line::properties& props) |
1657 { | 1811 { |