我的目标是在 openGl 中重新创建气泡图的实现,使其变得更快。作为参考,当前实现使用画布以 8 fps 运行。它在安卓手机的屏幕上绘制了 5200 个圆圈。它们实时改变颜色、大小和位置。
我曾尝试对它们进行精灵批处理,但由于某种未知原因,我一次无法批处理超过 15 个。然后我尝试将它们全部放入带纹理的矩形中,但是构建网格需要很长时间,即使我不在两次绘制之间更改它,它也很慢。
现在,我认为可以优化很多我当前的着色器,但我缺乏太多的知识来做这件事。
一个可能需要优化的地方是网格生成,目前它是这样的:x, y, z, r, g, b, a, tx, ty, x, y, z, .... where (x, y , z) 是顶点位置, (r, g, b, a) 是颜色, (tx, ty) 是纹理坐标,但是 (z, r, g, b, a) 在相同的所有顶点上相等正方形。(tx, ty) 对于顶点 1 始终为 0,0;1, 0 代表顶点 2,依此类推...
此外,每个正方形有 6 个顶点而不是 4 个,因为同一个网格有分离的正方形
我的顶点着色器:
uniform mat4 uMVPMatrix;
attribute vec4 aPosition;
attribute vec4 aColor;
attribute vec4 aTexCoordinate;
varying vec2 vTexCoordinate;
varying vec4 vColor;
void main() {
vColor = aColor;
vTexCoordinate = aTexCoordinate.xy;
gl_Position = uMVPMatrix * aPosition;
}
我的片段着色器:
private final String FragmentShaderCode =
precision mediump float;
uniform sampler2D u_Texture;
varying vec4 vColor;
varying vec2 vTexCoordinate;
void main() {
gl_FragColor = texture2D(u_Texture, vTexCoordinate) *vColor;
}
我真的不明白着色器代码是如何翻译成“在这里绘制这种颜色”的,所以我真的无法想象我应该如何解决这些冗余问题。
编辑/更新:
事实证明,有两种(不相关的?)方法导致速度变慢。EGLImpl.eglSwapBuffers 和 GLES20.glClear。但是,如果我不绘制 5200 个方格,这些方法不会导致减速。根据这篇文章,它是由着色器引起的(如果我不绘制 5200 个三角形,它就不会发生),不幸的是,发帖人忘记告诉着色器做了什么导致这些方法变慢。
更新 2,绘制代码,但不确定它是否有帮助
public void draw(float[] mvpMatrix) {
if (!isPacked) {
pack();
}
GLES20.glUseProgram(GlProgram);
// ////////////////////
int mTextureUniformHandle = GLES20.glGetUniformLocation(GlProgram, "u_Texture");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
GLES20.glUniform1i(mTextureUniformHandle, 0);
// ///////////////////////
VertexBuffer.position(0);
int PositionHandle = GLES20.glGetAttribLocation(GlProgram, "aPosition");
GLES20.glEnableVertexAttribArray(PositionHandle);
GLES20.glVertexAttribPointer(PositionHandle, 3, GLES20.GL_FLOAT, false, (3 + 4 + 2) * 4, VertexBuffer);
// ///////////////
VertexBuffer.position(3);
int ColorHandle = GLES20.glGetAttribLocation(GlProgram, "aColor");
GLES20.glEnableVertexAttribArray(ColorHandle);
GLES20.glVertexAttribPointer(ColorHandle, 4, GLES20.GL_FLOAT, false, (3 + 4 + 2) * 4, VertexBuffer);
// /////////////////
VertexBuffer.position(7);
int TexCoordinate = GLES20.glGetAttribLocation(GlProgram, "aTexCoordinate");
GLES20.glEnableVertexAttribArray(TexCoordinate);
GLES20.glVertexAttribPointer(TexCoordinate, 2, GLES20.GL_FLOAT, false, (3 + 4 + 2) * 4, VertexBuffer);
// /////////////////
int MVPMatrixHandle = GLES20.glGetUniformLocation(GlProgram, "uMVPMatrix");
GLES20.glUniformMatrix4fv(MVPMatrixHandle, 1, false, mvpMatrix, 0);
// /////////////
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, totalvertz);
GLES20.glDisableVertexAttribArray(PositionHandle);
GLES20.glDisableVertexAttribArray(ColorHandle);
GLES20.glDisableVertexAttribArray(TexCoordinate);
}