如何在由六个三角形条组成的矩形上显示纹理(opengl es)

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

我正在寻求有关 OpenGL ES 2.0 的帮助。每次当我尝试对由 4 个以上的三角形组成的矩形进行纹理处理时,第二次和每次重复的纹理都会被破坏。我的意思是,它被拉长了。就像下图一样。

拉伸示例:

我在互联网上寻找任何解决方案,但没有帮助。我认为这可能是纹理坐标或绘图的问题。

class 三角形

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);
}

我就是这样画的

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);
}

注意,中间的点必须关联到v坐标1,因为它是左纹理的右边界。但它们也必须与 v 坐标 0 相关联,因为下一个矩形从该点开始,因此它也是右纹理的左边界。

 (-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)

要实现您想要的效果,您还必须增加纹理坐标:

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
});

注意,现在第一个纹理矩形的 v 坐标在 [0, 1] 范围内,而第一个纹理矩形的 v 坐标第二个纹理矩形在 [1, 2].

范围内
(0, 0)  (0, 1)  (0, 2)
     +----+----+
     |   /|   /|
     |  / |  / |
     | /  | /  |
     |/   |/   |
     +----+----+
(0, 1)  (1, 1)  (1, 2)

必须将纹理参数 GL_TEXTURE_WRAP_T 设置为 GL_REPEAT 才能使其生效。参见 glTexParameter

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