Background2D.cpp 30 KB

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