草庐IT

android - Nexus 10 - 渲染到外部渲染目标仅适用于横向

coder 2023-12-17 原文

我们正在 Nexus 10 上使用 OpenGL ES 2.0 开发动态壁纸。

动态壁纸使用 2 个小型 (128x128) 外部帧缓冲区在它们之间进行乒乓渲染以模糊图像。

虽然这在任何设备上都运行良好(即使在旧的 Motorola Milestone 上),但 Nexus 10 存在一个奇怪的问题。仅当设备处于横向时才有效。如果设备在任何其他位置(90、180 或 270 度)旋转,则帧缓冲区只有清晰的颜色。我已将 glClearColor 设置为红色,因此可以清楚地看到这些帧缓冲区已被清除但没有任何渲染。

我已经在 Tegra 2、Tegra 3、Adreno 200、Adreno 320、2 个 PowerVR GPU 上对其进行了测试,它运行良好。

这看起来像是一些奇怪的驱动程序错误,但也可能是 Mali 驱动程序的一些细节。请指教。

代码摘录。

初始化帧缓冲区:

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

渲染到 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); 

在 2 个 FB 之间进行乒乓渲染以模糊图像:

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

测试应用程序以重现错误

您可以在这里下载测试 APK:https://dl.dropboxusercontent.com/u/7197208/LiveWallpaperAnimTest.apk 这是一个动态壁纸应用程序,安装它并选择“测试”动态壁纸(有一个带玫瑰的图标)。

如您所见,在默认横向模式下,您会在鸟周围看到一些“光晕”效果,这是通过 2 个帧缓冲区之间的乒乓渲染实现的。在任何其他设备方向上它都不起作用,并用清晰的颜色(红色)填充 FB。

附加链接

我也已将此问题发布到 Mali Developer CenterGoogle 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

最佳答案

Mali 驱动程序支持团队确认这是一个驱动程序错误,并将在下一个驱动程序版本中修复它。作为临时解决方法,他们建议在 glBindFramebuffer 之后调用 glViewport。 此解决方法有效 - 在更改调用顺序后,我设法实现了正确的渲染。

一旦固定驱动程序可用,我已建议 Google 联系 ARM 以包含用于 Nexus 10 的固定 OpenGL ES 驱动程序。如果有人愿意让这一切更快发生,您可以在 Android 错误跟踪器中给问题加注星标:http://code.google.com/p/android/issues/detail?id=57391

指向我已提交此问题的 Mali 开发人员中心论坛的链接: http://forums.arm.com/index.php?/topic/16894-nexus-10-render-to-external-rendertarget-works-only-in-landscape/

由于此驱动bug已被ARM验证确认,请您去star Android issue #57391而不是投票给这个 SO 问题。希望这会迫使谷歌关注问题并发布固件更新,让 Nexus 10 变得更好。这就是我为这个问题分配赏金的原因。

编辑。这个错误终于在 Android 4.4 中得到修复。

关于android - Nexus 10 - 渲染到外部渲染目标仅适用于横向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17403197/

有关android - Nexus 10 - 渲染到外部渲染目标仅适用于横向的更多相关文章

  1. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  2. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  3. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  4. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  5. ruby - 从外部访问类的实例变量 - 2

    我理解(我认为)Ruby中类变量和类的实例变量之间的区别。我想知道如何从该类外部访问该类的实例变量。从内部(即在类方法中而不是实例方法中),它可以直接访问,但是从外部,有没有办法做MyClass.class.[@$#]variablename?我没有任何具体原因要这样做,只是学习Ruby并想知道是否可行。 最佳答案 classMyClass@my_class_instance_var="foo"class上述yield:>>foo我相信Arkku演示了如何从类外部访问类变量(@@),而不是类实例变量(@)。我从这篇文章中提取了上述内

  6. 由于 libgmp.10.dylib 的问题,Ruby 2.2.0 无法运行 - 2

    我刚刚安装了带有RVM的Ruby2.2.0,并尝试使用它得到了这个:$rvmuse2.2.0--defaultUsing/Users/brandon/.rvm/gems/ruby-2.2.0dyld:Librarynotloaded:/usr/local/lib/libgmp.10.dylibReferencedfrom:/Users/brandon/.rvm/rubies/ruby-2.2.0/bin/rubyReason:Incompatiblelibraryversion:rubyrequiresversion13.0.0orlater,butlibgmp.10.dylibpro

  7. ruby - ri 有空文件 – Ubuntu 11.10, Ruby 1.9 - 2

    我正在运行Ubuntu11.10并像这样安装Ruby1.9:$sudoapt-getinstallruby1.9rubygems一切都运行良好,但ri似乎有空文档。ri告诉我文档是空的,我必须安装它们。我执行此操作是因为我读到它会有所帮助:$rdoc--all--ri现在,当我尝试打开任何文档时:$riArrayNothingknownaboutArray我搜索的其他所有内容都是一样的。 最佳答案 这个呢?apt-getinstallri1.8编辑或者试试这个:(非rvm)geminstallrdocrdoc-datardoc-da

  8. ruby-on-rails - gem install rmagick -v 2.13.1 错误 Failed to build gem native extension on Mac OS 10.9.1 - 2

    我已经通过提供MagickWand.h的路径尝试了一切,我安装了命令工具。谁能帮帮我?$geminstallrmagick-v2.13.1Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingrmagick:ERROR:Failedtobuildgemnativeextension./Users/ghazanfarali/.rvm/rubies/ruby-1.8.7-p357/bin/rubyextconf.rbcheckingforRubyversion>=1.8.5...yescheckingfor/

  9. ruby-on-rails - Rails 渲染带有驼峰命名法的 json 对象 - 2

    我在一个简单的RailsAPI中有以下Controller代码:classApi::V1::AccountsControllerehead:not_foundendendend问题在于,生成的json具有以下格式:{id:2,name:'Simpleaccount',cash_flows:[{id:1,amount:34.3,description:'simpledescription'},{id:2,amount:1.12,description:'otherdescription'}]}我需要我生成的json是camelCase('cashFlows'而不是'cash_flows'

  10. ruby - 无法安装 gem - make 未被识别为内部或外部命令可运行程序或批处理文件 - 2

    我想在Windows7上安装带有ruby​​1.9.3的rspec-railsgem。我收到一些错误消息,提示无法安装某些json库。所以,我使用下面的说明来解决它。来源=The'json'nativegemrequiresinstalledbuildtools从[rubyinstaller.org][3]下载[Ruby1.9.3][2]从[rubyinstaller.org][3]下载DevKit文件对于Ruby1.9.3,使用[DevKit-tdm-32-4.5.2-20110712-1620-sfx.exe][4]将DevKit解压到路径C:\Ruby193\DevKit运行cd

随机推荐