cocos2dx中DrawNode画线锯齿和非凸多边形填充
来源:互联网 发布:淘宝宝贝描述图片宽度 编辑:程序博客网 时间:2024/05/22 06:37
记录一下在cocos2dx中使用DrawNode所遇到的2个问题
1.画线锯齿问题
ios版本下,在AppController.mm中设置multiSampling和numberOfSamples,如下
CCEAGLView *eaglView = [CCEAGLView viewWithFrame: [window bounds] pixelFormat: (NSString*)cocos2d::GLViewImpl::_pixelFormat depthFormat: cocos2d::GLViewImpl::_depthFormat preserveBackbuffer: NO sharegroup: nil multiSampling: YES numberOfSamples: 4 ];
android版本下,在cocos2d/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dActivity.java中加入EGL_SAMPLE_BUFFERS和EGL_SAMPLES,如下
@Override public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { int[] EGLattribs = { EGL10.EGL_RED_SIZE, configAttribs[0], EGL10.EGL_GREEN_SIZE, configAttribs[1], EGL10.EGL_BLUE_SIZE, configAttribs[2], EGL10.EGL_ALPHA_SIZE, configAttribs[3], EGL10.EGL_DEPTH_SIZE, configAttribs[4], EGL10.EGL_STENCIL_SIZE,configAttribs[5], EGL10.EGL_RENDERABLE_TYPE, 4, //EGL_OPENGL_ES2_BIT EGL10.EGL_SAMPLE_BUFFERS,1, EGL10.EGL_SAMPLES,8, EGL10.EGL_NONE };
原理,开启多重采样以达到扛锯齿。缺点,对于性能要求高,在模拟机上非常卡,真机测试还行。
2.非凸多边形填充
在ios上发现DrawNode画的多边形存在一个多边形填充检测的bug,情况如下图所示
一翻寻找之后,找到了一个多边形分割算法,测试可用,现在分享出来。
triangulate.h
typedef std::vector< Vec2 > Vector2dVector;class Triangulate{public: // triangulate a contour/polygon, places results in STL vector // as series of triangles. static bool Process(const Vector2dVector &contour, Vector2dVector &result); // compute area of a contour/polygon static float Area(const Vector2dVector &contour); // decide if point Px/Py is inside triangle defined by // (Ax,Ay) (Bx,By) (Cx,Cy) static bool InsideTriangle(float Ax, float Ay, float Bx, float By, float Cx, float Cy, float Px, float Py);private: static bool Snip(const Vector2dVector &contour,int u,int v,int w,int n,int *V);triangulate.cpp
static const float EPSILON=0.0000000001f;float Triangulate::Area(const Vector2dVector &contour){ int n = contour.size(); float A=0.0f; for(int p=n-1,q=0; q<n; p=q++) { A+= contour[p].x*contour[q].y - contour[q].x*contour[p].y; } return A*0.5f;}/* InsideTriangle decides if a point P is Inside of the triangle defined by A, B, C. */bool Triangulate::InsideTriangle(float Ax, float Ay, float Bx, float By, float Cx, float Cy, float Px, float Py){ float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy; float cCROSSap, bCROSScp, aCROSSbp; ax = Cx - Bx; ay = Cy - By; bx = Ax - Cx; by = Ay - Cy; cx = Bx - Ax; cy = By - Ay; apx= Px - Ax; apy= Py - Ay; bpx= Px - Bx; bpy= Py - By; cpx= Px - Cx; cpy= Py - Cy; aCROSSbp = ax*bpy - ay*bpx; cCROSSap = cx*apy - cy*apx; bCROSScp = bx*cpy - by*cpx; return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));};bool Triangulate::Snip(const Vector2dVector &contour,int u,int v,int w,int n,int *V){ int p; float Ax, Ay, Bx, By, Cx, Cy, Px, Py; Ax = contour[V[u]].x; Ay = contour[V[u]].y; Bx = contour[V[v]].x; By = contour[V[v]].y; Cx = contour[V[w]].x; Cy = contour[V[w]].y; if ( EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) ) return false; for (p=0;p<n;p++) { if( (p == u) || (p == v) || (p == w) ) continue; Px = contour[V[p]].x; Py = contour[V[p]].y; if (InsideTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) return false; } return true;}bool Triangulate::Process(const Vector2dVector &contour,Vector2dVector &result){ /* allocate and initialize list of Vertices in polygon */ int n = contour.size(); if ( n < 3 ) return false; int *V = new int[n]; /* we want a counter-clockwise polygon in V */ if ( 0.0f < Area(contour) ) for (int v=0; v<n; v++) V[v] = v; else for(int v=0; v<n; v++) V[v] = (n-1)-v; int nv = n; /* remove nv-2 Vertices, creating 1 triangle every time */ int count = 2*nv; /* error detection */ for(int m=0, v=nv-1; nv>2; ) { /* if we loop, it is probably a non-simple polygon */ if (0 >= (count--)) { //** Triangulate: ERROR - probable bad polygon! return false; } /* three consecutive vertices in current polygon, <u,v,w> */ int u = v ; if (nv <= u) u = 0; /* previous */ v = u+1; if (nv <= v) v = 0; /* new v */ int w = v+1; if (nv <= w) w = 0; /* next */ if ( Snip(contour,u,v,w,nv,V) ) { int a,b,c,s,t; /* true names of the vertices */ a = V[u]; b = V[v]; c = V[w]; /* output Triangle */ result.push_back( contour[a] ); result.push_back( contour[b] ); result.push_back( contour[c] ); m++; /* remove v from remaining polygon */ for(s=v,t=v+1;t<nv;s++,t++) V[s] = V[t]; nv--; /* resest error detection counter */ count = 2*nv; } } delete V; return true;}原算法地址,用法例子如下:
Vector2dVector a; for (int i=0; i<count; i++) { a.push_back(verts[i]); } Vector2dVector result; // Invoke the triangulator to triangulate this polygon. Triangulate::Process(a,result); // print out the results. unsigned long tcount = result.size()/3; for (int i=0; i<tcount; i++) { const Vec2 &p1 = result[i*3+0]; const Vec2 &p2 = result[i*3+1]; const Vec2 &p3 = result[i*3+2];// printf("Triangle %d => (%0.0f,%0.0f) (%0.0f,%0.0f) (%0.0f,%0.0f)\n",i+1,p1.x,p1.y,p2.x,p2.y,p3.x,p3.y); this->drawTriangle(p1, p2, p3, fillColor);//当前类继承drawnode }
0 0
- cocos2dx中DrawNode画线锯齿和非凸多边形填充
- OpenGL:填充非凸多边形
- OpenGL: 填充非凸多边形
- glBegin glVertex2f glEnd画线 线有形状 大小 插值方式的非抗锯齿和抗锯齿版本
- cocos2dx DrawNode和ClippingRectangleNode 使用详解
- OpenGL: 填充非凸多边形 (转)
- OpenGL填充非凸多边形(网格化)
- cocos2dx-js cc.DrawNode
- win32画线考虑去锯齿
- OpenGL非规则多边形(凹多边形,凸多边形)二维纹理映射(填充)
- cocos2dx-3.2(34) DrawNode 绘图API
- cocos2dx给DrawNode的shader传递Texture2D
- cocos2dx抗锯齿
- cocos2dx抗锯齿问题
- cocos2dx 抗锯齿问题
- DrawNode
- osg创建非凸多边形
- 【cocos2dx 3.x】画线
- C2064: term does not evaluate to a function解决方法
- 为PHP开发C语言扩展
- New Articles Posted On The ProcessMaker Blog!
- JAVA内存模型,重排序的概念
- 初步介绍PHP扩展开发经验分享
- cocos2dx中DrawNode画线锯齿和非凸多边形填充
- QgsRubberBand类
- 用C/C++扩展你的PHP 为你的php增加功能
- springmvc(基础一) @RequestMapping 用法详解之地址映射
- Phabricator命令行工具Arcanist的基本用法
- iptables命令详解(1)
- 在Linux下用C扩展PHP(打包成so)的方法
- 二叉树的三种非递归遍历和morris遍历
- 改造间隙扯淡1:机器人产品