Bildschirm.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. #include "Bildschirm.h"
  2. #include "Punkt.h"
  3. #include "Bild.h"
  4. #include "Farbe.h"
  5. #include "Fenster.h"
  6. #include "Text.h"
  7. #include "Objekt.h"
  8. using namespace Framework;
  9. // Inhalt der Bildschirmklass aus Bildschirm.h
  10. // Konstruktor
  11. Bildschirm::Bildschirm( WFenster *f )
  12. {
  13. fenster = f;
  14. pDirect3D = 0;
  15. pDevice = 0;
  16. pBackBuffer = 0;
  17. renderB = new Bild();
  18. ref = 1;
  19. InitializeCriticalSection( &threadSave );
  20. members = new ObjektArray();
  21. füllFarbe = new Farbe( 0, 0, 0, 0 );
  22. vollbild = 0;
  23. backBufferGröße = 0;
  24. }
  25. // Destruktor
  26. Bildschirm::~Bildschirm()
  27. {
  28. if( renderB )
  29. renderB->release();
  30. renderB = 0;
  31. if( pDevice )
  32. {
  33. pDevice->Release();
  34. pDevice = NULL;
  35. }
  36. if( pDirect3D )
  37. {
  38. pDirect3D->Release();
  39. pDirect3D = NULL;
  40. }
  41. if( pBackBuffer )
  42. {
  43. pBackBuffer->Release();
  44. pBackBuffer = NULL;
  45. }
  46. if( fenster )
  47. fenster->release();
  48. if( füllFarbe )
  49. füllFarbe->release();
  50. if( backBufferGröße )
  51. backBufferGröße->release();
  52. DeleteCriticalSection( &threadSave );
  53. delete members;
  54. }
  55. // nicht konstant
  56. void Bildschirm::lock()
  57. {
  58. EnterCriticalSection( &threadSave );
  59. }
  60. void Bildschirm::unlock()
  61. {
  62. LeaveCriticalSection( &threadSave );
  63. }
  64. void Bildschirm::update()
  65. {
  66. lock();
  67. HRESULT result;
  68. backRect.pBits = NULL;
  69. if( pDirect3D )
  70. {
  71. pDirect3D->Release();
  72. pDirect3D = 0;
  73. }
  74. if( pDevice )
  75. {
  76. pDevice->Release();
  77. pDevice = 0;
  78. }
  79. if( pBackBuffer )
  80. {
  81. pBackBuffer->Release();
  82. pBackBuffer = 0;
  83. }
  84. pDirect3D = Direct3DCreate9( D3D_SDK_VERSION );
  85. D3DPRESENT_PARAMETERS d3dpp;
  86. ZeroMemory( &d3dpp,sizeof( d3dpp ) );
  87. d3dpp.Windowed = !vollbild;
  88. d3dpp.hDeviceWindow = fenster->getFensterHandle();
  89. d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  90. d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
  91. d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
  92. d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
  93. Punkt *größe;
  94. if( !backBufferGröße )
  95. größe = fenster->getGröße();
  96. else
  97. größe = backBufferGröße->getThis();
  98. d3dpp.BackBufferHeight = größe->getY();
  99. d3dpp.BackBufferWidth = größe->getX();
  100. if( renderB )
  101. renderB->release();
  102. renderB = new Bild();
  103. if( !füllFarbe )
  104. renderB->neuBild( größe, new Farbe() );
  105. else
  106. renderB->neuBild( größe, füllFarbe->getThis() );
  107. result = pDirect3D->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,fenster->getFensterHandle(),
  108. D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,&d3dpp,&pDevice );
  109. result = pDevice->GetBackBuffer( 0,0,D3DBACKBUFFER_TYPE_MONO,&pBackBuffer );
  110. unlock();
  111. }
  112. void Bildschirm::addMember( Objekt *obj ) // Fügt ein Objekt hinzu
  113. {
  114. lock();
  115. members->addObjekt( obj );
  116. members->updateIndex( 0 );
  117. unlock();
  118. }
  119. void Bildschirm::removeMember( Objekt *obj ) // Entfernt ein Objekt
  120. {
  121. lock();
  122. members->removeObjekt( obj );
  123. members->updateIndex( 0 );
  124. unlock();
  125. }
  126. void Bildschirm::render()
  127. {
  128. int count = 0;
  129. if( renderB && pDevice )
  130. {
  131. lock();
  132. if( füllFarbe ) // clear screen
  133. renderB->füllRegion( 0, 0, renderB->getBreite(), renderB->getHöhe(), füllFarbe->getFarbe() );
  134. members->render( renderB ); // zeichnen nach zwischenbuffer
  135. // Beginne Bild
  136. HRESULT result;
  137. result = pDevice->Clear( 0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),0.0f,0 );
  138. result = pBackBuffer->LockRect( &backRect, 0, 0 );
  139. // kopieren zum Bildschrirm
  140. for(int y = 0; y < renderB->getHöhe(); y++)
  141. {
  142. memcpy( &( ( BYTE *)backRect.pBits )[backRect.Pitch * y], (void*)&( ( renderB->getBuffer() )[renderB->getBreite() * y] ), sizeof( D3DCOLOR ) * renderB->getBreite() );
  143. }
  144. // Beende Bild
  145. result = pBackBuffer->UnlockRect();
  146. result = pDevice->Present( 0, 0, 0, 0 );
  147. if( result != S_OK )
  148. {
  149. count++;
  150. update();
  151. }
  152. else if( count )
  153. count--;
  154. unlock();
  155. }
  156. if( !pDevice )
  157. {
  158. count++;
  159. update();
  160. }
  161. if( count > 10 )
  162. {
  163. WMessageBox( fenster ? fenster->getFensterHandle() : 0, new Text( "Fehler" ), new Text( "Es int ein Fehler beim rendern." ), MB_ICONERROR );
  164. count = 0;
  165. }
  166. }
  167. void Bildschirm::setFüllFarbeZ( Farbe *f ) // setzt die Fill Farbe
  168. {
  169. if( füllFarbe )
  170. füllFarbe->release();
  171. füllFarbe = f;
  172. }
  173. void Bildschirm::setFüllFarbe( Farbe *f )
  174. {
  175. if( !füllFarbe )
  176. füllFarbe = new Farbe();
  177. füllFarbe->setFarbe( f->getFarbe() );
  178. }
  179. void Bildschirm::setFüllFarbe( int f )
  180. {
  181. if( !füllFarbe )
  182. füllFarbe = new Farbe();
  183. füllFarbe->setFarbe( f );
  184. }
  185. void Bildschirm::setVollbild( bool vollbild ) // setzt vollbild
  186. {
  187. this->vollbild = vollbild;
  188. }
  189. void Bildschirm::tick( double tickval )
  190. {
  191. members->tick( tickval );
  192. }
  193. void Bildschirm::setBackBufferGröße( int breite, int höhe ) // setzt die Größe des Backbuffers
  194. {
  195. if( !backBufferGröße )
  196. backBufferGröße = new Punkt();
  197. backBufferGröße->setP( breite, höhe );
  198. }
  199. void Bildschirm::setBackBufferGröße( Punkt *größe )
  200. {
  201. if( !backBufferGröße )
  202. backBufferGröße = new Punkt();
  203. backBufferGröße->setP( größe->x, größe->y );
  204. größe->release();
  205. }
  206. void Bildschirm::setBackBufferGrößeZ( Punkt *größe )
  207. {
  208. if( backBufferGröße )
  209. backBufferGröße->release();
  210. backBufferGröße = größe;
  211. }
  212. // constant
  213. Bild *Bildschirm::getRenderBild() const
  214. {
  215. return renderB->getThis();
  216. }
  217. ObjektArray *Bildschirm::getMembers() const // gibt die Objekte zurück
  218. {
  219. return members;
  220. }
  221. Farbe *Bildschirm::getFüllFarbe() const // gibt die Füll Farbe zurück
  222. {
  223. return füllFarbe ? füllFarbe->getThis(): 0;
  224. }
  225. Farbe *Bildschirm::zFüllFarbe() const
  226. {
  227. return füllFarbe;
  228. }
  229. bool Bildschirm::istVolbild() const // gibt zurück, ob vollbild an ist
  230. {
  231. return vollbild;
  232. }
  233. Punkt *Bildschirm::getBackBufferGröße() const // gibt die Größe des Backbuffers zurück
  234. {
  235. if( backBufferGröße )
  236. return backBufferGröße->getThis();
  237. return 0;
  238. }
  239. Punkt *Bildschirm::zBackBufferGröße() const
  240. {
  241. return backBufferGröße;
  242. }
  243. // Reference Counting
  244. Bildschirm *Bildschirm::getThis()
  245. {
  246. ref++;
  247. return this;
  248. }
  249. Bildschirm *Bildschirm::release()
  250. {
  251. ref--;
  252. if( !ref )
  253. delete this;
  254. return 0;
  255. }