OpenGL超级宝典学习笔记:纹理
本篇在讲什么 本篇章记录对OpenGL中纹理使用的学习 本篇适合什么 适合初学OpenGL的小白 本篇需要什么 对C++语法有简单认知 对OpenGL有简单认知 最好是有OpenGL超级宝典蓝宝书 依赖Visual Studio编辑器 本篇的特色 具有全流程的图文教学 重实践,轻理论,快速上手 提供全流程的源码内容 |
![]() ★提高阅读体验★ 👉 ♠ 一级标题 👈👉 ♥ 二级标题 👈👉 ♣ 三级标题 👈👉 ♦ 四级标题 👈 |
目录
- ♠ 纹理
- ♥ 创建并初始化纹理
- ♥ 更新纹理数据
- ♥ 纹理目标和类型
- ♥ 读取纹理数据
- ♥ 采样器类型
- ♥ 演示示例
- ♥ 从文件载入纹理
- ♥ 案例分析
- ♠ 推送
- ♠ 结语
♠ 纹理
纹理是一种结构化的存储形式,可供着色器读写,常用于存储图像数据,我们常见的png、jpg等图片存储的也是图像数据,只不过是经过编码的数据,不能直接被GPU使用,而纹理格式可以直接被GPU读取渲染
♥ 创建并初始化纹理
在下面的代码中我们对一个纹理进行生成、初始化和绑定的操作
// The type used for names in OpenGL is GLuint
GLuint texture;// Generate a name for the texture
glGenTextures(1, &texture);// Now bind it to the context using the GL_TEXTURE_2D binding point
glBindTexture(GL_TEXTURE_2D, texture);// Specify the amount of storage we want to use for the texture
glTexStorage2D(GL_TEXTURE_2D, // 2D texture1, // 1 mipmap levelGL_RGBA32F, // 32-bit floating-point RGBA data256, 256); // 256 x 256 texels
要点1:
通过glGenTextures
接口创建一个纹理
要点2:
通过glBindTexture
将纹理绑定到上下文
要点3:
通过glTexStorage2D
分配纹理的格式和需要的内存空间
♥ 更新纹理数据
在纹理初始化完成后,我们为其更新数据
// Define some data to upload into the texture
float * data = new float[256 * 256 * 4];// generate_texture() is a function that fills memory with image data
generate_texture(data, 256, 256);// Assume the texture is already bound to the GL_TEXTURE_2D target
glTexSubImage2D(GL_TEXTURE_2D, // 2D texture0, // Level 00, 0, // Offset 0, 0256, 256, // 256 x 256 texels, replace entire imageGL_RGBA, // Four channel dataGL_FLOAT, // Floating point datadata); // Pointer to data// Free the memory we allocated before - \GL now has our data
delete [] data;
要点1:
通过generate_texture
用图像数据填充内存
要点2:
通过glTexSubImage2D
更新纹理数据
♥ 纹理目标和类型
在上文中我们展示了通过GL_TEXTURE_2D
来创建和绑定2D纹理目标,其实还有更多的类型,例如可以通过GL_TEXTURE_2D
和GL_TEXTURE_3D
创建一维和三维纹理,下图展示纹理目标类型
纹理目标(GL_TEXTURE_*) | 说明 |
---|---|
1D | 一维纹理 |
2D | 二维纹理 |
3D | 三维纹理 |
RECTANGLE | 矩形纹理 |
1D_ARRAY | 一维数组纹理 |
2D_ARRAY | 二维数组纹理 |
CUBE_MAP | 立方体贴图纹理 |
CUBE_MAP_ARRAY | 立方体贴图数组纹理 |
BUFFER | 缓冲纹理 |
2D_MULTISAMPLE | 二维多重采样纹理 |
2D_MULTISAMPLE_ARRAY | 二维数组多重采样纹理 |
♥ 读取纹理数据
存储数据后我们就可以读取数据,用于着色片段,着色器中的纹理以采样器
变量形式存在,通用以取样器
类型声明统一变量与外界相连接
表示二维纹理的采样器类型为sampler2D
即对应我们上文绑定的目标GL_TEXTURE_2D
,下列片段着色器代码演示如何读取纹理
"#version 430 core \n"
" \n"
"uniform sampler2D s; \n"
" \n"
"out vec4 color; \n"
" \n"
"void main(void) \n"
"{ \n"
" color = texture(s, gl_FragCoord.xy / textureSize(s, 0)); \n"
"}
要点1:
采样器类型sampler2D
是二维纹理类型
要点2:
内置函数texture
从纹理中抓取颜色数据
♥ 采样器类型
如前文所述,纹理的每个维度都有一个目标点用于绑定纹理对象,每个目标都有对应的采样器类型,下面列表展示目标点和其对应的采样器类型
纹理目标 | 采样器类型 |
---|---|
GL_TEXTURE_1D | sample1D |
GL_TEXTURE_2D | sample2D |
GL_TEXTURE_3D | sample3D |
GL_TEXTURE_RECTANGLE | sample2Drect |
GL_TEXTURE_1D_ARRAY | sample1Darray |
GL_TEXTURE_2D_ARRAY | sample2Darray |
GL_TEXTURE_CUBE_MAP | sampleCube |
GL_TEXTURE_CUBE_MAP_ARRAY | sampleCubeArray |
GL_TEXTURE_BUFFER | sampleBuffer |
GL_TEXTURE_2D_MULTISAMPLE | sample2DMS |
GL_TEXTURE_2D_MULTISAMPLE_ARRAY | sample2DMSArray |
♥ 演示示例
全文代码这里粘了,具体参考OpenGL蓝宝书官方演示示例simpletexture
,示例内包含和上文相同的代码,下图为效果图
♥ 从文件载入纹理
在上文我们已经学习到了通过编码生成纹理数据,但这并不符合实际应用中的情况,现实中我们往往是通过文件载入纹理数据,这一块,我们学习如何通过加载.ktx
文件,显示纹理
#include <sb7ktx.h>// generate_texture() is a function that fills memory with image data
//generate_texture(data, 256, 256);texture = sb7::ktx::file::load("media/textures/pattern1.ktx");
这里我们只需要通过sb7::ktx::file::load
方法加载ktx文件即可,返回值附加给我们的texture
注意:
上述代码修改自超级宝典第七版例子simpletexture
,generate_texture生成纹理数据替换成文件加载,就可以得到上图所示的效果,我们文件的纹理填充到三角形里面了
♥ 案例分析
官方提供了一个加载外星人图片的例子alienrain
,运行效果如下图所示,我们简单分析一下
- 随机的速度、角度、偏移
for (int i = 0; i < 256; i++)
{droplet_x_offset[i] = random_float() * 2.0f - 1.0f;droplet_rot_speed[i] = (random_float() + 0.5f) * ((i & 1) ? -3.0f : 3.0f);droplet_fall_speed[i] = random_float() + 0.2f;
}
给数组内生成了一组随机的速度、角度、偏移值,并绑定到统一变量的缓存内
- 从本地加载外星人纹理
tex_alien_array = sb7::ktx::file::load("media/textures/aliens.ktx");
glBindTexture(GL_TEXTURE_2D_ARRAY, tex_alien_array);
从本地ktx文件内加载一组外星人纹理数据,绑定到纹理缓存数据内
- 顶点着色器
"layout (location = 0) in int alien_index;
用来从纹理数组取数据的下标
out VS_OUT
{ flat int alien; vec2 tc;
} vs_out;
记录外星人纹理数据的下标
layout (std140) uniform droplets
{ droplet_t droplet[256];
};
存储随机数值的统一变量
- 片段着色器
layout (location = 0) out vec4 color;
in VS_OUT
{ flat int alien; vec2 tc;
} fs_in;
uniform sampler2DArray tex_aliens;
void main(void)
{ color = texture(tex_aliens, vec3(fs_in.tc, float(fs_in.alien)));
}
根据顶点着色器传过来的外星人纹理数据的下标,从纹理数据缓存里取对应的纹理数据显示
- 创建外星人纹理
int alien_index;
for (alien_index = 0; alien_index < 256; alien_index++)
{glVertexAttribI1i(0, alien_index);glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
在render方法里没帧都会循环给alien_index赋0-255的值,对应顶点着色器里的外星人的alien_index,所以没帧都会有255个外星人生成
♠ 推送
- Github
https://github.com/KingSun5
♠ 结语
若是觉得博主的文章写的不错,不妨关注一下博主,点赞一下博文,另博主能力有限,若文中有出现什么错误的地方,欢迎各位评论指摘。
相关文章:

OpenGL超级宝典学习笔记:纹理
前言 本篇在讲什么 本篇章记录对OpenGL中纹理使用的学习 本篇适合什么 适合初学OpenGL的小白 本篇需要什么 对C语法有简单认知 对OpenGL有简单认知 最好是有OpenGL超级宝典蓝宝书 依赖Visual Studio编辑器 本篇的特色 具有全流程的图文教学 重实践,轻理…...

主辅助服务市场出清模型研究【旋转备用】(Matlab代码实现)
👨🎓个人主页:研学社的博客💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密…...

不用费劲,这5款效率工具为你解决学习工作烦恼
今天我要向大家推荐5款超级好用的效率软件,无论是在学习还是办公中都能够极大地提高效率。这些软件可以帮助你解决许多问题,而且每个都是真正的神器。 1.键盘仿真鼠标——NeatMouse NeatMouse 是一个小型的工具能够使用鼠标光标控制指针。当你的鼠标不…...

PostgreSQL 数据库大小写规则
PostgreSQL 数据库对大小写的处理规则如下: 严格区分大小写默认把所有 SQL 语句都转换成小写再执行加双引号的 SQL 语句除外 如果想要成功执行名称中带有大写字母的对象,则需要把对象名称加上双引号。 验证如下: 想要创建数据库 IZone&…...

【springmvc】执行流程
SpringMVC执行流程 原理图 1、SpringMVC常用组件 DispatcherServlet:前端控制器,不需要工程师开发,由框架提供 作用:统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理用户的请求 HandlerMa…...

什么是AIGC?
目录前言一、什么是AIGC?1、什么是PGC?2、什么是UGC?3、什么是PUCG?4、什么是AIGC?二、总结前言 很明显,ChatGPT的爆火,带动了AIGC(AI-Generated Content)概念的火热。 …...

【深度强化学习】(2) Double DQN 模型解析,附Pytorch完整代码
大家好,今天和大家分享一个深度强化学习算法 DQN 的改进版 Double DQN,并基于 OpenAI 的 gym 环境库完成一个小游戏,完整代码可以从我的 GitHub 中获得: https://github.com/LiSir-HIT/Reinforcement-Learning/tree/main/Model 1…...
【正则表达式】正则表达式语法规则
正则表达式语法规则1.普通字符 字符描述[ABC]匹配 […] 中的所有字符[^ABC]匹配除了 […] 中字符的所有字符[A-Z][A-Z] 表示一个区间,匹配所有大写字母,[a-z] 表示所有小写字母.匹配除换行符以外的任意字符[\s\S]匹配所有。\s 是匹配所有空白符…...

1636_isatty函数的功能
全部学习汇总: GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 前面刚刚看完了一个函数和三个文件指针,一行代码懂了半行。但是继续分析我之前看到的代码还是遇到了困难,因为之前自己对于UNIX的一些基础知…...

基于Stackelberg博弈的光伏用户群优化定价模型(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

EXCEL职业版本(3)
Excel职业版本(3) 公式与函数 运算符 算数运算符 关系运算符 地址的引用 相对引用:你变它就变,如影随形 A2:A5 绝对引用:以不变应万变 $A$2 混合引用:识时务者为俊杰,根据时…...

查找Pycharm跑代码下载模型存放位置以及有关模型下载小技巧(model_name_or_path参数)
目录一、前言二、发现问题三、删除这些模型方法一:直接删除注意方法二:代码删除一、前言 当服务器连不上,只能在本地跑代码时需要使用***预训练语言模型进行处理 免不了需要把模型下载到本地 时间一长就会发现C盘容量不够 二、发现问题 正…...
JS学习笔记day04
今日内容 零、 复习昨日 一、事件 二、DOM操作 三、案例 零、 复习昨日 js 脚本语言,弱类型 引入方案: 3种 js的内容: 语法dombom 语法 变量 var 数据类型 引用类型 - 对象,JSON {key:value,key:value} 数组 var arr new Array();var arr [1,2];下标取值赋值pop() s…...
异步控制流程 遍历篇
文章目录基础方法onlyOnce 只执行一次,第二次报错once 只执行一次,第二次无效iteratorSymbol 判断是否具有迭代器并返回迭代器arrayEach 普通数组遍历baseEach 对象类型遍历symbolEach 具有迭代器类型遍历异步遍历each异步控制流程的目的: 对…...

ICASSP 2023论文模型开源|语音分离Mossformer
人类能在复杂的多人说话环境中轻易地分离干扰声音,选择性聆听感兴趣的主讲人说话。但这对机器却不容易,如何构建一个能够媲美人类听觉系统的自动化系统颇具挑战性。 本文将详细解读ICASSP2023本届会议收录的单通道语音分离模型Mossformer论文࿰…...
vs2019 更改工程项目名称
本地 解决方案所在的位置为:D:\Projcet 解决方案名称:hello.sln 位置:D:\Projcet\hello.sln 工程项目名称:test 位置:D:\Projcet\test (文件夹中包含头文件,源文件) 工程包含的文件: fun.h …...

FusionCompute安装和配置步骤
1. 先去华为官网下载FusionCompute的镜像 下载地址:https://support.huawei.com/enterprise/zh/distributed-storage/fusioncompute-pid-8576912/software/251713663?idAbsPathfixnode01%7C22658044%7C7919788%7C9856606%7C21462752%7C8576912 下载后放在D盘中&am…...
makefile 参数和基本使用
make 常用选项make[-f file] [options] [target]make 默认在当前目录中查找GUNmakefile、makefile 及 Makefile 文件作为make的输入文件-f 指定文件作为输入文件-v 显示版本号-n 只输出命令不执行, 一般作为测试-s 执行命令不显示命令,-w 显示执行前和执…...

golang 占位符还傻傻分不清?
xdm ,写 C/C 语言的时候有格式控制符,例如 %s , %d , %c , %p 等等 在写 golang 的时候,也是有对应的格式控制符,也叫做占位符,写这个占位符,需要有对应的数据与之对应,不能瞎搞 基本常见常用…...

manacher算法详解
例题 求一个字符串的最长回文子串的长度 O(N2)O(N^2)O(N2)的解法很容易想,就是从每个字符位置向左右同时拓展,然后检查当前是不是回文,更新长度,可以简单写一下代码 int solve(string &ss){int ans 0;int n ss.length();s…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...