2013-07-01 12 views
5

Chúng tôi đang phát triển nền sống với OpenGL ES 2.0 trên Nexus 10Nexus 10 - trả cho rendertarget bên ngoài chỉ hoạt động trong phong cảnh

Live Wallpaper sử dụng 2 nhỏ (128x128) framebuffers bên ngoài để làm cho ping-pong vẽ giữa chúng làm mờ hình ảnh.

Mặc dù tính năng này hoạt động hoàn hảo trên mọi thiết bị (ngay cả trên Motorola Milestone tuổi) có vấn đề lạ với Nexus 10. Điều này chỉ hoạt động nếu thiết bị đang ở hướng ngang. Nếu thiết bị được xoay ở bất kỳ vị trí nào khác (90, 180 hoặc 270 độ), các bộ đệm khung chỉ có màu sắc rõ ràng. Tôi đã đặt glClearColor thành màu đỏ để hiển thị rõ ràng rằng các bộ đệm khung này bị xóa nhưng không có gì được hiển thị vào chúng.

Tôi đã thử nghiệm nó trên Tegra 2, Tegra 3, Adreno 200, Adreno 320, 2 PowerVR GPU và nó hoạt động tốt.

Điều này trông giống như một số lỗi trình điều khiển lạ, nhưng cũng có thể là một số chi tiết cụ thể của trình điều khiển Mali. Làm ơn cho lời khuyên.

Trích đoạn mã.

Init framebuffers:

private void initBloomStuff() { 
    mBloomTextureID = loadTexture("textures/empty128.png"); 
    mBloomVertTextureID = loadTexture("textures/empty128.png"); 

    mBloomFBHeight = 128; 
    mBloomFBWidth = 128; 

    float blurSize = 1.0f; 

    // Texel offset for blur filter kernel 
    m_fTexelOffset = 1.0f/mBloomFBWidth/blurSize; 

    ByteBuffer tmpFB, tmpRB; 
    IntBuffer handle, renderbuffers; 
    int result; 

    tmpFB = ByteBuffer.allocateDirect(4); 
    tmpFB.order(ByteOrder.nativeOrder()); 
    handle = tmpFB.asIntBuffer(); 
    GLES20.glGenFramebuffers(1, handle); 
    framebufferHandle = handle.get(0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBloomTextureID); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebufferHandle); 
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mBloomTextureID, 0); 

    checkGlError("FB 1"); 
    tmpRB = ByteBuffer.allocateDirect(4); 
    renderbuffers = tmpRB.asIntBuffer(); 
    GLES20.glGenRenderbuffers(1, renderbuffers); 
    checkGlError("FB 1 - glGenRenderbuffers"); 
    depthbufferHandle = renderbuffers.get(0); 
    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthbufferHandle); 
    checkGlError("FB 1 - glBindRenderbuffer"); 
    GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, mBloomFBWidth, mBloomFBHeight); 
    checkGlError("FB 1 - glRenderbufferStorage"); 
    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthbufferHandle); 
    checkGlError("FB 1 - glFramebufferRenderbuffer"); 

    result = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); 
    if (result != GLES20.GL_FRAMEBUFFER_COMPLETE) { 
     Log.d(TAG, "Error creating framebufer 1: " + result); 
    } else { 
     Log.d(TAG, "Created framebufer 1: " + result); 
    } 

    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, 0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 

    tmpFB = ByteBuffer.allocateDirect(4); 
    tmpFB.order(ByteOrder.nativeOrder()); 
    handle = tmpFB.asIntBuffer(); 
    GLES20.glGenFramebuffers(1, handle); 
    framebufferVertHandle = handle.get(0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBloomVertTextureID); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebufferVertHandle); 
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mBloomVertTextureID, 0); 

    checkGlError("FB 2"); 
    tmpRB = ByteBuffer.allocateDirect(4); 
    renderbuffers = tmpRB.asIntBuffer(); 
    GLES20.glGenRenderbuffers(1, renderbuffers); 
    checkGlError("FB 2 - glGenRenderbuffers"); 
    depthbufferVertHandle = renderbuffers.get(0); 
    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthbufferVertHandle); 
    checkGlError("FB 2 - glBindRenderbuffer"); 
    GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, mBloomFBWidth, mBloomFBHeight); 
    checkGlError("FB 2 - glRenderbufferStorage"); 
    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthbufferVertHandle); 
    checkGlError("FB 2 - glFramebufferRenderbuffer"); 

    result = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); 
    if (result != GLES20.GL_FRAMEBUFFER_COMPLETE) { 
     Log.d(TAG, "Error creating framebufer 2: " + result); 
    } else { 
     Log.d(TAG, "Created framebufer 2: " + result); 
    } 

    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, 0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 

    mTriangleVerticesVignette = ByteBuffer.allocateDirect(mQuadTriangles.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
    mTriangleVerticesVignette.put(mQuadTriangles).position(0); 
} 

Render để FB:

GLES20.glUseProgram(mProgram); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mStemTextureID); 
    drawBird(); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mSphereTextureID); 
    drawSphere(); 

    GLES20.glViewport(0, 0, mBloomFBWidth, mBloomFBHeight); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebufferHandle); 
    // GLES20.glBindRenderbuffer(GLES20.GL_FRAMEBUFFER, depthbufferHandle); 

    GLES20.glClearColor(1.0f, 0.5f, 0.5f, 1.0f); 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mStemTextureID); 
    drawBird(); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mSphereTextureID); 
    drawSphere(); 

    GLES20.glViewport(0, 0, screenWidth, screenHeight); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 
    // GLES20.glBindRenderbuffer(GLES20.GL_FRAMEBUFFER, 0); 

Ping-pong vẽ giữa 2 FBS để làm mờ hình ảnh:

GLES20.glUseProgram(mBloomProgram); 
    GLES20.glUniform1i(mBloom_sTexture, 0); 
    GLES20.glUniform1f(mBloom_bloomFactor, 0.8f); 

    GLES20.glActiveTexture(GL10.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBloomTextureID); 
    GLES20.glViewport(0, 0, mBloomFBWidth, mBloomFBHeight); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebufferVertHandle); 
    GLES20.glUniform1f(mBloom_TexelOffsetX, m_fTexelOffset); 
    GLES20.glUniform1f(mBloom_TexelOffsetY, 0.0f); 
    GLES20.glActiveTexture(GL10.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBloomTextureID); 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
    drawBloom(); 
    GLES20.glViewport(0, 0, screenWidth, screenHeight); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 

    GLES20.glActiveTexture(GL10.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBloomVertTextureID); 
    GLES20.glViewport(0, 0, mBloomFBWidth, mBloomFBHeight); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebufferHandle); 
    GLES20.glUniform1f(mBloom_TexelOffsetX, 0.0f); 
    GLES20.glUniform1f(mBloom_TexelOffsetY, m_fTexelOffset); 
    GLES20.glActiveTexture(GL10.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBloomVertTextureID); 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
    drawBloom(); 
    GLES20.glViewport(0, 0, screenWidth, screenHeight); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 

    GLES20.glActiveTexture(GL10.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBloomTextureID); 
    GLES20.glViewport(0, 0, mBloomFBWidth, mBloomFBHeight); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebufferVertHandle); 
    GLES20.glUniform1f(mBloom_TexelOffsetX, m_fTexelOffset/2); 
    GLES20.glUniform1f(mBloom_TexelOffsetY, m_fTexelOffset/2); 
    GLES20.glActiveTexture(GL10.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBloomTextureID); 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
    drawBloom(); 
    GLES20.glViewport(0, 0, screenWidth, screenHeight); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 

ứng dụng thử nghiệm để tái tạo lỗi

Bạn có thể tải APK thử nghiệm tại đây: https://dl.dropboxusercontent.com/u/7197208/LiveWallpaperAnimTest.apk Đây là ứng dụng hình nền động, cài đặt ứng dụng và chọn 'Thử nghiệm' hình nền động (có biểu tượng có hoa hồng).

Như bạn có thể thấy, theo hướng ngang mặc định, bạn sẽ thấy một số hiệu ứng 'nở' xung quanh chim được thực hiện bằng cách hiển thị bóng bàn giữa 2 bộ đệm khung. Trong bất kỳ định hướng thiết bị nào khác, nó không hoạt động và lấp đầy FB bằng màu sắc rõ ràng (màu đỏ).

liên kết bổ sung

Tôi cũng đăng tải vấn đề này để Center Mali DeveloperGoogle Code:

http://forums.arm.com/index.php?/topic/16894-nexus-10-render-to-external-rendertarget-works-only-in-landscape/

http://code.google.com/p/android/issues/detail?id=57391

Trả lời

1

Mali hỗ trợ tài xế đội xác nhân rằng đây là lỗi trình điều khiển và sẽ khắc phục trong phiên bản trình điều khiển tiếp theo. Để giải quyết tạm thời, họ đề nghị gọi glViewport sau glBindFramebuffer. Cách giải quyết này hoạt động - sau khi thay đổi thứ tự cuộc gọi, tôi đã quản lý để đạt được kết xuất chính xác.

Tôi đã đề xuất Google liên hệ với ARM để bao gồm trình điều khiển OpenGL ES cố định cho Nexus 10 ngay sau khi có sẵn trình điều khiển cố định.Nếu bất cứ ai sẵn sàng cho điều này xảy ra nhanh hơn, bạn có thể sao một vấn đề trong bug tracker Android: http://code.google.com/p/android/issues/detail?id=57391

Liên kết đến Mali diễn đàn Trung tâm Nhà phát triển nơi mà tôi đã nộp vấn đề này: http://forums.arm.com/index.php?/topic/16894-nexus-10-render-to-external-rendertarget-works-only-in-landscape/

Như lỗi trình điều khiển này là đã được xác minh và xác nhận bởi ARM, vui lòng truy cập và gắn dấu sao Android issue #57391 thay vì bỏ phiếu cho câu hỏi SO này. Hy vọng rằng điều này sẽ buộc Google chú ý đến vấn đề và phát hành bản cập nhật chương trình cơ sở, cải thiện Nexus 10. Đây là lý do tôi đã chỉ định tiền thưởng cho câu hỏi này.

EDIT. Lỗi này cuối cùng đã được khắc phục trong Android 4.4.

Các vấn đề liên quan