#include "Bildschirm.h" #include "Punkt.h" #include "Bild.h" #include "Farbe.h" #include "Fenster.h" #include "Text.h" #include "Objekt.h" using namespace Framework; // Inhalt der Bildschirmklass aus Bildschirm.h // Konstruktor Bildschirm::Bildschirm( WFenster *f ) { fenster = f; pDirect3D = 0; pDevice = 0; pBackBuffer = 0; renderB = new Bild(); ref = 1; InitializeCriticalSection( &threadSave ); members = new ObjektArray(); füllFarbe = new Farbe( 0, 0, 0, 0 ); vollbild = 0; backBufferGröße = 0; } // Destruktor Bildschirm::~Bildschirm() { if( renderB ) renderB->release(); renderB = 0; if( pDevice ) { pDevice->Release(); pDevice = NULL; } if( pDirect3D ) { pDirect3D->Release(); pDirect3D = NULL; } if( pBackBuffer ) { pBackBuffer->Release(); pBackBuffer = NULL; } if( fenster ) fenster->release(); if( füllFarbe ) füllFarbe->release(); if( backBufferGröße ) backBufferGröße->release(); DeleteCriticalSection( &threadSave ); delete members; } // nicht konstant void Bildschirm::lock() { EnterCriticalSection( &threadSave ); } void Bildschirm::unlock() { LeaveCriticalSection( &threadSave ); } void Bildschirm::update() { lock(); HRESULT result; backRect.pBits = NULL; if( pDirect3D ) { pDirect3D->Release(); pDirect3D = 0; } if( pDevice ) { pDevice->Release(); pDevice = 0; } if( pBackBuffer ) { pBackBuffer->Release(); pBackBuffer = 0; } pDirect3D = Direct3DCreate9( D3D_SDK_VERSION ); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp,sizeof( d3dpp ) ); d3dpp.Windowed = !vollbild; d3dpp.hDeviceWindow = fenster->getFensterHandle(); d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; Punkt *größe; if( !backBufferGröße ) größe = fenster->getGröße(); else größe = backBufferGröße->getThis(); d3dpp.BackBufferHeight = größe->getY(); d3dpp.BackBufferWidth = größe->getX(); if( renderB ) renderB->release(); renderB = new Bild(); if( !füllFarbe ) renderB->neuBild( größe, new Farbe() ); else renderB->neuBild( größe, füllFarbe->getThis() ); result = pDirect3D->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,fenster->getFensterHandle(), D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,&d3dpp,&pDevice ); result = pDevice->GetBackBuffer( 0,0,D3DBACKBUFFER_TYPE_MONO,&pBackBuffer ); unlock(); } void Bildschirm::addMember( Objekt *obj ) // Fügt ein Objekt hinzu { lock(); members->addObjekt( obj ); members->updateIndex( 0 ); unlock(); } void Bildschirm::removeMember( Objekt *obj ) // Entfernt ein Objekt { lock(); members->removeObjekt( obj ); members->updateIndex( 0 ); unlock(); } void Bildschirm::render() { int count = 0; if( renderB && pDevice ) { lock(); if( füllFarbe ) // clear screen renderB->füllRegion( 0, 0, renderB->getBreite(), renderB->getHöhe(), füllFarbe->getFarbe() ); members->render( renderB ); // zeichnen nach zwischenbuffer // Beginne Bild HRESULT result; result = pDevice->Clear( 0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),0.0f,0 ); result = pBackBuffer->LockRect( &backRect, 0, 0 ); // kopieren zum Bildschrirm for(int y = 0; y < renderB->getHöhe(); y++) { memcpy( &( ( BYTE *)backRect.pBits )[backRect.Pitch * y], (void*)&( ( renderB->getBuffer() )[renderB->getBreite() * y] ), sizeof( D3DCOLOR ) * renderB->getBreite() ); } // Beende Bild result = pBackBuffer->UnlockRect(); result = pDevice->Present( 0, 0, 0, 0 ); if( result != S_OK ) { count++; update(); } else if( count ) count--; unlock(); } if( !pDevice ) { count++; update(); } if( count > 10 ) { WMessageBox( fenster ? fenster->getFensterHandle() : 0, new Text( "Fehler" ), new Text( "Es int ein Fehler beim rendern." ), MB_ICONERROR ); count = 0; } } void Bildschirm::setFüllFarbeZ( Farbe *f ) // setzt die Fill Farbe { if( füllFarbe ) füllFarbe->release(); füllFarbe = f; } void Bildschirm::setFüllFarbe( Farbe *f ) { if( !füllFarbe ) füllFarbe = new Farbe(); füllFarbe->setFarbe( f->getFarbe() ); } void Bildschirm::setFüllFarbe( int f ) { if( !füllFarbe ) füllFarbe = new Farbe(); füllFarbe->setFarbe( f ); } void Bildschirm::setVollbild( bool vollbild ) // setzt vollbild { this->vollbild = vollbild; } void Bildschirm::tick( double tickval ) { members->tick( tickval ); } void Bildschirm::setBackBufferGröße( int breite, int höhe ) // setzt die Größe des Backbuffers { if( !backBufferGröße ) backBufferGröße = new Punkt(); backBufferGröße->setP( breite, höhe ); } void Bildschirm::setBackBufferGröße( Punkt *größe ) { if( !backBufferGröße ) backBufferGröße = new Punkt(); backBufferGröße->setP( größe->x, größe->y ); größe->release(); } void Bildschirm::setBackBufferGrößeZ( Punkt *größe ) { if( backBufferGröße ) backBufferGröße->release(); backBufferGröße = größe; } // constant Bild *Bildschirm::getRenderBild() const { return renderB->getThis(); } ObjektArray *Bildschirm::getMembers() const // gibt die Objekte zurück { return members; } Farbe *Bildschirm::getFüllFarbe() const // gibt die Füll Farbe zurück { return füllFarbe ? füllFarbe->getThis(): 0; } Farbe *Bildschirm::zFüllFarbe() const { return füllFarbe; } bool Bildschirm::istVolbild() const // gibt zurück, ob vollbild an ist { return vollbild; } Punkt *Bildschirm::getBackBufferGröße() const // gibt die Größe des Backbuffers zurück { if( backBufferGröße ) return backBufferGröße->getThis(); return 0; } Punkt *Bildschirm::zBackBufferGröße() const { return backBufferGröße; } // Reference Counting Bildschirm *Bildschirm::getThis() { ref++; return this; } Bildschirm *Bildschirm::release() { ref--; if( !ref ) delete this; return 0; }