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