#include "Bildschirm.h" #include "Bild.h" #include "Fenster.h" #include "Text.h" #include "Zeichnung.h" #include "Globals.h" #include "Zeit.h" #include "ToolTip.h" #include "MausEreignis.h" #include #include "Datei.h" #include "Mat3.h" #include "Model3D.h" #include "GraphicsApi.h" #ifdef WIN32 #include "Kam3D.h" #include #include #include #include #include "comdef.h" #endif using namespace Framework; // Inhalt der Bildschirmklass aus Bildschirm.h // Konstruktor Bildschirm::Bildschirm( WFenster *f ) : ReferenceCounter(), api( 0 ), fenster( f ), members( new RCArray() ), fillColor( 0xFF000000 ), deckFarbe( 0 ), onTop( 0 ), renderOnTop( 0 ), renderZeichnungen( 1 ), rendering( 0 ), renderZeit( new ZeitMesser() ), tips( new RCArray< ToolTip >() ), tipAnzahl( 0 ), testRend( 1 ), fill( 1 ), rend( 0 ) {} // Destruktor Bildschirm::~Bildschirm() { lock(); #ifdef WIN32 if( fenster ) fenster->release(); #endif members->release(); tipAnzahl = 0; 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( int i = 0; i < tipAnzahl; ++i ) rend |= tips->z( i )->tick( tickval ); for( auto i = members->getIterator(); i; i++ ) rend |= i->tick( tickval ); } else if( onTop ) { rend |= onTop->tick( tickval ); for( int i = 0; i < tipAnzahl; ++i ) rend |= tips->z( i )->tick( tickval ); } 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( int i = tipAnzahl - 1; i >= 0; i-- ) tips->z( i )->doPublicMausEreignis( me ); for( int i = members->getEintragAnzahl() - 1; i >= 0; i-- ) members->z( i )->doPublicMausEreignis( me ); } else if( onTop ) { onTop->doPublicMausEreignis( me ); for( int i = tipAnzahl - 1; i >= 0; i-- ) tips->z( i )->doPublicMausEreignis( me ); } 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( int i = tipAnzahl - 1; i >= 0; i-- ) tips->z( i )->doTastaturEreignis( te ); unlock(); } void Bildschirm::addToolTip( ToolTip *tip ) // fügt ToolTip hinzu { lock(); tips->add( tip, tipAnzahl ); ++tipAnzahl; rend = 1; unlock(); } bool Bildschirm::removeToolTip( ToolTip *zTip ) // entfernt ToolTip { lock(); bool gefunden = 0; for( int i = 0; i < tipAnzahl; ++i ) { ToolTip *tmp = tips->z( i ); if( tmp == zTip ) { tips->remove( i ); --tipAnzahl; gefunden = 1; rend = 1; break; } } unlock(); return gefunden; } // constant Bild *Bildschirm::getRenderBild() const { return (Bild *)api->zUIRenderBild()->getThis(); } Bild *Bildschirm::zRenderBild() const { return api->zUIRenderBild(); } Iterator Bildschirm::getMembers() const // gibt die Zeichnunge zurück { return members->getIterator(); } 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 ? (GraphicsApi *)api->getThis() : 0; } #ifdef WIN32 int MonitorEnum( HMONITOR m, HDC dc, LPRECT r, LPARAM p ) { 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; ( ( 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 * >(); EnumDisplayMonitors( 0, 0, (MONITORENUMPROC)MonitorEnum, (LPARAM)monitore ); int anz = monitore->getEintragAnzahl(); if( id >= monitore->getEintragAnzahl() ) { for( int i = 0; i < anz; ++i ) delete monitore->get( i ); delete monitore; Monitor m; m.existiert = 0; return m; } Monitor m = *monitore->get( id ); for( int i = 0; i < anz; ++i ) delete monitore->get( i ); delete monitore; return m; } // Bildschirm2D // Konstruktor Bildschirm2D::Bildschirm2D( WFenster *fenster ) : Bildschirm( fenster ) { api = new DirectX9(); api->initialize( (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( auto i = members->getIterator(); i; i++ ) i->render( *ui ); // zeichnen nach zwischenbuffer ui->releaseAlpha(); } else { for( auto i = members->getIterator(); i; i++ ) i->render( *ui ); // zeichnen nach zwischenbuffer if( renderOnTop && deckFarbe ) ui->alphaRegion( 0, 0, ui->getBreite(), ui->getHeight(), deckFarbe ); } for( int i = 0; i < tipAnzahl; ++i ) tips->z( i )->render( *ui ); } 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( (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( (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( auto i = kameras->getIterator(); i; i++ ) rend3D |= i->tick( tickval ); unlock(); } void Bildschirm3D::doMausEreignis( MausEreignis &me ) // sendet maus Ereignis { lock(); __super::doMausEreignis( me ); for( int i = kameras->getEintragAnzahl() - 1; i >= 0; i-- ) kameras->z( i )->doMausEreignis( me ); unlock(); } void Bildschirm3D::doTastaturEreignis( TastaturEreignis &te ) // sendet tastatur Ereignis { lock(); __super::doTastaturEreignis( te ); for( int i = kameras->getEintragAnzahl() - 1; i >= 0; i-- ) kameras->z( i )->doTastaturEreignis( te ); unlock(); } void Bildschirm3D::render() // Zeichnet das Bild { if( !rend && !rend3D && testRend ) return; rendering = 1; 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( auto i = kameras->getIterator(); i; i++ ) api->renderKamera( i._ ); 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( auto i = members->getIterator(); i; i++ ) i->render( *ui ); // zeichnen nach zwischenbuffer ui->releaseAlpha(); } else { for( auto i = members->getIterator(); i; i++ ) i->render( *ui ); // zeichnen nach zwischenbuffer if( renderOnTop && deckFarbe ) ui->alphaRegion( 0, 0, ui->getBreite(), ui->getHeight(), deckFarbe ); } for( int i = 0; i < tipAnzahl; ++i ) tips->z( i )->render( *ui ); } if( renderOnTop && onTop ) onTop->render( *ui ); } unlock(); api->presentFrame(); renderZeit->messungEnde(); #ifdef _DEBUG //std::cout << renderZeit->getSekunden() << "\n"; #endif rendering = 0; rend = 0; } #endif