Background2D.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104
  1. #include "core/Background2D.h"
  2. #include <OgreHardwareBufferManager.h>
  3. #include <OgreLogManager.h>
  4. #include <OgreMaterialManager.h>
  5. #include <OgreException.h>
  6. #include "core/CameraManager.h"
  7. #include "core/ConfigVar.h"
  8. #include "core/DebugDraw.h"
  9. #include "core/Logger.h"
  10. #include "core/Timer.h"
  11. //------------------------------------------------------------------------------
  12. ConfigVar cv_debug_background2d( "debug_background2d", "Draw background debug info", "false" );
  13. ConfigVar cv_show_background2d( "show_background2d", "Draw background", "true" );
  14. ConfigVar cv_background2d_manual( "background2d_manual", "Manual scrolling for 2d background", "false" );
  15. //------------------------------------------------------------------------------
  16. Background2D::Background2D():
  17. m_AlphaMaxVertexCount( 0 ),
  18. m_AddMaxVertexCount( 0 ),
  19. m_SubtractMaxVertexCount( 0 ),
  20. m_MultiplyMaxVertexCount( 0 ),
  21. m_ScrollEntity( NULL ),
  22. m_ScrollPositionStart( Ogre::Vector2::ZERO ),
  23. m_ScrollPositionEnd( Ogre::Vector2::ZERO ),
  24. m_ScrollType( Background2D::NONE ),
  25. m_ScrollSeconds( 0 ),
  26. m_ScrollCurrentSeconds( 0 ),
  27. m_Position( Ogre::Vector2::ZERO ),
  28. m_PositionReal( Ogre::Vector2::ZERO )
  29. ,m_range( Ogre::AxisAlignedBox::BOX_INFINITE )
  30. // for ffvii
  31. ,m_virtual_screen_size( 320, 240 )
  32. {
  33. m_SceneManager = Ogre::Root::getSingleton().getSceneManager( "Scene" );
  34. m_RenderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
  35. CreateVertexBuffers();
  36. m_AlphaMaterial = Ogre::MaterialManager::getSingleton().create( "Background2DAlpha", "General" );
  37. Ogre::Pass* pass = m_AlphaMaterial->getTechnique( 0 )->getPass( 0 );
  38. pass->setVertexColourTracking( Ogre::TVC_AMBIENT );
  39. pass->setCullingMode( Ogre::CULL_NONE );
  40. pass->setDepthCheckEnabled( true );
  41. pass->setDepthWriteEnabled( true );
  42. pass->setLightingEnabled( false );
  43. pass->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
  44. pass->setAlphaRejectFunction( Ogre::CMPF_GREATER );
  45. pass->setAlphaRejectValue( 0 );
  46. Ogre::TextureUnitState* tex = pass->createTextureUnitState();
  47. tex->setTextureName( "system/blank.png" );
  48. tex->setNumMipmaps( -1 );
  49. tex->setTextureFiltering( Ogre::TFO_NONE );
  50. m_AddMaterial = Ogre::MaterialManager::getSingleton().create( "Background2DAdd", "General" );
  51. pass = m_AddMaterial->getTechnique( 0 )->getPass( 0 );
  52. pass->setVertexColourTracking( Ogre::TVC_AMBIENT );
  53. pass->setCullingMode( Ogre::CULL_NONE );
  54. pass->setDepthCheckEnabled( true );
  55. pass->setDepthWriteEnabled( true );
  56. pass->setLightingEnabled( false );
  57. pass->setSceneBlending( Ogre::SBT_ADD );
  58. pass->setAlphaRejectFunction( Ogre::CMPF_GREATER );
  59. pass->setAlphaRejectValue( 0 );
  60. tex = pass->createTextureUnitState();
  61. tex->setTextureName( "system/blank.png" );
  62. tex->setNumMipmaps( -1 );
  63. tex->setTextureFiltering( Ogre::TFO_NONE );
  64. m_SubtractMaterial = Ogre::MaterialManager::getSingleton().create( "Background2DSubtract", "General" );
  65. pass = m_SubtractMaterial->getTechnique( 0 )->getPass( 0 );
  66. pass->setVertexColourTracking( Ogre::TVC_AMBIENT );
  67. pass->setCullingMode( Ogre::CULL_NONE );
  68. pass->setDepthCheckEnabled( true );
  69. pass->setDepthWriteEnabled( true );
  70. pass->setLightingEnabled( false );
  71. pass->setSceneBlending( Ogre::SBF_ONE, Ogre::SBF_ONE_MINUS_SOURCE_COLOUR ); // FIXME: SUBTRACT
  72. pass->setAlphaRejectFunction( Ogre::CMPF_LESS );
  73. pass->setAlphaRejectValue( 0 );
  74. tex = pass->createTextureUnitState();
  75. tex->setTextureName( "system/blank.png" );
  76. tex->setNumMipmaps( -1 );
  77. tex->setTextureFiltering( Ogre::TFO_NONE );
  78. m_MultiplyMaterial = Ogre::MaterialManager::getSingleton().create( "Background2DMultiply", "General" );
  79. pass = m_MultiplyMaterial->getTechnique( 0 )->getPass( 0 );
  80. pass->setVertexColourTracking( Ogre::TVC_AMBIENT );
  81. pass->setCullingMode( Ogre::CULL_NONE );
  82. pass->setDepthCheckEnabled( true );
  83. pass->setDepthWriteEnabled( true );
  84. pass->setLightingEnabled( false );
  85. pass->setSceneBlending( Ogre::SBT_ADD ); // FIXME: MULTIPLY
  86. pass->setAlphaRejectFunction( Ogre::CMPF_GREATER );
  87. pass->setAlphaRejectValue( 0 );
  88. tex = pass->createTextureUnitState();
  89. tex->setTextureName( "system/blank.png" );
  90. tex->setNumMipmaps( -1 );
  91. tex->setTextureFiltering( Ogre::TFO_NONE );
  92. m_SceneManager->addRenderQueueListener( this );
  93. }
  94. //------------------------------------------------------------------------------
  95. Background2D::~Background2D()
  96. {
  97. m_SceneManager->removeRenderQueueListener( this );
  98. for( unsigned int i = 0; i < m_Animations.size(); ++i )
  99. {
  100. delete m_Animations[ i ];
  101. }
  102. DestroyVertexBuffers();
  103. }
  104. //------------------------------------------------------------------------------
  105. void
  106. Background2D::InputDebug(const QGears::Event& event)
  107. {
  108. if( cv_background2d_manual.GetB() == true )
  109. {
  110. if (event.type == QGears::ET_KEY_IMPULSE && event.param1 == OIS::KC_W)
  111. {
  112. m_PositionReal.y += 2;
  113. }
  114. else if (event.type == QGears::ET_KEY_IMPULSE && event.param1 == OIS::KC_A)
  115. {
  116. m_PositionReal.x += 2;
  117. }
  118. else if (event.type == QGears::ET_KEY_IMPULSE && event.param1 == OIS::KC_S)
  119. {
  120. m_PositionReal.y -= 2;
  121. }
  122. else if (event.type == QGears::ET_KEY_IMPULSE && event.param1 == OIS::KC_D)
  123. {
  124. m_PositionReal.x -= 2;
  125. }
  126. CameraManager::getSingleton().Set2DScroll( m_PositionReal );
  127. }
  128. }
  129. //------------------------------------------------------------------------------
  130. void
  131. Background2D::Update()
  132. {
  133. for( unsigned int i = 0; i < m_AnimationPlayed.size(); ++i )
  134. {
  135. for( unsigned int j = 0; j < m_Animations.size(); ++j )
  136. {
  137. if( m_Animations[ j ]->GetName() == m_AnimationPlayed[ i ].name )
  138. {
  139. float delta_time = Timer::getSingleton().GetGameTimeDelta();
  140. float time = m_Animations[ j ]->GetTime();
  141. float end_time = m_Animations[ j ]->GetLength();
  142. // if animation ended
  143. if( time + delta_time >= end_time )
  144. {
  145. // set to last frame of animation
  146. if( time != end_time )
  147. {
  148. m_Animations[ j ]->SetTime( end_time );
  149. }
  150. if( m_AnimationPlayed[ i ].state == Background2DAnimation::ONCE )
  151. {
  152. for( unsigned int k = 0; k < m_AnimationPlayed[ i ].sync.size(); ++k )
  153. {
  154. ScriptManager::getSingleton().ContinueScriptExecution( m_AnimationPlayed[ i ].sync[ k ] );
  155. }
  156. m_AnimationPlayed[ i ].sync.clear();
  157. m_AnimationPlayed[ i ].name = ""; // mark to erase this way
  158. }
  159. else // LOOPED
  160. {
  161. // in case of looped we need to sync with end
  162. m_Animations[ j ]->SetTime( time + delta_time - end_time );
  163. }
  164. }
  165. else
  166. {
  167. m_Animations[ j ]->AddTime( delta_time );
  168. }
  169. }
  170. }
  171. }
  172. // remove stopped animations
  173. std::vector< AnimationPlayed >::iterator i = m_AnimationPlayed.begin();
  174. for( ; i != m_AnimationPlayed.end(); )
  175. {
  176. if( ( *i ).name == "" )
  177. {
  178. i = m_AnimationPlayed.erase( i );
  179. }
  180. else
  181. {
  182. ++i;
  183. }
  184. }
  185. }
  186. //------------------------------------------------------------------------------
  187. void
  188. Background2D::UpdateDebug()
  189. {
  190. // is this necessary? does it cost to apply camera 2d Scroll?
  191. // if so maybe move this check to applyScroll
  192. if( m_PositionReal != GetScreenScroll() )
  193. {
  194. applyScroll();
  195. }
  196. if( cv_debug_background2d.GetB() == true )
  197. {
  198. DEBUG_DRAW.SetTextAlignment( DEBUG_DRAW.LEFT );
  199. DEBUG_DRAW.SetScreenSpace( true );
  200. DEBUG_DRAW.SetColour( Ogre::ColourValue( 0.0f, 0.8f, 0.8f, 1.0f ) );
  201. for( unsigned int i = 0; i < m_AnimationPlayed.size(); ++i )
  202. {
  203. DEBUG_DRAW.Text( 150.0f, static_cast<float>(34 + i * 12), "Background 2D animation: " + m_AnimationPlayed[ i ].name );
  204. }
  205. }
  206. }
  207. //------------------------------------------------------------------------------
  208. void
  209. Background2D::calculateScreenScale( void )
  210. {
  211. Ogre::Viewport *viewport( CameraManager::getSingleton().getViewport() );
  212. Ogre::Real scale_width = static_cast<Ogre::Real>(viewport->getActualWidth());
  213. Ogre::Real scale_height = static_cast<Ogre::Real>(viewport->getActualHeight());
  214. scale_width /= m_virtual_screen_size.x;
  215. scale_height /= m_virtual_screen_size.y;
  216. m_screen_scale = scale_height;
  217. m_screen_proportion.x = m_screen_scale / scale_width;
  218. m_screen_proportion.y = m_screen_scale / scale_height;
  219. }
  220. //------------------------------------------------------------------------------
  221. void
  222. Background2D::OnResize()
  223. {
  224. calculateScreenScale();
  225. for( unsigned int i = 0; i < m_Tiles.size(); ++i )
  226. {
  227. Tile &tile( m_Tiles[ i ] );
  228. Ogre::Vector2 top_left(static_cast<Ogre::Real>(tile.x), static_cast<Ogre::Real>(- tile.y));
  229. Ogre::Vector2 top_right(static_cast<Ogre::Real>(tile.x + tile.width), static_cast<Ogre::Real>(top_left.y));
  230. Ogre::Vector2 bottom_right(static_cast<Ogre::Real>(top_right.x), static_cast<Ogre::Real>(-(tile.y + tile.height)));
  231. Ogre::Vector2 bottom_left(static_cast<Ogre::Real>(top_left.x), static_cast<Ogre::Real>(bottom_right.y));
  232. virtualScreenToWorldSpace( top_left );
  233. virtualScreenToWorldSpace( top_right );
  234. virtualScreenToWorldSpace( bottom_right );
  235. virtualScreenToWorldSpace( bottom_left );
  236. float new_x1 = top_left.x;
  237. float new_y1 = top_left.y;
  238. float new_x2 = top_right.x;
  239. float new_y2 = top_right.y;
  240. float new_x3 = bottom_right.x;
  241. float new_y3 = bottom_right.y;
  242. float new_x4 = bottom_left.x;
  243. float new_y4 = bottom_left.y;
  244. Ogre::HardwareVertexBufferSharedPtr vertex_buffer;
  245. if( m_Tiles[ i ].blending == QGears::B_ALPHA )
  246. {
  247. vertex_buffer = m_AlphaVertexBuffer;
  248. }
  249. else if( m_Tiles[ i ].blending == QGears::B_ADD )
  250. {
  251. vertex_buffer = m_AddVertexBuffer;
  252. }
  253. else if( m_Tiles[ i ].blending == QGears::B_SUBTRACT )
  254. {
  255. vertex_buffer = m_SubtractVertexBuffer;
  256. }
  257. else if( m_Tiles[ i ].blending == QGears::B_MULTIPLY )
  258. {
  259. vertex_buffer = m_MultiplyVertexBuffer;
  260. }
  261. float* writeIterator = ( float* )vertex_buffer->lock( Ogre::HardwareBuffer::HBL_NORMAL );
  262. writeIterator += m_Tiles[ i ].start_vertex_index * TILE_VERTEX_INDEX_SIZE;
  263. *writeIterator++ = new_x1;
  264. *writeIterator++ = new_y1;
  265. writeIterator += 7;
  266. *writeIterator++ = new_x2;
  267. *writeIterator++ = new_y2;
  268. writeIterator += 7;
  269. *writeIterator++ = new_x3;
  270. *writeIterator++ = new_y3;
  271. writeIterator += 7;
  272. ///*
  273. *writeIterator++ = new_x1;
  274. *writeIterator++ = new_y1;
  275. writeIterator += 7;
  276. *writeIterator++ = new_x3;
  277. *writeIterator++ = new_y3;
  278. writeIterator += 7;
  279. //*/
  280. *writeIterator++ = new_x4;
  281. *writeIterator++ = new_y4;
  282. vertex_buffer->unlock();
  283. }
  284. applyScroll();
  285. }
  286. //------------------------------------------------------------------------------
  287. void
  288. Background2D::Clear()
  289. {
  290. m_ScrollEntity = NULL;
  291. m_ScrollPositionStart = Ogre::Vector2::ZERO;
  292. m_ScrollPositionEnd = Ogre::Vector2::ZERO;
  293. m_ScrollSeconds = 0;
  294. m_ScrollCurrentSeconds = 0;
  295. m_Position = Ogre::Vector2::ZERO;
  296. m_PositionReal = Ogre::Vector2::ZERO;
  297. m_range = Ogre::AxisAlignedBox::BOX_INFINITE;
  298. UnsetScroll();
  299. for( unsigned int i = 0; i < m_Animations.size(); ++i )
  300. {
  301. delete m_Animations[ i ];
  302. }
  303. m_Animations.clear();
  304. for( unsigned int i = 0; i < m_AnimationPlayed.size(); ++i )
  305. {
  306. for( unsigned int j = 0; j < m_AnimationPlayed[ i ].sync.size(); ++j )
  307. {
  308. ScriptManager::getSingleton().ContinueScriptExecution( m_AnimationPlayed[ i ].sync[ j ] );
  309. }
  310. }
  311. m_AnimationPlayed.clear();
  312. m_Tiles.clear();
  313. DestroyVertexBuffers();
  314. CreateVertexBuffers();
  315. }
  316. //------------------------------------------------------------------------------
  317. void
  318. Background2D::ScriptAutoScrollToEntity( Entity* entity )
  319. {
  320. m_ScrollEntity = entity;
  321. }
  322. //------------------------------------------------------------------------------
  323. Entity*
  324. Background2D::GetAutoScrollEntity() const
  325. {
  326. return m_ScrollEntity;
  327. }
  328. //------------------------------------------------------------------------------
  329. void
  330. Background2D::ScriptScrollToPosition( const float x, const float y, const ScrollType type, const float seconds )
  331. {
  332. LOG_TRIVIAL( "[SCRIPT] Background2d set scroll to position \"" + Ogre::StringConverter::toString( Ogre::Vector2( x, y ) ) + "\"." );
  333. Ogre::Vector2 position = Ogre::Vector2( x, y );
  334. m_ScrollEntity = NULL;
  335. if( type == Background2D::NONE )
  336. {
  337. SetScroll( position );
  338. return;
  339. }
  340. m_ScrollPositionStart = m_Position;
  341. m_ScrollPositionEnd = position;
  342. m_ScrollType = type;
  343. m_ScrollSeconds = seconds;
  344. m_ScrollCurrentSeconds = 0;
  345. }
  346. //------------------------------------------------------------------------------
  347. int
  348. Background2D::ScriptScrollSync()
  349. {
  350. ScriptId script = ScriptManager::getSingleton().GetCurrentScriptId();
  351. LOG_TRIVIAL( "[SCRIPT] Wait Background2d scroll for function \"" + script.function + "\" in script entity \"" + script.entity + "\"." );
  352. m_ScrollSync.push_back( script );
  353. return -1;
  354. }
  355. //------------------------------------------------------------------------------
  356. void
  357. Background2D::UnsetScroll()
  358. {
  359. m_ScrollType = Background2D::NONE;
  360. for( unsigned int i = 0; i < m_ScrollSync.size(); ++i )
  361. {
  362. ScriptManager::getSingleton().ContinueScriptExecution( m_ScrollSync[ i ] );
  363. }
  364. m_ScrollSync.clear();
  365. }
  366. //------------------------------------------------------------------------------
  367. const Ogre::Vector2&
  368. Background2D::GetScrollPositionStart() const
  369. {
  370. return m_ScrollPositionStart;
  371. }
  372. //------------------------------------------------------------------------------
  373. const Ogre::Vector2&
  374. Background2D::GetScrollPositionEnd() const
  375. {
  376. return m_ScrollPositionEnd;
  377. }
  378. //------------------------------------------------------------------------------
  379. Background2D::ScrollType
  380. Background2D::GetScrollType() const
  381. {
  382. return m_ScrollType;
  383. }
  384. //------------------------------------------------------------------------------
  385. float
  386. Background2D::GetScrollSeconds() const
  387. {
  388. return m_ScrollSeconds;
  389. }
  390. //------------------------------------------------------------------------------
  391. void
  392. Background2D::SetScrollCurrentSeconds( const float seconds )
  393. {
  394. m_ScrollCurrentSeconds = seconds;
  395. }
  396. //------------------------------------------------------------------------------
  397. float
  398. Background2D::GetScrollCurrentSeconds() const
  399. {
  400. return m_ScrollCurrentSeconds;
  401. }
  402. //------------------------------------------------------------------------------
  403. void
  404. Background2D::SetScreenScroll( const Ogre::Vector2& position )
  405. {
  406. SetScroll( position / m_screen_scale );
  407. }
  408. //------------------------------------------------------------------------------
  409. void
  410. Background2D::SetScroll( const Ogre::Vector2& position )
  411. {
  412. m_Position = position;
  413. Ogre::Vector3 pos_3d( m_Position.x, m_Position.y, 0 );
  414. if( !m_range.contains( pos_3d ) )
  415. {
  416. Ogre::Vector3 max_3d( m_range.getMaximum() );
  417. Ogre::Vector3 min_3d( m_range.getMinimum() );
  418. Ogre::Vector2 max( max_3d.x, max_3d.y );
  419. Ogre::Vector2 min( min_3d.x, min_3d.y );
  420. m_Position.makeCeil( min );
  421. m_Position.makeFloor( max );
  422. }
  423. applyScroll();
  424. }
  425. //------------------------------------------------------------------------------
  426. void
  427. Background2D::applyScroll()
  428. {
  429. if( cv_background2d_manual.GetB() != true )
  430. {
  431. m_PositionReal = GetScreenScroll();
  432. CameraManager::getSingleton().Set2DScroll( m_PositionReal );
  433. }
  434. }
  435. //------------------------------------------------------------------------------
  436. const Ogre::Vector2&
  437. Background2D::GetScroll() const
  438. {
  439. return m_Position;
  440. }
  441. //------------------------------------------------------------------------------
  442. const Ogre::Vector2
  443. Background2D::GetScreenScroll() const
  444. {
  445. return GetScroll() * m_screen_scale;
  446. }
  447. //------------------------------------------------------------------------------
  448. void
  449. Background2D::SetImage( const Ogre::String& image )
  450. {
  451. Ogre::LogManager::getSingleton().stream()
  452. << "Background2D::SetImage " << image;
  453. Ogre::Pass* pass = m_AlphaMaterial->getTechnique( 0 )->getPass( 0 );
  454. Ogre::TextureUnitState* tex = pass->getTextureUnitState( 0 );
  455. tex->setTextureName( image );
  456. pass = m_AddMaterial->getTechnique( 0 )->getPass( 0 );
  457. tex = pass->getTextureUnitState( 0 );
  458. tex->setTextureName( image );
  459. pass = m_SubtractMaterial->getTechnique( 0 )->getPass( 0 );
  460. tex = pass->getTextureUnitState( 0 );
  461. tex->setTextureName( image );
  462. pass = m_MultiplyMaterial->getTechnique( 0 )->getPass( 0 );
  463. tex = pass->getTextureUnitState( 0 );
  464. tex->setTextureName( image );
  465. }
  466. //------------------------------------------------------------------------------
  467. void
  468. Background2D::SetRange( const Ogre::Vector4& range )
  469. {
  470. SetRange( ( int )range.x, ( int )range.y, ( int )range.z, ( int )range.w );
  471. }
  472. //------------------------------------------------------------------------------
  473. void
  474. Background2D::SetRange( const int min_x, const int min_y, const int max_x, const int max_y )
  475. {
  476. Ogre::LogManager::getSingleton().stream()
  477. << "Background2D::SetRange " << min_x << " " << min_y << " " << max_x << " " << max_y;
  478. Ogre::Vector2 half_virtual_screen_size( m_virtual_screen_size / 2 );
  479. half_virtual_screen_size /= m_screen_proportion;
  480. m_range.setMaximum( max_x - half_virtual_screen_size.x , max_y - half_virtual_screen_size.y, 1 );
  481. m_range.setMinimum( min_x + half_virtual_screen_size.x , min_y + half_virtual_screen_size.y, 0 );
  482. Ogre::LogManager::getSingleton().stream()
  483. << "Background2D::SetRange " << m_range;
  484. calculateScreenScale();
  485. }
  486. //------------------------------------------------------------------------------
  487. void
  488. Background2D::AddTile( const QGears::Tile& tile )
  489. {
  490. // TODO: move depth calculation to flevelBackgroundLoader maybe? and let Backgorund2D only handle 0 <= depth <= 1 or so?
  491. // maybe just move the < 4095 part to flevel background loader?
  492. Ogre::Real depth( 0.0001f );
  493. if( tile.depth >= 1 )
  494. {
  495. if( tile.depth < 4095 )
  496. {
  497. const Ogre::Matrix4 &cam_projection( CameraManager::getSingleton().GetCurrentCamera()->getProjectionMatrixWithRSDepth() );
  498. Ogre::Vector4 res( 0, 0, -tile.depth, 1 );
  499. res = cam_projection * res;
  500. res /= res.w;
  501. depth = res.z;
  502. }
  503. else
  504. {
  505. depth = 0.9999f;
  506. }
  507. }
  508. AddTile( tile.destination, tile.width, tile.height, depth, tile.uv, tile.blending );
  509. }
  510. //------------------------------------------------------------------------------
  511. void
  512. Background2D::AddTile( const Ogre::Vector2& destination, const int width, const int height, const float depth, const Ogre::Vector4& uv, const Blending blending )
  513. {
  514. AddTile( static_cast<int>(destination.x), static_cast<int>(destination.y), width, height, depth, uv.x, uv.y, uv.z, uv.w, blending );
  515. }
  516. //------------------------------------------------------------------------------
  517. void
  518. Background2D::virtualScreenToWorldSpace( Ogre::Vector2& pos ) const
  519. {
  520. pos.x /= m_virtual_screen_size.x / 2;
  521. pos.y /= m_virtual_screen_size.y / 2;
  522. pos.x *= m_screen_proportion.x;
  523. pos.y *= m_screen_proportion.y;
  524. }
  525. //------------------------------------------------------------------------------
  526. void
  527. Background2D::AddTile( const int x, const int y, const int width, const int height, const float depth, const float u1, const float v1, const float u2, const float v2, const Blending blending )
  528. {
  529. Ogre::RenderOperation render_op;
  530. Ogre::HardwareVertexBufferSharedPtr vertex_buffer;
  531. unsigned int max_vertex_count;
  532. if( blending == QGears::B_ALPHA )
  533. {
  534. render_op = m_AlphaRenderOp;
  535. vertex_buffer = m_AlphaVertexBuffer;
  536. max_vertex_count = m_AlphaMaxVertexCount;
  537. }
  538. else if( blending == QGears::B_ADD )
  539. {
  540. render_op = m_AddRenderOp;
  541. vertex_buffer = m_AddVertexBuffer;
  542. max_vertex_count = m_AddMaxVertexCount;
  543. }
  544. else if( blending == QGears::B_SUBTRACT )
  545. {
  546. render_op = m_SubtractRenderOp;
  547. vertex_buffer = m_SubtractVertexBuffer;
  548. max_vertex_count = m_SubtractMaxVertexCount;
  549. }
  550. else if( blending == QGears::B_MULTIPLY )
  551. {
  552. render_op = m_MultiplyRenderOp;
  553. vertex_buffer = m_MultiplyVertexBuffer;
  554. max_vertex_count = m_MultiplyMaxVertexCount;
  555. }
  556. else
  557. {
  558. LOG_ERROR( "Unknown blending type." );
  559. return;
  560. }
  561. if( render_op.vertexData->vertexCount + TILE_VERTEX_COUNT > max_vertex_count )
  562. {
  563. LOG_ERROR( "Max number of tiles reached. Can't create more than " + Ogre::StringConverter::toString( max_vertex_count / TILE_VERTEX_COUNT ) + " tiles." );
  564. return;
  565. }
  566. Tile tile;
  567. tile.x = x;
  568. tile.y = y;
  569. tile.width = width;
  570. tile.height = height;
  571. tile.start_vertex_index = render_op.vertexData->vertexCount;
  572. tile.blending = blending;
  573. size_t index( m_Tiles.size() );
  574. m_Tiles.push_back( tile );
  575. Ogre::Vector2 top_left(static_cast<Ogre::Real>(x), static_cast<Ogre::Real>(-y));
  576. Ogre::Vector2 top_right(static_cast<Ogre::Real>(x + width), static_cast<Ogre::Real>(top_left.y));
  577. Ogre::Vector2 bottom_right(static_cast<Ogre::Real>(top_right.x), static_cast<Ogre::Real>(-(y + height)));
  578. Ogre::Vector2 bottom_left( top_left.x, bottom_right.y );
  579. virtualScreenToWorldSpace( top_left );
  580. virtualScreenToWorldSpace( top_right );
  581. virtualScreenToWorldSpace( bottom_right );
  582. virtualScreenToWorldSpace( bottom_left );
  583. float new_x1 = top_left.x;
  584. float new_y1 = top_left.y;
  585. float new_x2 = top_right.x;
  586. float new_y2 = top_right.y;
  587. float new_x3 = bottom_right.x;
  588. float new_y3 = bottom_right.y;
  589. float new_x4 = bottom_left.x;
  590. float new_y4 = bottom_left.y;
  591. float* writeIterator = ( float* )vertex_buffer->lock( Ogre::HardwareBuffer::HBL_NORMAL );
  592. writeIterator += render_op.vertexData->vertexCount * TILE_VERTEX_INDEX_SIZE;
  593. *writeIterator++ = new_x1;
  594. *writeIterator++ = new_y1;
  595. *writeIterator++ = depth;
  596. *writeIterator++ = 1;
  597. *writeIterator++ = 1;
  598. *writeIterator++ = 1;
  599. *writeIterator++ = 1;
  600. *writeIterator++ = u1;
  601. *writeIterator++ = v1;
  602. *writeIterator++ = new_x2;
  603. *writeIterator++ = new_y2;
  604. *writeIterator++ = depth;
  605. *writeIterator++ = 1;
  606. *writeIterator++ = 1;
  607. *writeIterator++ = 1;
  608. *writeIterator++ = 1;
  609. *writeIterator++ = u2;
  610. *writeIterator++ = v1;
  611. *writeIterator++ = new_x3;
  612. *writeIterator++ = new_y3;
  613. *writeIterator++ = depth;
  614. *writeIterator++ = 1;
  615. *writeIterator++ = 1;
  616. *writeIterator++ = 1;
  617. *writeIterator++ = 1;
  618. *writeIterator++ = u2;
  619. *writeIterator++ = v2;
  620. *writeIterator++ = new_x1;
  621. *writeIterator++ = new_y1;
  622. *writeIterator++ = depth;
  623. *writeIterator++ = 1;
  624. *writeIterator++ = 1;
  625. *writeIterator++ = 1;
  626. *writeIterator++ = 1;
  627. *writeIterator++ = u1;
  628. *writeIterator++ = v1;
  629. *writeIterator++ = new_x3;
  630. *writeIterator++ = new_y3;
  631. *writeIterator++ = depth;
  632. *writeIterator++ = 1;
  633. *writeIterator++ = 1;
  634. *writeIterator++ = 1;
  635. *writeIterator++ = 1;
  636. *writeIterator++ = u2;
  637. *writeIterator++ = v2;
  638. *writeIterator++ = new_x4;
  639. *writeIterator++ = new_y4;
  640. *writeIterator++ = depth;
  641. *writeIterator++ = 1;
  642. *writeIterator++ = 1;
  643. *writeIterator++ = 1;
  644. *writeIterator++ = 1;
  645. *writeIterator++ = u1;
  646. *writeIterator++ = v2;
  647. render_op.vertexData->vertexCount += TILE_VERTEX_COUNT;
  648. vertex_buffer->unlock();
  649. }
  650. //------------------------------------------------------------------------------
  651. void
  652. Background2D::UpdateTileUV( const unsigned int tile_id, const float u1, const float v1, const float u2, const float v2 )
  653. {
  654. if( tile_id >= m_Tiles.size() )
  655. {
  656. LOG_ERROR( "Tile with id " + Ogre::StringConverter::toString( tile_id ) + " doesn't exist." );
  657. return;
  658. }
  659. Ogre::HardwareVertexBufferSharedPtr vertex_buffer;
  660. if( m_Tiles[ tile_id ].blending == QGears::B_ALPHA )
  661. {
  662. vertex_buffer = m_AlphaVertexBuffer;
  663. }
  664. else if( m_Tiles[ tile_id ].blending == QGears::B_ADD )
  665. {
  666. vertex_buffer = m_AddVertexBuffer;
  667. }
  668. else if( m_Tiles[ tile_id ].blending == QGears::B_SUBTRACT )
  669. {
  670. vertex_buffer = m_SubtractVertexBuffer;
  671. }
  672. else if( m_Tiles[ tile_id ].blending == QGears::B_MULTIPLY )
  673. {
  674. vertex_buffer = m_MultiplyVertexBuffer;
  675. }
  676. float* writeIterator = ( float* )vertex_buffer->lock( Ogre::HardwareBuffer::HBL_NORMAL );
  677. writeIterator += m_Tiles[ tile_id ].start_vertex_index * TILE_VERTEX_INDEX_SIZE;
  678. writeIterator += 7;
  679. *writeIterator++ = u1;
  680. *writeIterator++ = v1;
  681. writeIterator += 7;
  682. *writeIterator++ = u2;
  683. *writeIterator++ = v1;
  684. writeIterator += 7;
  685. *writeIterator++ = u2;
  686. *writeIterator++ = v2;
  687. writeIterator += 7;
  688. *writeIterator++ = u1;
  689. *writeIterator++ = v1;
  690. writeIterator += 7;
  691. *writeIterator++ = u2;
  692. *writeIterator++ = v2;
  693. writeIterator += 7;
  694. *writeIterator++ = u1;
  695. *writeIterator++ = v2;
  696. vertex_buffer->unlock();
  697. }
  698. //------------------------------------------------------------------------------
  699. void
  700. Background2D::AddAnimation( Background2DAnimation* animation )
  701. {
  702. m_Animations.push_back( animation );
  703. }
  704. //------------------------------------------------------------------------------
  705. void
  706. Background2D::PlayAnimation( const Ogre::String& animation, const Background2DAnimation::State state )
  707. {
  708. bool found = false;
  709. for( unsigned int i = 0; i < m_Animations.size(); ++i )
  710. {
  711. if( m_Animations[ i ]->GetName() == animation )
  712. {
  713. found = true;
  714. m_Animations[ i ]->SetTime( 0 );
  715. m_Animations[ i ]->AddTime( 0 );
  716. }
  717. }
  718. for( unsigned int i = 0; i < m_AnimationPlayed.size(); ++i )
  719. {
  720. if( m_AnimationPlayed[ i ].name == animation )
  721. {
  722. m_AnimationPlayed.erase( m_AnimationPlayed.begin() + i );
  723. }
  724. }
  725. if( found == true )
  726. {
  727. AnimationPlayed anim;
  728. anim.name = animation;
  729. anim.state = state;
  730. m_AnimationPlayed.push_back( anim );
  731. }
  732. else
  733. {
  734. LOG_ERROR( "Background2D doesn't has animation \"" + animation + "\"." );
  735. }
  736. }
  737. //------------------------------------------------------------------------------
  738. void
  739. Background2D::ScriptPlayAnimationLooped( const char* name )
  740. {
  741. PlayAnimation( Ogre::String( name ), Background2DAnimation::LOOPED );
  742. }
  743. //------------------------------------------------------------------------------
  744. void
  745. Background2D::ScriptPlayAnimationOnce( const char* name )
  746. {
  747. PlayAnimation( Ogre::String( name ), Background2DAnimation::ONCE );
  748. }
  749. //------------------------------------------------------------------------------
  750. int
  751. Background2D::ScriptAnimationSync( const char* animation )
  752. {
  753. for( unsigned int i = 0; i < m_AnimationPlayed.size(); ++i )
  754. {
  755. if( m_AnimationPlayed[ i ].name == animation )
  756. {
  757. ScriptId script = ScriptManager::getSingleton().GetCurrentScriptId();
  758. m_AnimationPlayed[ i ].sync.push_back( script );
  759. return -1;
  760. }
  761. }
  762. return 1;
  763. }
  764. //------------------------------------------------------------------------------
  765. void
  766. Background2D::renderQueueEnded( Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation )
  767. {
  768. if( cv_show_background2d.GetB() == false )
  769. {
  770. return;
  771. }
  772. if( queueGroupId == Ogre::RENDER_QUEUE_MAIN )
  773. {
  774. m_RenderSystem->_setWorldMatrix( Ogre::Matrix4::IDENTITY );
  775. m_RenderSystem->_setProjectionMatrix( Ogre::Matrix4::IDENTITY );
  776. Ogre::Viewport *viewport( CameraManager::getSingleton().getViewport() );
  777. float width = static_cast<float>(viewport->getActualWidth());
  778. float height = static_cast<float>(viewport->getActualHeight());
  779. Ogre::Matrix4 view;
  780. view.makeTrans( Ogre::Vector3( m_PositionReal.x * 2 / width, -m_PositionReal.y * 2 / height, 0 ) );
  781. m_RenderSystem->_setViewMatrix( view );
  782. if( m_AlphaRenderOp.vertexData->vertexCount != 0 )
  783. {
  784. m_SceneManager->_setPass( m_AlphaMaterial->getTechnique( 0 )->getPass( 0 ), true, false );
  785. m_RenderSystem->_render( m_AlphaRenderOp );
  786. }
  787. if( m_AddRenderOp.vertexData->vertexCount != 0 )
  788. {
  789. m_SceneManager->_setPass( m_AddMaterial->getTechnique( 0 )->getPass( 0 ), true, false );
  790. m_RenderSystem->_render( m_AddRenderOp );
  791. }
  792. if( m_SubtractRenderOp.vertexData->vertexCount != 0 )
  793. {
  794. m_SceneManager->_setPass( m_SubtractMaterial->getTechnique( 0 )->getPass( 0 ), true, false );
  795. m_RenderSystem->_render( m_SubtractRenderOp );
  796. }
  797. if( m_MultiplyRenderOp.vertexData->vertexCount != 0 )
  798. {
  799. m_SceneManager->_setPass( m_MultiplyMaterial->getTechnique( 0 )->getPass( 0 ), true, false );
  800. m_RenderSystem->_render( m_MultiplyRenderOp );
  801. }
  802. }
  803. }
  804. //------------------------------------------------------------------------------
  805. void
  806. Background2D::CreateVertexBuffers()
  807. {
  808. m_AlphaMaxVertexCount = 2048 * TILE_VERTEX_COUNT;
  809. m_AlphaRenderOp.vertexData = new Ogre::VertexData;
  810. m_AlphaRenderOp.vertexData->vertexStart = 0;
  811. Ogre::VertexDeclaration* vDecl = m_AlphaRenderOp.vertexData->vertexDeclaration;
  812. size_t offset = 0;
  813. vDecl->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
  814. offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 );
  815. vDecl->addElement( 0, offset, Ogre::VET_FLOAT4, Ogre::VES_DIFFUSE );
  816. offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT4 );
  817. vDecl->addElement( 0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES );
  818. m_AlphaVertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer( vDecl->getVertexSize( 0 ), m_AlphaMaxVertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false );
  819. m_AlphaRenderOp.vertexData->vertexBufferBinding->setBinding( 0, m_AlphaVertexBuffer );
  820. m_AlphaRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
  821. m_AlphaRenderOp.useIndexes = false;
  822. m_AddMaxVertexCount = 256 * TILE_VERTEX_COUNT;
  823. m_AddRenderOp.vertexData = new Ogre::VertexData;
  824. m_AddRenderOp.vertexData->vertexStart = 0;
  825. vDecl = m_AddRenderOp.vertexData->vertexDeclaration;
  826. offset = 0;
  827. vDecl->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
  828. offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 );
  829. vDecl->addElement( 0, offset, Ogre::VET_FLOAT4, Ogre::VES_DIFFUSE );
  830. offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT4 );
  831. vDecl->addElement( 0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES );
  832. m_AddVertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer( vDecl->getVertexSize( 0 ), m_AddMaxVertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false );
  833. m_AddRenderOp.vertexData->vertexBufferBinding->setBinding( 0, m_AddVertexBuffer );
  834. m_AddRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
  835. m_AddRenderOp.useIndexes = false;
  836. m_SubtractMaxVertexCount = 256 * TILE_VERTEX_COUNT; // FIXME: 256?
  837. m_SubtractRenderOp.vertexData = new Ogre::VertexData;
  838. m_SubtractRenderOp.vertexData->vertexStart = 0;
  839. vDecl = m_SubtractRenderOp.vertexData->vertexDeclaration;
  840. offset = 0;
  841. vDecl->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
  842. offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 );
  843. vDecl->addElement( 0, offset, Ogre::VET_FLOAT4, Ogre::VES_DIFFUSE );
  844. offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT4 );
  845. vDecl->addElement( 0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES );
  846. m_SubtractVertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer( vDecl->getVertexSize( 0 ), m_SubtractMaxVertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false );
  847. m_SubtractRenderOp.vertexData->vertexBufferBinding->setBinding( 0, m_SubtractVertexBuffer );
  848. m_SubtractRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
  849. m_SubtractRenderOp.useIndexes = false;
  850. m_MultiplyMaxVertexCount = 256 * TILE_VERTEX_COUNT; // FIXME: 256?
  851. m_MultiplyRenderOp.vertexData = new Ogre::VertexData;
  852. m_MultiplyRenderOp.vertexData->vertexStart = 0;
  853. vDecl = m_MultiplyRenderOp.vertexData->vertexDeclaration;
  854. offset = 0;
  855. vDecl->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
  856. offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 );
  857. vDecl->addElement( 0, offset, Ogre::VET_FLOAT4, Ogre::VES_DIFFUSE );
  858. offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT4 );
  859. vDecl->addElement( 0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES );
  860. m_MultiplyVertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer( vDecl->getVertexSize( 0 ), m_MultiplyMaxVertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false );
  861. m_MultiplyRenderOp.vertexData->vertexBufferBinding->setBinding( 0, m_AMultiplyVertexBuffer );
  862. m_MultiplyRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
  863. m_MultiplyRenderOp.useIndexes = false;
  864. }
  865. //------------------------------------------------------------------------------
  866. void
  867. Background2D::DestroyVertexBuffers()
  868. {
  869. delete m_AlphaRenderOp.vertexData;
  870. m_AlphaRenderOp.vertexData = 0;
  871. m_AlphaVertexBuffer.setNull();
  872. m_AlphaMaxVertexCount = 0;
  873. delete m_AddRenderOp.vertexData;
  874. m_AddRenderOp.vertexData = 0;
  875. m_AddVertexBuffer.setNull();
  876. m_AddMaxVertexCount = 0;
  877. delete m_SubtractRenderOp.vertexData;
  878. m_SubtractRenderOp.vertexData = 0;
  879. m_SubtractVertexBuffer.setNull();
  880. m_SubtractMaxVertexCount = 0;
  881. delete m_MultiplyRenderOp.vertexData;
  882. m_MultiplyRenderOp.vertexData = 0;
  883. m_MultiplyVertexBuffer.setNull();
  884. m_MultiplyMaxVertexCount = 0;
  885. }
  886. //------------------------------------------------------------------------------
  887. void
  888. Background2D::load( const QGears::Background2DFilePtr& background )
  889. {
  890. assert( !background.isNull() );
  891. background->load();
  892. SetImage( background->getTextureName() );
  893. m_virtual_screen_size = background->getClip();
  894. SetRange( background->getRange() );
  895. const Ogre::Vector3& position( background->getPosition() );
  896. const Ogre::Quaternion& orientation( background->getOrientation() );
  897. const Ogre::Radian& fov( background->getFov() );
  898. CameraManager::getSingleton().Set2DCamera( position, orientation, fov );
  899. load( background->getTiles() );
  900. }
  901. //------------------------------------------------------------------------------
  902. void
  903. Background2D::load( const QGears::Background2DFile::TileList& tiles )
  904. {
  905. QGears::Background2DFile::TileList::const_iterator it( tiles.begin() );
  906. QGears::Background2DFile::TileList::const_iterator it_end( tiles.end() );
  907. size_t tile_index( 0 );
  908. while( it != it_end )
  909. {
  910. AddTile( *it );
  911. load( tile_index++, it->animations );
  912. ++it;
  913. }
  914. }
  915. //------------------------------------------------------------------------------
  916. void
  917. Background2D::load( const size_t tile_index, const QGears::AnimationMap& animations )
  918. {
  919. QGears::AnimationMap::const_iterator it( animations.begin() );
  920. QGears::AnimationMap::const_iterator it_end( animations.end() );
  921. while( it != it_end )
  922. {
  923. const QGears::String& name( it->first );
  924. const QGears::Animation& animation( it->second );
  925. Background2DAnimation* anim( new Background2DAnimation( name, this, tile_index ) );
  926. anim->SetLength( animation.length );
  927. QGears::KeyFrameList::const_iterator itk( animation.key_frames.begin() );
  928. QGears::KeyFrameList::const_iterator itk_end( animation.key_frames.end() );
  929. while( itk != itk_end )
  930. {
  931. anim->AddUVKeyFrame( *(itk++) );
  932. }
  933. AddAnimation( anim );
  934. ++it;
  935. }
  936. }
  937. //------------------------------------------------------------------------------