How to display texture on rectangle made of six triangle strips (opengl es)

Viewed 293

Im looking for help with OpenGL ES 2.0. Every time when i try texturing rectangle made of more than 4 triangles, second and every next repeat of texture are broken. I mean, its stretched. Like on the picture below.

Example of stretching:

I was looking in internet for any solution of this but it doesn't help. Im think it maybe be a problem with texture coordinates or drawing.

class of triangle

public AdvencedRect(){
    vertices = new float[]{
            -2, 1, 0, //0
            -2, -1, 0, //1
            0, -1, 0, //2
            0, 1, 0, //3
            2, 1, 0, //4
            2, -1, 0 //5
    };
    texCoords = ARECT.TEXCOORDS;


    texBuffer = setFloatBuffer(new float[]{
            0,0,
            0,1,
            1,1,

            1,0,
            0,0,
            1,1
    });
    orderBuffer = setShortBuffer(new short[]{
            0, 1, 3, 2, 4, 5

    });
    verticesAmount = 6;
    objBuffer = setFloatBuffer(vertices);
}

It is how im drawing

public void draw(float[] vPMatrix, int program)
{
    setHandlers(program);
    float[] scratch = rotator.rotate(vPMatrix);

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texDataHandle);
    GLES20.glEnableVertexAttribArray(positionHandle);
    GLES20.glVertexAttribPointer(
            positionHandle,
            OBJ3D.VERTICEVERTEX,
            GLES20.GL_FLOAT,
            OBJ3D.NORMALIZED,
            OBJ3D.STRIDE,
            objBuffer
    );

    GLES20.glEnableVertexAttribArray(texCoordHandle);
    GLES20.glVertexAttribPointer(
            texCoordHandle,
            OBJ3D.TEXVERTEX,
            GLES20.GL_FLOAT,
            OBJ3D.NORMALIZED,
            0,
            texBuffer
    );

    GLES20.glUniform1f(xModifierHandle, xModifier);
    GLES20.glUniform1f(yModifierHandle, yModifier);

    GLES20.glUniformMatrix4fv(
            vPMatrixHandle,
            OBJ3D.COUNT,
            OBJ3D.TRANSPOSE,
            scratch,
            OBJ3D.OFFSET
    );

    GLES20.glDrawElements(
            GLES20.GL_TRIANGLE_STRIP,
            verticesAmount,
            GLES20.GL_UNSIGNED_SHORT,
            orderBuffer
    );

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glUniform1i(texUniformHandle, OBJ3D.X);

    GLES20.glDisableVertexAttribArray(texCoordHandle);
    GLES20.glDisableVertexAttribArray(positionHandle);
}
1 Answers

Note, the points in the middle have to be associated to the v coordinate 1, because its the right border of the left texture. But they also have to be associated to the v coordinate 0, because the next rectangle starts at this point and so it is the left border of the right texture, too.

 (-2, 1)   (0, 1)  (2, 1)
        +----+----+
        |   /|   /|
        |  / |  / |
        | /  | /  |
        |/   |/   |
        +----+----+
(-2, -1)  (0, -1)  (2, -1)
(0, 0)      (1, 0)  (0, 0)      (1, 0)
      +----+              +----+
      |   /|              |   /|
      |  / |              |  / |
      | /  |              | /  |
      |/   |              |/   |
      +----+              +----+
(0, 1)     (1, 1)   (0, 1)      (1, 1)

To achieve what you want, you've to increment the texture coordinates, too:

vertices = new float[]{
    -2,  1, 0, // 0
    -2, -1, 0, // 1
     0,  1, 0, // 2
     0, -1, 0, // 3
     2,  1, 0, // 4
     2, -1, 0  // 5
};

texBuffer = setFloatBuffer(new float[]{
    0, 0,
    0, 1,
    1, 0,
    1, 1,
    2, 0,
    2, 1
});

orderBuffer = setShortBuffer(new short[]{
    0, 1, 2, 3, 4, 5
});

Note, now the v coordinates for the 1st textured rectangle are in range [0, 1] and the v coordinate for the 2nd textured rectangle are in range [1, 2].

(0, 0)  (0, 1)  (0, 2)
     +----+----+
     |   /|   /|
     |  / |  / |
     | /  | /  |
     |/   |/   |
     +----+----+
(0, 1)  (1, 1)  (1, 2)

The texture parameter GL_TEXTURE_WRAP_T has to be set to GL_REPEAT to make this work. See glTexParameter.

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texDataHandle);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
Related