Programuję grę Android 2d używając opengl es 2.0. Po narysowaniu moich duszków do bufora wstecznego rysuję światła do FBO i próbuję ponownie wtopić je w bufor powrotny. Kiedy rysuję FBO do framebuffera, nawet trasparent bez żadnego koloru, ilość klatek na sekundę spada z 60 na 30 na Samsung Galaxy w (ma adreno 205 jako gpu). Szukałem wszędzie i próbowałem wszystkiego, nawet jeśli narysowałem pojedynczy obraz na scenie i wstawiłem przezroczystą teksturę FBO na ekran, w którym liczba klatek na sekundę spada. Próbowałem innych gier z efektami świetlnymi na tym telefonie i działają dobrze, prawie każda gra jest w porządku na tym telefonie, wierzę, że używają również bufora ramki. Na Galaxy SII (mali 400 gpu) działa dobrze, jestem całkiem nowy na opengl, więc wierzę, że gdzieś popełniam błąd, dzielę się moim kodem.Replikacja ramek FBO do tekstury jest bardzo powolna, używając OpenGL ES 2.0 na Androida, dlaczego?
// 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);
Robię to raz przy tworzeniu powierzchni. Nie jestem pewien, czy jest poprawny. Zachowuję teksturę i identyfikatory bufora ramki, aby przełączać się do nich, gdy tego potrzebuję. Mój kod rysunek:
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();
Wszystko staje się prawidłowo na ekranie, ale wydajność jest zniszczony tylko kiedy narysować FBO tekstury. Dziękuję bardzo za pomoc. Pracowałem nad tym bardzo ciężko i nie znalazłem rozwiązania.
Późna odpowiedź, ale robię coś podobnego na HD2 pod ICS i to prawie tak samo. Mogę renderować wszystko bez problemu przy 60 klatkach na sekundę, ale kiedy używam FBO, liczba klatek spada do 45, a jeśli używam innego FBO to spada do 30. –
Hmm ... Widziałem kilka gier na Samsunga Galaxy bez problemu działało i wydawało się, że używają bufora ramki do oświetlenia 2d, mój kod działa powoli. Zastanawiam się, czy robię błędy. – mao
galaxy używa chipsetu sgx. tak jak powiedziałem przed jego związkiem z małą architekturą gmem i kaflami, za każdym razem, gdy zmieniasz framebuffer stary, musisz zostać skopiowany do zwykłego memu, jeśli usuniesz go jako pierwsze po wywołaniu, nie trzeba go kopiować z powrotem z normalnego mem do gmem, to dlatego framebuffery są powolne, szczególnie na adreno 200 :) możesz sprawdzić aplikację używając framebufferów z profilerem adreno, jeśli masz urządzenie adreno, po prostu podłącz je i pobierz aktualną ramkę, następnie sprawdź fb w teksturach. jeśli znajdziesz taki, będziesz pewny, – ZZZ