在我的OpenGL ES Android游戏中,我正在尝试根据其z值(即z平面中的位置)以连续顺序绘制形状。这意味着首先绘制最小的最远的形状(纹理)然后绘制更大的形状。我已将形状属性存储在arraylist中,并且在绘制和更新时我使用的是迭代器。假设这是带有z值的arrayList(只是一个例子)
ArrayList arraylistBricks
Form::open(array('url' => '/uploaded/'.$client->id,'files' => true)) !!}
我使用Collections.sort(..)为每一帧排序这个arrayList,排序后列表看起来像这样
obj (0) ... z = -20
obj (1) ... z = -37
obj (2) ... z = -31
obj (3) -...z = -20
即 - 最小的形状首先在列表中,并且首先被绘制。我可以看到arraylist真的是排序但不知何故没有发生。我想要的是较小的形状应该在较大的形状后面。 GPU是否有某种绘图顺序?我刚刚从skia迁移到opengl并对此感到惊讶。
我在这里想念什么?我怎么能解决这个问题?
obj (0) ... z = -37
obj (1) ... z = -31
obj (2) ... z = -20
obj (3) -...z = -20
render-method
private void drawShape() {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboDataListLevelSprites.get(iName).getBuff_id_vertices());
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, 0);
for (int i = 0; i < BrickProperties.get_buff_id_uvs().length; i++) {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, BrickProperties.get_buff_id_uvs()[i]);
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 0, 0);
for (Iterator<BrickProperties> shapeIterator = arrayListBricks.iterator(); shapeIterator.hasNext(); ) {
BrickProperties bp = shapeIterator.next();
int buffIndexVal = bp.get_status_diff();
if (buffIndexVal == i) {
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, bp.getTranslateData()[0], bp.getTranslateData()[1], bp.getTranslateData()[2]);
if (bp.get_status() == 0) {
Matrix.rotateM(mModelMatrix, 0, bp.getAngleInDegrees(), 0, 1, 0);
}
render();
}
}
}
}
更新(摘录)
private void render() {
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
}
答案 0 :(得分:0)
OpenGL ES 2具有内置深度测试功能。您可以使用glEnable(GL_DEPTH_TEST)
启用它。
不要忘记每帧清除缓冲区(或者如果使用OpenGL ES 3,则验证帧缓冲区)。
答案 1 :(得分:0)
不要这样做 - 你会失去早期zs测试的所有好处,以便在被遮挡之前杀死被遮挡的碎片。这意味着首先绘制最小的最远的形状(纹理)然后绘制较大的形状。
以前后渲染顺序渲染不透明片段(启用深度测试,启用深度写入),然后以后向前渲染顺序渲染透明顶层(启用深度测试,禁用深度写入)。 / p>