我有一个点类,它使用缓冲区绘制一些点。我希望能够改变所绘制内容的内容(用新点更新场景)。重新创建一个全新的对象听起来并不好,所以我一直试图改变缓冲区的内容。最近我发现了glBufferSubData()
,但我不知道如何使用它。
这是我的观点类:
public class Point {
private int mProgram, mPositionHandle, mColorHandle, mMVPMatrixHandle;
private FloatBuffer vertexBuffer,colorBuffer;
private static final int COORDS_PER_VERTEX = 3;
private static final int COORDS_PER_COLOR = 3;
private int vertexCount,colorCount;
private final String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"attribute mediump vec4 vColor;" +
"varying mediump vec4 vaColor;" +
"void main() {" +
" vaColor = vColor;" +
" gl_Position = uMVPMatrix * vPosition;" +
" gl_PointSize = 20.0;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"varying mediump vec4 vaColor;" +
"void main() {" +
" gl_FragColor = vaColor;" +
"}";
private static int vertexStride = COORDS_PER_VERTEX * 4;
private final int colorStride = COORDS_PER_COLOR * 4;
public Point(float pointCoords[],float colorCoords[]){
this.vertexCount = pointCoords.length / COORDS_PER_VERTEX;
this.colorCount = colorCoords.length / COORDS_PER_COLOR;
ByteBuffer vbb = ByteBuffer.allocateDirect(pointCoords.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(pointCoords);
vertexBuffer.position(0);
ByteBuffer cbb = ByteBuffer.allocateDirect(colorCoords.length * 4);
cbb.order(ByteOrder.nativeOrder());
colorBuffer = cbb.asFloatBuffer();
colorBuffer.put(colorCoords);
colorBuffer.position(0);
int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
// create empty OpenGL ES Program
mProgram = GLES20.glCreateProgram();
// create empty OpenGL ES Program
mProgram = GLES20.glCreateProgram();
// add the vertex shader to program
GLES20.glAttachShader(mProgram, vertexShader);
// add the fragment shader to program
GLES20.glAttachShader(mProgram, fragmentShader);
// creates OpenGL ES program executables
GLES20.glLinkProgram(mProgram);
}
public void draw(float[] mvpMatrix) {
// Add program to OpenGL ES environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the point coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
mColorHandle = GLES20.glGetAttribLocation(mProgram,"vColor");
GLES20.glEnableVertexAttribArray(mColorHandle);
// Set color for drawing the triangle
GLES20.glVertexAttribPointer(mColorHandle, COORDS_PER_COLOR, GLES20.GL_FLOAT, false,
colorStride, colorBuffer);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//TRANSLATION
float[] transMatrix = new float[16];
Matrix.setIdentityM(transMatrix,0);
Matrix.translateM(transMatrix,0,0.5f,0,0);
Matrix.multiplyMM(transMatrix,0,mvpMatrix,0,transMatrix,0);
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, vertexCount);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
/**
* Change content of buffer
*/
public void changeBufferData(float[] newBufferInfo) {
GLES20.glBufferSubData(?,0,newBufferInfo.length*4,vertexBuffer);
}
}
答案 0 :(得分:0)
您目前正在使用客户端顶点数组,其中每个绘图使用glVertexAttribPointer
上传数据。动态更新它不会比你现在做的更昂贵,因为你已经不得不为每次绘制操作分配和复制数据到驱动程序拥有的内存中。
但是,正如您所说,重新创建缓冲区是昂贵的,因此强烈建议避免客户端顶点上传...
您缺少的部分是需要创建顶点缓冲区对象(glGenBuffers
等),然后您可以使用它而不是客户端属性。 glBufferData
和glSubBufferData
用于修补其中一个缓冲区对象的内容。