解决android opengl glReadPixels 慢的问题一

2023-05-16

解决android opengl glReadPixels 慢的问题

由于android的gpu跟cpu内存是分离的,导致数据拷贝的过程中会非常慢,网上资料相对较少,下面是我解决这个问题的一点心的,使用PBO代码如下

1.  初始化纹理方法

public static int loadTexture(final Bitmap img, final int usedTexId, int i) {
		if(img == null)
			return NO_TEXTURE;
		
//		ByteBuffer img_buffer = ByteBuffer.allocate(img.getByteCount());
//		img.copyPixelsToBuffer(img_buffer);
		ByteBuffer pbo_point = null;
        int textures[] = new int[1];
        if (usedTexId == NO_TEXTURE) {
            GLES30.glGenTextures(1, textures, 0);
            GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textures[0]);
            GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D,
                    GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
            GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D,
                    GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR);
            GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D,
                    GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
            GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D,
                    GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
            GLES30.glGenBuffers(1, pbo);
            GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, pbo.get(0));
            GLES30.glBufferData(GLES30.GL_PIXEL_PACK_BUFFER,width*height*4, null, GLES30.GL_DYNAMIC_READ);
            GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, 0);
             GLUtils.texImage2D(GLES30.GL_TEXTURE_2D, 0, img, 0);
        } 
        else {
        	  GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, usedTexId);
//        	  GLUtils.texSubImage2D(GLES30.GL_TEXTURE_2D, 0, 0, 0, img);
              textures[0] = usedTexId;
        }
        return textures[0];
    }

2. 初始化PBO


  

  
public static int loadFramebuffer(int texture, int width,int height){
	
		IntBuffer framebuffer = IntBuffer.allocate(1);
		IntBuffer depthRenderbuffer = IntBuffer.allocate(1);
		IntBuffer max = IntBuffer.allocate(10);
		int temp = 0;
		GLES30.glGetIntegerv(GLES30.GL_MAX_RENDERBUFFER_SIZE, max);
		temp = max.get(0);
		if (temp <= width && temp <= height)
		{
			return -1;
		}
		GLES30.glGenFramebuffers(1, framebuffer);
		GLES30.glGenRenderbuffers(1, depthRenderbuffer);
		GLES30.glBindRenderbuffer(GLES30.GL_RENDERBUFFER, depthRenderbuffer.get(0));
		GLES30.glRenderbufferStorage(GLES30.GL_RENDERBUFFER, GLES30.GL_RGBA, width, height);
		
		GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, framebuffer.get(0));
		GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, texture, 0);
		GLES30.glFramebufferRenderbuffer(GLES30.GL_FRAMEBUFFER,GLES30.GL_DEPTH_ATTACHMENT, GLES30.GL_RENDERBUFFER, depthRenderbuffer.get(0));
		
		int status = 0;
		status = GLES30.glCheckFramebufferStatus(GLES30.GL_FRAMEBUFFER);
		if (status == GLES30.GL_FRAMEBUFFER_COMPLETE){
			Log.d(TAG,"frame buffer init ok!!!!!!!");
			GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, 0);
			GLES30.glDeleteRenderbuffers(1, depthRenderbuffer);
			GLES30.glDeleteFramebuffers(1, framebuffer);
			return framebuffer.get();
		}
		Log.d(TAG,"frame buffer init file!!!!!!!");
		return -1;
		
	}

3.  surface creat 初始化

public void onSurfaceCreated ( GL10 glUnused, EGLConfig config )
   {
      String vShaderStr =
    		  "attribute vec4 position;\n" +
            "attribute vec4 inputTextureCoordinate;\n" +
            " \n" +
            "varying vec2 textureCoordinate;\n" +
            " \n" +
            "void main()\n" +
            "{\n" +
            "    gl_Position = position;\n" +
            "    textureCoordinate = inputTextureCoordinate.xy;\n" +
            "}";           

      String fShaderStr =
          "precision highp float;					  	\n"
		 + "varying highp vec2 textureCoordinate;\n"
		 +  "uniform sampler2D inputImageTexture;\n"
         + "void main()                                  \n"
         + "{                                            \n"
         + "  gl_FragColor = texture2D(inputImageTexture, textureCoordinate);	\n"
         + "}                                            \n";

      int vertexShader;
      int fragmentShader;
      int programObject;
      int[] linked = new int[1];

      // Load the vertex/fragment shaders
      vertexShader = LoadShader ( GLES30.GL_VERTEX_SHADER, vShaderStr );
      fragmentShader = LoadShader ( GLES30.GL_FRAGMENT_SHADER, fShaderStr );

      // Create the program object
      programObject = GLES30.glCreateProgram();

      if ( programObject == 0 )
      {
         return;
      }

      GLES30.glAttachShader ( programObject, vertexShader );
      GLES30.glAttachShader ( programObject, fragmentShader );

      // Bind vPosition to attribute 0
      GLES30.glBindAttribLocation ( programObject, 0, "vPosition" );

      // Link the program
      GLES30.glLinkProgram ( programObject );

      // Check the link status
      GLES30.glGetProgramiv ( programObject, GLES30.GL_LINK_STATUS, linked, 0 );

      if ( linked[0] == 0 )
      {
    	 Log.e ( TAG, vShaderStr );
    	 Log.e ( TAG, fShaderStr );
         Log.e ( TAG, "Error linking program:" );
         Log.e ( TAG, GLES30.glGetProgramInfoLog ( programObject ) );
         GLES30.glDeleteProgram ( programObject );
         return;
      }

      // Store the program object
      mProgramObject = programObject;
       mGLAttribPosition = GLES30.glGetAttribLocation(programObject, "position");
       mGLUniformTexture = GLES30.glGetUniformLocation(programObject, "inputImageTexture");
       mGLAttribTextureCoordinate = GLES30.glGetAttribLocation(programObject,
               "inputTextureCoordinate");
       Log.d(TAG,"id = " + color_id + "mGLUniformTexture= " + mGLUniformTexture);
     // GLES30.glClearColor ( 1.0f, 1.0f, 1.0f, 0.0f );

   }

4. 最后使用pbo 画出来

public void onDrawFrame ( GL10 glUnused )
   {
	  index++;
	  mTextureId = loadTexture(bitmap,mTextureId,0);
      // Set the viewport
          GLES30.glViewport ( 0, 0, width ,height);

      // Clear the color buffer
      GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
      GLES30.glClear ( GLES30.GL_COLOR_BUFFER_BIT );
      // Use the program object
      GLES30.glUseProgram ( mProgramObject );


      mVertices.position(0);
      GLES30.glVertexAttribPointer ( mGLAttribPosition, 3, GLES30.GL_FLOAT, false, 0, mVertices );
      GLES30.glEnableVertexAttribArray ( mGLAttribPosition );
      
      mGLTextureBuffer.position(0);
      GLES30.glVertexAttribPointer ( mGLAttribTextureCoordinate, 2, GLES30.GL_FLOAT, false, 0, mGLTextureBuffer );
      GLES30.glEnableVertexAttribArray ( mGLAttribTextureCoordinate );
     
//      
      if (mTextureId >= 0)
      {
    	  //loadFramebuffer(mTextureId,width,height);
	      GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
	      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mTextureId);
	      GLES30.glUniform1i(mGLUniformTexture, 0);
	      
      }
      GLES30.glDrawArrays ( GLES30.GL_TRIANGLE_STRIP, 0, 4 );
       Log.d("jni", "刷新时间");
      return;
   }

总结:虽然使用一个PBO但是效果改变不是很明显,因为单个PBO传输还是需要等待的,假如使用2个pbo,这样错开接收就会使效率大大提高,请看下篇使用2个PBO速度慢的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

解决android opengl glReadPixels 慢的问题一 的相关文章

  • 将数据从服务传递到活动

    我有自行运行的服务 服务自动启动 我有活动 在此 Activity 按钮中启动该方法DoIt Button setOnClickListener new OnClickListener public void onClick View v
  • 如何替换 Android 中已弃用的 Bundle/Argument get(key) 调用

    我有以下扩展函数 允许我在应用程序活动和片段之间传递捆绑数据项 inline fun
  • 如何在应用程序关闭时在 Android 通知中显示操作按钮?

    我有一个安卓应用程序 对于通知 我们必须显示一些操作按钮 当应用程序打开时 我们可以自由地构建通知并显示操作按钮 但是当应用程序关闭时 通知会在 Android 的通知托盘中收到 应用程序开发人员无法控制构建用户界面和操作按钮 我们现在如何
  • socket.io xhr 在连接缓慢时出现错误(3G 移动网络)

    当我在 3G 移动网络 互联网连接速度慢 上测试我的真实聊天应用程序时 Socket io反复断开然后重新连接 我已经记录了原因 它说 xhr post error 这提高了 transport error 然后断开连接 我可以知道什么意思
  • Android 中的列表(特别是 RecyclerView 和 CardView)如何工作

    请原谅我问这个问题 但我是 Android 开发新手 尽管我正在尝试了解developer android com 网站上的基础知识 但大多数示例 即使他们说它们是为 Android Studio 构建的 尚未设置为使用 Gradle 因此
  • 覆盖 Android 中的电源按钮

    我正在开发一个应用程序 其中我需要在按下电源按钮时执行一个操作 但不幸的是我无法处理按下电源按钮时的操作 我尝试使用 onKeyDown 和dispatchKeyEvent 方法 但似乎没有任何效果 任何人都可以建议我解决这个问题的任何其他
  • 退出设备上的 system.img

    我正在为我们部署给客户的设备 LG p509 Optimus 1 开发自动应用程序更新解决方案 我们可以控制这些设备 并且目前在它们上安装自定义内核 但不是完整的自定义 ROM 由于我们试图在设备上自动更新我们的应用程序 因此我们需要由我们
  • ADB TCPIP 连接问题

    我有两台 Galaxy S3 其中一个已扎根 另一个则未扎根 因此 当我尝试通过本地网络连接它们时 计算机可以看到已root的计算机 但是正常的就卡在tcpip这一步了 所以 我写 adb tcpip 5555 It says restar
  • 华为手机“受保护的应用程序”设置及处理方法

    我有一台搭载 Android 5 0 的华为 P8 用于测试应用程序 该应用程序需要在后台运行 因为它跟踪 BLE 区域 我发现华为内置了一个名为 受保护的应用程序 的 功能 可以从手机设置 电池管理器 gt 受保护的应用程序 访问该功能
  • 需要 Android webview window.open() 和 window.close() 的信息

    我正在开发一个安卓应用程序 这是我网站的 WebView 该网站包含一个弹出按钮 单击该按钮后 将打开一个新窗口并显示内容 该链接可以来自外部站点 然而 当我实现此操作时 新选项卡正在打开 之后它会弹出以打开浏览器 尽管在 Web 视图中打
  • Ionic 2 RC0 和 Angular 2 最新的 Android 构建错误(ngc:错误:静态解析符号值时遇到错误)

    当我使用构建android时出现错误ionic build android命令 ngc 错误 静态解析符号值时遇到错误 引用本地 非导出 符号 字典 考虑导出符号 原始 ts文件中的位置14 8 解析符号TRANSLATION PROVID
  • Android -room 持久库 - DAO 调用是异步的,因此如何获取回调?

    从我读到的Room 不允许您在主线程上发出数据库查询 因为可能会导致主线程延迟 所以想象一下我正在尝试更新 UI 主线程上的文本视图 其中一些数据我将如何得到回调 让我给你举个例子 想象一下 我想将我的业务模型数据存储到一个名为 事件 的对
  • Android模拟器中的网络访问

    我试图通过我的 Android 应用程序访问互联网 但我既成功又失败 我在构建应用程序时启动模拟器 并且应用程序安装得很好 我可以使用浏览器访问互联网 但是 当我尝试这个小代码片段时 InetAddress inet try inet In
  • Android SearchView 在启动时隐藏键盘

    我有一个小问题正在尝试解决 当我打开应用程序时 键盘会显示输入搜索视图的查询 不过 我只想在单击搜索视图时显示键盘 我该如何解决 Thanks 这对我有用 用于隐藏焦点的代码 searchView SearchView view findV
  • 受信任的网络活动 - 地址栏不隐藏(Android 72 的 Chrome)

    我已经关注了this https developers google com web updates 2017 10 using twa了解如何使用受信任的 Web 活动的指南 一切正常 但地址栏仍然出现 一开始我认为这是因为当应用程序正在
  • 离子初始加载时间

    我正在使用 Ionic 构建一个简单的应用程序 但我的应用程序在冷启动时的初始加载时间方面存在性能问题 这是我所做的 collection repeat 代替带有 track by 的 ng repeat 原生滚动 overflow scr
  • fs-extra:源和目标不能相同。 (科尔多瓦)

    我在使用 cordova 构建时遇到错误 Error Source and destination must not be the same 构建系统 Ionic ionic cli 4 10 1 ionic framework ionic
  • 丢失应用程序的密钥库文件(但已启用 Google Play 应用程序签名)

    我已经失去了原来的keystore用于签署我的应用程序的文件 我的应用启用了 Google Play 应用签名 如果我联系 Google 支持人员 是否可以重置密钥 以便我可以继续上传到此包 我希望我可以做到这一点 因为应用程序签名已启用
  • LifeCycleAware Fragment 中的片段生命周期事件

    我有一个生命周期感知片段和一个LifecycleObserver class public class MyFragment extends Fragment Override public void onCreate Nullable B
  • 如何访问我的 Android 程序中的联系人

    我正在制作一个短信应用程序 并且想要访问我的 Android 应用程序中的联系人 我想访问联系人 就像他们在实际联系人列表中一样 选择后 我需要返回到我的活动 在其中我可以向该人发送短信 或者是否可以访问存储联系人的数据库 我的代码如下所示

随机推荐

  • win10键盘锁住了怎么解决

    有win10系统用户在使用的时候 xff0c 发现键盘被锁住了 xff0c 导致无法使用 xff0c 经过分析可能是不小心按到了键盘上的锁住键 锁定键盘的快捷键 笔记本电脑 xff1a Fn 43 Numlock 键 第一种方法 xff1a
  • 用Python读取CSV文件的5种方式

    典型的数据集stocks csv xff1a 一个股票的数据集 xff0c 其实就是常见的表格数据 有股票代码 xff0c 价格 xff0c 日期 xff0c 时间 xff0c 价格变动和成交量 这个数据集其实就是一个表格数据 xff0c
  • 多媒体技术选择题

    理论上 USB1 1的最高传输速率为12Mbps USB2 0的最高传输速率为480Mbps 实际上 只要小于理论值的数字就行了 Flash MX 软件 制作网络交互动画的编辑工具 Photoshop软件 是处理图像 图形的工具 电话质量采
  • C++程序设计选择题

    1 1 在哪种派生方式中 xff0c 派生类可以访问基类中的 protected 成员 B A public 和 private B public 和 protected C protected 和 private D 仅 protecte
  • MySQL之 XtraBackup 备份

    MySQL 系列连载之 XtraBackup 备份原理 xff08 1 xff09 导读 在日常的linux运维工作中 xff0c 大数据量备份与还原 xff0c 始终是个难点 关于mysql的备份和恢复 xff0c 比较传统的是用mysq
  • HP服务器硬盘坏了一块,教你如何快速更换

    一 需求描述 客户公司的一台HP DL360p Gen8服务器硬盘坏了 xff0c 为了防止另外一块硬盘也损坏 xff0c 急需去将坏的硬盘进行更换 服务器更换硬盘不同普通电脑更换硬盘 xff0c 需要人工去导数据 xff0c 服务器更换硬
  • win 7 电脑错误676、734、678、651等解决办法

    错误676 734等解决办法 运营商办理的网络接入方式都会提供宽带账号和密码 在使用拨号上网的时候 xff0c 经常会出现各种错误代码导致不能上网 以下是个人理解的处理办法 觉得实用请分享 xff0c 不喜勿喷 xff01 01 错误691
  • 序列检测——有限状态机FSM(附verilog代码)

    题目 xff1a 使用状态机检测 1101 xff0c 串行输入的测试序列为 11101101011010 xff0c 输出信号为valid有效信号 xff0c 检测到时输出高 xff0c 否则为低 xff0c 考虑序列叠加情况 xff0c
  • MFC中的CreateProcess函数的应用

    MFC与CMD信息的传递与返回 HANDLE hRead hWrite SECURITY ATTRIBUTES sa sa nLength 61 sizeof SECURITY ATTRIBUTES sa lpSecurityDescrip
  • 解决 eclipse移植androidstudio Could not determine 的问题

    解决 eclipse移植androidstudio Could not determine 的问题 因为帮朋友移植eclipse工程到android studio上开发 xff0c 按照教程先在eclipse 导出android 的工程 x
  • string与float数据的转换

    问题 xff1a 如何将6位小数的string数据转化为2位小数的float数据显示 xff1f 先通过atof 转化为6位小数的float数据 xff1b temp 61 atof strtemp sscanf 61 strtemp 34
  • C语言中结构体内存分配(内含数组与结构体版)----超级详细版

    在网上看资料了很久 xff0c 看的我头晕都没看懂 xff0c 不如自己操作一遍 xff0c 总结出来了经验 首先我们要理解这几个概念 xff1a 1 结构体变量的首地址是其最长基本类型成员的整数倍 xff1b 2 结构体每个成员相对于结构
  • MFC中IP control控件的简单使用方法

    下面代码实现 xff1a 把IP Address控件里的值转化为 CString格式 CString strx m IP GetWindowText strx MessageBox strx 此段代码 xff1a 用获取的IP地址值 xff
  • 运行JAVA程序环境变量配置方法-详细介绍

    运行JAVA程序环境变量配置方法 详细介绍 系统配置 xff1a Win10 64位 遇到问题 xff1a 仅仅只想在计算机想直接通过cmd输入java jar运行 jar包 结果很明显 xff0c java 不是内部或外部命令 xff0c
  • MFC中界面背景图的设定以及动态更改透明背景的静态文本时重叠现象

    背景图的设定 第一种 xff08 平铺 xff09 将代码加入在BOOL CXXXDlg OnInitDialog 中 CDialogEx SetBackgroundColor RGB 155 170 190 纯色背景 CDialogEx
  • VISA操作表

    VISA操作表 操作表 xff1a 1 VISA资源模板 xff1a viClose xff08 vi xff09 xff1a 关闭特定的对话通道 viGetAttribute xff08 vi xff0c attribute xff0c
  • MFC在子窗口中输入数据在其他窗口中的数据传输

    第一种方法 xff1a 子窗口中将输入数据保存在建立的文件中 xff0c 在其他窗口读取文件内容 xff1b 第二种方法 xff1a 子窗口头文件中加入 CString Inputaccount 子窗口 cpp文件函数DoDataExcha
  • MySQL8.0安装配置(Linux版)设置简单密码 &远程访问

    MySQL8 0安装配置 xff08 Linux版 xff09 声明 xff1a 本文基于centos 7 6 可从myql官网查看linux操作系统对应的版本MySQL Download MySQL Yum Repository 注意 x
  • 另一台电脑登陆远程桌面,无法显示之前打开的界面的解决办法

    采用另一台电脑登陆远程桌面 xff0c 无法显示之前打开界面 xff08 例 Pycharm xff09 的解决办法 第一步第二步第三步 第一步 登陆远程桌面 xff0c 记录端口号A 如下图绿色框所示 第二步 1 查找指定用户 xff08
  • 解决android opengl glReadPixels 慢的问题一

    解决android opengl glReadPixels 慢的问题 由于android的gpu跟cpu内存是分离的 xff0c 导致数据拷贝的过程中会非常慢 xff0c 网上资料相对较少 xff0c 下面是我解决这个问题的一点心的 xff