纹理

纹理是一个2D图片(甚至也有1D和3D的纹理),它可以用来添加物体的细节。
这是两张照片叠加的效果

由下面两张叠加而成

源代码

shaders类在自定义着色器 中有完整的源代码。
下边我们使用stb_image.h来解析图片。

#define GLEW_STATIC // 这个一定要加不然报错 静态链接库#include<GL/glew.h>
#include<GLFW/glfw3.h>
#include<iostream>
#include "Shaders.h"#define STB_IMAGE_IMPLEMENTATION#include "stb_image.h"using namespace std;void processInput(GLFWwindow);void processInput(GLFWwindow *window) {//如果键盘输入esc 则触发 退出if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {// 设置 要求退出glfwSetWindowShouldClose(window, true);}
}// 逆时针方向绘制  默认情况下,逆时针的顶点连接顺序被定义为三角形的正
// 逆时针或顺时针都是相对于观察者方向的
// uv(st)坐标 u(s)为x轴 v(t)为y轴  是给图片定义的 范围都是0 - 1
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, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f    // 左上
};
// 使用索引来减小画点的开销 (未用索引缓冲对象时,每个点都需要画一次(即使重复了))
unsigned int indices[]{0, 1, 2, //第一个三角形的索引2, 3, 0 //第二个三角形的索引
};int main() {// 初始化GLFWglfwInit();// 提示 我们使用的版本是3.3// 主版本glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);// 次版本glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);// 简介glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 创建一个窗口对象GLFWwindow *window = glfwCreateWindow(800, 600, "Test window", NULL, NULL);if (window == NULL) {cout << "open window failed." << endl;// 终止 glfwglfwTerminate();}// 绑定window到上下文对象 创建完窗口我们就可以通知GLFW将我们窗口的上下文设置为当前线程的主上下文了glfwMakeContextCurrent(window);glewExperimental = true;// GLEW_OK 0//init GLEWif (glewInit() != GLEW_OK) {cout << "glew init failed." << endl;// 终止 glfwglfwTerminate();return -1;}// OpenGL渲染窗口的尺寸大小// glViewport函数前两个参数控制窗口左下角的位置。第三个和第四个参数控制渲染窗口的宽度和高度(像素)glViewport(0, 0, 800, 600);// 设置剔除 (opegl默认正面背面都显示(不剔除))//glEnable(GL_CULL_FACE);// 剔除背面 GL_BACK 剔除正面 GL_FRONT//glCullFace(GL_BACK);// 线框模式//第一个参数表示我们打算将其应用到所有的三角形的正面和背面,第二个参数告诉我们用线来绘制//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//VAO对象unsigned int VAO;// 生成一个VAO对象 这个方法可以生成多个 由第一个参数决定glGenVertexArrays(1, &VAO);// 绑定 VAOglBindVertexArray(VAO);unsigned int VBO; //如果多个可以用 VBO[]数组 这个方法可以生成多个 由第一个参数决定glGenBuffers(1, &VBO);//将新创建的缓冲绑定到 GL_ARRAY_BUFFER目标上glBindBuffer(GL_ARRAY_BUFFER, VBO);// glBufferData 是一个专门用来把用户定义的数据复制到当前绑定缓冲的函数// GL_STATIC_DRAW 数据不会或几乎不会改变。glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);unsigned int EBO;glGenBuffers(1, &EBO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);Shaders *shaders = new Shaders("./shaders/vertexSource.txt", "./shaders/fragmentSource.txt");// glVertexAttribPointer函数告诉OpenGL该如何解析顶点数据(应用到逐个顶点属性上)// 从 0号栏位 开始 将数据每三个为一组 单位为float 每次跳6*float字节 偏移为0glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *) 0);// 以顶点属性位置值作为参数,启用顶点属性;顶点属性默认是禁用的//读取到0号栏位上glEnableVertexAttribArray(0);// 读取颜色属性 从 1号栏位 开始 将数据每三个为一组 单位为float 每次跳6*float字节 偏移为3个floatglVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *) (3 * sizeof(float)));// 读取到1号栏位上glEnableVertexAttribArray(1);// 读取纹理坐标glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *) (6 * sizeof(float)));glEnableVertexAttribArray(2);// 纹理缓冲对象unsigned int TexBufferA;unsigned int TexBufferB;//创建纹理缓冲对象glGenTextures(1, &TexBufferA);// 绑定//glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, TexBufferA);//glActiveTexture(GL_TEXTURE3);// stb_image.h 使用int width, height, nrchannels;//  在OpenGl中 y轴的读取是与正常图片相反了 所以需要 设置 翻转(flip)垂直(vertically)加载(load) 为truestbi_set_flip_vertically_on_load(true);//获取图片的rgbunsigned char *data1 = stbi_load("container.jpg", &width, &height, &nrchannels, 0);cout<<width<<" "<<height<<endl;if (data1) {// 纹理可以通过glTexImage2D来生成glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data1);//直接在生成纹理之后调用glGenerateMipmap。这会为当前绑定的纹理自动生成所有需要的多级渐远纹理。 必须要有 glGenerateMipmap 否则无法显示纹理 glGenerateMipmap(GL_TEXTURE_2D);} else {cout << "load image failed." << endl;}//释放图像的内存stbi_image_free(data1);glBindTexture(GL_TEXTURE_2D,0);glGenTextures(1, &TexBufferB);glBindTexture(GL_TEXTURE_2D, TexBufferB);unsigned char *data2 = stbi_load("ground-texture.jpg", &width, &height, &nrchannels, 0);cout<<width<<" "<<height<<endl;if (data2) {// 纹理可以通过glTexImage2D来生成glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data2);//直接在生成纹理之后调用glGenerateMipmap。这会为当前绑定的纹理自动生成所有需要的多级渐远纹理。glGenerateMipmap(GL_TEXTURE_2D);} else {cout << "load image failed." << endl;}stbi_image_free(data2);glBindTexture(GL_TEXTURE_2D,0);//渲染循环 ,它能在我们让GLFW退出前一直保持运行。下面几行的代码就实现了一个简单的渲染循环://glfwWindowShouldClose 我们每次循环的开始前检查一次GLFW是否被要求退出while (!glfwWindowShouldClose(window)) {//自定义事件 当键盘触发esc 退出processInput(window);glClearColor(0.2, 0.3, 0.3, 1.0);// GL_COLOR_BUFFER_BIT 颜色,GL_DEPTH_BUFFER_BIT 深度 和 GL_STENCIL_BUFFER_BIT 模板// 清除前面的那一帧的颜色glClear(GL_COLOR_BUFFER_BIT);// 绑定 TextureBufferglActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, TexBufferA);glActiveTexture(GL_TEXTURE3);glBindTexture(GL_TEXTURE_2D, TexBufferB);// 绑定 VAOglBindVertexArray(VAO);shaders->use();// 如果只有单个纹理,则不需要以下操作,OpenGL会自动绑定glUniform1i(glGetUniformLocation(shaders->ID, "ourTexture1"), 0);glUniform1i(glGetUniformLocation(shaders->ID, "ourTexture3"), 3);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);//可以不需要这个 绑定VAO的同时也会自动绑定EBO//glDrawElements函数从当前绑定到GL_ELEMENT_ARRAY_BUFFER目标的EBO中获取索引glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//解绑VAOglBindVertexArray(0);glfwSwapBuffers(window);glfwPollEvents();}// 最后终止 glfwglfwTerminate();return 0;
}

shaders

顶点着色器

#version 330 core
// 0号栏位读取顶点坐标
layout (location = 0) in vec3 aPos;
//1号栏位读取颜色颜色
layout (location = 1) in vec3 aColor;
// 2号栏位读取 纹理坐标
layout (location = 2) in vec2 aTexCoord;
out vec4 vertexColor;
out vec2 TexCoord;
void main()
{
//  gl_Position 是固定的名称 用来保存 顶点坐标的gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);vertexColor = vec4(aColor.x,aColor.y,aColor.z,1.0);TexCoord = aTexCoord;
}

片元着色器

#version 330 core
out vec4 FragColor;
//uniform vec4 outColor;
in vec4 vertexColor;
// 获取顶底着色器过来的纹理坐标
in vec2 TexCoord;
uniform sampler2D ourTexture1;
uniform sampler2D ourTexture3;
void main()
{                                          //FragColor = vertexColor;// 采样纹理的颜色 第一个参数是纹理采样器 是cpu传过来的 第二个参数的对应的纹理坐标FragColor  = mix(texture(ourTexture1,TexCoord) , texture(ourTexture3,TexCoord),0.55);
}

stb_image.h 代码

texture 纹理(贴图)相关推荐

  1. Texture(纹理贴图)和Material(材质)概念上的区别

    我的理解是:纹理更偏向于"图",而材质更偏向于"属性". 打个比方说,对同一个立方体模型进行处理: 加纹理信息,可以认为是贴上图,比如木头的纹理图,大理石的纹理 ...

  2. 【Unity3D】纹理贴图 ( 纹理 Texture 简介 | 为 3D 模型设置纹理贴图 )

    文章目录 一.纹理 Texture 简介 二.为 3D 模型设置纹理贴图 一.纹理 Texture 简介 上一篇博客 [Unity3D]材质 Material ( 材质简介 | 创建材质 | 设置材质 ...

  3. three.js—纹理贴图texture的使用

    three.js-纹理贴图texture的使用 成品 方法 加载 贴图 多贴图使用 成品 通过在物体对象上贴图就可以完成上面的地球制作和全景看房效果. 方法 加载 var texture = new ...

  4. zbrush 添加纹理贴图_zbrush零基础新手必看入门讲解

    哈喽大家好,我是你们的好朋友叮当. zbrush ZBrush操作所需的屏幕分辨率较高,当显示器没法达到所需分辨率时,菜单就会智能化的分两行显示,ZBrush的菜单是按照英文字母顺序来排列的,使用起来 ...

  5. 纹理窗口Qt+OpenGL之纹理贴图

    上班之余抽点时间出来写写博文,希望对新接触的朋友有帮助.今天在这里和大家一起学习一下纹理窗口 NeNe的代码中是加载到了一个正方体当中,代码很长.其实单纯的想要纹理贴图是很便利的.具体的纹理贴图技巧在 ...

  6. Windows 8 Directx 开发学习笔记(十一)地形纹理贴图

    前一篇实现木箱贴图时,木箱的六个面都正好用一整张纹理图,即六个面的纹理坐标均在[0,1]内.然而在为比较大的模型贴图时,像山峰河谷模型,如果只用一张纹理图,那么每个三角形只得到几个纹理元素,无法为提供 ...

  7. Windows 8 Directx 开发学习笔记(十)纹理贴图实现旋转的木箱

    纹理贴图映射(texturemapping)是可以显著提高场景细节和真实感的一种技术,基本原理是将图像数据映射到3D三角形表面(之前的文章提到过,三维模型其实是由很多个三角形拼接而成).当使用纹理资源 ...

  8. 【光线追踪系列十一】纹理贴图

    本文主要参照 Ray Tracing: The Next Week,其中只是主要精炼光追相关理论,具体实现可参照原文. 一.纹理实现 实现之前,你应该已经充分理解了[光线追踪系列六]反射与金属类特性. ...

  9. OpenGL ES教程VI之纹理贴图(原文对照)

    注:又是一篇,是否有人能解释得清楚,2是重复两次,那么是否N就是重复N次呢?接近1.0的坐标值整数部分加上几就是重复几次吗?这个好像之前验证过不一定的. 转自:http://melord.iteye. ...

最新文章

  1. 让资源管理器不显示最近常用文件夹
  2. shiro系列二、身份验证和授权
  3. 操作系统第一篇【引论】
  4. hdu 4414 Finding crosses
  5. java的事务类型及定义
  6. DOM3 textInput事件-softbar
  7. 通过读取配置文件,启动mongodb
  8. 阶段3 1.Mybatis_03.自定义Mybatis框架_3.自定义mybatis的编码-根据测试类中缺少的创建接口和类...
  9. CodeBook算法
  10. SpringBoot中配置文件dev、test、和prod各自代表什么意思?
  11. 黑客红客骇客红客蓝客飞客是什么?有什么区别?(学习资料)
  12. 爬豆瓣电影top名单
  13. java抽象和接口的理解_Java学习笔记16---抽象类与接口的浅显理解
  14. 系统架构师(十)设计模式
  15. 基于OpenCV的单目相机标定与三维定位
  16. WIN10系统如何彻底关闭防火墙
  17. 电路之KCL和KVL的独立方程数总结
  18. 用Python告诉你广州房租现状
  19. linux挂载4T及以上硬盘
  20. 《Adobe Fireworks CS5中文版经典教程》——1.6 撤销操作

热门文章

  1. Iptables详解+实例
  2. 金融行业 | 电子银行系统性能优化解决方案
  3. 细说新一代HTML5/JavaScript的UI控件wijmo5 的新架构
  4. cacti添加I/O监控
  5. 业务单号自动增长的处理办法
  6. android camera滑动,Android怎么实现小米相机底部滑动指示器
  7. 如何利用python自动化办公项目_python办公自动化:自动进行word文档处理和排版
  8. 搭建linux测试环境有什么用_谈谈现在搭建网站用什么程序好,选择对的程序是很重要的开头...
  9. python用map提取一个数的个十百位数_如何使用python中的map函数?
  10. webview跟html通信的原理,1.iOS: webView与html的交互