Bildschirm.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. #include "Bildschirm.h"
  2. #include <iostream>
  3. #include "Bild.h"
  4. #include "Datei.h"
  5. #include "Fenster.h"
  6. #include "Globals.h"
  7. #include "GraphicsApi.h"
  8. #include "Mat3.h"
  9. #include "MausEreignis.h"
  10. #include "Model3D.h"
  11. #include "Text.h"
  12. #include "ToolTip.h"
  13. #include "Zeichnung.h"
  14. #include "Zeit.h"
  15. #ifdef WIN32
  16. # include <d3d11.h>
  17. # include <d3d9.h>
  18. # include <D3Dcompiler.h>
  19. # include <DirectXMath.h>
  20. # include "comdef.h"
  21. # include "Kam3D.h"
  22. #endif
  23. using namespace Framework;
  24. // Inhalt der Bildschirmklass aus Bildschirm.h
  25. // Konstruktor
  26. Bildschirm::Bildschirm(WFenster* f)
  27. : ReferenceCounter(),
  28. api(0),
  29. fenster(f),
  30. members(new RCArray<Zeichnung>()),
  31. fillColor(0xFF000000),
  32. deckFarbe(0),
  33. onTop(0),
  34. renderOnTop(0),
  35. renderZeichnungen(1),
  36. rendering(0),
  37. renderZeit(new ZeitMesser()),
  38. tips(new RCArray<ToolTip>()),
  39. testRend(1),
  40. fill(1),
  41. rend(0)
  42. {}
  43. // Destruktor
  44. Bildschirm::~Bildschirm()
  45. {
  46. lock();
  47. #ifdef WIN32
  48. if (fenster) fenster->release();
  49. #endif
  50. members->release();
  51. tips->release();
  52. renderZeit->release();
  53. if (onTop) onTop->release();
  54. if (api) api->release();
  55. unlock();
  56. }
  57. // nicht konstant
  58. void Bildschirm::lock()
  59. {
  60. cs.lock();
  61. }
  62. void Bildschirm::unlock()
  63. {
  64. cs.unlock();
  65. }
  66. void Bildschirm::setFill(bool f)
  67. {
  68. fill = f;
  69. }
  70. // Aktualisiert die Objekte, mit der die Grafikkarte verwaltet wird
  71. void Bildschirm::update()
  72. {
  73. lock();
  74. api->update();
  75. unlock();
  76. }
  77. void Bildschirm::setTestRend(
  78. bool tr) // legt fest, ob vo rendern auf updates geprüft werden soll
  79. {
  80. testRend = tr;
  81. }
  82. void Bildschirm::setRenderZeichnungen(
  83. bool rO) // legt fest, ob die Zeichnunge gerendert werden
  84. {
  85. lock();
  86. renderZeichnungen = rO;
  87. rend = 1;
  88. unlock();
  89. }
  90. void Bildschirm::setOnTop(
  91. bool onTop) // legt fest, ob das onTop Zeichnung gerendert wid
  92. {
  93. renderOnTop = onTop;
  94. rend = 1;
  95. }
  96. void Bildschirm::setOnTopZeichnung(Zeichnung* obj) // setzt das OnTop Zeichnung
  97. {
  98. lock();
  99. if (onTop) onTop->release();
  100. onTop = obj;
  101. rend = 1;
  102. unlock();
  103. }
  104. void Bildschirm::setdeckFarbe(int f) // setzt die deckFarbe
  105. {
  106. deckFarbe = f;
  107. rend = 1;
  108. }
  109. void Bildschirm::addMember(Zeichnung* obj) // Fügt ein Zeichnung hinzu
  110. {
  111. lock();
  112. members->add(obj);
  113. rend = 1;
  114. unlock();
  115. }
  116. void Bildschirm::removeMember(Zeichnung* zObj) // Entfernt ein Zeichnung
  117. {
  118. lock();
  119. for (int i = 0; i < members->getEintragAnzahl(); i++)
  120. {
  121. if (members->z(i) == zObj) members->remove(i);
  122. }
  123. rend = 1;
  124. unlock();
  125. }
  126. // Zeichnet ein Bild und präsentiert es auf dem Bildschirm
  127. void Bildschirm::render()
  128. {
  129. lock();
  130. api->update();
  131. rend = 1;
  132. unlock();
  133. }
  134. void Bildschirm::setFillFarbe(int f) // setzt die Fill Farbe
  135. {
  136. fillColor = f;
  137. rend = 1;
  138. }
  139. void Bildschirm::setVollbild(bool vollbild) // setzt vollbild
  140. {
  141. lock();
  142. api->setFullScreen(vollbild);
  143. unlock();
  144. }
  145. void Bildschirm::tick(double tickval)
  146. {
  147. lock();
  148. if (!renderOnTop)
  149. {
  150. for (Iterator<ToolTip*> i = tips->begin(); i; i++)
  151. {
  152. i->tick(tickval);
  153. if (i->getReferenceCount() == 1) i.remove();
  154. }
  155. for (Zeichnung* i : *members)
  156. rend |= i->tick(tickval);
  157. }
  158. else if (onTop)
  159. {
  160. rend |= onTop->tick(tickval);
  161. for (Iterator<ToolTip*> i = tips->begin(); i; i++)
  162. {
  163. i->tick(tickval);
  164. if (i->getReferenceCount() == 1) i.remove();
  165. }
  166. }
  167. unlock();
  168. }
  169. void Bildschirm::setBackBufferSize(
  170. int breite, int height) // setzt die Größe des Backbuffers
  171. {
  172. lock();
  173. api->setBackBufferSize(Vec2<int>(breite, height));
  174. unlock();
  175. }
  176. void Bildschirm::setBackBufferSize(Punkt& size)
  177. {
  178. lock();
  179. api->setBackBufferSize(size);
  180. unlock();
  181. }
  182. void Bildschirm::doMausEreignis(MausEreignis& me) // sendet maus Ereignis
  183. {
  184. int fBr = api->getBackBufferSize().x;
  185. int fHi = api->getBackBufferSize().y;
  186. #ifdef WIN32
  187. if (fenster)
  188. {
  189. fBr = fenster->getKörperBreite();
  190. fHi = fenster->getKörperHöhe();
  191. }
  192. #endif
  193. me.mx = (int)(me.mx * api->getBackBufferSize().x / (double)fBr + 0.5);
  194. me.my = (int)(me.my * api->getBackBufferSize().y / (double)fHi + 0.5);
  195. lock();
  196. if (!renderOnTop)
  197. {
  198. for (Iterator<ToolTip*> i = tips->begin(); i; i++)
  199. {
  200. i->doPublicMausEreignis(me);
  201. if (i->getReferenceCount() == 1) i.remove();
  202. }
  203. for (int i = members->getEintragAnzahl() - 1; i >= 0; i--)
  204. members->z(i)->doPublicMausEreignis(me);
  205. }
  206. else if (onTop)
  207. {
  208. onTop->doPublicMausEreignis(me);
  209. for (Iterator<ToolTip*> i = tips->begin(); i; i++)
  210. {
  211. i->doPublicMausEreignis(me);
  212. if (i->getReferenceCount() == 1) i.remove();
  213. }
  214. }
  215. unlock();
  216. }
  217. void Bildschirm::doTastaturEreignis(
  218. TastaturEreignis& te) // sendet tastatur Ereignis
  219. {
  220. lock();
  221. if (!renderOnTop)
  222. {
  223. for (int i = members->getEintragAnzahl() - 1; i >= 0; i--)
  224. members->z(i)->doTastaturEreignis(te);
  225. }
  226. for (Iterator<ToolTip*> i = tips->begin(); i; i++)
  227. {
  228. i->doTastaturEreignis(te);
  229. if (i->getReferenceCount() == 1) i.remove();
  230. }
  231. unlock();
  232. }
  233. void Bildschirm::addToolTip(ToolTip* tip) // fügt ToolTip hinzu
  234. {
  235. lock();
  236. tips->add(tip);
  237. rend = 1;
  238. unlock();
  239. }
  240. // constant
  241. Bild* Bildschirm::getRenderBild() const
  242. {
  243. return dynamic_cast<Bild*>(api->zUIRenderBild()->getThis());
  244. }
  245. Bild* Bildschirm::zRenderBild() const
  246. {
  247. return api->zUIRenderBild();
  248. }
  249. Iterator<Zeichnung*>
  250. Bildschirm::getMembers() const // gibt die Zeichnunge zurück
  251. {
  252. return members->begin();
  253. }
  254. int Bildschirm::getFillFarbe() const // gibt die Füll Farbe zurück
  255. {
  256. return fillColor;
  257. }
  258. bool Bildschirm::istVolbild() const // gibt zurück, ob vollbild an ist
  259. {
  260. return api->isFullScreen();
  261. }
  262. const Punkt
  263. Bildschirm::getBackBufferSize() const // gibt die Größe des Backbuffers zurück
  264. {
  265. return api->getBackBufferSize();
  266. }
  267. void Bildschirm::warteAufRendern() const // wartet auf die render Funktion
  268. {
  269. while (rendering)
  270. {
  271. if (!rendering) return;
  272. }
  273. }
  274. double Bildschirm::getRenderZeit()
  275. const // gibt zurück wie viele Sekunden das Rendern dauert
  276. {
  277. return renderZeit->getSekunden();
  278. }
  279. // Gibt die Grafik API zurück (ohne erhöhten Reference Counter)
  280. GraphicsApi* Bildschirm::zGraphicsApi() const
  281. {
  282. return api;
  283. }
  284. // Gibt die Grafik API zurück
  285. GraphicsApi* Bildschirm::getGraphicsApi() const
  286. {
  287. return api ? dynamic_cast<GraphicsApi*>(api->getThis()) : 0;
  288. }
  289. #ifdef WIN32
  290. int MonitorEnum(HMONITOR m, HDC dc, LPRECT r, LPARAM p)
  291. {
  292. MONITORINFOEXA info;
  293. ZeroMemory(&info, sizeof(info));
  294. info.cbSize = sizeof(info);
  295. GetMonitorInfo(m, &info);
  296. Monitor* mon = new Monitor();
  297. mon->existiert = 1;
  298. mon->x = r->left;
  299. mon->y = r->top;
  300. mon->breite = r->right - r->left;
  301. mon->height = r->bottom - r->top;
  302. mon->name = info.szDevice;
  303. ((Array<Monitor*>*)p)->add(mon);
  304. return 1;
  305. }
  306. Monitor Framework::getMonitor(int id)
  307. {
  308. if (id < 0)
  309. {
  310. Monitor m;
  311. m.existiert = 0;
  312. return m;
  313. }
  314. Array<Monitor*>* monitore = new Array<Monitor*>();
  315. DISPLAY_DEVICE dispDev;
  316. ZeroMemory(&dispDev, sizeof(dispDev));
  317. dispDev.cb = sizeof(dispDev);
  318. EnumDisplayDevices(NULL, id, &dispDev, 0);
  319. EnumDisplayMonitors(0, 0, (MONITORENUMPROC)MonitorEnum, (LPARAM)monitore);
  320. int anz = monitore->getEintragAnzahl();
  321. Monitor result;
  322. result.existiert = 0;
  323. for (Monitor* m : *monitore)
  324. {
  325. if (m->name.istGleich(dispDev.DeviceName))
  326. {
  327. result = *m;
  328. }
  329. delete m;
  330. }
  331. monitore->release();
  332. return result;
  333. }
  334. // Bildschirm2D
  335. // Konstruktor
  336. Bildschirm2D::Bildschirm2D(WFenster* fenster)
  337. : Bildschirm(fenster)
  338. {
  339. api = new DirectX9();
  340. api->initialize(dynamic_cast<WFenster*>(fenster->getThis()),
  341. fenster->getKörperGröße(),
  342. 0);
  343. }
  344. // Destruktor
  345. Bildschirm2D::~Bildschirm2D() {}
  346. void Bildschirm2D::render() // Zeichnet das Bild
  347. {
  348. if (!rend && testRend) return;
  349. rendering = 1;
  350. Bild* ui = api->zUIRenderBild();
  351. if (ui)
  352. {
  353. lock();
  354. renderZeit->messungStart();
  355. api->beginFrame(fill && (rend || !testRend), 0, fillColor);
  356. if (renderZeichnungen)
  357. {
  358. if (renderOnTop && deckFarbe
  359. && (deckFarbe & (fillColor | 0xFF000000)) == deckFarbe)
  360. {
  361. ui->setAlpha(255 - (unsigned char)(deckFarbe >> 24));
  362. for (Zeichnung* z : *members)
  363. z->render(*ui); // zeichnen nach zwischenbuffer
  364. ui->releaseAlpha();
  365. }
  366. else
  367. {
  368. for (Zeichnung* z : *members)
  369. z->render(*ui); // zeichnen nach zwischenbuffer
  370. if (renderOnTop && deckFarbe)
  371. ui->alphaRegion(
  372. 0, 0, ui->getBreite(), ui->getHeight(), deckFarbe);
  373. }
  374. for (Iterator<ToolTip*> i = tips->begin(); i; i++)
  375. {
  376. i->render(*ui);
  377. if (i->getReferenceCount() == 1) i.remove();
  378. }
  379. }
  380. if (renderOnTop && onTop) onTop->render(*ui);
  381. api->presentFrame();
  382. renderZeit->messungEnde();
  383. unlock();
  384. }
  385. rendering = 0;
  386. rend = 0;
  387. }
  388. // Bildschirm3D
  389. // Konstruktor
  390. Bildschirm3D::Bildschirm3D(WFenster* fenster)
  391. : Bildschirm(fenster),
  392. kameras(new RCArray<Kam3D>()),
  393. rend3D(0)
  394. {
  395. if (DirectX12::isAvailable())
  396. api = new DirectX12();
  397. else if (DirectX11::isAvailable())
  398. api = new DirectX11();
  399. else
  400. api = new DirectX9();
  401. api->initialize(dynamic_cast<WFenster*>(fenster->getThis()),
  402. fenster->getKörperGröße(),
  403. 0);
  404. }
  405. Bildschirm3D::Bildschirm3D(WFenster* fenster, GraphicApiType apiTyp)
  406. : Bildschirm(fenster),
  407. kameras(new RCArray<Kam3D>()),
  408. rend3D(0)
  409. {
  410. if (apiTyp == DIRECTX9) api = new DirectX9();
  411. if (apiTyp == DIRECTX11) api = new DirectX11();
  412. if (apiTyp == DIRECTX12) api = new DirectX12();
  413. api->initialize(dynamic_cast<WFenster*>(fenster->getThis()),
  414. fenster->getKörperGröße(),
  415. 0);
  416. }
  417. Bildschirm3D::Bildschirm3D(WFenster* fenster, GraphicsApi* api)
  418. : Bildschirm(fenster),
  419. kameras(new RCArray<Kam3D>()),
  420. rend3D(0)
  421. {
  422. this->api = api;
  423. api->initialize(dynamic_cast<WFenster*>(fenster->getThis()),
  424. fenster->getKörperGröße(),
  425. 0);
  426. }
  427. // Destruktor
  428. Bildschirm3D::~Bildschirm3D()
  429. {
  430. kameras->release();
  431. }
  432. // nicht constant
  433. void Bildschirm3D::addKamera(Kam3D* obj) // Fügt ein Zeichnung hinzu
  434. {
  435. lock();
  436. kameras->add(obj);
  437. rend3D = 1;
  438. unlock();
  439. }
  440. void Bildschirm3D::removeKamera(Kam3D* zObj) // Entfernt ein Zeichnung
  441. {
  442. lock();
  443. for (int i = 0; kameras->z(i); i++)
  444. {
  445. if (kameras->z(i) == zObj)
  446. {
  447. kameras->remove(i);
  448. break;
  449. }
  450. }
  451. rend3D = 1;
  452. unlock();
  453. }
  454. void Bildschirm3D::tick(double tickval)
  455. {
  456. lock();
  457. __super::tick(tickval);
  458. for (Kam3D* k : *kameras)
  459. rend3D |= k->tick(tickval);
  460. unlock();
  461. }
  462. void Bildschirm3D::doMausEreignis(MausEreignis& me) // sendet maus Ereignis
  463. {
  464. std::unique_lock<std::mutex> lk(mutex);
  465. waitingUserInput++;
  466. lk.unlock();
  467. lock();
  468. __super::doMausEreignis(me);
  469. for (int i = kameras->getEintragAnzahl() - 1; i >= 0; i--)
  470. kameras->z(i)->doMausEreignis(me);
  471. unlock();
  472. lk.lock();
  473. waitingUserInput--;
  474. if (waitingUserInput == 0)
  475. {
  476. lk.unlock();
  477. waiting.notify_all();
  478. }
  479. }
  480. void Bildschirm3D::doTastaturEreignis(
  481. TastaturEreignis& te) // sendet tastatur Ereignis
  482. {
  483. std::unique_lock<std::mutex> lk(mutex);
  484. waitingUserInput++;
  485. lk.unlock();
  486. lock();
  487. __super::doTastaturEreignis(te);
  488. for (int i = kameras->getEintragAnzahl() - 1; i >= 0; i--)
  489. kameras->z(i)->doTastaturEreignis(te);
  490. unlock();
  491. lk.lock();
  492. waitingUserInput--;
  493. if (waitingUserInput == 0)
  494. {
  495. lk.unlock();
  496. waiting.notify_all();
  497. }
  498. }
  499. void Bildschirm3D::render() // Zeichnet das Bild
  500. {
  501. if (!rend && !rend3D && testRend) return;
  502. std::unique_lock<std::mutex> lk(mutex);
  503. if (waitingUserInput > 0)
  504. waiting.wait(lk);
  505. rendering = 1;
  506. lk.unlock();
  507. lock();
  508. renderZeit->messungStart();
  509. // Clear the back buffer.
  510. api->beginFrame(fill && (rend || !testRend),
  511. fill && (rend3D || !testRend || rend),
  512. fillColor);
  513. if (rend3D || !testRend || rend)
  514. {
  515. // Render 3d Objects
  516. for (Kam3D* k : *kameras)
  517. api->renderKamera(k);
  518. rend3D = 0;
  519. }
  520. // render User Interface
  521. Bild* ui = api->zUIRenderBild();
  522. if ((rend || !testRend) && ui)
  523. {
  524. if (renderZeichnungen)
  525. {
  526. if (renderOnTop && deckFarbe
  527. && (deckFarbe & (fillColor | 0xFF000000)) == deckFarbe)
  528. {
  529. ui->setAlpha(255 - (unsigned char)(deckFarbe >> 24));
  530. for (Zeichnung* z : *members)
  531. z->render(*ui); // zeichnen nach zwischenbuffer
  532. ui->releaseAlpha();
  533. }
  534. else
  535. {
  536. for (Zeichnung* z : *members)
  537. z->render(*ui); // zeichnen nach zwischenbuffer
  538. if (renderOnTop && deckFarbe)
  539. ui->alphaRegion(
  540. 0, 0, ui->getBreite(), ui->getHeight(), deckFarbe);
  541. }
  542. for (Iterator<ToolTip*> i = tips->begin(); i; i++)
  543. {
  544. i->render(*ui);
  545. if (i->getReferenceCount() == 1) i.remove();
  546. }
  547. }
  548. if (renderOnTop && onTop) onTop->render(*ui);
  549. }
  550. api->presentFrame();
  551. unlock();
  552. renderZeit->messungEnde();
  553. # ifdef _DEBUG
  554. // std::cout << renderZeit->getSekunden() << "\n";
  555. # endif
  556. rendering = 0;
  557. rend = 0;
  558. }
  559. #endif