关于读取Texture内容

以下为几种数据拷贝方式:

(1)glCopyPixels 直接将屏幕像素拷贝到framebuffer,没有经过内存,严格来说不算拷贝texture方式

(2)glReadPixels 从帧缓存中读取一个像素块到内存data中, 可以结合FBo使用

(3)glGetTexImage()根据纹理Id,读取数据到内存


(1)glGetTeImage使用比较方便:但是速度较慢。

exp1:获取指定Id的纹理数据

unsigned char* output_image = new unsigned char[M_WIDTH * M_HEIGHT * 3];

glBindTexture(GL_TEXTURE_2D, texture_ID);

glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, output_image);

exp2:获取纹理再拷贝

unsigned char* output_image = new unsigned char[M_WIDTH * M_HEIGHT * 3];

glBindTexture(GL_TEXTURE_2D, src_id);

glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, output_image);

glBindTexture(GL_TEXTURE_2D, dest_id);

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, M_WIDTH ,M_HEIGHT , GL_RGB, GL_UNSIGNED_BYTE, output_image);

glBindTexture(GL_TEXTURE_2D, 0);

此时数据保存到output_image 中, 可以另存成图片文件

但是Opengl ES 不支持。

(2)FBO拷贝

GLuint fbo

glGenFramebuffers(1, &fbo);

glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);

glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, src_id, 0);

glBindTexture(GL_TEXTURE_2D, dest_id);

glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,  M_WIDTH ,M_HEIGHT);

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);

(3)glReadPixels 是从framebuffers里面读,而不是texture,但是可以借助FBO,可以绑定到FBO,然后从FBO用glReadPixels读取

glGenFramebuffers(1, &offscreen_fbo);

glBindFramebuffer(GL_FRAMEBUFFER, offscreen_fbo);


//创建tex

glGenTextures(1, &my_texture);

glBindTexture(GL_TEXTURE_2D, my_texture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

//

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHEMENT0, GL_TEXTURE_2D, my_texture, 0);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

if(status != GL_FRAMEBUFFER_COMPLETE){

printf("failed  %x", status);

}


//

glBindFramebuffer(GL_FRAMEBUFFER, offscreen_fbo);

glViewport(0, 0, width, height);

GLubyte* pixels = (GLubyte*) malloc(width * height * sizeof(GLubyte) * 4);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
//

glBindFramebuffer(GL_FRAMEBUFFER, sceen_framebuffer);

glViewPort(0, 0, screen_width, screen_height);


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要获取SurfaceTexture的图像,可以使用SurfaceTexture的updateTexImage()方法。这个方法会将最新的图像数据更新到SurfaceTexture中,并将纹理矩阵更新为与最新的图像数据相匹配。 在调用updateTexImage()方法之后,可以使用OpenGL ES纹理来渲染SurfaceTexture的图像。可以使用SurfaceTexture的getTransformMatrix(float[] mtx)方法来获取纹理矩阵,以将纹理正确地映射到屏幕上。 以下是使用SurfaceTexture获取图像并将其渲染到屏幕上的代码示例: ```java // 获取相机 Camera camera = Camera.open(); // 创建一个SurfaceTexture并设置默认缓冲区大小 SurfaceTexture surfaceTexture = new SurfaceTexture(0); surfaceTexture.setDefaultBufferSize(camera.getParameters().getPreviewSize().width, camera.getParameters().getPreviewSize().height); // 将SurfaceTexture设置为相机预览输出的目标 camera.setPreviewTexture(surfaceTexture); // 开始预览 camera.startPreview(); // 创建一个GLSurfaceView用于渲染图像 GLSurfaceView glSurfaceView = new GLSurfaceView(this); glSurfaceView.setEGLContextClientVersion(2); // 创建一个渲染器并将SurfaceTexture的纹理与之关联 Renderer renderer = new Renderer(surfaceTexture); glSurfaceView.setRenderer(renderer); // 将GLSurfaceView添加到布局中 FrameLayout layout = findViewById(R.id.layout); layout.addView(glSurfaceView); // 渲染器类 class Renderer implements GLSurfaceView.Renderer { private SurfaceTexture surfaceTexture; private int textureId; public Renderer(SurfaceTexture surfaceTexture) { this.surfaceTexture = surfaceTexture; } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // 创建一个纹理并将其与SurfaceTexture关联 int[] textures = new int[1]; GLES20.glGenTextures(1, textures, 0); textureId = textures[0]; GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); surfaceTexture.attachToGLContext(textureId); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { GLES20.glViewport(0, 0, width, height); } @Override public void onDrawFrame(GL10 gl) { // 更新SurfaceTexture中的图像数据 surfaceTexture.updateTexImage(); // 获取纹理矩阵 float[] mtx = new float[16]; surfaceTexture.getTransformMatrix(mtx); // 渲染图像 GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); GLES20.glUseProgram(program); GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer); GLES20.glVertexAttribPointer(texCoordHandle, 2, GLES20.GL_FLOAT, false, 0, texCoordBuffer); GLES20.glUniformMatrix4fv(mtxHandle, 1, false, mtx, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); GLES20.glUniform1i(texSamplerHandle, 0); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); } } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值