comparison src/gl-render.cc @ 12334:63dc132a1000

Move axes labels and title positioning to axes::properties
author Konstantinos Poulios <logari81@gmail.com>
date Thu, 03 Feb 2011 19:30:13 +0100
parents f103b9c1ca05
children 24b38afd6a45
comparison
equal deleted inserted replaced
12333:f103b9c1ca05 12334:63dc132a1000
1025 zpTick, zpTick, 0., 1025 zpTick, zpTick, 0.,
1026 signum(ypTick-ypTickN)*fy*xticklen/2, 1026 signum(ypTick-ypTickN)*fy*xticklen/2,
1027 0., 0, (box && xstate != AXE_ANY_DIR)); 1027 0., 0, (box && xstate != AXE_ANY_DIR));
1028 } 1028 }
1029 1029
1030 text::properties& xlabel_props = 1030 gh_manager::get_object (props.get_xlabel ()).set ("visible", "on");
1031 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_xlabel ()).get_properties ());
1032
1033 xlabel_props.set_visible ("on");
1034
1035 if (! xlabel_props.get_string ().empty ())
1036 {
1037 if (xlabel_props.horizontalalignmentmode_is ("auto"))
1038 {
1039 xlabel_props.set_horizontalalignment
1040 (xstate > AXE_DEPTH_DIR
1041 ? "center" : (xyzSym ? "left" : "right"));
1042
1043 xlabel_props.set_horizontalalignmentmode ("auto");
1044 }
1045
1046 if (xlabel_props.verticalalignmentmode_is ("auto"))
1047 {
1048 xlabel_props.set_verticalalignment
1049 (xstate == AXE_VERT_DIR || x2Dtop ? "bottom" : "top");
1050
1051 xlabel_props.set_verticalalignmentmode ("auto");
1052 }
1053
1054 if (xlabel_props.positionmode_is ("auto")
1055 || xlabel_props.rotationmode_is ("auto"))
1056 {
1057 double angle = 0;
1058 ColumnVector p
1059 = graphics_xform::xform_vector ((x_min+x_max)/2,
1060 ypTick, zpTick);
1061
1062 if (tick_along_z)
1063 p(2) += (signum(zpTick-zpTickN)*fz*xtickoffset);
1064 else
1065 p(1) += (signum(ypTick-ypTickN)*fy*xtickoffset);
1066
1067 p = xform.transform (p(0), p(1), p(2), false);
1068
1069 switch (xstate)
1070 {
1071 case AXE_ANY_DIR:
1072 p(0) += (xyzSym ? wmax : -wmax);
1073 p(1) += hmax;
1074 break;
1075
1076 case AXE_VERT_DIR:
1077 p(0) -= wmax;
1078 angle = 90;
1079 break;
1080
1081 case AXE_HORZ_DIR:
1082 p(1) += (x2Dtop ? -hmax : hmax);
1083 break;
1084 }
1085
1086 if (xlabel_props.positionmode_is ("auto"))
1087 {
1088 p = xform.untransform (p(0), p(1), p(2), true);
1089 xlabel_props.set_position (p.extract_n (0, 3).transpose ());
1090 xlabel_props.set_positionmode ("auto");
1091 }
1092
1093 if (xlabel_props.rotationmode_is ("auto"))
1094 {
1095 xlabel_props.set_rotation (angle);
1096 xlabel_props.set_rotationmode ("auto");
1097 }
1098 }
1099 }
1100 } 1031 }
1101 else 1032 else
1102 gh_manager::get_object (props.get_xlabel ()).set ("visible", "off"); 1033 gh_manager::get_object (props.get_xlabel ()).set ("visible", "off");
1103 } 1034 }
1104 1035
1198 zpTick, zpTick, 1129 zpTick, zpTick,
1199 signum(xpTick-xpTickN)*fx*yticklen/2, 1130 signum(xpTick-xpTickN)*fx*yticklen/2,
1200 0., 0., 1, (box && ystate != AXE_ANY_DIR)); 1131 0., 0., 1, (box && ystate != AXE_ANY_DIR));
1201 } 1132 }
1202 1133
1203 text::properties& ylabel_props = 1134 gh_manager::get_object (props.get_ylabel ()).set ("visible", "on");
1204 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_ylabel ()).get_properties ());
1205
1206 ylabel_props.set_visible ("on");
1207
1208 if (! ylabel_props.get_string ().empty ())
1209 {
1210 if (ylabel_props.horizontalalignmentmode_is ("auto"))
1211 {
1212 ylabel_props.set_horizontalalignment
1213 (ystate > AXE_DEPTH_DIR
1214 ? "center" : (!xyzSym ? "left" : "right"));
1215
1216 ylabel_props.set_horizontalalignmentmode ("auto");
1217 }
1218
1219 if (ylabel_props.verticalalignmentmode_is ("auto"))
1220 {
1221 ylabel_props.set_verticalalignment
1222 (ystate == AXE_VERT_DIR && !y2Dright ? "bottom" : "top");
1223
1224 ylabel_props.set_verticalalignmentmode ("auto");
1225 }
1226
1227 if (ylabel_props.positionmode_is ("auto")
1228 || ylabel_props.rotationmode_is ("auto"))
1229 {
1230 double angle = 0;
1231 ColumnVector p = graphics_xform::xform_vector (xpTick, (y_min+y_max)/2, zpTick);
1232
1233 if (tick_along_z)
1234 p(2) += (signum(zpTick-zpTickN)*fz*ytickoffset);
1235 else
1236 p(0) += (signum(xpTick-xpTickN)*fx*ytickoffset);
1237
1238 p = xform.transform (p(0), p(1), p(2), false);
1239
1240 switch (ystate)
1241 {
1242 case AXE_ANY_DIR:
1243 p(0) += (!xyzSym ? wmax : -wmax);
1244 p(1) += hmax;
1245 break;
1246
1247 case AXE_VERT_DIR:
1248 p(0) += (y2Dright ? wmax : -wmax);
1249 angle = 90;
1250 break;
1251
1252 case AXE_HORZ_DIR:
1253 p(1) += hmax;
1254 break;
1255 }
1256
1257 if (ylabel_props.positionmode_is ("auto"))
1258 {
1259 p = xform.untransform (p(0), p(1), p(2), true);
1260 ylabel_props.set_position (p.extract_n (0, 3).transpose ());
1261 ylabel_props.set_positionmode ("auto");
1262 }
1263
1264 if (ylabel_props.rotationmode_is ("auto"))
1265 {
1266 ylabel_props.set_rotation (angle);
1267 ylabel_props.set_rotationmode ("auto");
1268 }
1269 }
1270 }
1271 } 1135 }
1272 else 1136 else
1273 gh_manager::get_object (props.get_ylabel ()).set ("visible", "off"); 1137 gh_manager::get_object (props.get_ylabel ()).set ("visible", "off");
1274 } 1138 }
1275 1139
1404 signum(xPlane-xPlaneN)*fx*zticklen/2, 1268 signum(xPlane-xPlaneN)*fx*zticklen/2,
1405 0., 0., 2, false); 1269 0., 0., 2, false);
1406 } 1270 }
1407 } 1271 }
1408 1272
1409 text::properties& zlabel_props = 1273 gh_manager::get_object (props.get_zlabel ()).set ("visible", "on");
1410 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_zlabel ()).get_properties ());
1411
1412 zlabel_props.set_visible ("on");
1413
1414 if (! zlabel_props.get_string ().empty ())
1415 {
1416 bool camAuto = props.cameraupvectormode_is ("auto");
1417
1418 if (zlabel_props.horizontalalignmentmode_is ("auto"))
1419 {
1420 zlabel_props.set_horizontalalignment
1421 ((zstate > AXE_DEPTH_DIR || camAuto) ? "center" : "right");
1422
1423 zlabel_props.set_horizontalalignmentmode ("auto");
1424 }
1425
1426 if (zlabel_props.verticalalignmentmode_is ("auto"))
1427 {
1428 zlabel_props.set_verticalalignment
1429 (zstate == AXE_VERT_DIR
1430 ? "bottom" : ((zSign || camAuto) ? "bottom" : "top"));
1431
1432 zlabel_props.set_verticalalignmentmode ("auto");
1433 }
1434
1435 if (zlabel_props.positionmode_is ("auto")
1436 || zlabel_props.rotationmode_is ("auto"))
1437 {
1438 double angle = 0;
1439 ColumnVector p;
1440
1441 if (xySym)
1442 {
1443 p = graphics_xform::xform_vector (xPlaneN, yPlane,
1444 (z_min+z_max)/2);
1445 if (xisinf (fy))
1446 p(0) += (signum(xPlaneN-xPlane)*fx*ztickoffset);
1447 else
1448 p(1) += (signum(yPlane-yPlaneN)*fy*ztickoffset);
1449 }
1450 else
1451 {
1452 p = graphics_xform::xform_vector (xPlane, yPlaneN,
1453 (z_min+z_max)/2);
1454 if (xisinf (fx))
1455 p(1) += (signum(yPlaneN-yPlane)*fy*ztickoffset);
1456 else
1457 p(0) += (signum(xPlane-xPlaneN)*fx*ztickoffset);
1458 }
1459
1460 p = xform.transform (p(0), p(1), p(2), false);
1461
1462 switch (zstate)
1463 {
1464 case AXE_ANY_DIR:
1465 if (camAuto)
1466 {
1467 p(0) -= wmax;
1468 angle = 90;
1469 }
1470
1471 // FIXME -- what's the correct offset?
1472 //
1473 // p[0] += (!xySym ? wmax : -wmax);
1474 // p[1] += (zSign ? hmax : -hmax);
1475
1476 break;
1477
1478 case AXE_VERT_DIR:
1479 p(0) -= wmax;
1480 angle = 90;
1481 break;
1482
1483 case AXE_HORZ_DIR:
1484 p(1) += hmax;
1485 break;
1486 }
1487
1488 if (zlabel_props.positionmode_is ("auto"))
1489 {
1490 p = xform.untransform (p(0), p(1), p(2), true);
1491 zlabel_props.set_position (p.extract_n (0, 3).transpose ());
1492 zlabel_props.set_positionmode ("auto");
1493 }
1494
1495 if (zlabel_props.rotationmode_is ("auto"))
1496 {
1497 zlabel_props.set_rotation (angle);
1498 zlabel_props.set_rotationmode ("auto");
1499 }
1500 }
1501 }
1502 } 1274 }
1503 else 1275 else
1504 gh_manager::get_object (props.get_zlabel ()).set ("visible", "off"); 1276 gh_manager::get_object (props.get_zlabel ()).set ("visible", "off");
1505 } 1277 }
1506 1278
1507 void 1279 void
1508 opengl_renderer::draw_axes_title (const axes::properties& props) 1280 opengl_renderer::draw_axes_children (const axes::properties& props)
1281 {
1282 // Children
1283
1284 GLboolean antialias;
1285 glGetBooleanv (GL_LINE_SMOOTH, &antialias);
1286
1287 if (antialias == GL_TRUE)
1288 glEnable (GL_LINE_SMOOTH);
1289
1290 Matrix children = props.get_all_children ();
1291 std::list<graphics_object> obj_list;
1292 std::list<graphics_object>::iterator it;
1293
1294 // 1st pass: draw light objects
1295
1296 // Start with the last element of the array of child objects to
1297 // display them in the oder they were added to the array.
1298
1299 for (octave_idx_type i = children.numel () - 1; i >= 0; i--)
1300 {
1301 graphics_object go = gh_manager::get_object (children (i));
1302
1303 if (go.get_properties ().is_visible ())
1304 {
1305 if (go.isa ("light"))
1306 draw (go);
1307 else
1308 obj_list.push_back (go);
1309 }
1310 }
1311
1312 // 2nd pass: draw other objects (with units set to "data")
1313
1314 it = obj_list.begin ();
1315 while (it != obj_list.end ())
1316 {
1317 graphics_object go = (*it);
1318
1319 // FIXME: check whether object has "units" property and it is set
1320 // to "data"
1321 if (! go.isa ("text") || go.get ("units").string_value () == "data")
1322 {
1323 set_clipping (go.get_properties ().is_clipping ());
1324 draw (go);
1325
1326 it = obj_list.erase (it);
1327 }
1328 else
1329 it++;
1330 }
1331
1332 // 3rd pass: draw remaining objects
1333
1334 glDisable (GL_DEPTH_TEST);
1335
1336 for (it = obj_list.begin (); it != obj_list.end (); it++)
1337 {
1338 graphics_object go = (*it);
1339
1340 set_clipping (go.get_properties ().is_clipping ());
1341 draw (go);
1342 }
1343
1344 glEnable (GL_DEPTH_TEST);
1345
1346 set_clipping (false);
1347
1348 // FIXME: finalize rendering (transparency processing)
1349 // FIXME: draw zoom box, if needed
1350 }
1351
1352 void
1353 opengl_renderer::draw_axes (const axes::properties& props)
1509 { 1354 {
1510 double x_min = props.get_x_min (); 1355 double x_min = props.get_x_min ();
1511 double x_max = props.get_x_max (); 1356 double x_max = props.get_x_max ();
1512 double y_min = props.get_y_min (); 1357 double y_min = props.get_y_min ();
1513 double y_max = props.get_y_max (); 1358 double y_max = props.get_y_max ();
1514 double z_min = props.get_z_min (); 1359 double z_min = props.get_z_min ();
1515 double z_max = props.get_z_max (); 1360 double z_max = props.get_z_max ();
1516 1361
1517 // Title
1518
1519 // FIXME: bbox has to be moved to axes::properties
1520 ColumnVector bbox(4);
1521 bbox(0) = octave_Inf;
1522 bbox(1) = octave_Inf;
1523 bbox(2) = -octave_Inf;
1524 bbox(3) = -octave_Inf;
1525 for (int i = 0; i <= 1; i++)
1526 for (int j = 0; j <= 1; j++)
1527 for (int k = 0; k <= 1; k++)
1528 {
1529 ColumnVector p = xform.transform (i ? x_max : x_min,
1530 j ? y_max : y_min,
1531 k ? z_max : z_min, false);
1532 bbox(0) = std::min (bbox(0), p(0));
1533 bbox(1) = std::min (bbox(1), p(1));
1534 bbox(2) = std::max (bbox(2), p(0));
1535 bbox(3) = std::max (bbox(3), p(1));
1536 }
1537
1538 bbox(2) = bbox(2)-bbox(0);
1539 bbox(3) = bbox(3)-bbox(1);
1540
1541 Matrix x_zlim = props.get_transform_zlim ();
1542
1543 text::properties& title_props =
1544 reinterpret_cast<text::properties&> (gh_manager::get_object (props.get_title ()).get_properties ());
1545
1546 if (! title_props.get_string ().empty ()
1547 && title_props.positionmode_is ("auto"))
1548 {
1549 ColumnVector p = xform.untransform (bbox(0)+bbox(2)/2, (bbox(1)-10),
1550 (x_zlim(0)+x_zlim(1))/2, true);
1551
1552 title_props.set_position (p.extract_n(0, 3).transpose ());
1553 title_props.set_positionmode ("auto");
1554 }
1555
1556 set_clipbox (x_min, x_max, y_min, y_max, z_min, z_max);
1557 }
1558
1559 void
1560 opengl_renderer::draw_axes_children (const axes::properties& props)
1561 {
1562 // Children
1563
1564 GLboolean antialias;
1565 glGetBooleanv (GL_LINE_SMOOTH, &antialias);
1566
1567 if (antialias == GL_TRUE)
1568 glEnable (GL_LINE_SMOOTH);
1569
1570 Matrix children = props.get_all_children ();
1571 std::list<graphics_object> obj_list;
1572 std::list<graphics_object>::iterator it;
1573
1574 // 1st pass: draw light objects
1575
1576 // Start with the last element of the array of child objects to
1577 // display them in the oder they were added to the array.
1578
1579 for (octave_idx_type i = children.numel () - 1; i >= 0; i--)
1580 {
1581 graphics_object go = gh_manager::get_object (children (i));
1582
1583 if (go.get_properties ().is_visible ())
1584 {
1585 if (go.isa ("light"))
1586 draw (go);
1587 else
1588 obj_list.push_back (go);
1589 }
1590 }
1591
1592 // 2nd pass: draw other objects (with units set to "data")
1593
1594 it = obj_list.begin ();
1595 while (it != obj_list.end ())
1596 {
1597 graphics_object go = (*it);
1598
1599 // FIXME: check whether object has "units" property and it is set
1600 // to "data"
1601 if (! go.isa ("text") || go.get ("units").string_value () == "data")
1602 {
1603 set_clipping (go.get_properties ().is_clipping ());
1604 draw (go);
1605
1606 it = obj_list.erase (it);
1607 }
1608 else
1609 it++;
1610 }
1611
1612 // 3rd pass: draw remaining objects
1613
1614 glDisable (GL_DEPTH_TEST);
1615
1616 for (it = obj_list.begin (); it != obj_list.end (); it++)
1617 {
1618 graphics_object go = (*it);
1619
1620 set_clipping (go.get_properties ().is_clipping ());
1621 draw (go);
1622 }
1623
1624 glEnable (GL_DEPTH_TEST);
1625
1626 set_clipping (false);
1627
1628 // FIXME: finalize rendering (transparency processing)
1629 // FIXME: draw zoom box, if needed
1630 }
1631
1632 void
1633 opengl_renderer::draw_axes (const axes::properties& props)
1634 {
1635 setup_opengl_transformation (props); 1362 setup_opengl_transformation (props);
1636 1363
1637 // draw axes object 1364 // draw axes object
1638 1365
1639 draw_axes_planes (props); 1366 draw_axes_planes (props);
1645 draw_axes_y_grid (props); 1372 draw_axes_y_grid (props);
1646 draw_axes_z_grid (props); 1373 draw_axes_z_grid (props);
1647 1374
1648 set_linestyle ("-"); 1375 set_linestyle ("-");
1649 1376
1650 draw_axes_title (props); 1377 set_clipbox (x_min, x_max, y_min, y_max, z_min, z_max);
1651 1378
1652 draw_axes_children (props); 1379 draw_axes_children (props);
1653 } 1380 }
1654 1381
1655 void 1382 void