0

私の目的は、openGl でバブル チャートの実装を再作成して、高速化することです。参考までに、現在の実装はキャンバスを使用して 8 fps で実行されます。Androidフォンの画面に5200個の円を描きます。色、サイズ、位置がリアルタイムで変化します。

それらをスプライト バッチしようとしましたが、何らかの理由で一度に 15 個以上をバッチ処理できません。次に、それらすべてをテクスチャ付きの長方形に入れようとしましたが、メッシュの構築には時間がかかり、描画間で変更しなくても遅くなります。

現時点では、現在のシェーダーを最適化することは可能だと思いますが、それを行うにはあまりにも多くの知識が不足しています。

最適化する可能性のある場所の 1 つは、メッシュ生成です。現在、次のようになっています: x、y、z、r、g、b、a、tx、ty、x、y、z、.... (x、y , z) は頂点の位置、(r, g, b, a) は色、(tx, ty) はテクスチャ座標ですが、(z, r, g, b, a) は同じ座標のすべての頂点で等しくなります。四角。(tx, ty) は、頂点 1 に対して常に 0,0 です。頂点 2 の場合は 1、0 など...

また、各正方形には 4 つではなく 6 つの頂点があります。これは、同じメッシュに分離した正方形があるためです。

私の頂点シェーダー:

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;
}

シェーダー コードが「ここにこの色を描画する」にどのように変換されるのかよくわかりません。そのため、これらの冗長性の問題をどのように解決すればよいのか想像できません。

編集/更新:

プロファイラーのスクリーンキャプチャ

速度低下の原因となる 2 つの (関係のない?) メソッドがあることが判明しました。EGLImpl.eglSwapBuffers および GLES20.glClear。ただし、5200 の正方形を描画しなければ、これらの方法で速度が低下することはありません。この投稿によると、シェーダーが原因です (5200 の三角形を描画しないと発生しません)。残念ながら、ポスターは、これらのメソッドが遅くなる原因となったシェーダーの動作を伝えるのを忘れていました。

Update 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);
}
4

1 に答える 1

1

5200 個のクワッドを描画するのは簡単です。正しく実装されていれば、どのデバイスでもスムーズに動作するはずです。

シェーダーは単純すぎて最適化できません。ここでできることはほとんどありません。

先に進む前に、OpenGL エラーを確認しましたか? ( glGetError() == 0?) これらは、フレームレートの大幅な低下を引き起こす可能性があります。

編集:他にもいくつか考えられることがありますが、コードを見ないと難しいです:

  • FloatBuffers を効率的に使用していますか?
  • フレームごとに新しい頂点バッファーを作成しないようにしていますか?
  • すべてのクワッドは 1 つのメッシュ内にある必要があります。これは、1 つのドロー コールを意味します。これは事実ですか?
于 2013-09-06T20:00:26.790 に答える