OpenGL原理与实践——核心模式(三):Texture-纹理系统理论与应用

news2025/8/12 4:05:54

目录

初识——纹理系统是什么?怎么用?

Texture —— UV坐标系统

Texture Wrapping:UV超过了[0,1]怎么办?

Texture Filter:UV经过计算得到的是浮点数怎么办?

在OpenGL中该怎么做呢?

Texture Unit——OpenGL提供了多个Texture锚定点,显示多个纹理图

整理代码、建立ffImage类

Texture纹理的应用


初识——纹理系统是什么?怎么用?

Texture —— UV坐标系统

  • UV坐标定义到每一个顶点上
  • 通过插值,到纹理图片上采样
  • 得到像素点颜色 

Texture Wrapping:UV超过了[0,1]怎么办?

OpenGL提供了几种方式,如图

Texture Filter:UV经过计算得到的是浮点数怎么办?

Texture Filter的结果以及相关情况下的设置

也就是说在纹理变小的时候,采用Nearest进行采样;纹理变大的时候,采用Linear方式采样。

在OpenGL中该怎么做呢?

①在C++当中创建Texture,并且绑定到系统中进行渲染和数据传递

②在shader中进行处理 

Texture Unit——OpenGL提供了多个Texture锚定点,显示多个纹理图

整理代码、建立ffImage类

新建ffImage.h及ffImage.cpp

//ffImage.h
#pragma once
#include "Base.h"

class ffImage
{
private:
	int			m_width;
	int			m_height;
	int			m_picType;
	ffRGBA*		m_data;
public:
	int			getWidth()const { return m_width; }
	int			getHeight()const { return m_height; }
	int			getPicType()const { return m_picType; }
	ffRGBA*		getData()const { return m_data; }

	ffRGBA		getColor(int x, int y)const {
		if (x<0 || x>m_width - 1 || y<0 || y>m_height - 1) {
			return ffRGBA(0, 0, 0, 0);
		}
		return m_data[y * m_width + x];
	}

	ffImage(int _width = 0, int _height = 0, int _picType = 0, ffRGBA* _data = nullptr) {
		m_width = _width;
		m_height = _height;
		m_picType = _picType;

		int _sumSize = m_width * m_height;
		if (_data && _sumSize) {
			m_data = new ffRGBA[_sumSize];
			memcpy(m_data, _data, sizeof(ffRGBA) * _sumSize);
		}
		else {
			m_data = nullptr;
		}
	}
	~ffImage() {
		if (m_data) {
			delete[]m_data;
		}
	}

public:
	static ffImage* readFromFile(const char* _fileName);

};

//ffImage.cpp
#include "ffImage.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

ffImage* ffImage::readFromFile(const char* _fileName)
{
	int		_picType = 0;
	int		_width = 0;
	int		_height = 0;

	//stbimage读入图片是反过来的
	stbi_set_flip_vertically_on_load(true);

	unsigned char* bits = stbi_load(_fileName, &_width, &_height, &_picType, STBI_rgb_alpha);
	ffImage* _image = new ffImage(_width, _height, _picType, (ffRGBA*)bits);

	stbi_image_free(bits);
	return _image;
}

Texture纹理的应用

同样的,建立一个句柄:

unsigned int _texture = 0;

纹理的相关处理:

void initTexture() {
	_pImage = ffImage::readFromFile("res/wall.jpg");
	//纹理绑定
	glGenTextures(1, &_texture);
	glBindTexture(GL_TEXTURE_2D, _texture);
	//纹理属性设置
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	//读入图片数据
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _pImage->getWidth(), _pImage->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE,_pImage->getData());
}

同样的,需要在顶点数组中添加UV信息:

	float vertices[] = {
		//顶点信息				颜色信息			纹理信息
		0.5f, 0.5f, 0.0f,		1.0f,0.0f,0.0f,		1.0f,1.0f,
		0.5f, -0.5f, 0.0f,	 	0.0f,1.0f,0.0f,		1.0f,0.0f,
		-0.5f, -0.5f, 0.0f,		0.0f,0.0f,1.0f,		0.0f,0.0f,
		-0.5f, 0.5f, 0.0f,		0.0f,1.0f,0.0f,		0.0f,1.0f
	};

同样的,新建一个锚点(layout):

	//对哪个锚点进行操作:layout=0的锚点,读3个顶点,类型为float,不需要归一化,每次步长为3个float大小,从0处开始读
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(sizeof(float)*3));
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(sizeof(float)*6));

同样的,激活这个锚点2

	//打开锚点:激活
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	glEnableVertexAttribArray(2);

同样的,更新一下shader

//vertexShader.glsl
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aUV;

out vec4 outColor;
out vec2 outUV;

void main()
{
   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
   outColor = vec4(aColor, 1.0f);
   outUV = aUV;
};
//fragmentShader.glsl
#version 330 core
out vec4 FragColor;

in vec4 outColor;
in vec2 outUV;

uniform sampler2D outTexture;

void main()
{
    FragColor = texture(outTexture, outUV);
};

这里值得注意一点,在fragmentShader中的sampler2D,这里并没有通过C++的代码传入数据,因为我们只用了一张纹理贴图,默认texture unit为0,而这个sampler2D也是默认取为0的texture unit

渲染结果:

混合结果:

//fragmentShader.glsl
#version 330 core
out vec4 FragColor;

in vec4 outColor;
in vec2 outUV;

uniform sampler2D outTexture;

void main()
{
    FragColor = texture(outTexture, outUV) * outColor;
};

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

列表和标签企业报告版的完整报告解决方案

列表和标签企业报告版的完整报告解决方案 无缝集成到所有主要开发环境和编程语言&#xff1a;Visual Studio、.NET/。NET核心(C#、VB.NET)、C/C、Delphi/VCL、Java、Progress、DataFlex、dBASE PLUS、Xbase等。 通过现代数据绑定灵活连接到任何数据源&#xff1a;List&Labe…

自适应点云配准(RANSAC、ICP)

点云配准 实验目标 任务一&#xff1a;将两个形状、大小相同的点云进行配准&#xff0c;进而估计两个点云之间的位姿。 任务二&#xff1a;将一些列深度图反向投影得到点云&#xff0c;经过配准后&#xff0c;得到每个深度图之间的位姿变换&#xff0c;并将相应的点云融合到一…

【云原生】Docker镜像的创建,Dockerfile

内容预知 1.Dokcer镜像的创建 1.1 基于现有镜像创建 1.2 基于本地模板创建 1.3 基于Dockerfile 创建 联合文件系统(UnionFS ) 镜像加载原理 容器中操作系统容量小的原因 Docker镜像结构的分层 Dockefile的引入 2. Dockerfile 操作命令的指令 2.1 FROM 镜像 2.2 MA…

股票接口实时交易数据怎么查询?

股票数据接口作为软件应用而言&#xff0c;很多资源和数据是由自身提供的&#xff0c;像其他一些功能还是需要调用第三方提供的服务&#xff0c;这其中就涉及到股票数据接口api的调用功能&#xff0c;通过api来获取实时交易数据查询更方便&#xff0c;因此&#xff0c;如果交易…

【学习笔记17】JavaScript作用域

笔记首发 一、作用域 &#x1f634;我们学变量&#xff0c;不是在任何地方都可以使用&#x1f634;变量有一个使用区间, 这个可以使用的区间就叫做作用域 1、全局作用域 &#x1f62b; script标签内部声明的变量&#xff0c;就是全局作用域的变量&#x1f60f;在全局作用域声明…

计算机网络的定义和分类

计算机网络早期定义&#xff1a;自治互联的计算机集合 计算机网络系统的基本组成为&#xff1a;通信子网资源子网 计算机网络分类&#xff1a; 公用网通常是由电信公司出资建造的大型网络。 专用网通常是由某个部门为满足本单位特殊业务的需要建造的网络&#xff…

基于springboot+jpa+camunda实现简单的请假审批流程

整个camunda的绘图、具体使用&#xff0c;参照上一篇文章Camunda工作流引擎简记。 源码地址&#xff0c;相关技术储备如下 springboot–v2.5.4jpa–v2.5.4postgresql–v11camunda–v7.16.0 整个过程不需要建表&#xff0c;这就是JPA面向对象编程的好处&#xff0c;这也是我认…

33 - C++中的字符串类

---- 整理自狄泰软件唐佐林老师课程 1. 历史遗留问题 C语言 不支持真正意义上的字符串 C语言用 字符数组 和 一组函数 实现字符串操作 C语言 不支持自定义类型&#xff0c;因此无法获得字符串类型 解决方案 从C到C的进化过程 引入了 自定义类型在C中可以通过类完成字符串类型…

iOS上架app store详细教材

1、安装iOS上架辅助软件Appuploader 2、申请iOS发布证书&#xff08;p12&#xff09; 3、申请iOS发布描述文件&#xff08;mobileprovision&#xff09; 4、打包ipa 5、上传ipa到iTunes Conn 1、安装iOS上架辅助软件Appuploader2、申请iOS发布证书&#xff08;p12&#xff09;…

ImmunoChemistry艾美捷牛膜联蛋白V-荧光素凋亡检测试剂盒方案

ImmunoChemistry艾美捷牛膜联蛋白V-荧光素细胞凋亡检测试剂盒提供了一种经验证的方法&#xff0c;可使用重组荧光素结合的牛膜连蛋白V和碘化丙啶&#xff08;PI&#xff09;快速、轻松地区分两个死亡细胞群和活细胞群。这些细胞将被膜联蛋白V-荧光素&#xff08;绿色荧光&#…

docker容器持久化

第六章容器持久化 容器数据卷 什么是容器数据卷&#xff1f; 容器之间可以有一个数据共享技术&#xff01;docker容器中产生的数据&#xff0c;同步到本地&#xff01; 这就是卷技术&#xff01;目录的挂载&#xff0c;将我们容器内的目录&#xff0c;挂在到linux上面&#x…

线性时间选择(Top K)问题(Java)

线性时间选择&#xff08;Top K&#xff09;问题&#xff08;Java&#xff09; 文章目录线性时间选择&#xff08;Top K&#xff09;问题&#xff08;Java&#xff09;1、前置介绍2、分治法求解3、代码实现4、复杂度分析5、扩展6、参考资料1、前置介绍 定义 选择问题&#xff0…

docker可视化与制作和提交自己的镜像

第四章docker可视化 portainer docker的图形化管理工具&#xff01;提供一个后台面板供我们操作&#xff01; docker run -d -p 8080:9000 \--restartalways -v /var/run/docker.sock:/var/run/docker.sock --privilegedtrue portainer/portainer 访问测试&#xff1a;外网…

Python_数据容器_元组tuple

一、元组tuple定义 为什么需要元组 列表是可以修改的&#xff0c;如果想要传递的信息不被篡改&#xff0c;列表就不适合了 元组和列表一样&#xff0c;都是可以封装多个不同类型的元素在内 最大的不同点在于&#xff1a; 元祖一旦定义完成&#xff0c;就不可修改 所以&am…

SpringBoot中使用JDBC

JDBC基础使用&#xff1a; JDBC基础使用_做测试的喵酱的博客-CSDN博客 一、SpringBoot使用JDBC&#xff0c;依赖 依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId&…

linux zookeeper kafka_2.12-2.2.0 集群

文章目录一、zookeeper服务搭建1. 下载2. 解压3. 创建目录4. 调整配置5. 配置myid6. 开放防火墙7.启动验证zk二、kafka集群搭建2.1. 下载软件2.2. 解压2.3. 配置2.5. 启动kafka三、测试验证3.1. 创建一个主题3.2. 发送消息3.3. 消费消息预先准备&#xff1a;上传软件至服务器19…

使用Avalonia跨Linux平台

Avalonia&#xff0c;读&#xff1a;阿瓦隆尼亚 这里的跨平台指的是&#xff0c;使用c#语言开发跨Linux平台。c#在Windows桌面开发中很强&#xff0c;但是在Linux桌面中&#xff0c;不能跨平台&#xff0c;Qt可以在Linux中跨平台&#xff0c;但是那是另外一门语言了。Avalonia…

计算机组成原理4小时速成:计算机运算方法,无符号数和有符号数,定点数和浮点数,移位运算,加减运算,乘法运算,原码,反码,补码

计算机组成原理4小时速成&#xff1a;计算机运算方法&#xff0c;无符号数和有符号数&#xff0c;定点数和浮点数&#xff0c;移位运算&#xff0c;加减运算&#xff0c;乘法运算&#xff0c;原码&#xff0c;反码&#xff0c;补码 2022找工作是学历、能力和运气的超强结合体&…

[激光原理与应用-16]:《激光原理与技术》-2- 光的本质(粒子、波动说、电磁波、量子)

目录 前言&#xff1a;“光” 一、光的微粒说 - 牛顿 二、光的波动说 - 托马斯杨 惠更斯 三、光是电磁波 - 麦克斯韦 四、光的波动说受到的挑战&#xff0c;光的波动说重新唤醒 五、光量子假说 - 爱因斯坦 六、光的理论综合 七、光的重要特性 7.1 光的相干性 7.2 相…

安装ideaIU-2022.1.4报错问题解决办法

原来版本是2020 现在因为要用到JDK17 而IDEA2020支持的JDK只能到14 所以我们现在在下载一个2022 .1.4 这时我们安装好后 会发现如下错误 原因分析&#xff1a; JetBrains 会将各个产品的这些文件也放到这个目录中&#xff0c;而新版本的 IntelliJ IDEA 在安装时遭遇了旧版本…