// // REDPolygonClippingNode.hpp // cocos2d_libs // // Created by RedInfinity on 2024/1/17. // #ifndef REDPolygonClippingNode_hpp #define REDPolygonClippingNode_hpp ///C++标准库 #include #include ///项目代码 #include "platform/CCPlatformMacros.h" #include "base/CCStencilStateManager.h" #include "2d/CCNode.h" #include "renderer/CCRenderer.h" #include "renderer/CCGroupCommand.h" #include "renderer/CCCustomCommand.h" #include "math/Vec2.h" #include "math/Mat4.h" NS_CC_BEGIN /** * 描述:多边形裁切node,通过接收一组顶点数据(闭合多边形)控制只显示多边形内或多边形外的图形。 */ class PolygonClippingNode final : public Node { public: /** * 功能:创建多边形裁切node对象 * 返回值:多边形裁切node对象 */ static PolygonClippingNode* create(); /** * 功能:通过数据创建多边形裁切node对象 * 参数 verts:闭合多边形的顶点数据 * 参数 close:顶点数据是否闭合(顶点数组最后一个元素坐标等于第一个元素坐标) * 参数 clockwise:多边形的顶点是否以顺时针方向填充。我们以OpenGL绘制顺序为准,默认期望为逆时针。 * 返回值:多边形裁切node对象 */ static PolygonClippingNode* createWithData(const std::vector& verts, const bool& close, const bool& clockwise); /** * 功能:通过文件创建多边形裁切node对象 * 参数 fileName:闭合多边形的顶点数据文件 * 返回值:多边形裁切node对象 */ static PolygonClippingNode* createWithFile(const std::string& fileName); /** * 功能:设置闭合多边形的顶点数据 * 参数 verts:闭合多边形的顶点数据 * 参数 close:顶点数据是否闭合(最后一个坐标等于第一个坐标) * 参数 clockwise:多边形的顶点是否以顺时针方向填充 */ void setPolygonVerts(const std::vector& verts, const bool& close, const bool& clockwise = false); /** * 功能:是否反转显示,改为只显示多边形外的图像 * 参数 inverted:是否反转显示 */ void setInverted(bool inverted); /** * 功能:获取是否反转显示 * 返回值:是否反转显示 */ bool isInverted() const; /** * 功能:设置闭合多边形的顶点数据文件 * 参数 fileName:闭合多边形的顶点数据文件名称 */ void setPolygonFile(const std::string& fileName); /** * 功能:获取闭合多边形的顶点数据文件 * 返回值:当前获取闭合多边形的顶点数据文件,如果不是通过文件创建则返回空 */ const std::string& getPolygonFile() const; virtual void visit(Renderer* renderer, const Mat4& parentTransform, uint32_t parentFlags) override; virtual void draw(Renderer* renderer, const Mat4 &transform, uint32_t flags) override; private: PolygonClippingNode(); ~PolygonClippingNode(); /** * 功能:通过数据初始化多边形裁切node * 参数 verts:闭合多边形的顶点数据 * 参数 close:顶点数据是否闭合 * 参数 clockwise:多边形的顶点是否以顺时针方向填充 * 返回值:初始化是否成功 */ bool _initWithData(const std::vector& verts, const bool& close, const bool& clockwise); /** * 功能:通过文件初始化多边形裁切node * 参数 fileName:闭合多边形的顶点数据文件 * 返回值:初始化是否成功 */ bool _initWithFile(const std::string& fileName); /** * 功能:解析闭合多边形的顶点数据文件 * 参数 fileName:闭合多边形的顶点数据文件 * 返回值:逆时针绘制的闭合多边形顶点数组 */ std::vector _parseFile(const std::string& fileName); /** * 功能:创建着色器程序 */ void _createGLProgram(); /** * 功能:绑定vao和vbo */ void _bindVAOAndVBO(); /** * 功能:更新OpenGL绘制的顶点数据 * 参数 verts:逆时针绘制的闭合多边形顶点数组 */ void _updateOpenGLDrawVerts(std::vector verts); /** * 功能:找到多边形顶点数组中一个凸位顶点 * 参数 verts:多边形顶点数组 * 返回值:凸位顶点在数组中的索引,如果不存在则返回第一个顶点的索引 */ int _findConvexVertex(const std::vector& verts); /** * 功能:检查三个顶点画出来的三角形是否为正面(正面:由三个顶点逆时针绘制构成) * 参数 vert1:绘制三角形的第一个顶点 * 参数 vert2:绘制三角形的第二个顶点 * 参数 vert3:绘制三角形的第三个顶点 * 返回值:三角形是否为正面 */ bool _isPositiveTriangle(const Vec2& vert1, const Vec2& vert2, const Vec2& vert3); /** * 功能:检查三个顶点画出来的三角形是否完全位于多边形内 * 参数 verts:多边形顶点数组 * 参数 vert1:绘制三角形的第一个顶点 * 参数 vert2:绘制三角形的第二个顶点 * 参数 vert3:绘制三角形的第三个顶点 * 返回值:三角形是否为多边形的内嵌三角形 */ bool _isEmbeddedTriangle(const std::vector& verts, const Vec2& vert1, const Vec2& vert2, const Vec2& vert3); /** * 功能:检查任意一点是否位于三角形内部 * 参数 point:指定点的坐标 * 参数 vert1:绘制三角形的第一个顶点 * 参数 vert2:绘制三角形的第二个顶点 * 参数 vert3:绘制三角形的第三个顶点 * 返回值:指定点是否位于三角形内部 */ bool _isInteriorPoint(const Vec2& point, const Vec2& vert1, const Vec2& vert2, const Vec2& vert3); private: ///闭合多边形的顶点数据文件,只有通过文件设值时才不为空 std::string _polygonFile = ""; ///闭合多边形的顶点数据 Vec2* _verts = nullptr; ///闭合多边形的顶点数量 int _vertsCnt = 0; ///闭合多边形的顶点数据是否修改的脏标记 bool _vertsDirty= false; ///顶点数组对象 GLuint _vao; ///顶点缓冲对象 GLuint _vbo; ///渲染指令组 GroupCommand _groupCommand; CustomCommand _beforeVisitCmd; CustomCommand _customDrawCmd; CustomCommand _afterDrawCmd; CustomCommand _afterVisitCmd; ///OpenGL模版状态管理器 StencilStateManager* _stencilStateManager = nullptr; }; NS_CC_END #endif /* REDPolygonClippingNode_hpp */