Framebuffer FBO render to textur ist sehr langsam, mit OpenGL ES 2.0 auf Android, warum?
Ich bin die Programmierung einer Android-2d-Spiel mit opengl es 2.0. Nachdem ich zeichne meine sprites zu den backbuffer ich zeichne leuchtet, um ein FBO und versuchen, mischen Sie es auf der Rückseite Puffer wieder.
Wenn ich zeichne die FBO in den framebuffer, auch trasparent ohne jede Farbe, die Frameraten drops von 60 auf 30 auf einem Samsung Galaxy w (es hat eine adreno 205 als gpu). Ich habe überall gesucht und alles ausprobiert, selbst wenn ich zeichnen Sie ein einzelnes sprite auf der Bühne und mischen Sie eine trasparent FBO-textur auf dem Bildschirm die framerate-drops. Ich habe versucht, andere Spiele mit Lichteffekten auf das Telefon, und Sie laufen gut, fast jedes Spiel ist gut auf das Telefon, ich glaube, Sie benutzen den framebuffer als gut.
Auf dem Galaxy SII (mali 400 gpu) läuft wunderbar, ich bin ganz neu in opengl so ich glaube ich mache irgendwo einen Fehler, ich Teile mein code.
//Create a framebuffer and renderbuffer
GLES20.glGenFramebuffers(1, fb, offset);
GLES20.glGenRenderbuffers(1, depthRb, offset);
//Create a texture to hold the frame buffer
GLES20.glGenTextures(1, renderTex, offset);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTex[offset]);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA,
screenWidth, screenHeight, 0,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE,
null);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_LINEAR);
//bind renderbuffer
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthRb[offset]);
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16,
screenWidth, screenHeight);
//bind the framebuffer
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[offset]);
//specify texture as color attachment
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D, renderTex[offset], 0);
//specify depth_renderbufer as depth attachment
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT,
GLES20.GL_RENDERBUFFER, depthRb[0]);
//Check FBO status.
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
if ( status == GLES20.GL_FRAMEBUFFER_COMPLETE )
{
Log.d("GLGame framebuffer creation", "Framebuffer complete");
}
//set default framebuffer
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
Ich mache das einmal an der Oberfläche der Schöpfung. Nicht sicher, ob richtig ist. Ich halte die textur-und framebuffer-ids zu wechseln, um Sie, wenn ich Sie brauche.
Meine Zeichnung-code:
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
ShaderProgram program = glgame.getProgram();
//put vertices in the floatbuffer
mTriangleVertices.put(vertices, 0, len);
mTriangleVertices.flip();
GLES20.glVertexAttribPointer(program.POSITION_LOCATION, 2, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
//preparing parameter for texture position
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
GLES20.glEnableVertexAttribArray(program.POSITION_LOCATION);
//preparing parameter for texture coords
GLES20.glVertexAttribPointer(program.TEXTURECOORD_LOCATION, 2, GLES20.GL_FLOAT,
false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES,
mTriangleVertices);
//set projection matrix
GLES20.glEnableVertexAttribArray(program.TEXTURECOORD_LOCATION);
GLES20.glUniformMatrix4fv(program.MATRIX_LOCATION, 1, false, matrix, 0);
//draw triangle with indices to form a rectangle
GLES20.glDrawElements(GLES20.GL_TRIANGLES, numSprites * 6, GLES20.GL_UNSIGNED_SHORT,
indicesbuf);
//clear buffers
mTriangleVertices.clear();
mVertexColors.clear();
Alles, was auf dem Bildschirm gerendert wird korrekt, aber die performance ruiniert werden, nur, wenn ich zeichne die FBO-textur.
Ich danke Ihnen sehr für Ihre Hilfe. Ich arbeitete sehr hart an diesem und nicht das finden einer Lösung.
Hmm... ich habe gesehen, einige Spiele auf dem Samsung Galaxy w läuft ohne Probleme und schien Sie verwenden einen framebuffer für 2d-Leuchten, mein code läuft langsam statt. Ich Frage mich, ob ich bin, Fehler zu machen.
galaxy verwendet sgx-Chipsatz. wie ich schon sagte, bevor seine zu kleinen gmem und Fliesen-Architektur, jedes mal, wenn u ändern Sie die framebuffer-alte brauche, um kopiert zu normalen mem, wenn Sie klar es Weg, wie ein Erster Anruf nach dem binden Sie nicht brauchen, um zurück kopiert werden aus normalen mem, gmem, das ist, warum Framebuffer sind langsam, vor allem auf adreno 200 🙂 können Sie prüfen, ist die app mit Framebuffer mit adreno profiler, wenn Sie haben, adreno Gerät, einfach einstecken und laden Sie aktuelle Bild, dann überprüfen Sie für die fb-Texturen. wenn Sie eines finden, werden Sie sicher sein,
und auf HD2 kommt auf den verwendeten Treiber in deinem build, ich habe eine 2.3.3 build und jeder fb binden erkannt wird, wie die Blockierung lösen und den gleichen code auf ics ist anerkannt als non-blocking beheben, und führen etwa 5-10 fps schneller. Ich denke, es kann in Bezug auf die Tatsache, dass qualcomm öffnete Ihre Treiber für die devs einige Zeit nach ics starten.
InformationsquelleAutor mao | 2012-05-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Laut qualcomm docs, müssen Sie glclear nach jedem glbindframebuffer, dies ist ein problem im Zusammenhang mit Fliesen-Architektur, wenn Sie wechseln Framebuffer, Daten müssen kopiert von fastmem zur normalen Speicher speichern der aktuellen framebuffer an und aus slowmem zu schnell mem um die Inhalte der neu gebundenen Rahmen, in Fall werden Sie bei der Lichtung nach glbind keine Daten kopiert von slowmem zu fastmem und sparen Sie Zeit, aber Sie brauchen, um das Design Ihrer render-pipeline oft, so wird es vermeiden, die Daten zu Lesen hin und her zwischen schnellen und langsamen Speicher, so versuchen, so zu tun glclear nach jedem binden, und es sollte helfen, Sie können auch verwenden, adreno profiler, um zusätzliche Informationen über problematische Anrufe, aber ich bezweifle, dass es helfen wird, mit adreno200 ich werde versuchen, zwei Puffer für die Unschärfe und ich am Ende mit 10fps, bindframebuffer Anruf kann bis zu 20msec, wenn Ihr nicht gelöscht, wenn es ist, es sollte bei 2ms.
Hier ist der qualcomm doc.
Wenn Sie möchten, zu bewahren den Inhalt der framebuffer, nur
glClear(0);
, das scheint auch das problem zu beheben.Vielen Dank für diese Antwort. Ist dieser qualcomm doc mehr vorhanden ist ?
Nun, es sieht aus wie es tut :). Prüfen Sie es einfach. Und es ist ziemlich logisch, da wenn der erste Schritt nach dem kopieren der Daten auf fmem ist zu löschen, dann brauchen Sie nicht, etwas zu kopieren. Die beste Antwort ist, benchmark, und wenn Sie das tun, dann werden Sie se, dass es die Dinge beschleunigen.
InformationsquelleAutor ZZZ