复习 OpenGL 纹理映射 总结

2023-10-27

今天系统的复习了一下OpenGL纹理映射

主要参考资料是这两个 OpenGL 教程

http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/

https://learnopengl-cn.readthedocs.io/zh/latest/01%20Getting%20started/06%20Textures/

总体来看,第二个教程更详尽一些,比第一个教程多介绍了一下 如何把 Texture2D 对象,传到 fragment shader 的 sampler2D 的 uniform 变量中。

很久以前,自己总结过OpenGL Texture2D 使用的关键步骤

opengl 使用 texture2d 关键步骤

今天再结合现在的经验补充几点。

OpenGL Texture2D 对象 的生成,其实和 一个 VBO 的生成步骤类似。

首先是 Generate 

vbo 是  glGenBuffers(1,&_vbo);

texture 是 glGenTextures(1,&_tex);

然后,需要 bind ,才能指明要操作哪个 vbo / 哪个 texture2d

vbo : glBindBuffer(_vbo);

texture: glBindTexture(_tex);

接下来,就是真正把内存中的数据,存储到缓冲区内.

vbo 使用 glBufferData()

texture 使用 glTexImage2D()

针对 VBO 来说,通常是顶点的位置数据,颜色数据,uv数据,法线数据等等模型顶点相关的数据。至于这些顶点的数据,是直接写在代码的 数组里面的,还是 从 模型文件里读取的,这些OpenGL 都不关心,只要把数据的指针准备好,用 glBufferData() 存储到vbo就好了。

相应的,对于 texture2d 来说,glTexImage2D() 是把一段表示图片每个像素颜色信息的 内存数据,存储到  texture 里。同样它也并不关心数据的来路。无论是读取图片,还是自己在内存里手写,无论是 bmp ,jpg,png ,tga 格式, 无论是否带 alpha 通道,这些都无所谓,只要有数据指针就行。

但是区别的地方在于,glTexImage2D 需要关心 颜色信息的具体格式,也就是说 它有些参数,需要知道 这段内存数据交由它之后,它要如何理解。比如是 rgb 还是 rgba ,每个像素 所占位数 等信息。

二者之间有所区别的原因是 ,vbo 里的数据,能够通过 vao 传到 shader 里,可以自己随意编写 glsl 来解析。但是 sampler2D 类型的数据,在 shader 里面 的 灵活性 就要差很多,在 shader 里面使用时,颜色信息已经通过传参数决定了,没有更多底层的细节暴露出来。所以 给 texture 一段内存数据时,参数要更加明确,让 GL 知道 图片 每个像素的颜色 在内存里 是如何排布的。

vbo ,texture2d 二者相同:数据给到 OpenGL 之后,内存里的数据就可以释放了,因为数据已经存储到了 OpenGL 的显存里 (?).所以数据指针 指向的内存,可以尽快 delete 销毁 .

说到图片数据加载到内存,最简单的图片数据格式,应该是 bmp 格式,因为它 基本上就是把每个像素的颜色值,按照顺序摆放在 文件里,所以解析起来非常方便。

这里有一篇自己以前的总结

http://blog.csdn.net/korekara88730/article/details/78304643

里面有现成的自己手写的解析 24位 bmp 格式的代码。每个教程在取图片像素数据时,都使用了不同的库。我这次复习时,使用的图片解析“库” 就是 上面链接里 ,自己手写的 解析 24 位 bmp 的 代码。它可以将图片解析为一个The24BitBmp对象,此对象包含 图片的 宽度,高度,包含颜色数据的一个 连续 内存的指针。给 OpenGL 的 glTexImage2D() 做参数 完全够用。


texture2d 已经准备好了,在使用时,有几个值得留意的地方。

1. texture2d 是一张图片,体现在 shader 里,通常是 fragment shader 里的一个 sampler2D 的 uniform 变量。形如 uniform sampler2D myTextureSampler;

那么,如何把 c++ 代码里的 GLuint texture2d 与 shader 里的 sampler2D 变量 联系起来呢 ?

方法类似  VAO .

VAO 是 VBO 数据 到 vertex shader 参数 的一个桥梁。VAO 负责用 glEnableVertexAttribArray()  来控制 shader 开启/关闭 vertex shader 里面 哪些 in 类型的变量。

而 glActiveTexture(GL_TEXTURE0 ... N ) 用于决定开启 哪些 texture2D 对象,可以给 fragment shader 调用。

默认 GL_TEXTURE0 总是开启的。

通过 glActiveTexture(GL_TEXTURE ...N) 告诉 shader 第 N 个 texture2D 开启了

然后通过 glBindTexture(GL_TEXTURE_2D,_tex) 告诉 第 N 个 texture2D 对象 究竟 对应哪个图片数据。

最后,把 shader 里面 sampler2D 的变量名, 和 C++ 里面 texture2D 对象真正对应起来, 是依靠 glUniform1i().

比如 fragment shader 里 ,有个 uniform 的 sampler2D 变量 名叫 outTexture1 ,它想要对应 C++ 里 GL_TEXURE1 这张图片,则代码 如下 :

glUniform1i(glGetUniformLocation(shaderProgram, "outTexture1"),1);


这样,通过 

glActiveTexture(GL_TEXTUREN)

glBindTexture(GL_TEXTUREN,tex)

glUniform1i(glGetUniformLocation(shaderProgram, "着色器里的变量名"),N);

这 3个函数组合的套路, 就真正的把 一张图片的颜色信息,传递到 shader 里面了。


在 fragment shader 里最终使用时,就可以简单的通过

color = texture(textureSampler,UV).rgb

来输出,显示 图片的颜色了。


uv 参数的传递方法,和  顶点位置数据,顶点颜色数据 的传递方法完全一样。

uv 就是 该点 所对应 在 图片里的2d坐标,所以是一个 vec2 类型的变量。需要通过 VBO->VAO->VertexShader->FragmentShader 这样一个完整的流程,最终传递到  fragment shader 里面去。


总结一下,如果想渲染一个 带有图片的 多边形,需要经过如下几个关键步骤 :

1. 多边形位置数据数组

2.位置数据数组 -> posVBO

3. 多边形各个顶点 uv 数据数组

4.uv数据数组 -> uvVBO

5.解析图片各像素颜色数据,存到一个 数组中

6.颜色数据数组 -> 存储到 texture2D 的 handle 中

7. 编写 vertex shader ,包含 vertex pos ,vertex uv

8. 编写 fragment shader ,包含  uv ,和 sampler2D 

9. 生成 VAO ,把 posVBO ,uvVBO 传递到 vertex shader 

10. 激活 和 使用 GL_TEXTURE0(N) ,把 texture2D 的 handle 与 fragment shader 的 sampler2D 变量对应起来

11. 做最终渲染


经过这么一大串 折腾,才能在 OpenGL 里看到一个能够显示 图片的面片。


下一步继续跟着教程走,做好 键盘鼠标控制 镜头移动,再下一步是 读取 model 文件的数据,和 手写 顶点数据说拜拜。



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

复习 OpenGL 纹理映射 总结 的相关文章

  • what引导的宾语从句

    what引导宾语从句时在从句中作主语 宾语或表语 表示 所 的 1 表示 的东西或事情 相当于 the thing that all that everything that They ve done what they can to he
  • wifi一键配网smartconfig原理及应用

    https blog csdn net flyingcys article details 49283273 智能家居 家电现阶段还处于普及阶段 由于家庭wifi网络的普及 目前普遍采用wifi与路由器完成连接 与手机 云端进行数据交互 智
  • 数据结构与算法 -- 子序列问题

    一 子序列问题 子数组问题是连续的 而子序列问题是不连续的 比如说字符串 I wanna keep a giraffe in my backyard 的一种子序列就可以是 Igbackd 子序列不再要求答案是一个连续的串 一个字符串的子序列
  • 第58步 深度学习图像识别:Transformer可视化(Pytorch)

    一 写在前面 1 pytorch grad cam库 这一期补上基于基于Transformer框架可视化的教程和代码 使用的是pytorch grad cam库 以Bottleneck Transformer模型为例 2 算法分类 pyto
  • Julia概率分布和统计推理

    贷款审批预测数据示例 贝叶斯理论 P Y X P X P XY P X Y P Y 如果 X 是我们的数据 也称为证据 Y 是我们的模型假设 则 P Y 是我们看到任何证据之前的概率 称为先验概率 在实践中 我们通常假设服从均匀分布或正态分
  • 恢复硬盘U盘数据好帮手-finaldata

    FinalData可以很容易地从格式化后的文件和被病毒破坏的文件恢复 甚至在极端的情况下 如果目录结构被部分破坏也可以恢复 只要数据仍然保存在硬盘上 点击下载finaldata企业版
  • 数字图像处理笔记(十):形态学图像处理

    1 引言 数学形态学的语言是集合论 利用集合论知识我们可以实现图像 腐蚀 膨胀 开操作 笔操作 下面就让我们学习一下这些基于形态学的图像处理 2 腐蚀和膨胀 膨胀与腐蚀能实现多种多样的功能 主要如下 消除噪声 分割 isolate 出独立的
  • linux对一个文件夹中的所有文件重命名

    在Linux中 你可以使用mv命令对一个文件夹下的所有文件进行重命名 下面是几种常见的用法 方法1 批量添加前缀或后缀 cd 目标文件夹路径 for file in do mv file 前缀 file done 添加前缀 for file
  • python绘制风向玫瑰图

    一 风向 流向角度和数学角关系 1 数学角和风向角相互转换 数学角向东为0 按照逆时针旋转 北风为0 即指向南为0 顺时针增加 数学角转风向角 1 根据u v获得数学角 2 根据数学角换算风向 360 360是对360取余 数学角向东为0
  • Python核心编程——第4章 多线程编程 笔记

    Python核心编程 第4章 多线程编程 笔记 引言 通用概念 python相关概念 多线程的实现方式 两大模块 三种替代方案 使用Thread类主要的三种创建线程的方法 相关模块 代码实现部分 python3 最简单的线程 定时等待 使用
  • Kubernetes踩坑(一): 部署问题记录

    一 etcd服务启动后报错etcd cluster ID mismatch 检车service配置cluster选项有无问题 若无问题 则可能是此前的etcd bootstrap加速启动缓存残留导致 坑爹的是rm rf var lib et
  • MyBatis中的reflection包(一)ObjectFactory,PropertyTokenizer, Invoker, Reflector

    内容概要 reflection是MyBatis关于反射的工具包 是实现其它功能的基石之一 这里我不准备贴上源码然而逐行解释 而是从需求分析的角度来复现 ObjectFactory 现在有这样的需求 给你一个Class对象 要求你创建它的实例
  • 嵌入式数据结构(查找)(哈希表)

    嵌入式自学第十二天 1 2 代码实现 list c define CRT SECURE NO WARNINGS include list h include stdlib h include string h include stdio h
  • 2023版ChatGPT 能用来帮助谈恋爱吗,如果用 ChatGPT 来谈恋爱会发生什么?

    大家好啊 有没有和ChatGPT聊过天的 5G高手 们呢 ChatGPT是美国AI公司OpenAI开发出来的一款人工智能聊天机器 会通过学习和理解自然语言来跟我们聊天 不管你想聊啥 从诗歌到哲学 它都可以让你感觉像在跟一个超水平牛逼闪耀的老
  • 静态Web服务器-返回固定页面数据

    学习目标 能够写出组装固定页面数据的响应报文 1 开发自己的静态Web服务器 实现步骤 编写一个TCP服务端程序 获取浏览器发送的http请求报文数据 读取固定页面数据 把页面数据组装成HTTP响应报文数据发送给浏览器 HTTP响应报文数据
  • RISC-V IDE MRS使用笔记(九):使用WCH-LinkW实现无线下载、调试

    RISC V IDE MRS使用笔记 九 使用WCH LinkW实现无线下载 调试 1 硬件环境 WCH LinkW无线仿真调试器2块 CH32V307开发板1块 2 软件环境 MRS V185版本 3 无线仿真调试器配对与连接 通过WCH
  • Beam技术

    一 简介 在大数据处理中 流计算技术包括Storm Spark Streaming和Flink 实际应用中还包括Storm Trident Samura以及Google MillWhell和亚马逊的Kinesis等技术 离线处理基本上都基于
  • vue3 ts页面赋值发现不生效

    在 onMounted 周期中 dataForm value route params data 赋值不生效
  • MOOC浙大数据结构课后题记录——PTA数据结构题目集(全)

    目录 第一周 最大子列和算法 二分查找 01 复杂度1 最大子列和问题 20分 01 复杂度2 Maximum Subsequence Sum 25分 01 复杂度3 二分查找 20分 第二周 线性结构 02 线性结构1 两个有序链表序列的
  • element 中 表格设置滚动条

    element 中 表格设置滚动条 表格设置滚动条 1 使用header 直接设个表格的高度 就会为表填加上表格 2 表格自定义使用css样式添加滚动条 样式一 deep el table body wrapper height 200px

随机推荐

  • 进行页面跳转时,不将请求参数显示在url的方法

    在SSM项目中 ajax不能实现跳转 反正我是不知道 href会将传参显示在url上 但有些人不想在页面跳转时 将传参显示在url中 反正我不想 就比如这种 有以下两种方法 将传参数放在session中 用js创建动态form表单 页面跳转
  • html2canvas给指定区域添加满屏水印

    效果图如下 直接贴上代码 下载插件 npm i html2canvas
  • 劲爆!java架构师百度网盘

    第一份资料 Kafka实战笔记 Kafka入门 为什么选择Kafka Karka的安装 管理和配置 Kafka的集群 第一个Kafka程序 afka的生产者 Kafka的消费者 深入理解Kafka 可靠的数据传递 Spring和Kalka的
  • 2021-06-20

    conda换源后安装包报错 只搜索第一个源 为了安装qiskit包 首先给conda增加了多个源 如下图 而后在安装qiskit包时 conda报错 但是提示只有第一个404 其他源没有提示 所以问题是 conda安装时是否遍历了所有已添加
  • 英文数字汇总,KMGT,毫微纳

    以5MB为例 现在的习惯是读作 五兆 可是 兆的本意是万亿 在这里却成了百万 5MB的标准读法应该是 五百万字节 网络的带宽 100M 常读作 一百兆 若读作 一百百万 会有人反对 可1000 不是也读作 一千千米 吗 还有气象预报的 五百
  • 讯飞星火大模型申请及测试:诚意满满

    大家好 我是可夫小子 关注AIGC 读书和自媒体 解锁更多ChatGPT AI绘画玩法 加 keeepdance 备注 chatgpt 拉你进群 最近国产大模型跟下饺子似 隔几天就发布一个 厂家发布得起劲 大家看多了也麻木了 而且无一例外都
  • 计算图像帧的平均灰度值

    2016 7 15 在处理视频中 需要对视频流中的图像帧进行区分 分离出其中的亮暗帧图像 区分亮暗图像 是依据图像的平均灰度值来实现的 我们知道 对于一幅灰度图像 每个像素点的灰度值可以通过指针来访问 i j 处的灰度值 img gt im
  • 运行项目出现java.lang.ClassNotFoundException: org.springframework.web.util.IntrospectorCleanupListener

    java lang ClassNotFoundException org springframework web util IntrospectorCleanupListener at org apache catalina loader
  • spyder 出现ValueError: PyCapsule_GetPointer called with incorrect name

    我太难了 经过一堆试验 终于出了坑 总的来说 1 卸载pyqt5 命令 pip uninstall pyqt5 2 重新安装低版本的pyqt5 命令 pip install PyQt5 5 10 1 如果出现pip vendor urlli
  • meta-compilation

    RPython GraalVM 转载于 https my oschina net crcc blog 2239743
  • k8s的pv和pvc创建

    NFS使用PV和PVC 1 配置nfs存储 2 定义PV 实现 下图的pv和pvc测试 pv的定义 这里定义5个PV 并且定义挂载的路径以及访问模式 还有PV划分的大小 vim pv yaml apiVersion v1 kind Pers
  • Pytorch实战笔记(1)——BiLSTM 实现情感分析

    本文展示的是使用 Pytorch 构建一个 BiLSTM 来实现情感分析 本文的架构是第一章详细介绍 BiLSTM 第二章粗略介绍 BiLSTM 就是说如果你想快速上手可以跳过第一章 第三章是核心代码部分 目录 1 BiLSTM的详细介绍
  • JDK11.0.7下载及安装详细教程,步骤解释(win10)

    0 背景知识 JRE Java Runtime Environment JDK Java Development Kit JRE顾名思义是java运行时环境 包含了java虚拟机 java基础类库 是使用java语言编写的程序运行所需要的软
  • HW娱乐板块-你们都是天才~

    接下几天会是各类系统升级改造的时机了 大家都很有想法 就你tm叫韩毅啊 今年你是HW最出名的人物 虽然我不知道他在干什么 但是闸机已经被打穿了 从小我就想当一个百万富翁 我每天加班 可我的梦想却离我越来越遥远 我来到了护网为了实现我的梦想
  • 家里的wifi服务器无响应,宽带wifi服务器无响应

    宽带wifi服务器无响应 内容精选 换一换 当您调用API时 如果遇到 APIGW 开头的错误码 请参见API网关错误码进行处理 正常返回值说明200 OKGET和PUT操作正常返回 201 CreatedPOST操作正常返回 202 Ac
  • 如何用IDaaS云身份认证落地“零信任”安全架构

    题记 2020的RSAC Zero trust 零信任 去年有39家公司打 Zero trust 标签 今年数量激增到91家 可以说零信任理念已被国外同行广泛接受 零信任不仅仅是技术 更是理念的转变 会成为未来十年主流的网络安全架构 为什么
  • 记一次在Tweak中引入Swift framework的过程

    最近想在一个插件里打通App和web端 实现通过web控制App 方案是选用socket io作为服务端和web前端 iOS端socket io是一个纯swift实现的库 目前Theos对swift的支持还不是很完善 但是可以完成一般的工作
  • 大学生团体天梯赛(第八届)

    题目地址 天梯赛 include
  • 浅谈算法和数据结构: 十 平衡查找树之B树

    前面讲解了平衡查找树中的2 3树以及其实现红黑树 2 3树种 一个节点最多有2个key 而红黑树则使用染色的方式来标识这两个key 维基百科对B树的定义为 在计算机科学中 B树 B tree 是一种树状数据结构 它能够存储数据 对其进行排序
  • 复习 OpenGL 纹理映射 总结

    今天系统的复习了一下OpenGL纹理映射 主要参考资料是这两个 OpenGL 教程 http www opengl tutorial org beginners tutorials tutorial 5 a textured cube ht