qparticles.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. #include <QDebug>
  2. #include <QGLShader>
  3. #include <QPainter>
  4. #include <QEvent>
  5. #include <QTouchEvent>
  6. #include <QGraphicsSceneMouseEvent>
  7. #include <QtGui/qdrawutil.h>
  8. #include <QVarLengthArray>
  9. #include <QtCore/qmath.h>
  10. #include <QtCore/qglobal.h>
  11. #include <QVector2D>
  12. #include "qparticles.h"
  13. #include "vertexpositioncolor.h"
  14. #define KLIMITTOPAGE
  15. #define KDEFAULTPARTICLES 100
  16. const QVector2D t1(2.0f, 0.0f);
  17. const QVector2D t2(0.0f, 2.0f);
  18. QParticles::QParticles(QDeclarativeItem *parent) :
  19. QDeclarativeItem(parent), clock(this), m_lastTickTime(0), m_upTime(0), m_particles(0), data(0),
  20. m_colors(KCOLORS), m_InitShader(false),iColorInit(false), iParticleInit(false), m_particleSize(2.0f),
  21. m_SquareParticle(true), m_BaseShader(NULL)
  22. {
  23. qDebug() << "QParticles::QParticles-> new:" << this;
  24. setFlag(QGraphicsItem::ItemHasNoContents, false);
  25. setAcceptedMouseButtons(Qt::LeftButton);
  26. setAcceptTouchEvents(true);
  27. setFiltersChildEvents(true);
  28. generateParticles(KDEFAULTPARTICLES);
  29. qDebug() << "QParticles::QParticles<-";
  30. }
  31. void QParticles::generateColors()
  32. {
  33. if(iColorInit)
  34. {
  35. return;
  36. }
  37. iColorInit = true;
  38. int cnt = m_colors.count();
  39. QColor color;
  40. for(int i=0; i<cnt; ++i)
  41. {
  42. color.setHslF((qreal)i / KCOLORS, 1.0, 0.50);
  43. m_colors[i].setX(color.red()/255.0);
  44. m_colors[i].setY(color.green()/255.0);
  45. m_colors[i].setZ(color.blue()/255.0);
  46. }
  47. }
  48. void QParticles::generateParticles( int aNewParticleCount)
  49. {
  50. // qDebug() << "->generateParticles";
  51. m_particles.resize(aNewParticleCount);
  52. if(m_SquareParticle)
  53. {
  54. data.resize(aNewParticleCount*6);
  55. }
  56. else
  57. {
  58. data.resize(aNewParticleCount*3);
  59. }
  60. iParticleInit = false;
  61. // qDebug() << "<-generateParticles";
  62. }
  63. void QParticles::generateParticles(const QRectF & boundingRect)
  64. {
  65. // qDebug() << "generateParticles()" << iParticleInit << "particlescount:" << m_particles.count() << "" << &m_particles ;
  66. if(iParticleInit)
  67. {
  68. return;
  69. }
  70. iParticleInit = true;
  71. int cnt = m_particles.count();
  72. for(int i=0; i<cnt; ++i)
  73. {
  74. QVector2D & pos(m_particles[i].Position);
  75. pos.setX( randInt(0, boundingRect.width()));
  76. pos.setY( randInt(0, boundingRect.height()));
  77. }
  78. }
  79. //void QParticles::geometryChanged(const QRectF &newGeometry,
  80. // const QRectF &oldGeometry)
  81. //{
  82. // qDebug() << "QParticles::geometryChanged->";
  83. // qDebug() << "old:" << oldGeometry;
  84. // qDebug() << "new:" << newGeometry;
  85. // QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
  86. // qDebug() << "QParticles::geometryChanged<-";
  87. //}
  88. void QParticles::componentComplete()
  89. {
  90. qDebug() << "QParticles::componentComplete->";
  91. QDeclarativeItem::componentComplete();
  92. qDebug() << boundingRect();
  93. qDebug("[%f,%f] [%fx%f] opacity:%f Active:%d Visible:%d", x(), y(), width(), height(), opacity(), isActive(), isVisible());
  94. QBrush m_color(QColor(255, 255, 255, 255), Qt::SolidPattern);
  95. m_pen = QPen(m_color, 2);
  96. startRedraw();
  97. // qDebug() << "QParticles::componentComplete<-";
  98. }
  99. bool QParticles::updateParticles(qreal deltaTime, const QRectF & boundingRect, bool dontNull)
  100. {
  101. QPointF TL(boundingRect.topLeft());
  102. QPointF BR(boundingRect.bottomRight());
  103. int cnt = m_particles.count();
  104. bool velocity(false);
  105. QVector2D a;
  106. for (int i = 0; i < cnt; ++i)
  107. {
  108. QParticle & p = m_particles[i];
  109. a = p.Force * p.InvertMass;
  110. p.Velocity += a * deltaTime;
  111. p.Velocity = p.Velocity * (qreal)0.96;
  112. p.Position += p.Velocity * deltaTime;
  113. if (p.Position.x() < TL.x())
  114. {
  115. p.Velocity.setX(-p.Velocity.x());
  116. p.Position.setX(TL.x());
  117. }
  118. else if ( p.Position.x() > BR.x())
  119. {
  120. p.Velocity.setX(-p.Velocity.x());
  121. p.Position.setX(BR.x());
  122. }
  123. if (p.Position.y() < TL.y())
  124. {
  125. p.Velocity.setY(-p.Velocity.y());
  126. p.Position.setY(TL.y());
  127. }
  128. else if (p.Position.y() > BR.y())
  129. {
  130. p.Velocity.setY(-p.Velocity.y());
  131. p.Position.setY(BR.y());
  132. }
  133. p.Force.setX((qreal)0.0);
  134. p.Force.setY((qreal)0.0);
  135. if((m_touchpos.count() == 0) && !p.zeroVelocity(dontNull))
  136. {
  137. velocity = true;
  138. // qDebug() << i << p.Velocity;
  139. }
  140. // m_drawParticles[i] = p.Position.toPointF();
  141. }
  142. return velocity;
  143. }
  144. void QParticles::applyTouchGravity(const QPointF & center)
  145. {
  146. int cnt = m_particles.count();
  147. QVector2D dir;
  148. QVector2D force;
  149. float distSq;
  150. float dist;
  151. qreal forceSize;
  152. for (int i = 0; i < cnt; ++i)
  153. {
  154. QParticle & p(m_particles[i]);
  155. dir.setX(center.x() - p.Position.x());
  156. dir.setY(center.y() - p.Position.y());
  157. // qreal distSq = (qreal)1.0 / (dir.x() * dir.x() + dir.y() * dir.y());
  158. // qreal dist = qSqrt(distSq);
  159. distSq = 1.0f/(dir.x() * dir.x() + dir.y() * dir.y());
  160. // qreal distSq = (dir.x() * dir.x() + dir.y() * dir.y());
  161. dist = qSqrt(distSq);
  162. // qreal dist = Q_rsqrt(distSq);
  163. dir *= dist;
  164. // qreal forceSize = (qreal)500.0 * qMin((qreal)1.0, ((qreal)5000.0 * distSq));
  165. forceSize = 500.0f * qMin(1.0f, (6000.0f * distSq));
  166. force.setX(dir.x() * forceSize);
  167. force.setY(dir.y() * forceSize);
  168. {
  169. p.Force += force;
  170. }
  171. }
  172. }
  173. //bool QParticles::sceneEvent(QEvent *event)
  174. //{
  175. // bool rv = QDeclarativeItem::sceneEvent(event);
  176. // if (event->type() == QEvent::UngrabMouse) {
  177. // setKeepMouseGrab(false);
  178. // }
  179. // return rv;
  180. //}
  181. //bool QParticles::event(QEvent *event)
  182. //{
  183. // if (!isVisible())
  184. // return QDeclarativeItem::event(event);
  185. // switch (event->type()) {
  186. // case QEvent::TouchBegin:
  187. // case QEvent::TouchUpdate: {
  188. // QTouchEvent *touch = static_cast<QTouchEvent*>(event);
  189. // const QList<QTouchEvent::TouchPoint> & touchPoints(touch->touchPoints());
  190. // {
  191. // int count = touchPoints.count();
  192. // qDebug() << count << "----------------------------------";
  193. // for(int i=0; i<count; ++i)
  194. // {
  195. // qDebug("[%d] id[%d][%d,%d] state:%x", i, touchPoints[i].id(), (int)touchPoints[i].pos().x(),
  196. // (int)touchPoints[i].pos().y(), (int)touchPoints[i].state() );
  197. // }
  198. // }
  199. //// d->touchPoints.clear();
  200. //// for (int i = 0; i < touch->touchPoints().count(); ++i) {
  201. //// if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased)) {
  202. //// d->touchPoints << touch->touchPoints().at(i);
  203. //// }
  204. //// }
  205. //// updatePinch();
  206. // }
  207. // return true;
  208. // case QEvent::TouchEnd:
  209. // qDebug() << "QEvent::TouchEnd";
  210. //// d->touchPoints.clear();
  211. //// updatePinch();
  212. // break;
  213. // default:
  214. // return QDeclarativeItem::event(event);
  215. // }
  216. // return QDeclarativeItem::event(event);
  217. //}
  218. bool QParticles::sceneEvent(QEvent *event)
  219. {
  220. QEvent::Type eventType(event->type());
  221. switch (eventType)
  222. {
  223. case QEvent::TouchBegin:
  224. case QEvent::TouchUpdate:
  225. case QEvent::TouchEnd:
  226. {
  227. startRedraw();
  228. const QList<QTouchEvent::TouchPoint> touchPoints(static_cast<QTouchEvent *>(event)->touchPoints());
  229. // {
  230. // int count = touchPoints.count();
  231. // qDebug() << count << "QEvent::Touch----------------------------------";
  232. // for(int i=0; i<count; ++i)
  233. // {
  234. // qDebug("[%d] id[%d][%d,%d] state:0x%x", i, touchPoints[i].id(), (int)touchPoints[i].pos().x(),
  235. // (int)touchPoints[i].pos().y(), (int)touchPoints[i].state() );
  236. // }
  237. // }
  238. m_touchpos.clear();
  239. foreach(const QTouchEvent::TouchPoint touchPoint, touchPoints)
  240. {
  241. if( touchPoint.state() != Qt::TouchPointReleased)
  242. {
  243. m_touchpos.append(touchPoint.pos());
  244. }
  245. }
  246. if(m_touchpos.count() == 0)
  247. {
  248. m_upTime = m_lastTickTime;
  249. /// qDebug() << "----- empty";
  250. }
  251. else
  252. {
  253. // qDebug() << "-----" << m_touchpos.count();
  254. }
  255. return true;
  256. }
  257. #if defined(Q_WS_WIN)
  258. case QEvent::GraphicsSceneMousePress:
  259. case QEvent::GraphicsSceneMouseMove:
  260. {
  261. startRedraw();
  262. QGraphicsSceneMouseEvent * MouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
  263. m_touchpos.clear();
  264. qDebug() << "QEvent::GraphicsSceneMouseMove";
  265. // qDebug( "Pos[%f,%f] ScenePos[%f,%f] screenPos[%f,%f]", MouseEvent->pos().x(), MouseEvent->pos().y(),
  266. // MouseEvent->scenePos().x(), MouseEvent->scenePos().y(), MouseEvent->screenPos().x(), MouseEvent->screenPos().y()
  267. // );
  268. m_touchpos.append(MouseEvent->pos());
  269. // qDebug() << MouseEvent->pos();
  270. return true;
  271. }
  272. case QEvent::GraphicsSceneMouseRelease:
  273. {
  274. m_upTime = m_lastTickTime;
  275. m_touchpos.clear();
  276. qDebug() << "QEvent::GraphicsSceneMouseRelease ----- empty";
  277. return true;
  278. }
  279. #endif
  280. default:
  281. {
  282. // qDebug() << "eventType:" << eventType;
  283. }
  284. }
  285. return QDeclarativeItem::sceneEvent(event);
  286. }
  287. void QParticles::tick(int time)
  288. {
  289. if(m_lastTickTime == 0)
  290. {
  291. m_lastTickTime = time;
  292. return;
  293. }
  294. int diff = time - m_lastTickTime;
  295. // qDebug() << "diff:" << diff;
  296. if(diff < 20)
  297. {
  298. return;
  299. }
  300. qreal elapsedTimeS = qreal(diff) / qreal(1000.0);
  301. //qreal elapsedTimeS = 33.0f / 1000.0f;
  302. // qDebug() << "diff:" << (time - m_lastTickTime);
  303. //<< "elapsed:" << elapsedTimeMs;
  304. {
  305. // touch gravity
  306. int touchCount = m_touchpos.count();
  307. for(int i=0; i< touchCount; ++i)
  308. {
  309. // qDebug() << "[" << i << "]" << m_touchpos[i];
  310. applyTouchGravity(m_touchpos[i]);
  311. }
  312. // if(touchCount == 0)
  313. // {
  314. // qDebug() << "tick touch points empty";
  315. // }
  316. }
  317. int sinceKeyUp = time - m_upTime;
  318. bool dontnull((sinceKeyUp < 1000) || m_touchpos.count());
  319. QRectF boundingrect;
  320. // if(m_DrawOnUI)
  321. // {
  322. // boundingrect = topLevelItem()->boundingRect();
  323. // }
  324. // else
  325. {
  326. boundingrect = boundingRect();
  327. }
  328. boundingrect.setHeight(boundingrect.height() - m_particleSize);
  329. // qDebug() << "OnUi:" << m_DrawOnUI << " boundingrect: " << boundingrect;
  330. //#ifdef KLIMITTOPAGE
  331. // boundingrect.translate(scenePos());
  332. //#endif
  333. // qDebug() << "boundingrect:" << boundingrect;
  334. bool velocity = updateParticles(elapsedTimeS, boundingrect, dontnull);
  335. if(!dontnull && !velocity)
  336. {
  337. stopRedraw();
  338. qDebug() << "stoping";
  339. }
  340. update();
  341. m_lastTickTime = time;
  342. }
  343. int QParticles::randInt(int low, int high) const
  344. {
  345. // Random number between low and high
  346. return qrand() % ((high + 1) - low) + low;
  347. }
  348. void QParticles::onActivated()
  349. {
  350. qDebug() << "QParticles::onActivated->";
  351. qDebug("[%f,%f] [%fx%f] opacity:%f Active:%d Visible:%d", x(), y(), width(), height(), opacity(), isActive(), isVisible());
  352. qDebug() << "QParticles::onActivated<-";
  353. }
  354. void QParticles::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
  355. {
  356. // qDebug() << "paint: opacity:" << painter->opacity() << " active:" << isActive();
  357. // qDebug() << "m_touchpos" << &m_touchpos << " m_particles:" << &m_particles << "&m_MatrixLoc" << &m_MatrixLoc << "this" << this;
  358. //<< " matrix:" << painter->matrix();
  359. qDebug("pos[%f,%f] size[%fx%f] opacity:%f Active:%d Visible:%d scene[%f,%f]", x(), y(),
  360. width(), height(), opacity(), isActive(), isVisible(), scenePos().x(), scenePos().y());
  361. //qDebug() << "viewport:" << painter->viewport() << " window:" << painter->window();
  362. // qDebug() << "wt" << scenePos() << " >> " << painter->worldTransform().map(scenePos());
  363. // qDebug() << "tr" << scenePos() << " >> " << painter->transform().map(scenePos());
  364. // qDebug() << "dt" << scenePos() << " >> " << painter->deviceTransform().map(scenePos());
  365. // qDebug() << "ct" << scenePos() << " >> " << painter->combinedTransform().map(scenePos());
  366. // return;
  367. // init
  368. generateColors();
  369. if(isActive())
  370. {
  371. generateParticles(boundingRect());
  372. }
  373. painter->save();
  374. painter->beginNativePainting();
  375. InitShaders();
  376. paintParticles(painter->opacity(), 3.0f);
  377. painter->endNativePainting();
  378. painter->restore();
  379. }
  380. void QParticles::stopRedraw()
  381. {
  382. clock.stop();
  383. m_lastTickTime = 0;
  384. m_upTime = 0;
  385. qDebug() << "stopRedraw";
  386. }
  387. void QParticles::startRedraw()
  388. {
  389. if(clock.state() == QAbstractAnimation::Running)
  390. {
  391. return;
  392. }
  393. qDebug() << "startRedraw";
  394. clock.start();
  395. m_lastTickTime = 0;
  396. m_upTime = 0;
  397. }
  398. void QParticles::InitShaders()
  399. {
  400. if(m_InitShader)
  401. {
  402. return;
  403. }
  404. qDebug() << "this" << this;
  405. m_InitShader = true;
  406. qDebug("currentContext:0x%x", QGLContext::currentContext());
  407. // m_BaseShader.release();
  408. // m_BaseShader.bind();
  409. delete m_BaseShader;
  410. m_BaseShader = new QGLShaderProgram(QGLContext::currentContext(), this);
  411. QGLShader* vs = new QGLShader(QGLShader::Vertex, QGLContext::currentContext(), this);
  412. const char *vssrc =
  413. "uniform mat4 matrix;\n"
  414. "attribute vec4 vertex;\n"
  415. "attribute vec4 color;\n"
  416. "varying mediump vec4 outColor;\n"
  417. "void main(void)\n"
  418. "{\n"
  419. " outColor = color;\n"
  420. " gl_Position = matrix * vertex;\n"
  421. "}\n";
  422. bool done = vs->compileSourceCode(vssrc);
  423. Q_ASSERT(done);
  424. QGLShader *fs = new QGLShader(QGLShader::Fragment, QGLContext::currentContext(), this);
  425. const char *fssrc =
  426. "varying mediump vec4 outColor;\n"
  427. "void main(void)\n"
  428. "{\n"
  429. " gl_FragColor = outColor;\n"
  430. "}\n";
  431. done = fs->compileSourceCode(fssrc);
  432. Q_ASSERT(done);
  433. done = m_BaseShader->addShader(vs);
  434. if(!done)
  435. {
  436. qDebug() << m_BaseShader->log();
  437. }
  438. Q_ASSERT(done);
  439. done = m_BaseShader->addShader(fs);
  440. if(!done)
  441. {
  442. qDebug() << m_BaseShader->log();
  443. }
  444. Q_ASSERT(done);
  445. done = m_BaseShader->link();
  446. if(!done)
  447. {
  448. qDebug() << m_BaseShader->log();
  449. }
  450. Q_ASSERT(done);
  451. m_MatrixLoc = m_BaseShader->uniformLocation("matrix");
  452. qDebug() << "m_MatrixLoc:" << m_MatrixLoc;
  453. m_VertexAtribLoc = m_BaseShader->attributeLocation("vertex");
  454. qDebug() << "m_VertexAtribLoc:" << m_VertexAtribLoc;
  455. m_ColorAttribLoc = m_BaseShader->attributeLocation("color");
  456. qDebug() << "m_ColorAttribLoc:" << m_ColorAttribLoc;
  457. }
  458. QVector3D QParticles::convertColor(int aColor) const
  459. {
  460. return QVector3D(float((aColor & 0xFF0000) >> 16) / 255,
  461. float((aColor & 0xFF00)>> 8) / 255,
  462. float(aColor & 0xFF) / 255);
  463. }
  464. void QParticles::paintParticles( qreal aOpacity, qreal aParticleSize)
  465. {
  466. if(!iParticleInit)
  467. {
  468. return;
  469. }
  470. // qDebug() << "->paintParticles";
  471. // return;
  472. // generate vertices
  473. // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE );
  474. // glDisable(GL_CULL_FACE);
  475. // glEnable(GL_CU);
  476. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  477. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  478. glEnable(GL_BLEND);
  479. // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  480. // alloc buffer
  481. int count = m_particles.count();
  482. // generate data
  483. QVector4D color;
  484. QVector3D pos0;
  485. QVector3D pos1;
  486. QVector3D pos2;
  487. QVector3D pos3;
  488. int index;
  489. for(int i=0; i<count; ++i)
  490. {
  491. //qDebug() << m_particles[i].Position;
  492. //int len = (int(m_particles[i].FastVelocityLength() + 170) % KCOLORS);
  493. int len = (int)((m_particles[i].Velocity.length() + 170)) % KCOLORS;
  494. color = m_colors[len];
  495. color.setW(aOpacity);
  496. if(m_SquareParticle)
  497. {
  498. index = 6*i;
  499. data[index].Color = color;
  500. data[index+1].Color = color;
  501. data[index+2].Color = color;
  502. data[index+5].Color = color;
  503. }
  504. else
  505. {
  506. index = 3*i;
  507. data[index].Color = color;
  508. data[index+1].Color = color;
  509. data[index+2].Color = color;
  510. }
  511. pos3 = pos2 = pos1 = pos0 = m_particles[i].Position;
  512. if(m_SquareParticle)
  513. {
  514. index = 6*i;
  515. pos1.setX(pos1.x() + m_particleSize);
  516. pos2.setX(pos2.x() + m_particleSize);
  517. pos2.setY(pos2.y() + m_particleSize);
  518. pos3.setY(pos3.y() + m_particleSize);
  519. data[index].Position = pos0;
  520. data[index+1].Position = pos1;
  521. data[index+2].Position = pos2;
  522. data[index+3] = data[index];
  523. data[index+4] = data[index+2];
  524. data[index+5].Position = pos3;
  525. }
  526. else
  527. {
  528. index = 3*i;
  529. data[index].Position = pos0;
  530. pos0.setX(pos0.x() + m_particleSize);
  531. data[index+1].Position = pos0;
  532. pos0.setY(pos0.y() + m_particleSize);
  533. data[index+2].Position = pos0;
  534. }
  535. }
  536. m_BaseShader->bind();
  537. QMatrix4x4 modelview;
  538. {
  539. QRectF boundingRect = topLevelItem()->boundingRect();
  540. modelview.ortho( 0.0f,
  541. boundingRect.width(),
  542. boundingRect.height(),
  543. 0.0f,
  544. -100.0f, 100.0f);
  545. QMatrix4x4 translate;
  546. translate.translate(scenePos().x() , scenePos().y(), 0);
  547. // qDebug() << "boundingRect:" << boundingRect;
  548. // qDebug() << "scenePos:" << scenePos();
  549. modelview = modelview * translate ;
  550. }
  551. m_BaseShader->setUniformValue(m_MatrixLoc, modelview);
  552. m_BaseShader->enableAttributeArray(m_VertexAtribLoc);
  553. m_BaseShader->enableAttributeArray(m_ColorAttribLoc);
  554. m_BaseShader->setAttributeArray(m_VertexAtribLoc, GL_FLOAT, (void*)&(data[0].Position), 3, sizeof(TVertexPositionColor));
  555. m_BaseShader->setAttributeArray(m_ColorAttribLoc, GL_FLOAT, (void*)&(data[0].Color), 4, sizeof(TVertexPositionColor));
  556. if(m_SquareParticle)
  557. {
  558. glDrawArrays(GL_TRIANGLES, 0, 2*count);
  559. }
  560. else
  561. {
  562. glDrawArrays(GL_TRIANGLES, 0, count);
  563. }
  564. m_BaseShader->disableAttributeArray(m_VertexAtribLoc);
  565. m_BaseShader->disableAttributeArray(m_ColorAttribLoc);
  566. m_BaseShader->release();
  567. // qDebug() << "<-paintParticles";
  568. }
  569. void QParticles::setParticles(int aNewParticlesCount)
  570. {
  571. qDebug() << "setParticles:" << aNewParticlesCount;
  572. qDebug() << "this" << this;
  573. generateParticles(aNewParticlesCount);
  574. }
  575. int QParticles::particles() const
  576. {
  577. return m_particles.count();
  578. }
  579. void QParticles::setParticleSize(float aParticleSize)
  580. {
  581. m_particleSize = aParticleSize;
  582. }
  583. float QParticles::particleSize() const
  584. {
  585. return m_particleSize;
  586. }
  587. void QParticles::appendParticle()
  588. {
  589. m_particles.append(QParticle());
  590. }
  591. void QParticles::setSquareParticle(bool aSquareParticle)
  592. {
  593. m_SquareParticle = aSquareParticle;
  594. generateParticles(m_particles.count());
  595. }
  596. bool QParticles::squareParticle() const
  597. {
  598. return m_SquareParticle;
  599. }