OpenGL ES drawArrays绘制顺序

时间:2015-11-20 23:34:10

标签: opengl-es

我试图在OpenGL ES中使用TRIANGLE_STRIP显示一个球体,但结果很奇怪。所以我想通过使用GL_LINES_STRIP仅绘制任何初始4个顶点来查看如何连接点。如果我分配4个顶点缓冲区或更多,结果是不同的。是什么原因?

顶点生成:

 for (float angleA = -90f; angleA <90; angleA += step) {


        float r1 = (float) Math.cos(angleA * deg);
        float r2 = (float) Math.cos((angleA + step) * deg);
        float h1 = (float) Math.sin(angleA * deg);
        float h2 = (float) Math.sin((angleA + step) * deg);

        // Fixed latitude, 360 degrees rotation to traverse a weft
        for (float angleB = 0f; angleB <= 360; angleB += step) {

            float cos = (float) Math.cos(angleB * deg);
            float sin = (float) Math.sin(angleB * deg);
            float dx, dy, dz, u, w;

            float[] pt1 = new float[3];
            float[] pt2 = new float[3];

            pt1[0] = Math.round((r2 * cos) * radius);// radius*r1*sin;
            pt1[1] = Math.round((h2) * radius);//radius*h1*sin;
            pt1[2] = Math.round((r2 * sin) * radius);//*10f;radius*cos;

            pt2[0] = Math.round((r1 * cos) * radius);//radius*r2*sin;
            pt2[1] = Math.round((h1) * radius);// radius*h2*sin;
            pt2[2] = Math.round((r1 * sin) * radius);//10f;radius*cos;


            vertexBuffer.put(pt1);
            Log.d("VERTEX", "a1=" + (angleA + step) + "a2=" + (angleB) + "[" + pt1[0] + "_" + pt1[1] + "_" + pt1[2] + "]");
            vertexBuffer.put(pt2);
            Log.d("VERTEX", "a1=" + (angleA) + "a2=" + angleB + "[" + pt2[0] + "_" + pt2[1] + "_" + pt2[2] + "]");
        }
    }

前4个创建的顶点是[1,0,0],[0,-1,0],[0,0,1]和[0,-1,0]。 所以我希望只看到2行GL_LINES_STRIP(最后一行与第二行相反)。 如果我分配大小为4的缓冲区并在顶点count = 4上打破循环,则呈现符合预期:

 int nbPts = 4;
    ByteBuffer bb = ByteBuffer.allocateDirect(nbPts * 3 * 4);
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();

绘图部分:

 mPositionHandle = GLES20.glGetAttribLocation(mProgram, "position");
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, COORDS_PER_VERTEX * floorPoints, vertexBuffer);
    GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, 4);

现在,如果我添加所有点int nbPts = (int)((180/step)*(360/step+1))*2;并让循环将所有点添加到缓冲区,则显示

的结果
GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, 4);

是2行(就像最后一点不是[0,-1,0])

1 个答案:

答案 0 :(得分:0)

用于此glVertexAttribPointer()调用的参数看起来有问题:

GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
    GLES20.GL_FLOAT, false, COORDS_PER_VERTEX * floorPoints, vertexBuffer);

第五个参数是步幅,即两个属性值之间的字节差异。只有顶点位置存储在缓冲区中,这对应于一个顶点位置的大小,即COORDS_PER_VERTEX GLfloat值。所以电话应该是:

GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
    GLES20.GL_FLOAT, GL_FALSE, COORDS_PER_VERTEX * sizeof(GLfloat), vertexBuffer);

只要该属性紧密包装,您也可以传递0以获得步幅:

GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
    GLES20.GL_FLOAT, GL_FALSE, 0, vertexBuffer);