OpenGL超级宝典 纹理(一)
文章目录
- 纹理
- 创建并且初始化纹理
- 更新纹理数据
- 从着色器中读取数据
- 采样器类型
- 控制纹理数据的读取方式
- 创建采样器对象和绑定到纹理单元
- 纹理过滤
- 设置过滤器
- 加载纹理
- 完整代码展示
- shader
- vertex shader
- fragment shader
- Shader
- 源代码
- 效果
- 总结
纹理
纹理是一种结构化的存储形式,可供着色器读写。
纹理通常用于存储图形数据,并有多种形式和布局。
创建并且初始化纹理
纹理的创建和vbo的创建差不多
先创建纹理对象,然后分配内存,绑定到OpenGL,将数据添加到缓存。
GLuint texture;//1、创建纹理对象glCreateTextures(GL_TEXTURE_2D, 1, &texture);//2、分配纹理缓存空间glTextureStorage2D(texture, //纹理对象1, //mipmap层数,这个只是分配的内存!!!GL_RGB8, //数据格式width, //纹素的宽height); //纹素的长//3、绑定纹理对象到OpenGL上下文,告诉OpenGL纹理的类型glBindTexture(GL_TEXTURE_2D, texture);
更新纹理数据
//4、更新纹理数据glTextureSubImage2D(texture, //纹理对象0, //mipmap层数,这是纹理的!!!别和上面的弄混乱0, 0, //开始坐标width, height, //纹理宽和长GL_RGB, //纹理数据格式GL_UNSIGNED_BYTE, //数据类型image_data); //数据
从着色器中读取数据
着色器中的纹理以采样器变量形式存在,通过sampler类型的统一变量与外界进行连接。
glsl中二维纹理的采样器类型为sampler2D
#version 450 coreout vec4 color;uniform sampler2D s;in vec2 txcoord;void main()
{color = texture(s, txcoord);
}
采样器类型
控制纹理数据的读取方式
通常,纹理坐标都是标准化坐标,即坐标的范围为0.0~1.0。
通过OpenGL可以控制当提供的纹理坐标超出此范围时的情况,这称为采样器的包装模式(wrapping mode)。
同时,我们可以决定如何计算实际采样器之间的值,这称为采样器的过滤模式(filering mode)。
控制采样器包装和过滤模式的参数存储在采样器对象(sampler object)中。
创建采样器对象和绑定到纹理单元
//5.1、创建采样器对象glCreateSamplers(1, &s);//绑定到纹理单元,使用多个纹理的时候用,一个纹理不需要用!//glBindSampler(0, s);
纹理过滤
纹理图中的纹素和屏幕上的像素之间几乎从来不存在一一对应的关系
因此,纹理图像在进行纹理贴图的时候总是被拉伸或收缩。
glsl中有一个函数texture(),可以通过从拉伸或收缩的纹理图中计算颜色片段来对贴图进行调节。这个函数有几种重载:
vec4 texture(sampler1D s, float P);
vec4 texture(sampler2D s, vec2 P);
ivec4 texture(isampler2D s, vec2 P);
uvec4 texture(usampler3D s, vec3 P);
从拉伸或收缩的纹理图中计算颜色片段的过程称为纹理过滤(texture filering)。
拉伸纹理也叫作放大(magnification)
,收缩纹理也叫作缩小(minification)
。
利用采样器的参数,OpenGL支持分别在放大和缩小情况下分别设置构造纹素值的方法。这些条件称为
过滤器(filter)
。
这两个过滤器的名称分别为
GL_TEXTURE_MAG_FILTER
和GL_TEXTURE_MIN_FILTER,分别对应放大
和缩小
过滤器
我们可以从GL_NEAREST和GL_LINEAR这两个基本纹理过滤器中进行选择,分别对应最近邻
和线性
过滤
设置过滤器
//5.2、设置纹理过滤方式,多个纹理的时候用这个/*glSamplerParameterf(s, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glSamplerParameterf(s, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glSamplerParameterf(s, GL_TEXTURE_WRAP_S, GL_REPEAT);glSamplerParameterf(s, GL_TEXTURE_WRAP_T, GL_REPEAT);*///采用纹理嵌入的采样器对象,只有一个纹理的时候使用这个glTextureParameterf(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTextureParameterf(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTextureParameterf(texture, GL_TEXTURE_WRAP_S, GL_REPEAT);glTextureParameterf(texture, GL_TEXTURE_WRAP_T, GL_REPEAT);
加载纹理
这里我使用的加载纹理方式是使用stb_image库进行加载
可以通过此链接下载
https://github.com/nothings/stb/blob/master/stb_image.h
完整代码展示
shader
vertex shader
#version 450 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 tex_coord;out vec2 txcoord;uniform mat4 mvp;void main()
{txcoord = tex_coord;gl_Position = vec4(position, 1.0);
}
fragment shader
#version 450 coreout vec4 color;uniform sampler2D s;in vec2 txcoord;void main()
{color = texture(s, txcoord);
}
Shader
和上篇文章的一样
源代码
#define STB_IMAGE_IMPLEMENTATION
#include "sb7.h"
#include "Shader.h"
#include "stb_image.h"
#include "sb7ktx.h"
#include <iostream>using std::cout;
using std::endl;class my_applicaiton : public sb7::application
{public:void startup(){//加载纹理unsigned char* image_data = stbi_load("wall.jpg", &width, &height, &nrChannel, 0);if (!image_data){cout << "load image fail" << endl;}cout << "channel: " << nrChannel << endl;cout << "width: " << width << endl;cout << "height: " << height << endl;float data[] ={ //vertex_coord uv_coord-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 1.0f,0.5f, 0.5f, -0.5f, 1.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 1.0f,0.5f, 0.5f, 0.5f, 1.0f, 1.0f,-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 1.0f,0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.5f, -0.5f, 0.5f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.5f, -0.5f, -0.5f, 1.0f, 1.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.5f, 0.5f, -0.5f, 1.0f, 1.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f};//create shader instanceshader = new Shader("vs.vert", "fs.frag");//create shader object; glCreateVertexArrays(1, &vao);//bind vao to contentglBindVertexArray(vao);//create vbo objectglCreateBuffers(1, &vbo);//bind vbo to content glBindBuffer(GL_ARRAY_BUFFER, vbo);//分配内存glNamedBufferStorage(vbo, //缓存目标sizeof(data), //缓存大小nullptr, //无数据GL_DYNAMIC_STORAGE_BIT);//模式glNamedBufferSubData(vbo, //缓存0, //偏移量sizeof(data), //数据大小data); //数据//绑定缓存到vaoglVertexArrayVertexBuffer(vao, //绑定的vao0, //顶点属性vbo, //绑定的vbo0, //绑定点sizeof(float) * 5); //每个顶点之间的距离//绑定到vaoglVertexArrayAttribBinding(vao, //vao0, //顶点属性0); //绑定点glVertexArrayAttribFormat(vao, //vao0, //顶点属性3, //顶点分量GL_FLOAT, //数据类型GL_FALSE, //是否标准化0); //顶点属性的顶点与起始顶点的距离你glVertexArrayAttribBinding(vao, 1, 0);glVertexArrayAttribFormat(vao, 1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 3);//启用顶点属性glEnableVertexArrayAttrib(vao, 0);glEnableVertexArrayAttrib(vao, 1);//1、创建纹理对象glCreateTextures(GL_TEXTURE_2D, 1, &texture);//2、分配纹理缓存空间glTextureStorage2D(texture, //纹理对象1, //mipmap层数,这个只是分配的内存!!!GL_RGB8, //数据格式width, //纹素的宽height); //纹素的长//3、绑定纹理对象到OpenGL上下文,告诉OpenGL纹理的类型glBindTexture(GL_TEXTURE_2D, texture);//4、更新纹理数据glTextureSubImage2D(texture, //纹理对象0, //mipmap层数,这是纹理的!!!别和上面的弄混乱0, 0, //开始坐标width, height, //纹理宽和长GL_RGB, //纹理数据格式GL_UNSIGNED_BYTE, //数据类型image_data); //数据//5、控制纹理数据的读取方式//5.1、创建采样器对象glCreateSamplers(1, &s);//绑定到纹理单元,使用多个纹理的时候用glBindSampler(0, s);//5.2、设置纹理过滤方式/*glSamplerParameterf(s, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glSamplerParameterf(s, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glSamplerParameterf(s, GL_TEXTURE_WRAP_S, GL_REPEAT);glSamplerParameterf(s, GL_TEXTURE_WRAP_T, GL_REPEAT);*///采用纹理嵌入的采样器对象glTextureParameterf(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTextureParameterf(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTextureParameterf(texture, GL_TEXTURE_WRAP_S, GL_REPEAT);glTextureParameterf(texture, GL_TEXTURE_WRAP_T, GL_REPEAT);}void render(double currentTime){GLfloat colors[] = { 0.0, 0.5, 0.0, 1.0 };glClearBufferfv(GL_COLOR, 0, colors);shader->use();glDrawArrays(GL_TRIANGLES, 0, 36);//delete[] data;}void shutdown(){}private://vao object and vbo objectGLuint vao;GLuint vbo;//shader objectShader* shader;//texture objectGLuint texture;//samplerGLuint s;int width, height, nrChannel;
private:};DECLARE_MAIN(my_applicaiton);
效果
总结
- 创建纹理对象
- 分配纹理缓存空间
- 绑定纹理对象到OpenGL上下文,告诉OpenGL纹理的类型
- 更新纹理数据
- 控制纹理数据的读取方式
5.1 创建采样器对象
5.2 设置纹理过滤方式
OpenGL超级宝典 纹理(一)相关推荐
- OpenGL超级宝典(第7版)笔记20 统一变量 一致区块 uniform相关内容 清单5.9-5.28
OpenGL超级宝典(第7版)笔记20 统一变量 一致区块 uniform相关内容 清单5.9-5.28 文章目录 OpenGL超级宝典(第7版)笔记20 统一变量 一致区块 uniform相关内容 ...
- OpenGL超级宝典学习笔记——操作矩阵
为了更强大的功能和灵活性,我们有时需要直接操作矩阵.在OpenGL中4x4的矩阵用包含16个浮点数值的一维数组来表示,而不是用二维的4x4的数组来表示.OpenGL之所以这么做,因为使用一维数组更高效 ...
- OpenGL超级宝典(第7版)之第十一章高级数据管理
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 OpenGL超级宝典(第7版)之第十一章高级数据管理 前言 一.取消绑定 二.稀疏纹理 三.压缩纹理 四.压缩数据格式 五.高质量纹理 ...
- 《OpenGL超级宝典(第5版)》——第1章,第1.1节计算机图形的简单历史回顾
本节书摘来自异步社区<OpenGL超级宝典(第5版)>一书中的第1章,第1.1节计算机图形的简单历史回顾,作者 [美]Richard S. Wright , Jr.Nicholas Hae ...
- 《OpenGL超级宝典》编程环境配置
最近在接触OpenGL,使用的书籍就是那本<OpenGL超级宝典>,不过编程环境的搭建和设置还是比较麻烦的,在网上找了很多资料,找不到GLTools.lib这个库.没办法自己就借助源码自己 ...
- [转]OpenGL超级宝典 5e 环境配置
OpenGL超级宝典(第五版)环境配置 1.各种库的配置 (1)glew 下载:https://sourceforge.net/projects/glew/files/glew/1.7.0/glew- ...
- OpenGL超级宝典(第7版)笔记11 帧缓存运算 计算着色器 清单 3.13
OpenGL超级宝典(第7版)笔记11 帧缓存运算 计算着色器 清单 3.13 文章目录 OpenGL超级宝典(第7版)笔记11 帧缓存运算 计算着色器 清单 3.13 1 帧缓存运算 1.1 裁剪测 ...
- OpenGL超级宝典(第7版)之第十二章管线监控
OpenGL超级宝典(第7版)之第十二章管线监控 前言 一.查询 1.遮挡查询 二.OpenGL同步 前言 查询命令在图形管线中的执行进程 测量命令执行时间 同步应用程序与OpenGL以及同步多重Op ...
- OpenGL 游戏开发: 熟悉练习【《OpenGL超级宝典》第二章】
学习了<OpenGL超级宝典>第二章后,编写了我们的第一个OpenGL程序,也真正开始了OpenGL之旅. 下面来让我们一起重新练习熟悉一下第二章的3个例子吧! 1. "Tri ...
- win7 上配置openGL开发环境(配套openGL 超级宝典Super Bible 6th)
此教程配套openGL 超级宝典super Bible圣经 第六版基于最新openGL4.3,但只有英语版 第六版比第五版(第五版目前有中文版基于openGL3.2)跨了一个时代,改变非常巨大,所以笔 ...
最新文章
- JHipster技术简介
- matlab reshape函数_numpy中的np.ascontiguousarray()函数
- 梦工厂实验室 取石子之fans 博弈
- SpringBoot中使用POI实现Excel导入到数据库(图文教程已实践)
- 播放视频比较好的框架
- java人种_实在看不出藏族有大量矮黑血统
- Halcon中OCR的实现及关键函数解析
- 解决 windows npm ERR! asyncWrite is not a function 问题
- tomcat7中get请求中文乱码问题
- 有线异步通信原理_全光纤网络结构原理是什么 全光纤网络结构原理介绍【详解】...
- 视频编解码发展历程(从AVC到HEVC再到VVC)(一)
- linux r画图如何输出图片大小,R画图,设画布大小
- HCIP第十六天(VLAN IF接口,STP生成树协议,BPDU的配置)
- 采用to_excel保存文件不覆盖原有的sheet
- 【Unity】一些不错的unity插件
- 【Android--项目构建失败原因及解决】
- C++打造植物大战僵尸辅助!附完整项目源码
- 自我管理能力提升-角色定位
- Acwing:COW(DP+状态机 Python)
- 支付宝年度账单交互效果的实现