OpenGL系列(五)纹理贴图

概述

    OpenGL纹理是一种在三维图形中应用纹理映射的技术。纹理是一张图像,可以应用到三维模型的表面上,从而使得模型看起来更加真实和具有细节。通过纹理映射,可以将图像的像素值与三维模型的顶点进行匹配,从而为模型的表面增加细节和图案。

    OpenGL提供了一套用于加载、创建和使用纹理的API,使得纹理映射变得简单和高效。在OpenGL中,纹理被存储在纹理缓冲区中,并通过纹理坐标来进行访问。纹理坐标是一个二维向量,范围在[0,1]之间,用于映射纹理的像素值。

    为了应用纹理映射,需要先加载纹理图像并将其传输到OpenGL的纹理缓冲区中。然后,可以在绘制三维模型之前,将纹理坐标与模型的顶点进行匹配,并通过纹理坐标在纹理缓冲区中获取相应的像素值。最后,将像素值应用到模型的表面上,从而实现纹理映射。

OpenGL还提供了一些纹理过滤和纹理环绕的选项,用于控制纹理在放大和缩小时的插值和边界处理。这些选项可以改善纹理映射的质量和效果,使得纹理在不同大小和角度下都能正确显示。

总的来说,OpenGL纹理是一种强大的技术,可以为三维模型增加细节和图案,并提升图形渲染的质量和真实感。通过合理的纹理映射和纹理处理,可以使得模型在视觉上更加吸引人和逼真。

示例

    接下来通过一个简单的示例来介绍如何使用纹理贴图将一张图片映射到一个矩形中,效果如下图所示。

    在上图中,中间是一个矩形,在该矩形中显示的图片,下面分步介绍如何实现上面的效果。

1、创建纹理对象 

    要使用纹理,首先要创建纹理对象,代码如下。

    mTexture = 0;glGenTextures(1, &mTexture);glBindTexture(GL_TEXTURE_2D, mTexture);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

 创建纹理过程解析如下。

1)创建纹理对象:glGenTextures用于创建纹理对象,1表示创建一个纹理对象,成功后纹理对象的句柄保存到tex中。

2)绑定纹理对象:glBindTexture用于绑定纹理对象到纹理目标GL_TEXTURE_2D,绑定后对目标的操作会影响到被绑定的纹理对象。

3)设置参数:glTexParameterf用于设置纹理参数。参数GL_TEXTURE_WRAP_S设置为GL_CLAMP_TO_EDGE表示S方向超出范围[0.0,1.0]时使用边界的颜色,同样参数GL_TEXTURE_WRAP_T也设置为GL_CLAMP_TO_EDGE表示T方向超出范围[0.0,1.0]时使用边界的颜色。参数GL_TEXTURE_MIN_FILTER和GL_TEXTURE_MAG_FILTER都设置为GL_LINEAR表示纹理缩小和放大的过滤方式都是线性插值。

2、载入图片数据

    创建纹理对象后,接下来向该对象载入图片数据,流程如下。

    AAsset *pathAsset = AAssetManager_open(assetManager,path.c_str(), AASSET_MODE_BUFFER);unsigned char *filedata = (unsigned char *) AAsset_getBuffer(pathAsset);off_t assetLength = AAsset_getLength(pathAsset);stbi_set_flip_vertically_on_load(true);unsigned char *data = stbi_load_from_memory(filedata, assetLength,&w,&h,&n,0);if(data != nullptr){GLint format = GL_RGB;if(n == 4) format = GL_RGBA;glTexImage2D(GL_TEXTURE_2D,0, format, w,h,0,format,GL_UNSIGNED_BYTE, data);glGenerateMipmap(GL_TEXTURE_2D);}

载入图片数据流程解析如下

1)AAssetManager_open打开assets目录的图片文件

2)AAsset_getBuffer获取图片文件的缓冲

3)stbi_load_from_memory将图片缓冲解吗得到图片数据

4)glTexImage2D向纹理对象载入图片数据

5)glGenerateMipmap生成多级渐远纹理

3、绑定纹理单元

    纹理对象要绑定到特定的纹理单元,采样器才能采样,绑定方法如下

    glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, mTexture);

    这里把纹理对象绑定到0号纹理单元。

4、编写着色器

    纹理贴图的着色器如下。

    std::string strVs = R"(
#version 300 es
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;out vec2 vTexCoord;void main()
{gl_Position = vec4(aPos, 1.0);vTexCoord = aTexCoord;
}
)";std::string strFs = R"(
#version 300 es
precision mediump float;
out vec4 FragColor;
in vec2 vTexCoord;
uniform sampler2D sampler;
void main()
{FragColor = texture(sampler, vTexCoord);
}
)";

    在顶点着色器中,有两个顶点属性,0号属性aPos表示顶点位置,1号属性aTexCoord表示纹理坐标。

    在片元着色器中,vTexCoord是纹理坐标,sampler是纹理采样器,在main方法中调用采样函数texture对纹理进行采样,采样结果输出到FragColor。

5、开始绘制

    绘制纹理的流程如下所示。

    mShader->setInt("sampler",0);glClear(GL_COLOR_BUFFER_BIT);glClearColor(0.5f,0.6f,0.7f,1.0f);glBindVertexArray(VAO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

绘制流程解析如下:

mShader->setInt("sampler",0); 知会着色器的采样器到几号纹理单元采样,0表示0号纹理单元。

glBindVertexArray(VAO);绑定VAO,有了VAO才知道如何取得顶点数据。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 绑定索引数据

glDrawElements开始绘制,由于已经绑定了索引数据,所以最后的参数无须传索引数据的首地址。

6、工程地址

    本示例已经上传到github,地址如下。

示例工程地址

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

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

相关文章

验证码识别接口、多种样式验证码识别接口、中英文验证码识别接口

验证码识别接口、多种样式验证码识别接口、中英文验证码识别接口 本文提供一个基于OCR和机器学习的验证码识别接口,能够识别较复杂的中文、英文验证码,在OCR的基础上针对验证码进行算法优化。本接口是收费的(最低0.5分1次调用,试…

23种设计模式之代理模式

代理模式 1、概念 代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问 代理模式是常用的结构型设计模式之一,在Java RMI、Web Service、Spring AOP等技术和框架中都使用了代理模式 2、代理模式结构 Subject&a…

解析 Spring 框架中的三种 BeanName 生成策略

在 Spring 框架中,定义 Bean 时不一定需要指定名称,Spring 会智能生成默认名称。本文将介绍 Spring 的三种 BeanName 生成器,包括在 XML 配置、Java 注解和组件扫描中使用的情况,并解释它们如何自动创建和管理 Bean 名称。 1. Be…

Nodejs 第七十七章(MQ高级)

MQ介绍和基本使用在75章介绍过了,不再重复 MQ高级用法-延时消息 什么是延时消息? Producer 将消息发送到 MQ 服务端,但并不期望这条消息立马投递,而是延迟一定时间后才投递到 Consumer 进行消费,该消息即延时消息 插件安装 R…

业务安全蓝军测评标准解读—业务安全体系化

目录 1.前言 2.业务蓝军测评标准 2.1 业务安全脆弱性评分(ISVS) 2.2 ISVS评分的参考意义 2.3 纵向对比 2.4 横向对比 3.业务蓝军测评案例 3.1 APP虚假安装案例 3.1.1 定义测评对象和攻击目标 3.1.2 制定攻击方案 3.1.3 执行攻击并评估 3.2 人脸识别绕过案例 3.2.…

STM32硬件接口I2C应用(基于MP6050)

目录 概述 1 STM32Cube控制配置I2C 1.1 I2C参数配置 1.2 使用STM32Cube产生工程 2 HAL库函数介绍 2.1 初始化函数 2.2 写数据函数 2.3 读数据函数 3 认识MP6050 3.1 MP6050功能介绍 3.2 加速计测量寄存器 ​编辑3.3 温度计量寄存器 3.4 陀螺仪测量寄存器 4 MP60…

微信小程序组件传值

虽然微信小程序是比较轻量的,但是还是拥有组件的 这是文件的基本目录 我们的代码基本都在pages和components文件夹中 在component中创建组件 在component中 ,创建一个目录 我创建了一个 head目录 用于配置头部信息 我在这里创建了 一个头部组件&…

linux-计划任务

作用:定时自动完成特定的工作 计划任务的分类 一次性的计划任务:例如下周三对文档的重要文件备份一次 周期性的计划任务:每天12:00创建一个文件 命令 一次性的任务计划 at batch 周期性计划任务 crontab anacron 一次性计划任务 …

Github 2024-06-12 C开源项目日报 Top10

根据Github Trendings的统计,今日(2024-06-12统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目10PHP项目1PLpgSQL项目1C++项目1Ventoy: 100%开源的可启动USB解决方案 创建周期:1534 天开发语言:C协议类型:GNU General Public Licen…

品牌与产品:消费者决策的经济逻辑与品牌宣传的战略意义

在当今日益全球化的经济环境中,品牌与产品之间的关系对于企业的成功与否起着至关重要的作用。然而,在消费者做出购买决策时,他们到底是在选择产品本身,还是在选择附着在产品之上的品牌价值?同样,当客户选择…

载波相移CPS-SPWM调制方法的simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 载波相移CPS-SPWM调制方法的simulink建模与仿真,载波相移PWM方法: 2.系统仿真结果 单极倍频 釆用 调制波 反相 法 , 基本调制原理为 &…

【总线】设计fpga系统时,为什么要使用总线?

目录 为什么用总线 为什么选择AMBA 总结 系列文章 【总线】AMBA总线架构的发展历程-CSDN博客 【总线】设计fpga系统时,为什么要使用总线?-CSDN博客 为什么用总线 在FPGA系统设计中,使用总线是为了实现组件间的高效互联与通信&#xff0c…

惠州惠城:可燃气体报警器定期校准检测,安全更放心

在惠州惠城这片繁华的土地上,工业发展日新月异,安全问题愈发受到重视。其中,可燃气体报警器作为预防火灾和爆炸事故的重要设备,正在越来越多的场所得到应用。 今天,佰德就来探讨一下可燃气体报警器在惠州惠城的重要性…

3.2 窗口滚动条

本节讲述窗口滚动条的简单使用方法。如果窗口客户区的内容太多,为了方便浏览窗口客户区的所有内容,就需要在创建窗口时添加窗口垂直或水平滚动条样式。窗口过程处理WM_CREATE消息时初始化滚动条的位置和滚动范围。窗口过程处理WM_VSCROLL或WM_HSCROLL消息…

idea自定义注释模板

1、打开配置 setting -> Editor -> Live Template 2、添加TemplateGroup,并在添加的TemplateGroup下加LiveTemplate 3、配置Live Template 内容: **** Description: * $param$* return $return$ * author $user$* date $date$ $time$**/变量…

LLM微调方法(Efficient-Tuning)六大主流方法:思路讲解优缺点对比[P-tuning、Lora、Prefix tuning等]

LLM微调方法(Efficient-Tuning)六大主流方法:思路讲解&优缺点对比[P-tuning、Lora、Prefix tuning等] 由于LLM参数量都是在亿级以上,少则数十亿,多则数千亿。当我们想在用特定领域的数据微调模型时,如果想要full-tuning所有模…

opencv_GUI

图像入门 import numpy as np import cv2 as cv # 用灰度模式加载图像 img cv.imread(C:/Users/HP/Downloads/basketball.png, 0)# 即使图像路径错误,它也不会抛出任何错误,但是打印 img会给你Nonecv.imshow(image, img) cv.waitKey(5000) # 一个键盘绑…

Redis集群(5)

集群原理 节点通信 通信流程 在分布式存储系统中,维护节点元数据(如节点负责的数据、节点的故障状态等)是关键任务。常见的元数据维护方式分为集中式和P2P方式。Redis集群采用P2P的Gossip协议,这种协议的工作原理是节点之间不断…

解决生产问题的万能接口(Java编译器API的使用)

文章目录 前言Tool和ToolProvider编译器工具:JavaCompiler文件管理文件:FileObject文件管理器:JavaFileManager 诊断监听器:DiagnosticDemo:allPowerfulInterface具体实现测试 结语 前言 当生产环境出现问题时&#x…

【模拟-BM100 设计LRU缓存结构】

题目 BM100 设计LRU缓存结构 描述 设计LRU(最近最少使用)缓存结构,该结构在构造时确定大小,假设大小为 capacity ,操作次数是 n ,并有如下功能: Solution(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存get(key)&am…