我试图在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])
答案 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);