OpenGL纹理转换谜团:纹理写入FRAMEBUFFER后的镜像现象

在OpenGL中,最近将一个 GL_TEXTURE_2D 纹理写入GL_FRAMEBUFFER ,然后从GL_FRAMEBUFFER读取GL_TEXTURE_2D纹理后,发现GL_TEXTURE_2D纹理变为了输入纹理的镜像纹理。效果图如下图所示。

本文将探讨这个问题的原因,并提出两种解决方案。
纹理写入FrameBuffer后变为了镜像纹理

一、纹理写入帧缓冲

  • OpenGL中,我们通常使用以下API将纹理ID绑定到FRAMEBUFFER的颜色缓冲区
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, frameBufferId);  
GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, tex2DId, 0);
  • GL_TEXTURE_2D纹理渲染FRAMEBUFFER帧缓冲区中;
// 激活纹理
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
// 将所需的纹理对象绑定到Shader中纹理单元0上
GLES30.glUniform1i(mTextureIdHandle, 0);
// 绑定纹理
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, texId);
// 绑定FRAMEBUFFER缓冲区
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, frameBufferId);
// 绘制矩形
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mVertexCount);
// 取消FRAMEBUFFER的绑定
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, GLES30.GL_NONE);
  • 最后,绘制渲染GL_TEXTURE_2D纹理,从FrameBuffer中读取纹理数据
// 激活纹理
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
GLES30.glUniform1i(mTex2DIdHandle, 0);
// 绑定纹理
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, tex2DId);
// 绘制矩形
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mVertexCount);

二、问题原因

OpenGL中,帧缓冲区对象(FBO:Framebuffer Object)的纹理附件默认使用的是纹理坐标系,其原点约定在屏幕的左下角;而在纹理坐标系约定中,如在进行图像处理、计算机视觉等,我们通常使用的是以左上角为原点的纹理坐标系约定

FrameBuffer纹理附件坐标系

三、解决方案

当我们将纹理绑定到帧缓冲区对象的颜色附件中后,如果输出的纹理坐标与输入的纹理坐标系一直(即原点一直位于左上角),那么最终得到的纹理将会是输入纹理的镜像纹理。

为了解决这个问题,我们可以采取以下两种方法:

  1. 从帧缓冲区读取纹理数据后:调整输出纹理矩形的顶点坐标或纹理坐标的值,使其坐标系与FOB的坐标系相匹配,从而达到正常展示的目的。
    以下举例中为按帧缓冲区坐标系,调整纹理坐标后的顶点与纹理对应关系:
// 按帧缓冲区坐标系,调整纹理坐标后的顶点与纹理对应关系:
// 顶点个数
mVertexCount = 4;
// 顶点坐标
float vertices[] ={-1.0f, 1.0f, 0.0f,-1.0f, -1.0f, 0.0f,1.0f, 1.0f, 0.0f,1.0f, -1.0f, 0.0f};
// 纹理坐标
float texCoor[] =new float[] {0.0f, 1.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, 0.0f};
}

顶点坐标与帧缓冲区纹理坐标的对应关系

  1. 在绑定纹理到帧缓冲区之前,通过设置纹理的纹理坐标变换矩阵来翻转纹理坐标系。将原点从左上角变为左下角,与默认的纹理坐标系约定一致。
    (该方法需要在Shader中进行变化,有些复杂,可参考第一种方式,这里不详细说明)

四、案例源码下载

ExternalOES纹理数据 转换为 TEXTURE-2D纹理数据:
https://download.csdn.net/download/aiwusheng/88650498

工程代码截图

五、参考

解密视频魔法:ExternalOES转化TEXTURE_2D纹理:
https://editor.csdn.net/md/?articleId=135137815

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/316188.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Django(五)

员工管理系统 1.新建项目 2.创建app python manage.py startapp app012.1 注册app 3. 设计表结构(django) from django.db import modelsclass Department(models.Model):""" 部门表 """title models.CharField(verbos…

M3u8视频地址如何转为mp4视频

在当今数字化的时代,视频格式的转换已成为日常需求。M3u8格式的视频由于其分段的特性,常常给播放和编辑带来不便。而MP4格式则因其通用性和高质量而广受欢迎。那么,如何将M3u8视频地址转换为MP4格式呢?接下来,我们将为…

安装elasticsearch、kibana、IK分词器、扩展IK词典

安装elasticsearch、kibana、IK分词器、扩展IK词典 后面还会安装kibana,这个会提供可视化界面方面学习。 需要注意的是elasticsearch和kibana版本一定要一样!!! 否则就像这样 elasticsearch 1、创建网络 因为我们还需要部署k…

论文笔记:CellSense: Human Mobility Recovery via Cellular Network Data Enhancement

1 intro 1.1 背景 1.1.1 蜂窝计费记录(CBR) 人类移动性在蜂窝网络上的研究近些年得到了显著关注,这主要是因为手机的高渗透率和收集手机数据的边际成本低蜂窝服务提供商收集蜂窝计费记录(CBR)用于计费目的&#xf…

创建x11vnc系统进程

为方便使用vnc,所以寻找到一个比较好用的vnc服务端那就是x11vnc,索性就创建了一个系统进程 一、环境 系统:银河麒麟v4-sp2-server 软件:x11vnc【linux下】、VNCviewer【win下】 二、安装x11vnc 1、挂载光盘源并修改apt源 mou…

【算法每日一练]-数论 (保姆级教程 篇2 )#行列式 #甜甜花研究 #约数个数 #模数 #数树 #盒子与球

目录 今日知识点: 辗转相减法化下三角求行列式 组合数动态规划打表 约数个数等于质因数的次方1的乘积 求一个模数 将n个不同的球放入r个不同的盒子:f[i][j]f[i-1][j-1]f[i-1][j]*j 行列式 甜甜花的研究 约数个数 模数 数树 盒子与球 行列…

第一个Qt程序----Hellow word!

从今天起就开始我们的第一个Qt小程序,点击New Project后点击右侧的Application后点击Qt Widgets Application。Qt Widgets 模块提供了一组UI元素用于创建经典的桌面风格的用户界面,Widgets是小部件的意思,也可以称为控件,因此Qt …

高效视频剪辑:批量修改视频尺寸的技巧与步骤

随着社交媒体的兴起,视频已然是分享和交流的重要方式。但有时,要的视频尺寸并不总是符合需求。这就要对视频进行剪辑和调整。现在探讨一种高效的方法,可以批量修改视频尺寸,简化工作流程。现在一起来看看云炫AI智剪如何批量修改视…

Redis - 挖矿病毒 db0 库 backup 反复出现解决方案

问题描述 腾讯云的服务器,使用 Docker 部署了 Redis 之后,发现 DB0 中总是出现 4 条 key,分别是 backup01backup02backup03backup04 而自己每次存入 db0 中的数据过一会就会被无缘无故删除掉。 原因分析 挖矿病毒 解决方案 在启动的时候…

Zookeeper-Zookeeper分布式一致性协议ZAB源码解析

整个Zookeeper就是一个多节点分布式一致性算法的实现,底层采用的实现协议是ZAB。 ZAB协议介绍 ZAB 协议全称:Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。 Zookeeper 是一个为分布式应用提供高效且可靠的分布式协调服…

IOS - 手机安装包 ipa 常见几种方式

安装 ipa 包的方法有很多中,可以通过不同的软件安装,本文只列出了常用的几种,做个简单的归纳整理 1、iTunes 安装 数据线连接手机之后,会自动连接iTunes,(第一次连接的时候会提示是否信任此电脑&#xff0…

Clojure 实战(4):编写 Hadoop MapReduce 脚本

Hadoop简介 众所周知,我们已经进入了大数据时代,每天都有PB级的数据需要处理、分析,从中提取出有用的信息。Hadoop就是这一时代背景下的产物。它是Apache基金会下的开源项目,受Google两篇论文的启发,采用分布式的文件…