CCDrawNode3D.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. //
  2. // CCDrawNode3D3D.cpp
  3. // Redream2
  4. //
  5. // Created by 徐俊杰 on 2021/9/6.
  6. //
  7. #include "2d/CCDrawNode3D.h"
  8. #include "base/CCEventType.h"
  9. #include "base/CCConfiguration.h"
  10. #include "renderer/CCRenderer.h"
  11. #include "renderer/ccGLStateCache.h"
  12. #include "renderer/CCGLProgramState.h"
  13. #include "renderer/CCGLProgramCache.h"
  14. #include "base/CCDirector.h"
  15. #include "base/CCEventListenerCustom.h"
  16. #include "base/CCEventDispatcher.h"
  17. #include "2d/CCActionCatmullRom.h"
  18. #include "platform/CCGL.h"
  19. NS_CC_BEGIN
  20. struct CC_DLL V3F_C4B_T2F_Triangle
  21. {
  22. V3F_C4B_T2F a;
  23. V3F_C4B_T2F b;
  24. V3F_C4B_T2F c;
  25. };
  26. // Vec3 == CGPoint in 32-bits, but not in 64-bits (OS X)
  27. // that's why the "v3f" functions are needed
  28. static Vec3 v3fzero(0.0f,0.0f,0.0f);
  29. static inline Vec3 v3f(float x, float y, float z)
  30. {
  31. Vec3 ret(x, y, z);
  32. return ret;
  33. }
  34. static inline Vec3 v3fadd(const Vec3 &v0, const Vec3 &v1)
  35. {
  36. return v3f(v0.x+v1.x, v0.y+v1.y, v0.z+v1.z);
  37. }
  38. static inline Vec3 v3fsub(const Vec3 &v0, const Vec3 &v1)
  39. {
  40. return v3f(v0.x-v1.x, v0.y-v1.y, v0.z-v1.z);
  41. }
  42. static inline Vec3 v3fmult(const Vec3 &v, float s)
  43. {
  44. return v3f(v.x * s, v.y * s, v.z * s);
  45. }
  46. static inline Vec3 v3fperp(const Vec3 &p0)
  47. {
  48. return v3f(-p0.y, p0.x, p0.z);
  49. }
  50. static inline Vec3 v3fneg(const Vec3 &p0)
  51. {
  52. return v3f(-p0.x, -p0.y, -p0.z);
  53. }
  54. static inline float v3fdot(const Vec3 &p0, const Vec3 &p1)
  55. {
  56. return p0.x * p1.x + p0.y * p1.y + p0.z * p1.z;
  57. }
  58. static inline Vec3 v3fnormalize(const Vec3 &p)
  59. {
  60. Vec3 r(p.x, p.y, p.z);
  61. r.normalize();
  62. return v3f(r.x, r.y, r.z);
  63. }
  64. static inline Vec3 __v3f(const Vec3 &v)
  65. {
  66. //#ifdef __LP64__
  67. return v3f(v.x, v.y, v.z);
  68. // #else
  69. // return * ((Vec3*) &v);
  70. // #endif
  71. }
  72. static inline Tex2F __t(const Vec3 &v)
  73. {
  74. return Tex2F(v.x, v.y);
  75. }
  76. static Quaternion AxisAngleToQuaternionSafe (const Vec3& axis, float angle)
  77. {
  78. Quaternion q;
  79. float mag = Magnitude (axis);
  80. if (mag > 0.000001F)
  81. {
  82. float halfAngle = angle * 0.5F;
  83. q.w = cos (halfAngle);
  84. float s = sin (halfAngle) / mag;
  85. q.x = s * axis.x;
  86. q.y = s * axis.y;
  87. q.z = s * axis.z;
  88. return q;
  89. }
  90. else
  91. {
  92. return Quaternion::identity ();
  93. }
  94. }
  95. static void setDiscSectionPoints( Vec3 dest[], int count, const Vec3& center, const Vec3& normal, const Vec3& from, float angle, float radius) {
  96. Vec3 fromn = Normalize(from);
  97. Quaternion r = AxisAngleToQuaternionSafe( normal, CC_DEGREES_TO_RADIANS(angle / (count - 1)) );
  98. Vec3 tangent = fromn * radius;
  99. for( int i = 0; i < count; i++) {
  100. dest[i] = center + tangent;
  101. tangent = RotateVectorByQuat (r, tangent);
  102. }
  103. }
  104. // implementation of DrawNode3D
  105. DrawNode3D::DrawNode3D(GLfloat lineWidth, bool drawOnce)
  106. : _vao(0)
  107. , _vbo(0)
  108. , _vaoGLPoint(0)
  109. , _vboGLPoint(0)
  110. , _vaoGLLine(0)
  111. , _vboGLLine(0)
  112. , _bufferCapacity(0)
  113. , _bufferCount(0)
  114. , _buffer(nullptr)
  115. , _bufferCapacityGLPoint(0)
  116. , _bufferCountGLPoint(0)
  117. , _bufferGLPoint(nullptr)
  118. , _bufferCapacityGLLine(0)
  119. , _bufferCountGLLine(0)
  120. , _bufferGLLine(nullptr)
  121. , _dirty(false)
  122. , _dirtyGLPoint(false)
  123. , _dirtyGLLine(false)
  124. , _drawOnce(drawOnce)
  125. , _lineWidth(lineWidth)
  126. , _defaultLineWidth(lineWidth)
  127. {
  128. _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
  129. }
  130. DrawNode3D::~DrawNode3D()
  131. {
  132. free(_buffer);
  133. _buffer = nullptr;
  134. free(_bufferGLPoint);
  135. _bufferGLPoint = nullptr;
  136. free(_bufferGLLine);
  137. _bufferGLLine = nullptr;
  138. glDeleteBuffers(1, &_vbo);
  139. glDeleteBuffers(1, &_vboGLLine);
  140. glDeleteBuffers(1, &_vboGLPoint);
  141. _vbo = 0;
  142. _vboGLPoint = 0;
  143. _vboGLLine = 0;
  144. if (Configuration::getInstance()->supportsShareableVAO())
  145. {
  146. GL::bindVAO(0);
  147. glDeleteVertexArrays(1, &_vao);
  148. glDeleteVertexArrays(1, &_vaoGLLine);
  149. glDeleteVertexArrays(1, &_vaoGLPoint);
  150. _vao = _vaoGLLine = _vaoGLPoint = 0;
  151. }
  152. }
  153. DrawNode3D* DrawNode3D::create(GLfloat defaultLineWidth, bool drawOnce)
  154. {
  155. DrawNode3D* ret = new (std::nothrow) DrawNode3D(defaultLineWidth, drawOnce);
  156. if (ret && ret->init())
  157. {
  158. ret->autorelease();
  159. }
  160. else
  161. {
  162. CC_SAFE_DELETE(ret);
  163. }
  164. return ret;
  165. }
  166. void DrawNode3D::ensureCapacity(int count)
  167. {
  168. CCASSERT(count>=0, "capacity must be >= 0");
  169. if(_bufferCount + count > _bufferCapacity)
  170. {
  171. _bufferCapacity += MAX(_bufferCapacity, count);
  172. _buffer = (V3F_C4B_T2F*)realloc(_buffer, _bufferCapacity*sizeof(V3F_C4B_T2F));
  173. }
  174. }
  175. void DrawNode3D::ensureCapacityGLPoint(int count)
  176. {
  177. CCASSERT(count>=0, "capacity must be >= 0");
  178. if(_bufferCountGLPoint + count > _bufferCapacityGLPoint)
  179. {
  180. _bufferCapacityGLPoint += MAX(_bufferCapacityGLPoint, count);
  181. _bufferGLPoint = (V3F_C4B_T2F*)realloc(_bufferGLPoint, _bufferCapacityGLPoint*sizeof(V3F_C4B_T2F));
  182. }
  183. }
  184. void DrawNode3D::ensureCapacityGLLine(int count)
  185. {
  186. CCASSERT(count>=0, "capacity must be >= 0");
  187. if(_bufferCountGLLine + count > _bufferCapacityGLLine)
  188. {
  189. _bufferCapacityGLLine += MAX(_bufferCapacityGLLine, count);
  190. _bufferGLLine = (V3F_C4B_T2F*)realloc(_bufferGLLine, _bufferCapacityGLLine*sizeof(V3F_C4B_T2F));
  191. }
  192. }
  193. bool DrawNode3D::init()
  194. {
  195. _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
  196. setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR));
  197. ensureCapacity(512);
  198. ensureCapacityGLPoint(64);
  199. ensureCapacityGLLine(256);
  200. if (Configuration::getInstance()->supportsShareableVAO())
  201. {
  202. glGenVertexArrays(1, &_vao);
  203. GL::bindVAO(_vao);
  204. glGenBuffers(1, &_vbo);
  205. glBindBuffer(GL_ARRAY_BUFFER, _vbo);
  206. glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_T2F)* _bufferCapacity, _buffer, GL_STREAM_DRAW);
  207. // vertex
  208. glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
  209. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, vertices));
  210. // color
  211. glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR);
  212. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, colors));
  213. // texcoord
  214. glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORD);
  215. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, texCoords));
  216. glGenVertexArrays(1, &_vaoGLLine);
  217. GL::bindVAO(_vaoGLLine);
  218. glGenBuffers(1, &_vboGLLine);
  219. glBindBuffer(GL_ARRAY_BUFFER, _vboGLLine);
  220. glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_T2F)*_bufferCapacityGLLine, _bufferGLLine, GL_STREAM_DRAW);
  221. // vertex
  222. glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
  223. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, vertices));
  224. // color
  225. glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR);
  226. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, colors));
  227. // texcoord
  228. glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORD);
  229. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, texCoords));
  230. glGenVertexArrays(1, &_vaoGLPoint);
  231. GL::bindVAO(_vaoGLPoint);
  232. glGenBuffers(1, &_vboGLPoint);
  233. glBindBuffer(GL_ARRAY_BUFFER, _vboGLPoint);
  234. glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_T2F)*_bufferCapacityGLPoint, _bufferGLPoint, GL_STREAM_DRAW);
  235. // vertex
  236. glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
  237. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, vertices));
  238. // color
  239. glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR);
  240. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, colors));
  241. // Texture coord as pointsize
  242. glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORD);
  243. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, texCoords));
  244. GL::bindVAO(0);
  245. glBindBuffer(GL_ARRAY_BUFFER, 0);
  246. }
  247. else
  248. {
  249. glGenBuffers(1, &_vbo);
  250. glBindBuffer(GL_ARRAY_BUFFER, _vbo);
  251. glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_T2F)* _bufferCapacity, _buffer, GL_STREAM_DRAW);
  252. glGenBuffers(1, &_vboGLLine);
  253. glBindBuffer(GL_ARRAY_BUFFER, _vboGLLine);
  254. glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_T2F)*_bufferCapacityGLLine, _bufferGLLine, GL_STREAM_DRAW);
  255. glGenBuffers(1, &_vboGLPoint);
  256. glBindBuffer(GL_ARRAY_BUFFER, _vboGLPoint);
  257. glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_T2F)*_bufferCapacityGLPoint, _bufferGLPoint, GL_STREAM_DRAW);
  258. glBindBuffer(GL_ARRAY_BUFFER, 0);
  259. }
  260. CHECK_GL_ERROR_DEBUG();
  261. _dirty = true;
  262. _dirtyGLLine = true;
  263. _dirtyGLPoint = true;
  264. #if CC_ENABLE_CACHE_TEXTURE_DATA
  265. // Need to listen the event only when not use batchnode, because it will use VBO
  266. auto listener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom* event){
  267. /** listen the event that renderer was recreated on Android/WP8 */
  268. this->init();
  269. });
  270. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
  271. #endif
  272. return true;
  273. }
  274. void DrawNode3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
  275. {
  276. if(_bufferCount)
  277. {
  278. _customCommand.init(_globalZOrder, transform, flags);
  279. _customCommand.func = CC_CALLBACK_0(DrawNode3D::onDraw, this, transform, flags);
  280. renderer->addCommand(&_customCommand);
  281. }
  282. if(_bufferCountGLPoint)
  283. {
  284. _customCommandGLPoint.init(_globalZOrder, transform, flags);
  285. _customCommandGLPoint.func = CC_CALLBACK_0(DrawNode3D::onDrawGLPoint, this, transform, flags);
  286. renderer->addCommand(&_customCommandGLPoint);
  287. }
  288. if(_bufferCountGLLine)
  289. {
  290. _customCommandGLLine.init(_globalZOrder, transform, flags);
  291. _customCommandGLLine.func = CC_CALLBACK_0(DrawNode3D::onDrawGLLine, this, transform, flags);
  292. renderer->addCommand(&_customCommandGLLine);
  293. }
  294. }
  295. void DrawNode3D::onDraw(const Mat4 &transform, uint32_t /*flags*/)
  296. {
  297. getGLProgramState()->apply(transform);
  298. auto glProgram = this->getGLProgram();
  299. glProgram->setUniformLocationWith1f(glProgram->getUniformLocation("u_alpha"), _displayedOpacity / 255.0);
  300. GL::blendFunc(_blendFunc.src, _blendFunc.dst);
  301. if (_dirty)
  302. {
  303. glBindBuffer(GL_ARRAY_BUFFER, _vbo);
  304. glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_T2F)*_bufferCapacity, _buffer, GL_STREAM_DRAW);
  305. _dirty = false;
  306. }
  307. if (Configuration::getInstance()->supportsShareableVAO())
  308. {
  309. GL::bindVAO(_vao);
  310. }
  311. else
  312. {
  313. GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
  314. glBindBuffer(GL_ARRAY_BUFFER, _vbo);
  315. // vertex
  316. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, vertices));
  317. // color
  318. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, colors));
  319. // texcoord
  320. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, texCoords));
  321. }
  322. glDrawArrays(GL_TRIANGLES, 0, _bufferCount);
  323. glBindBuffer(GL_ARRAY_BUFFER, 0);
  324. if (Configuration::getInstance()->supportsShareableVAO())
  325. {
  326. GL::bindVAO(0);
  327. }
  328. CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, _bufferCount);
  329. CHECK_GL_ERROR_DEBUG();
  330. if (_drawOnce)
  331. {
  332. _bufferCount = 0;
  333. _dirty = true;
  334. }
  335. }
  336. void DrawNode3D::onDrawGLLine(const Mat4 &transform, uint32_t /*flags*/)
  337. {
  338. auto glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR);
  339. glProgram->use();
  340. glProgram->setUniformsForBuiltins(transform);
  341. glProgram->setUniformLocationWith1f(glProgram->getUniformLocation("u_alpha"), _displayedOpacity / 255.0);
  342. GL::blendFunc(_blendFunc.src, _blendFunc.dst);
  343. if (_dirtyGLLine)
  344. {
  345. glBindBuffer(GL_ARRAY_BUFFER, _vboGLLine);
  346. glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_T2F)*_bufferCapacityGLLine, _bufferGLLine, GL_STREAM_DRAW);
  347. _dirtyGLLine = false;
  348. }
  349. if (Configuration::getInstance()->supportsShareableVAO())
  350. {
  351. GL::bindVAO(_vaoGLLine);
  352. }
  353. else
  354. {
  355. glBindBuffer(GL_ARRAY_BUFFER, _vboGLLine);
  356. GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
  357. // vertex
  358. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, vertices));
  359. // color
  360. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, colors));
  361. // texcoord
  362. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, texCoords));
  363. }
  364. glLineWidth(_lineWidth);
  365. glDrawArrays(GL_LINES, 0, _bufferCountGLLine);
  366. if (Configuration::getInstance()->supportsShareableVAO())
  367. {
  368. GL::bindVAO(0);
  369. }
  370. glBindBuffer(GL_ARRAY_BUFFER, 0);
  371. CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,_bufferCountGLLine);
  372. CHECK_GL_ERROR_DEBUG();
  373. if (_drawOnce)
  374. {
  375. _bufferCountGLLine = 0;
  376. _dirtyGLLine = true;
  377. }
  378. }
  379. void DrawNode3D::onDrawGLPoint(const Mat4 &transform, uint32_t /*flags*/)
  380. {
  381. auto glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_COLOR_TEXASPOINTSIZE);
  382. glProgram->use();
  383. glProgram->setUniformsForBuiltins(transform);
  384. glProgram->setUniformLocationWith1f(glProgram->getUniformLocation("u_alpha"), _displayedOpacity / 255.0);
  385. GL::blendFunc(_blendFunc.src, _blendFunc.dst);
  386. if (_dirtyGLPoint)
  387. {
  388. glBindBuffer(GL_ARRAY_BUFFER, _vboGLPoint);
  389. glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_T2F)*_bufferCapacityGLPoint, _bufferGLPoint, GL_STREAM_DRAW);
  390. _dirtyGLPoint = false;
  391. }
  392. if (Configuration::getInstance()->supportsShareableVAO())
  393. {
  394. GL::bindVAO(_vaoGLPoint);
  395. }
  396. else
  397. {
  398. glBindBuffer(GL_ARRAY_BUFFER, _vboGLPoint);
  399. GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
  400. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, vertices));
  401. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, colors));
  402. glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid *)offsetof(V3F_C4B_T2F, texCoords));
  403. }
  404. glDrawArrays(GL_POINTS, 0, _bufferCountGLPoint);
  405. if (Configuration::getInstance()->supportsShareableVAO())
  406. {
  407. GL::bindVAO(0);
  408. }
  409. glBindBuffer(GL_ARRAY_BUFFER, 0);
  410. CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,_bufferCountGLPoint);
  411. CHECK_GL_ERROR_DEBUG();
  412. if (_drawOnce)
  413. {
  414. _bufferCountGLPoint = 0;
  415. _dirtyGLPoint = true;
  416. }
  417. }
  418. void DrawNode3D::drawPoint(const Vec3& position, const float pointSize, const Color4F &color)
  419. {
  420. ensureCapacityGLPoint(1);
  421. V3F_C4B_T2F *point = (V3F_C4B_T2F*)(_bufferGLPoint + _bufferCountGLPoint);
  422. V3F_C4B_T2F a = {position, Color4B(color), Tex2F(pointSize,0)};
  423. *point = a;
  424. _bufferCountGLPoint += 1;
  425. _dirtyGLPoint = true;
  426. }
  427. void DrawNode3D::drawPoints(const Vec3 *position, unsigned int numberOfPoints, const Color4F &color)
  428. {
  429. drawPoints(position, numberOfPoints, 1.0, color);
  430. }
  431. void DrawNode3D::drawPoints(const Vec3 *position, unsigned int numberOfPoints, const float pointSize, const Color4F &color)
  432. {
  433. ensureCapacityGLPoint(numberOfPoints);
  434. V3F_C4B_T2F *point = (V3F_C4B_T2F*)(_bufferGLPoint + _bufferCountGLPoint);
  435. for(unsigned int i=0; i < numberOfPoints; i++,point++)
  436. {
  437. V3F_C4B_T2F a = {position[i], Color4B(color), Tex2F(pointSize,0)};
  438. *point = a;
  439. }
  440. _bufferCountGLPoint += numberOfPoints;
  441. _dirtyGLPoint = true;
  442. }
  443. void DrawNode3D::drawLine(const Vec3 &origin, const Vec3 &destination, const Color4F &color, const Mat4& transform)
  444. {
  445. ensureCapacityGLLine(2);
  446. V3F_C4B_T2F *point = (V3F_C4B_T2F*)(_bufferGLLine + _bufferCountGLLine);
  447. V3F_C4B_T2F a = {transform.MultiplyPoint3(origin), Color4B(color), Tex2F(0.0, 0.0)};
  448. V3F_C4B_T2F b = {transform.MultiplyPoint3(destination), Color4B(color), Tex2F(0.0, 0.0)};
  449. *point = a;
  450. *(point+1) = b;
  451. _bufferCountGLLine += 2;
  452. _dirtyGLLine = true;
  453. }
  454. void DrawNode3D::drawPoly(const Vec3 *poli, unsigned int numberOfPoints, bool closePolygon, const Color4F &color, const Mat4& transform)
  455. {
  456. unsigned int vertex_count;
  457. if(closePolygon)
  458. {
  459. vertex_count = 2 * numberOfPoints;
  460. ensureCapacityGLLine(vertex_count);
  461. }
  462. else
  463. {
  464. vertex_count = 2 * (numberOfPoints - 1);
  465. ensureCapacityGLLine(vertex_count);
  466. }
  467. V3F_C4B_T2F *point = (V3F_C4B_T2F*)(_bufferGLLine + _bufferCountGLLine);
  468. unsigned int i = 0;
  469. for(; i<numberOfPoints-1; i++)
  470. {
  471. V3F_C4B_T2F a = {transform.MultiplyPoint3(poli[i]), Color4B(color), Tex2F(0.0, 0.0)};
  472. V3F_C4B_T2F b = {transform.MultiplyPoint3(poli[i+1]), Color4B(color), Tex2F(0.0, 0.0)};
  473. *point = a;
  474. *(point+1) = b;
  475. point += 2;
  476. }
  477. if(closePolygon)
  478. {
  479. V3F_C4B_T2F a = {transform.MultiplyPoint3(poli[i]), Color4B(color), Tex2F(0.0, 0.0)};
  480. V3F_C4B_T2F b = {transform.MultiplyPoint3(poli[0]), Color4B(color), Tex2F(0.0, 0.0)};
  481. *point = a;
  482. *(point+1) = b;
  483. }
  484. _bufferCountGLLine += vertex_count;
  485. }
  486. void DrawNode3D::drawWireArc( const Vec3& center, const Vec3& normal, const Vec3& from, float angle, float radius, const Color4F &color, const Mat4& transform)
  487. {
  488. const int kArcPoints = 60;
  489. static Vec3 s_Points[kArcPoints];
  490. setDiscSectionPoints (s_Points, kArcPoints, center, normal, from, angle, radius);
  491. drawPoly(s_Points, kArcPoints, false, color, transform);
  492. }
  493. void DrawNode3D::drawWireDisk (const Vec3 &center, const Vec3 &normal, float radius, const Color4F &color, const Mat4& transform)
  494. {
  495. Vec3 tangent = Cross (normal, Vec3(0,1,0));
  496. if (SqrMagnitude(tangent) < 0.001f)
  497. tangent = Cross (normal, Vec3(1,0,0));
  498. drawWireArc (center, normal, tangent, 360.0f, radius, color, transform);
  499. }
  500. void DrawNode3D::drawWireSphere(const Vec3 &center, float radius, const Color4F &color, const Mat4& transform)
  501. {
  502. drawWireArc (center, Vec3(0,1,0), Vec3(1,0,0), 360.0f, radius, color, transform);
  503. drawWireArc (center, Vec3(0,0,1), Vec3(1,0,0), 360.0f, radius, color, transform);
  504. drawWireArc (center, Vec3(1,0,0), Vec3(0,1,0), 360.0f, radius, color, transform);
  505. }
  506. void DrawNode3D::drawWireCube (const Vec3& center, const Vec3& siz, bool depthTest, const Color4F &color, const Mat4& transform)
  507. {
  508. Vec3 halfsize = siz * 0.5f;
  509. Vec3 p000 = center + Vec3(-halfsize.x, -halfsize.y, -halfsize.z);
  510. Vec3 p001 = center + Vec3(-halfsize.x, -halfsize.y, halfsize.z);
  511. Vec3 p010 = center + Vec3(-halfsize.x, halfsize.y, -halfsize.z);
  512. Vec3 p011 = center + Vec3(-halfsize.x, halfsize.y, halfsize.z);
  513. Vec3 p100 = center + Vec3( halfsize.x, -halfsize.y, -halfsize.z);
  514. Vec3 p101 = center + Vec3( halfsize.x, -halfsize.y, halfsize.z);
  515. Vec3 p110 = center + Vec3( halfsize.x, halfsize.y, -halfsize.z);
  516. Vec3 p111 = center + Vec3( halfsize.x, halfsize.y, halfsize.z);
  517. #define ADD_CUBE_LINE(aaa,bbb) drawLine(aaa, bbb, color, transform)
  518. ADD_CUBE_LINE(p000, p001);
  519. ADD_CUBE_LINE(p001, p011);
  520. ADD_CUBE_LINE(p011, p010);
  521. ADD_CUBE_LINE(p010, p000);
  522. ADD_CUBE_LINE(p100, p101);
  523. ADD_CUBE_LINE(p101, p111);
  524. ADD_CUBE_LINE(p111, p110);
  525. ADD_CUBE_LINE(p110, p100);
  526. ADD_CUBE_LINE (p000, p100);
  527. ADD_CUBE_LINE (p001, p101);
  528. ADD_CUBE_LINE (p010, p110);
  529. ADD_CUBE_LINE (p011, p111);
  530. #undef ADD_CUBE_LINE
  531. }
  532. void DrawNode3D::drawDot(const Vec3 &pos, float radius, const Color4F &color)
  533. {
  534. unsigned int vertex_count = 2*3;
  535. ensureCapacity(vertex_count);
  536. V3F_C4B_T2F a = {Vec3(pos.x - radius, pos.y - radius, pos.z), Color4B(color), Tex2F(-1.0, -1.0) };
  537. V3F_C4B_T2F b = {Vec3(pos.x - radius, pos.y + radius, pos.z), Color4B(color), Tex2F(-1.0, 1.0) };
  538. V3F_C4B_T2F c = {Vec3(pos.x + radius, pos.y + radius, pos.z), Color4B(color), Tex2F( 1.0, 1.0) };
  539. V3F_C4B_T2F d = {Vec3(pos.x + radius, pos.y - radius, pos.z), Color4B(color), Tex2F( 1.0, -1.0) };
  540. V3F_C4B_T2F_Triangle *triangles = (V3F_C4B_T2F_Triangle *)(_buffer + _bufferCount);
  541. V3F_C4B_T2F_Triangle triangle0 = {a, b, c};
  542. V3F_C4B_T2F_Triangle triangle1 = {a, c, d};
  543. triangles[0] = triangle0;
  544. triangles[1] = triangle1;
  545. _bufferCount += vertex_count;
  546. _dirty = true;
  547. }
  548. void DrawNode3D::drawRect(const Vec3 &p1, const Vec3 &p2, const Vec3 &p3, const Vec3& p4, const Color4F &color)
  549. {
  550. drawLine(p1, p2, color, Mat4::IDENTITY);
  551. drawLine(p2, p3, color, Mat4::IDENTITY);
  552. drawLine(p3, p4, color, Mat4::IDENTITY);
  553. drawLine(p4, p1, color, Mat4::IDENTITY);
  554. }
  555. void DrawNode3D::drawPolygon(const Vec3 *verts, int count, const Color4F &fillColor, float borderWidth, const Color4F &borderColor)
  556. {
  557. CCASSERT(count >= 0, "invalid count value");
  558. bool outline = (borderColor.a > 0.0f && borderWidth > 0.0f);
  559. auto triangle_count = outline ? (3*count - 2) : (count - 2);
  560. auto vertex_count = 3*triangle_count;
  561. ensureCapacity(vertex_count);
  562. V3F_C4B_T2F_Triangle *triangles = (V3F_C4B_T2F_Triangle *)(_buffer + _bufferCount);
  563. V3F_C4B_T2F_Triangle *cursor = triangles;
  564. for (int i = 0; i < count-2; i++)
  565. {
  566. V3F_C4B_T2F_Triangle tmp = {
  567. {verts[0], Color4B(fillColor), __t(v3fzero)},
  568. {verts[i+1], Color4B(fillColor), __t(v3fzero)},
  569. {verts[i+2], Color4B(fillColor), __t(v3fzero)},
  570. };
  571. *cursor++ = tmp;
  572. }
  573. if(outline)
  574. {
  575. struct ExtrudeVerts {Vec3 offset, n;};
  576. struct ExtrudeVerts* extrude = (struct ExtrudeVerts*)malloc(sizeof(struct ExtrudeVerts)*count);
  577. memset(extrude, 0, sizeof(struct ExtrudeVerts)*count);
  578. for (int i = 0; i < count; i++)
  579. {
  580. Vec3 v0 = __v3f(verts[(i-1+count)%count]);
  581. Vec3 v1 = __v3f(verts[i]);
  582. Vec3 v2 = __v3f(verts[(i+1)%count]);
  583. Vec3 n1 = v3fnormalize(v3fperp(v3fsub(v1, v0)));
  584. Vec3 n2 = v3fnormalize(v3fperp(v3fsub(v2, v1)));
  585. Vec3 offset = v3fmult(v3fadd(n1, n2), 1.0f / (v3fdot(n1, n2) + 1.0f));
  586. struct ExtrudeVerts tmp = {offset, n2};
  587. extrude[i] = tmp;
  588. }
  589. for(int i = 0; i < count; i++)
  590. {
  591. int j = (i+1)%count;
  592. Vec3 v0 = __v3f(verts[i]);
  593. Vec3 v1 = __v3f(verts[j]);
  594. Vec3 n0 = extrude[i].n;
  595. Vec3 offset0 = extrude[i].offset;
  596. Vec3 offset1 = extrude[j].offset;
  597. Vec3 inner0 = v3fsub(v0, v3fmult(offset0, borderWidth));
  598. Vec3 inner1 = v3fsub(v1, v3fmult(offset1, borderWidth));
  599. Vec3 outer0 = v3fadd(v0, v3fmult(offset0, borderWidth));
  600. Vec3 outer1 = v3fadd(v1, v3fmult(offset1, borderWidth));
  601. V3F_C4B_T2F_Triangle tmp1 = {
  602. {inner0, Color4B(borderColor), __t(v3fneg(n0))},
  603. {inner1, Color4B(borderColor), __t(v3fneg(n0))},
  604. {outer1, Color4B(borderColor), __t(n0)}
  605. };
  606. *cursor++ = tmp1;
  607. V3F_C4B_T2F_Triangle tmp2 = {
  608. {inner0, Color4B(borderColor), __t(v3fneg(n0))},
  609. {outer0, Color4B(borderColor), __t(n0)},
  610. {outer1, Color4B(borderColor), __t(n0)}
  611. };
  612. *cursor++ = tmp2;
  613. }
  614. free(extrude);
  615. }
  616. _bufferCount += vertex_count;
  617. _dirty = true;
  618. }
  619. void DrawNode3D::drawSolidPoly(const Vec3 *poli, unsigned int numberOfPoints, const Color4F &color)
  620. {
  621. drawPolygon(poli, numberOfPoints, color, 0.0, Color4F(0.0, 0.0, 0.0, 0.0));
  622. }
  623. void DrawNode3D::drawTriangle(const Vec3 &p1, const Vec3 &p2, const Vec3 &p3, const Color4F &color)
  624. {
  625. unsigned int vertex_count = 3;
  626. ensureCapacity(vertex_count);
  627. Color4B col = Color4B(color);
  628. V3F_C4B_T2F a = {Vec3(p1.x, p1.y, p1.z), col, Tex2F(0.0, 0.0) };
  629. V3F_C4B_T2F b = {Vec3(p2.x, p2.y, p2.z), col, Tex2F(0.0, 0.0) };
  630. V3F_C4B_T2F c = {Vec3(p3.x, p3.y, p3.z), col, Tex2F(0.0, 0.0) };
  631. V3F_C4B_T2F_Triangle *triangles = (V3F_C4B_T2F_Triangle *)(_buffer + _bufferCount);
  632. V3F_C4B_T2F_Triangle triangle = {a, b, c};
  633. triangles[0] = triangle;
  634. _bufferCount += vertex_count;
  635. _dirty = true;
  636. }
  637. void DrawNode3D::clear()
  638. {
  639. _bufferCount = 0;
  640. _dirty = true;
  641. _bufferCountGLLine = 0;
  642. _dirtyGLLine = true;
  643. _bufferCountGLPoint = 0;
  644. _dirtyGLPoint = true;
  645. _lineWidth = _defaultLineWidth;
  646. }
  647. const BlendFunc& DrawNode3D::getBlendFunc() const
  648. {
  649. return _blendFunc;
  650. }
  651. void DrawNode3D::setBlendFunc(const BlendFunc &blendFunc)
  652. {
  653. _blendFunc = blendFunc;
  654. }
  655. void DrawNode3D::setLineWidth(GLfloat lineWidth)
  656. {
  657. _lineWidth = lineWidth;
  658. }
  659. GLfloat DrawNode3D::getLineWidth()
  660. {
  661. return this->_lineWidth;
  662. }
  663. NS_CC_END