REDPolygonClippingNode.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. //
  2. // REDPolygonClippingNode.hpp
  3. // cocos2d_libs
  4. //
  5. // Created by RedInfinity on 2024/1/17.
  6. //
  7. #ifndef REDPolygonClippingNode_hpp
  8. #define REDPolygonClippingNode_hpp
  9. ///C++标准库
  10. #include <string>
  11. #include <vector>
  12. ///项目代码
  13. #include "platform/CCPlatformMacros.h"
  14. #include "base/CCStencilStateManager.h"
  15. #include "2d/CCNode.h"
  16. #include "renderer/CCRenderer.h"
  17. #include "renderer/CCGroupCommand.h"
  18. #include "renderer/CCCustomCommand.h"
  19. #include "math/Vec2.h"
  20. #include "math/Mat4.h"
  21. NS_CC_BEGIN
  22. /**
  23. * 描述:多边形裁切node,通过接收一组顶点数据(闭合多边形)控制只显示多边形内或多边形外的图形。
  24. */
  25. class PolygonClippingNode final : public Node {
  26. public:
  27. /**
  28. * 功能:创建多边形裁切node对象
  29. * 返回值:多边形裁切node对象
  30. */
  31. static PolygonClippingNode* create();
  32. /**
  33. * 功能:通过数据创建多边形裁切node对象
  34. * 参数 verts:闭合多边形的顶点数据
  35. * 参数 close:顶点数据是否闭合(顶点数组最后一个元素坐标等于第一个元素坐标)
  36. * 参数 clockwise:多边形的顶点是否以顺时针方向填充。我们以OpenGL绘制顺序为准,默认期望为逆时针。
  37. * 返回值:多边形裁切node对象
  38. */
  39. static PolygonClippingNode* createWithData(const std::vector<Vec2>& verts, const bool& close, const bool& clockwise);
  40. /**
  41. * 功能:通过文件创建多边形裁切node对象
  42. * 参数 fileName:闭合多边形的顶点数据文件
  43. * 返回值:多边形裁切node对象
  44. */
  45. static PolygonClippingNode* createWithFile(const std::string& fileName);
  46. /**
  47. * 功能:设置闭合多边形的顶点数据
  48. * 参数 verts:闭合多边形的顶点数据
  49. * 参数 close:顶点数据是否闭合(最后一个坐标等于第一个坐标)
  50. * 参数 clockwise:多边形的顶点是否以顺时针方向填充
  51. */
  52. void setPolygonVerts(const std::vector<Vec2>& verts, const bool& close, const bool& clockwise = false);
  53. /**
  54. * 功能:是否反转显示,改为只显示多边形外的图像
  55. * 参数 inverted:是否反转显示
  56. */
  57. void setInverted(bool inverted);
  58. /**
  59. * 功能:获取是否反转显示
  60. * 返回值:是否反转显示
  61. */
  62. bool isInverted() const;
  63. /**
  64. * 功能:设置闭合多边形的顶点数据文件
  65. * 参数 fileName:闭合多边形的顶点数据文件名称
  66. */
  67. void setPolygonFile(const std::string& fileName);
  68. /**
  69. * 功能:获取闭合多边形的顶点数据文件
  70. * 返回值:当前获取闭合多边形的顶点数据文件,如果不是通过文件创建则返回空
  71. */
  72. const std::string& getPolygonFile() const;
  73. virtual void visit(Renderer* renderer, const Mat4& parentTransform, uint32_t parentFlags) override;
  74. virtual void draw(Renderer* renderer, const Mat4 &transform, uint32_t flags) override;
  75. private:
  76. PolygonClippingNode();
  77. ~PolygonClippingNode();
  78. /**
  79. * 功能:通过数据初始化多边形裁切node
  80. * 参数 verts:闭合多边形的顶点数据
  81. * 参数 close:顶点数据是否闭合
  82. * 参数 clockwise:多边形的顶点是否以顺时针方向填充
  83. * 返回值:初始化是否成功
  84. */
  85. bool _initWithData(const std::vector<Vec2>& verts, const bool& close, const bool& clockwise);
  86. /**
  87. * 功能:通过文件初始化多边形裁切node
  88. * 参数 fileName:闭合多边形的顶点数据文件
  89. * 返回值:初始化是否成功
  90. */
  91. bool _initWithFile(const std::string& fileName);
  92. /**
  93. * 功能:解析闭合多边形的顶点数据文件
  94. * 参数 fileName:闭合多边形的顶点数据文件
  95. * 返回值:逆时针绘制的闭合多边形顶点数组
  96. */
  97. std::vector<Vec2> _parseFile(const std::string& fileName);
  98. /**
  99. * 功能:创建着色器程序
  100. */
  101. void _createGLProgram();
  102. /**
  103. * 功能:绑定vao和vbo
  104. */
  105. void _bindVAOAndVBO();
  106. /**
  107. * 功能:更新OpenGL绘制的顶点数据
  108. * 参数 verts:逆时针绘制的闭合多边形顶点数组
  109. */
  110. void _updateOpenGLDrawVerts(std::vector<Vec2> verts);
  111. /**
  112. * 功能:找到多边形顶点数组中一个凸位顶点
  113. * 参数 verts:多边形顶点数组
  114. * 返回值:凸位顶点在数组中的索引,如果不存在则返回第一个顶点的索引
  115. */
  116. int _findConvexVertex(const std::vector<Vec2>& verts);
  117. /**
  118. * 功能:检查三个顶点画出来的三角形是否为正面(正面:由三个顶点逆时针绘制构成)
  119. * 参数 vert1:绘制三角形的第一个顶点
  120. * 参数 vert2:绘制三角形的第二个顶点
  121. * 参数 vert3:绘制三角形的第三个顶点
  122. * 返回值:三角形是否为正面
  123. */
  124. bool _isPositiveTriangle(const Vec2& vert1, const Vec2& vert2, const Vec2& vert3);
  125. /**
  126. * 功能:检查三个顶点画出来的三角形是否完全位于多边形内
  127. * 参数 verts:多边形顶点数组
  128. * 参数 vert1:绘制三角形的第一个顶点
  129. * 参数 vert2:绘制三角形的第二个顶点
  130. * 参数 vert3:绘制三角形的第三个顶点
  131. * 返回值:三角形是否为多边形的内嵌三角形
  132. */
  133. bool _isEmbeddedTriangle(const std::vector<Vec2>& verts, const Vec2& vert1, const Vec2& vert2, const Vec2& vert3);
  134. /**
  135. * 功能:检查任意一点是否位于三角形内部
  136. * 参数 point:指定点的坐标
  137. * 参数 vert1:绘制三角形的第一个顶点
  138. * 参数 vert2:绘制三角形的第二个顶点
  139. * 参数 vert3:绘制三角形的第三个顶点
  140. * 返回值:指定点是否位于三角形内部
  141. */
  142. bool _isInteriorPoint(const Vec2& point, const Vec2& vert1, const Vec2& vert2, const Vec2& vert3);
  143. private:
  144. ///闭合多边形的顶点数据文件,只有通过文件设值时才不为空
  145. std::string _polygonFile = "";
  146. ///闭合多边形的顶点数据
  147. Vec2* _verts = nullptr;
  148. ///闭合多边形的顶点数量
  149. int _vertsCnt = 0;
  150. ///闭合多边形的顶点数据是否修改的脏标记
  151. bool _vertsDirty= false;
  152. ///顶点数组对象
  153. GLuint _vao;
  154. ///顶点缓冲对象
  155. GLuint _vbo;
  156. ///渲染指令组
  157. GroupCommand _groupCommand;
  158. CustomCommand _beforeVisitCmd;
  159. CustomCommand _customDrawCmd;
  160. CustomCommand _afterDrawCmd;
  161. CustomCommand _afterVisitCmd;
  162. ///OpenGL模版状态管理器
  163. StencilStateManager* _stencilStateManager = nullptr;
  164. };
  165. NS_CC_END
  166. #endif /* REDPolygonClippingNode_hpp */