0

I'm having a set of vertices (X,Y) of an irregular polygon, some having 4 vertices and some more than 4. I'm creating an array of vertices for drawing from the set of vertices I have using the getTransformedVertices() method. The indices and UV for the texture are unknown so I had to calculate tem using Triangulate() method below. I've setup the color and texture in the setColor() and setImage() methods.

However, the polygons having more than 4 vertices are not rendered properly. I've been trying for weeks now and almost the searched half of the internet. This is what I could come up with. The polygons with 4 vertices and the outlines are working properly. But I couldn't get the textures displayed properly on the polygon. Please help

The texture not rendered properly on a polygon having more than 4 vertices (BLUEBIRD POLYGON)

public class BoothRectangle
{
float angle;
float scale;
RectF base;
PointF translation;
int textureId;
int positionBufferId;
int textureBufferId;
PointF[] corners;
float[] verts;

// Geometric variables
public float vertices[];
public float colors[];
public short indices[];
public float uvs[];
public FloatBuffer vertexBuffer;
public ShortBuffer drawListBuffer;
public FloatBuffer colorBuffer;
public FloatBuffer uvBuffer;
TextPaint textPaint = new TextPaint();
String title;

public BoothRectangle(PointF[] corners, int textureId, float[] colors, String title)
{
    // Initialise our intital size around the 0,0 point
    base = new RectF(corners[1].x, corners[3].y, corners[0].x, corners[1].y);
    this.corners = corners;
    this.title = title;

    // Offset translation
    translation = new PointF(0f,0f);

    // Initial Size
    scale = 1f;

    // We start in our inital angle
    angle = 0f;

    this.textureId = textureId;
    this.colors = colors;
}

public void setColor(float[] topColor){
    List<Float> colorsList = new ArrayList<Float>();

    for(PointF point : corners){
        colorsList.add(topColor[0] / 255);
        colorsList.add(topColor[1] / 255);
        colorsList.add(topColor[2] / 255);
        colorsList.add(1f);
    }

    int i = 0;
    float[] colors = new float[colorsList.size()];
    for (Float f : colorsList) {
        colors[i++] = (f != null ? f : Float.NaN);
    }

    ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
    cbb.order(ByteOrder.nativeOrder());
    colorBuffer = cbb.asFloatBuffer();
    colorBuffer.put(colors);
    colorBuffer.position(0);

    int[] buffers = new int[1];
    GLES11.glGenBuffers(1, buffers, 0);
    GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, buffers[0]);
    GLES11.glBufferData(GLES11.GL_ARRAY_BUFFER, 4 * colors.length, colorBuffer, GLES11.GL_STATIC_DRAW);
    textureBufferId = buffers[0];
    GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, 0);   
}

public float[] getTransformedVertices()
{
    float z;
    List<Float> finalVertices = new ArrayList<Float>();

    if(textureId == 0)
        z = 0.5f;
    else
        z = 2.0f;

        finalVertices.clear();
        for(PointF point : corners){
            finalVertices.add(point.x);
            finalVertices.add(point.y);
            finalVertices.add(0.0f);
        }   

        int i = 0;
        float[] verticesArray = new float[finalVertices.size()];
        for (Float f : finalVertices) {
            verticesArray[i++] = (f != null ? f : Float.NaN);
        }
        return verticesArray;


}

public void setImage()
{

    uvs = new float[] {
        0.0f, 0.0f,
        1.0f, 0.0f,
        1.0f, 1.0f,         
        0.0f, 1.0f  
    };

    // The texture buffer
    ByteBuffer bb = ByteBuffer.allocateDirect(uvs.length * 4);
    bb.order(ByteOrder.nativeOrder());
    uvBuffer = bb.asFloatBuffer();
    uvBuffer.put(uvs);
    uvBuffer.position(0);

    int[] buffers = new int[1];
    GLES11.glGenBuffers(1, buffers, 0);
    GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, buffers[0]);
    GLES11.glBufferData(GLES11.GL_ARRAY_BUFFER, 4 * uvs.length, uvBuffer, GLES11.GL_STATIC_DRAW);
    textureBufferId = buffers[0];
    GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, 0);

}

public void initBooth()
{
    vertices = this.getTransformedVertices();

    indices = PolygonTriangulation.Process(vertices);

    if(indices==null){
        Log.d("PolygonTriangulation",title + " - failed");
        if(this.corners.length == 4){
            indices = new short[] {2, 1, 0, 2, 0, 3};
    }else{
        indices = new short[corners.length];
        for(int i=0;i<corners.length;i++){
            indices[i] = (short) i;
        }
    }
    }

    // The vertex buffer.
    ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

    ByteBuffer dlb = ByteBuffer.allocateDirect(indices.length * 2);
    dlb.order(ByteOrder.nativeOrder());
    drawListBuffer = dlb.asShortBuffer();
    drawListBuffer.put(indices);
    drawListBuffer.position(0);

    int[] buffers = new int[1];
    GLES11.glGenBuffers(1, buffers, 0);
    GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, buffers[0]);
    GLES11.glBufferData(GLES11.GL_ARRAY_BUFFER, 4 * vertices.length, vertexBuffer,   GLES11.GL_STATIC_DRAW);
    positionBufferId = buffers[0];
    GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, 0);

    if(this.textureId !=0){
        setImage();
    } else {
        setColor(colors);
    }
}

public void Render(GL10 gl){

if(textureId == 0){

    GLES11.glPushMatrix();
    GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, positionBufferId);
    GLES11.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    GLES11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
    GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, 0);

    GLES11.glFrontFace(GL10.GL_CW);
    GLES11.glColor4f(0.8f, 0.8f, 0.8f, 0.8f);
    GLES11.glLineWidth(3.0f);
    GLES11.glDrawArrays(GL10.GL_LINE_LOOP, 0, corners.length);

    GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, textureBufferId);
    gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
    GLES11.glColorPointer(4, GL10.GL_FLOAT, 0, 0);
    GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, 0);

    GLES11.glDrawElements(GL10.GL_TRIANGLES, indices.length,
            GL10.GL_UNSIGNED_SHORT, drawListBuffer);
    GLES11.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    GLES11.glDisableClientState(GL10.GL_COLOR_ARRAY);
    GLES11.glPopMatrix();

} else {
        GLES11.glPushMatrix();
        GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, positionBufferId);
        GLES11.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        GLES11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
        GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, 0);

        GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, textureBufferId);
        GLES11.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        GLES11.glTexCoordPointer(2, GL10.GL_FLOAT, 0, 0);
        GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, 0);

        GLES11.glEnable(GL10.GL_TEXTURE_2D);
        GLES11.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
        GLES11.glEnable(GL10.GL_BLEND);

        GLES11.glFrontFace(GL10.GL_CW);

        GLES11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

        GLES11.glBindTexture(GL10.GL_TEXTURE_2D, textureId);

        int error = gl.glGetError();
        if (error != GL10.GL_NO_ERROR)
        { 
            Log.e("OPENGL", "GL Texture Load Error: " + GLU.gluErrorString(error));
        }

        GLES11.glDrawElements(GL10.GL_TRIANGLES, indices.length,
                GL10.GL_UNSIGNED_SHORT, drawListBuffer);

        GLES11.glDisable(GL10.GL_BLEND);
        GLES11.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        GLES11.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        GLES11.glDisable(GL10.GL_TEXTURE_2D);
        GLES11.glPopMatrix();
    }
  }
}

PolygonTriangulation.java - got from AssetFX - http://www.experts-exchange.com/Programming/Languages/Java/Q_27882746.html

public class PolygonTriangulation {

static final float EPSILON=0.0000000001f;

static public float Area(float[] contour) {
    int n = contour.length;
    float A = 0.0f;

    for(int p = n - 3, q = 0; q < n; p=q, q+=3)
    {
        A += contour[p] * contour[q+1] - contour[q] * contour[p+1];
    }
    return A * 0.5f;
}

static public boolean 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));
}

static public boolean Snip(float[] 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]];
    Ay = contour[V[u+1]];

    Bx = contour[V[v]];
    By = contour[V[v+1]];

    Cx = contour[V[w]];
    Cy = contour[V[w+1]];

    if ( EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) ){
        return false;
    }

    for (p = 0; p < n; p++)
    {
        if( (p == u/2) || (p == v/2) || (p == w/2) ){
            continue;
        }

        Px = contour[V[p*2]];
        Py = contour[V[(p*2)+1]];

        if (InsideTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)){
            return false;
        }
    }
    return true;
}

//Brings in 3D vertex float array but processes it as 2D only.
static public short[] Process(float[] contour) {
    //Pre-return list
    ArrayList<Integer> vertexArray = new ArrayList<Integer>();

    /* allocate and initialize list of Vertices in polygon */
    int n = contour.length;
    if ( n/3 < 3 )
        return null;

    //The (n/3)*2 occurs as we are removing the z coordinate from the mix
    int[] V = new int[(n/3)*2];

    /* we want a counter-clockwise polygon in V */
    if (0.0f < Area(contour)){
        for (int s = 0, v = 0; v < n-1; s+=2, v += 3){
            V[s] = v;
            V[s + 1] = v + 1;
        }
    }
    else{
        for(int s = 0, v = 0; v < n-1; s += 2, v += 3){
            V[s] = (n - 1) - (v + 2);
            V[s + 1] = (n - 1) - (v + 1);
        }
    }

    int nv = n/3;

    /*  remove nv-2 Vertices, creating 1 triangle every time */
    int count = 2 * nv;   /* error detection */

    for(int v = nv - 1; nv > 2;)
    {
        /* if we loop, it is probably a non-simple polygon */
        if (0 >= (count--))
        {
            //** Triangulate: ERROR - probable bad polygon!
            Log.e("PolygonTriangulation","Invalid Polygon");
            return null;
        }

        /* 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*2, v*2, w*2, nv, V))
        {
            vertexArray.add(V[u*2]/3);
            vertexArray.add(V[v*2]/3);
            vertexArray.add(V[w*2]/3);

            // remove v from remaining polygon
            for(int s = v * 2, t = (v * 2) + 2; t < (nv * 2); s += 2, t += 2){
                V[s] = V[t];
                V[s+1] = V[t+1];
            }
            nv--;

            // reset error detection counter
            count = 2 * nv;
        }
    }
    //Convert ArrayList into short array
    short[] index = new short[vertexArray.size()];
    for(int i = 0; i < vertexArray.size(); i++){
        index[i] = vertexArray.get(i).shortValue();
    }
    return index;
}
}
ElamParithi Arul
  • 377
  • 1
  • 11
  • 1
    I didn't try to understand the full code, but it looks like you always specify texture coordinates for only 4 vertices, while the number of vertices is variable. You need texture coordinates for all the vertices. – Reto Koradi Nov 18 '14 at 04:58
  • Thank you sooo much Reto, I've updated the function `setColor()` based on the number of vertices but still, the blue color is torn apart. I'm fairly new to Opengl, can you tell me where else I'm missing the number of co-ordinates? Thanks a lot in advance. – ElamParithi Arul Nov 18 '14 at 09:57

0 Answers0