123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610 |
- #include "Bildschirm.h"
- #include <iostream>
- #include "Bild.h"
- #include "Datei.h"
- #include "Fenster.h"
- #include "Globals.h"
- #include "GraphicsApi.h"
- #include "Mat3.h"
- #include "MausEreignis.h"
- #include "Model3D.h"
- #include "Text.h"
- #include "ToolTip.h"
- #include "Zeichnung.h"
- #include "Zeit.h"
- #ifdef WIN32
- # include <d3d11.h>
- # include <d3d9.h>
- # include <D3Dcompiler.h>
- # include <DirectXMath.h>
- # include "comdef.h"
- # include "Kam3D.h"
- #endif
- using namespace Framework;
- // Inhalt der Bildschirmklass aus Bildschirm.h
- // Konstruktor
- Bildschirm::Bildschirm(WFenster* f)
- : ReferenceCounter(),
- api(0),
- fenster(f),
- members(new RCArray<Zeichnung>()),
- fillColor(0xFF000000),
- deckFarbe(0),
- onTop(0),
- renderOnTop(0),
- renderZeichnungen(1),
- rendering(0),
- renderZeit(new ZeitMesser()),
- tips(new RCArray<ToolTip>()),
- testRend(1),
- fill(1),
- rend(0)
- {}
- // Destruktor
- Bildschirm::~Bildschirm()
- {
- lock();
- #ifdef WIN32
- if (fenster) fenster->release();
- #endif
- members->release();
- tips->release();
- renderZeit->release();
- if (onTop) onTop->release();
- if (api) api->release();
- unlock();
- }
- // nicht konstant
- void Bildschirm::lock()
- {
- cs.lock();
- }
- void Bildschirm::unlock()
- {
- cs.unlock();
- }
- void Bildschirm::setFill(bool f)
- {
- fill = f;
- }
- // Aktualisiert die Objekte, mit der die Grafikkarte verwaltet wird
- void Bildschirm::update()
- {
- lock();
- api->update();
- unlock();
- }
- void Bildschirm::setTestRend(
- bool tr) // legt fest, ob vo rendern auf updates geprüft werden soll
- {
- testRend = tr;
- }
- void Bildschirm::setRenderZeichnungen(
- bool rO) // legt fest, ob die Zeichnunge gerendert werden
- {
- lock();
- renderZeichnungen = rO;
- rend = 1;
- unlock();
- }
- void Bildschirm::setOnTop(
- bool onTop) // legt fest, ob das onTop Zeichnung gerendert wid
- {
- renderOnTop = onTop;
- rend = 1;
- }
- void Bildschirm::setOnTopZeichnung(Zeichnung* obj) // setzt das OnTop Zeichnung
- {
- lock();
- if (onTop) onTop->release();
- onTop = obj;
- rend = 1;
- unlock();
- }
- void Bildschirm::setdeckFarbe(int f) // setzt die deckFarbe
- {
- deckFarbe = f;
- rend = 1;
- }
- void Bildschirm::addMember(Zeichnung* obj) // Fügt ein Zeichnung hinzu
- {
- lock();
- members->add(obj);
- rend = 1;
- unlock();
- }
- void Bildschirm::removeMember(Zeichnung* zObj) // Entfernt ein Zeichnung
- {
- lock();
- for (int i = 0; i < members->getEintragAnzahl(); i++)
- {
- if (members->z(i) == zObj) members->remove(i);
- }
- rend = 1;
- unlock();
- }
- // Zeichnet ein Bild und präsentiert es auf dem Bildschirm
- void Bildschirm::render()
- {
- lock();
- api->update();
- rend = 1;
- unlock();
- }
- void Bildschirm::setFillFarbe(int f) // setzt die Fill Farbe
- {
- fillColor = f;
- rend = 1;
- }
- void Bildschirm::setVollbild(bool vollbild) // setzt vollbild
- {
- lock();
- api->setFullScreen(vollbild);
- unlock();
- }
- void Bildschirm::tick(double tickval)
- {
- lock();
- if (!renderOnTop)
- {
- for (Iterator<ToolTip*> i = tips->begin(); i; i++)
- {
- i->tick(tickval);
- if (i->getReferenceCount() == 1) i.remove();
- }
- for (Zeichnung* i : *members)
- rend |= i->tick(tickval);
- }
- else if (onTop)
- {
- rend |= onTop->tick(tickval);
- for (Iterator<ToolTip*> i = tips->begin(); i; i++)
- {
- i->tick(tickval);
- if (i->getReferenceCount() == 1) i.remove();
- }
- }
- unlock();
- }
- void Bildschirm::setBackBufferSize(
- int breite, int height) // setzt die Größe des Backbuffers
- {
- lock();
- api->setBackBufferSize(Vec2<int>(breite, height));
- unlock();
- }
- void Bildschirm::setBackBufferSize(Punkt& size)
- {
- lock();
- api->setBackBufferSize(size);
- unlock();
- }
- void Bildschirm::doMausEreignis(MausEreignis& me) // sendet maus Ereignis
- {
- int fBr = api->getBackBufferSize().x;
- int fHi = api->getBackBufferSize().y;
- #ifdef WIN32
- if (fenster)
- {
- fBr = fenster->getKörperBreite();
- fHi = fenster->getKörperHöhe();
- }
- #endif
- me.mx = (int)(me.mx * api->getBackBufferSize().x / (double)fBr + 0.5);
- me.my = (int)(me.my * api->getBackBufferSize().y / (double)fHi + 0.5);
- lock();
- if (!renderOnTop)
- {
- for (Iterator<ToolTip*> i = tips->begin(); i; i++)
- {
- i->doPublicMausEreignis(me);
- if (i->getReferenceCount() == 1) i.remove();
- }
- for (int i = members->getEintragAnzahl() - 1; i >= 0; i--)
- members->z(i)->doPublicMausEreignis(me);
- }
- else if (onTop)
- {
- onTop->doPublicMausEreignis(me);
- for (Iterator<ToolTip*> i = tips->begin(); i; i++)
- {
- i->doPublicMausEreignis(me);
- if (i->getReferenceCount() == 1) i.remove();
- }
- }
- unlock();
- }
- void Bildschirm::doTastaturEreignis(
- TastaturEreignis& te) // sendet tastatur Ereignis
- {
- lock();
- if (!renderOnTop)
- {
- for (int i = members->getEintragAnzahl() - 1; i >= 0; i--)
- members->z(i)->doTastaturEreignis(te);
- }
- for (Iterator<ToolTip*> i = tips->begin(); i; i++)
- {
- i->doTastaturEreignis(te);
- if (i->getReferenceCount() == 1) i.remove();
- }
- unlock();
- }
- void Bildschirm::addToolTip(ToolTip* tip) // fügt ToolTip hinzu
- {
- lock();
- tips->add(tip);
- rend = 1;
- unlock();
- }
- // constant
- Bild* Bildschirm::getRenderBild() const
- {
- return dynamic_cast<Bild*>(api->zUIRenderBild()->getThis());
- }
- Bild* Bildschirm::zRenderBild() const
- {
- return api->zUIRenderBild();
- }
- Iterator<Zeichnung*>
- Bildschirm::getMembers() const // gibt die Zeichnunge zurück
- {
- return members->begin();
- }
- int Bildschirm::getFillFarbe() const // gibt die Füll Farbe zurück
- {
- return fillColor;
- }
- bool Bildschirm::istVolbild() const // gibt zurück, ob vollbild an ist
- {
- return api->isFullScreen();
- }
- const Punkt
- Bildschirm::getBackBufferSize() const // gibt die Größe des Backbuffers zurück
- {
- return api->getBackBufferSize();
- }
- void Bildschirm::warteAufRendern() const // wartet auf die render Funktion
- {
- while (rendering)
- {
- if (!rendering) return;
- }
- }
- double Bildschirm::getRenderZeit()
- const // gibt zurück wie viele Sekunden das Rendern dauert
- {
- return renderZeit->getSekunden();
- }
- // Gibt die Grafik API zurück (ohne erhöhten Reference Counter)
- GraphicsApi* Bildschirm::zGraphicsApi() const
- {
- return api;
- }
- // Gibt die Grafik API zurück
- GraphicsApi* Bildschirm::getGraphicsApi() const
- {
- return api ? dynamic_cast<GraphicsApi*>(api->getThis()) : 0;
- }
- #ifdef WIN32
- int MonitorEnum(HMONITOR m, HDC dc, LPRECT r, LPARAM p)
- {
- MONITORINFOEXA info;
- ZeroMemory(&info, sizeof(info));
- info.cbSize = sizeof(info);
- GetMonitorInfo(m, &info);
- Monitor* mon = new Monitor();
- mon->existiert = 1;
- mon->x = r->left;
- mon->y = r->top;
- mon->breite = r->right - r->left;
- mon->height = r->bottom - r->top;
- mon->name = info.szDevice;
- ((Array<Monitor*>*)p)->add(mon);
- return 1;
- }
- Monitor Framework::getMonitor(int id)
- {
- if (id < 0)
- {
- Monitor m;
- m.existiert = 0;
- return m;
- }
- Array<Monitor*>* monitore = new Array<Monitor*>();
- DISPLAY_DEVICE dispDev;
- ZeroMemory(&dispDev, sizeof(dispDev));
- dispDev.cb = sizeof(dispDev);
- EnumDisplayDevices(NULL, id, &dispDev, 0);
- EnumDisplayMonitors(0, 0, (MONITORENUMPROC)MonitorEnum, (LPARAM)monitore);
- int anz = monitore->getEintragAnzahl();
- Monitor result;
- result.existiert = 0;
- for (Monitor* m : *monitore)
- {
- if (m->name.istGleich(dispDev.DeviceName))
- {
- result = *m;
- }
- delete m;
- }
- monitore->release();
- return result;
- }
- // Bildschirm2D
- // Konstruktor
- Bildschirm2D::Bildschirm2D(WFenster* fenster)
- : Bildschirm(fenster)
- {
- api = new DirectX9();
- api->initialize(dynamic_cast<WFenster*>(fenster->getThis()),
- fenster->getKörperGröße(),
- 0);
- }
- // Destruktor
- Bildschirm2D::~Bildschirm2D() {}
- void Bildschirm2D::render() // Zeichnet das Bild
- {
- if (!rend && testRend) return;
- rendering = 1;
- Bild* ui = api->zUIRenderBild();
- if (ui)
- {
- lock();
- renderZeit->messungStart();
- api->beginFrame(fill && (rend || !testRend), 0, fillColor);
- if (renderZeichnungen)
- {
- if (renderOnTop && deckFarbe
- && (deckFarbe & (fillColor | 0xFF000000)) == deckFarbe)
- {
- ui->setAlpha(255 - (unsigned char)(deckFarbe >> 24));
- for (Zeichnung* z : *members)
- z->render(*ui); // zeichnen nach zwischenbuffer
- ui->releaseAlpha();
- }
- else
- {
- for (Zeichnung* z : *members)
- z->render(*ui); // zeichnen nach zwischenbuffer
- if (renderOnTop && deckFarbe)
- ui->alphaRegion(
- 0, 0, ui->getBreite(), ui->getHeight(), deckFarbe);
- }
- for (Iterator<ToolTip*> i = tips->begin(); i; i++)
- {
- i->render(*ui);
- if (i->getReferenceCount() == 1) i.remove();
- }
- }
- if (renderOnTop && onTop) onTop->render(*ui);
- api->presentFrame();
- renderZeit->messungEnde();
- unlock();
- }
- rendering = 0;
- rend = 0;
- }
- // Bildschirm3D
- // Konstruktor
- Bildschirm3D::Bildschirm3D(WFenster* fenster)
- : Bildschirm(fenster),
- kameras(new RCArray<Kam3D>()),
- rend3D(0)
- {
- if (DirectX12::isAvailable())
- api = new DirectX12();
- else if (DirectX11::isAvailable())
- api = new DirectX11();
- else
- api = new DirectX9();
- api->initialize(dynamic_cast<WFenster*>(fenster->getThis()),
- fenster->getKörperGröße(),
- 0);
- }
- Bildschirm3D::Bildschirm3D(WFenster* fenster, GraphicApiType apiTyp)
- : Bildschirm(fenster),
- kameras(new RCArray<Kam3D>()),
- rend3D(0)
- {
- if (apiTyp == DIRECTX9) api = new DirectX9();
- if (apiTyp == DIRECTX11) api = new DirectX11();
- if (apiTyp == DIRECTX12) api = new DirectX12();
- api->initialize(dynamic_cast<WFenster*>(fenster->getThis()),
- fenster->getKörperGröße(),
- 0);
- }
- Bildschirm3D::Bildschirm3D(WFenster* fenster, GraphicsApi* api)
- : Bildschirm(fenster),
- kameras(new RCArray<Kam3D>()),
- rend3D(0)
- {
- this->api = api;
- api->initialize(dynamic_cast<WFenster*>(fenster->getThis()),
- fenster->getKörperGröße(),
- 0);
- }
- // Destruktor
- Bildschirm3D::~Bildschirm3D()
- {
- kameras->release();
- }
- // nicht constant
- void Bildschirm3D::addKamera(Kam3D* obj) // Fügt ein Zeichnung hinzu
- {
- lock();
- kameras->add(obj);
- rend3D = 1;
- unlock();
- }
- void Bildschirm3D::removeKamera(Kam3D* zObj) // Entfernt ein Zeichnung
- {
- lock();
- for (int i = 0; kameras->z(i); i++)
- {
- if (kameras->z(i) == zObj)
- {
- kameras->remove(i);
- break;
- }
- }
- rend3D = 1;
- unlock();
- }
- void Bildschirm3D::tick(double tickval)
- {
- lock();
- __super::tick(tickval);
- for (Kam3D* k : *kameras)
- rend3D |= k->tick(tickval);
- unlock();
- }
- void Bildschirm3D::doMausEreignis(MausEreignis& me) // sendet maus Ereignis
- {
- std::unique_lock<std::mutex> lk(mutex);
- waitingUserInput++;
- lk.unlock();
- lock();
- __super::doMausEreignis(me);
- for (int i = kameras->getEintragAnzahl() - 1; i >= 0; i--)
- kameras->z(i)->doMausEreignis(me);
- unlock();
- lk.lock();
- waitingUserInput--;
- if (waitingUserInput == 0)
- {
- lk.unlock();
- waiting.notify_all();
- }
- }
- void Bildschirm3D::doTastaturEreignis(
- TastaturEreignis& te) // sendet tastatur Ereignis
- {
- std::unique_lock<std::mutex> lk(mutex);
- waitingUserInput++;
- lk.unlock();
- lock();
- __super::doTastaturEreignis(te);
- for (int i = kameras->getEintragAnzahl() - 1; i >= 0; i--)
- kameras->z(i)->doTastaturEreignis(te);
- unlock();
- lk.lock();
- waitingUserInput--;
- if (waitingUserInput == 0)
- {
- lk.unlock();
- waiting.notify_all();
- }
- }
- void Bildschirm3D::render() // Zeichnet das Bild
- {
- if (!rend && !rend3D && testRend) return;
- std::unique_lock<std::mutex> lk(mutex);
- if (waitingUserInput > 0)
- waiting.wait(lk);
- rendering = 1;
- lk.unlock();
- lock();
- renderZeit->messungStart();
- // Clear the back buffer.
- api->beginFrame(fill && (rend || !testRend),
- fill && (rend3D || !testRend || rend),
- fillColor);
- if (rend3D || !testRend || rend)
- {
- // Render 3d Objects
- for (Kam3D* k : *kameras)
- api->renderKamera(k);
- rend3D = 0;
- }
- // render User Interface
- Bild* ui = api->zUIRenderBild();
- if ((rend || !testRend) && ui)
- {
- if (renderZeichnungen)
- {
- if (renderOnTop && deckFarbe
- && (deckFarbe & (fillColor | 0xFF000000)) == deckFarbe)
- {
- ui->setAlpha(255 - (unsigned char)(deckFarbe >> 24));
- for (Zeichnung* z : *members)
- z->render(*ui); // zeichnen nach zwischenbuffer
- ui->releaseAlpha();
- }
- else
- {
- for (Zeichnung* z : *members)
- z->render(*ui); // zeichnen nach zwischenbuffer
- if (renderOnTop && deckFarbe)
- ui->alphaRegion(
- 0, 0, ui->getBreite(), ui->getHeight(), deckFarbe);
- }
- for (Iterator<ToolTip*> i = tips->begin(); i; i++)
- {
- i->render(*ui);
- if (i->getReferenceCount() == 1) i.remove();
- }
- }
- if (renderOnTop && onTop) onTop->render(*ui);
- }
- api->presentFrame();
- unlock();
- renderZeit->messungEnde();
- # ifdef _DEBUG
- // std::cout << renderZeit->getSekunden() << "\n";
- # endif
- rendering = 0;
- rend = 0;
- }
- #endif
|