42 { { -1, 0, 0 }, X, Z, false, true }, |
49 { { -1, 0, 0 }, X, Z, false, true }, |
43 { { 0, 0, 0 }, X, Y, true, true }, |
50 { { 0, 0, 0 }, X, Y, true, true }, |
44 { { 0, -1, 0 }, Z, Y, false, true }, |
51 { { 0, -1, 0 }, Z, Y, false, true }, |
45 }; |
52 }; |
46 |
53 |
|
54 struct overlayMeta { |
|
55 vertex v0, v1; |
|
56 ushort ox, oy; |
|
57 double lw, lh; |
|
58 str fname; |
|
59 QImage* img; |
|
60 } g_overlays[6]; |
|
61 |
47 cfg (str, gl_bgcolor, "#CCCCD9"); |
62 cfg (str, gl_bgcolor, "#CCCCD9"); |
48 cfg (str, gl_maincolor, "#707078"); |
63 cfg (str, gl_maincolor, "#707078"); |
49 cfg (float, gl_maincolor_alpha, 1.0); |
64 cfg (float, gl_maincolor_alpha, 1.0); |
50 cfg (int, gl_linethickness, 2); |
65 cfg (int, gl_linethickness, 2); |
51 cfg (bool, gl_colorbfc, true); |
66 cfg (bool, gl_colorbfc, true); |
465 paint.setRenderHint (QPainter::Antialiasing); |
483 paint.setRenderHint (QPainter::Antialiasing); |
466 |
484 |
467 m_hoverpos = g_origin; |
485 m_hoverpos = g_origin; |
468 |
486 |
469 if (m_camera != Free) { |
487 if (m_camera != Free) { |
|
488 // Paint the overlay image if we have one |
|
489 const overlayMeta& overlay = g_overlays[m_camera]; |
|
490 if (overlay.img != null) { |
|
491 QPoint v0 = coordconv3_2 (g_overlays[m_camera].v0), |
|
492 v1 = coordconv3_2 (g_overlays[m_camera].v1); |
|
493 |
|
494 QRect targRect (v0.x (), v0.y (), abs (v1.x () - v0.x ()), abs (v1.y () - v0.y ())), |
|
495 srcRect (0, 0, overlay.img->width (), overlay.img->height ()); |
|
496 paint.drawImage (targRect, *overlay.img, srcRect); |
|
497 } |
|
498 |
470 // Calculate 3d position of the cursor |
499 // Calculate 3d position of the cursor |
471 m_hoverpos = coordconv2_3 (m_pos, true); |
500 m_hoverpos = coordconv2_3 (m_pos, true); |
472 |
501 |
473 // Paint the coordinates onto the screen. |
502 // Paint the coordinates onto the screen. |
474 str text; |
503 str text; |
1204 // ============================================================================= |
1233 // ============================================================================= |
1205 void GLRenderer::deleteLists (LDObject* obj) { |
1234 void GLRenderer::deleteLists (LDObject* obj) { |
1206 for (const GL::ListType listType : g_glListTypes) |
1235 for (const GL::ListType listType : g_glListTypes) |
1207 glDeleteLists (obj->glLists[listType], 1); |
1236 glDeleteLists (obj->glLists[listType], 1); |
1208 } |
1237 } |
|
1238 |
|
1239 // ============================================================================= |
|
1240 Axis GLRenderer::cameraAxis (bool y) { |
|
1241 const staticCameraMeta* cam = &g_staticCameras[m_camera]; |
|
1242 return (y) ? cam->axisY : cam->axisX; |
|
1243 } |
|
1244 |
|
1245 // ============================================================================= |
|
1246 OverlayDialog::OverlayDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) { |
|
1247 rb_camera = new RadioBox ("Camera", {}, 0, Qt::Horizontal, this); |
|
1248 |
|
1249 for (int i = 0; i < 6; ++i) { |
|
1250 if (i == 3) |
|
1251 rb_camera->rowBreak (); |
|
1252 |
|
1253 rb_camera->addButton (g_CameraNames[i]); |
|
1254 } |
|
1255 |
|
1256 GL::Camera cam = g_win->R ()->camera (); |
|
1257 if (cam != GL::Free) |
|
1258 rb_camera->setValue ((int) cam); |
|
1259 |
|
1260 QGroupBox* gb_image = new QGroupBox ("Image", this); |
|
1261 |
|
1262 QLabel* lb_fpath = new QLabel ("File:"); |
|
1263 le_fpath = new QLineEdit; |
|
1264 le_fpath->setFocus (); |
|
1265 |
|
1266 QLabel* lb_ofs = new QLabel ("Origin:"); |
|
1267 btn_fpath = new QPushButton; |
|
1268 btn_fpath->setIcon (getIcon ("folder")); |
|
1269 connect (btn_fpath, SIGNAL (clicked ()), this, SLOT (slot_fpath ())); |
|
1270 |
|
1271 sb_ofsx = new QSpinBox; |
|
1272 sb_ofsy = new QSpinBox; |
|
1273 sb_ofsx->setRange (0, 10000); |
|
1274 sb_ofsy->setRange (0, 10000); |
|
1275 |
|
1276 QLabel* lb_dimens = new QLabel ("Dimensions (LDU):"); |
|
1277 dsb_lwidth = new QDoubleSpinBox; |
|
1278 dsb_lheight = new QDoubleSpinBox; |
|
1279 dsb_lwidth->setRange (0.0f, 10000.0f); |
|
1280 dsb_lheight->setRange (0.0f, 10000.0f); |
|
1281 |
|
1282 QDialogButtonBox* bbx_buttons = makeButtonBox (*this); |
|
1283 bbx_buttons->addButton (QDialogButtonBox::Help); |
|
1284 connect (bbx_buttons, SIGNAL (helpRequested ()), this, SLOT (slot_help())); |
|
1285 |
|
1286 QHBoxLayout* fpathlayout = new QHBoxLayout; |
|
1287 fpathlayout->addWidget (lb_fpath); |
|
1288 fpathlayout->addWidget (le_fpath); |
|
1289 fpathlayout->addWidget (btn_fpath); |
|
1290 |
|
1291 QGridLayout* metalayout = new QGridLayout; |
|
1292 metalayout->addWidget (lb_ofs, 0, 0); |
|
1293 metalayout->addWidget (sb_ofsx, 0, 1); |
|
1294 metalayout->addWidget (sb_ofsy, 0, 2); |
|
1295 metalayout->addWidget (lb_dimens, 1, 0); |
|
1296 metalayout->addWidget (dsb_lwidth, 1, 1); |
|
1297 metalayout->addWidget (dsb_lheight, 1, 2); |
|
1298 |
|
1299 QVBoxLayout* imagelayout = new QVBoxLayout (gb_image); |
|
1300 imagelayout->addLayout (fpathlayout); |
|
1301 imagelayout->addLayout (metalayout); |
|
1302 |
|
1303 QVBoxLayout* layout = new QVBoxLayout (this); |
|
1304 layout->addWidget (rb_camera); |
|
1305 layout->addWidget (gb_image); |
|
1306 layout->addWidget (bbx_buttons); |
|
1307 } |
|
1308 |
|
1309 str OverlayDialog::fpath () const { return le_fpath->text (); } |
|
1310 ushort OverlayDialog::ofsx () const { return sb_ofsx->value (); } |
|
1311 ushort OverlayDialog::ofsy () const { return sb_ofsy->value (); } |
|
1312 double OverlayDialog::lwidth () const { return dsb_lwidth->value (); } |
|
1313 double OverlayDialog::lheight () const { return dsb_lheight->value (); } |
|
1314 GL::Camera OverlayDialog::camera () const { return (GL::Camera) rb_camera->value (); } |
|
1315 |
|
1316 void OverlayDialog::slot_fpath () const { |
|
1317 le_fpath->setText (QFileDialog::getOpenFileName (null, "Overlay image")); |
|
1318 } |
|
1319 |
|
1320 void OverlayDialog::slot_help () const { |
|
1321 showDocumentation (g_docs_overlays); |
|
1322 } |
|
1323 |
|
1324 void GLRenderer::setupOverlay () { |
|
1325 if (camera () == Free) |
|
1326 return; |
|
1327 |
|
1328 OverlayDialog dlg; |
|
1329 |
|
1330 if (!dlg.exec ()) |
|
1331 return; |
|
1332 |
|
1333 QImage* img = new QImage (dlg.fpath ().chars ()); |
|
1334 overlayMeta& info = g_overlays[camera ()]; |
|
1335 |
|
1336 if (img->isNull ()) { |
|
1337 critical ("Failed to load overlay image!"); |
|
1338 delete img; |
|
1339 return; |
|
1340 } |
|
1341 |
|
1342 delete info.img; // delete the old image |
|
1343 |
|
1344 info.fname = dlg.fpath (); |
|
1345 info.lw = dlg.lwidth (); |
|
1346 info.lh = dlg.lheight (); |
|
1347 info.ox = dlg.ofsx (); |
|
1348 info.oy = dlg.ofsy (); |
|
1349 info.img = img; |
|
1350 |
|
1351 const Axis x2d = cameraAxis (false), |
|
1352 y2d = cameraAxis (true); |
|
1353 |
|
1354 double negXFac = g_staticCameras[m_camera].negX ? -1 : 1, |
|
1355 negYFac = g_staticCameras[m_camera].negY ? -1 : 1; |
|
1356 |
|
1357 info.v0 = info.v1 = g_origin; |
|
1358 info.v0[x2d] = -(info.ox * info.lw * negXFac) / img->width (); |
|
1359 info.v0[y2d] = (info.oy * info.lh * negYFac) / img->height (); |
|
1360 info.v1[x2d] = info.v0[x2d] + info.lw; |
|
1361 info.v1[y2d] = info.v0[y2d] + info.lh; |
|
1362 |
|
1363 // Set alpha of all pixels to 0.5 |
|
1364 for (long i = 0; i < img->width (); ++i) |
|
1365 for (long j = 0; j < img->height (); ++j) { |
|
1366 uint32 pixel = img->pixel (i, j); |
|
1367 img->setPixel (i, j, 0x80000000 | (pixel & 0x00FFFFFF)); |
|
1368 } |
|
1369 } |
|
1370 |
|
1371 void GLRenderer::clearOverlay () { |
|
1372 if (camera () == Free) |
|
1373 return; |
|
1374 |
|
1375 overlayMeta& info = g_overlays[camera ()]; |
|
1376 delete info.img; |
|
1377 } |