
texture 纹理(贴图)
由下面两张叠加而成
发布日期:2021-05-04 20:40:35
浏览次数:14
分类:技术文章
本文共 5643 字,大约阅读时间需要 18 分钟。
纹理
纹理是一个2D图片(甚至也有1D和3D的纹理),它可以用来添加物体的细节。
这是两张照片叠加的效果


源代码
shaders类在 中有完整的源代码。
下边我们使用stb_image.h
来解析图片。 #define GLEW_STATIC // 这个一定要加不然报错 静态链接库#include#include #include #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 - 1float 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() { // 初始化GLFW glfwInit(); // 提示 我们使用的版本是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; // 终止 glfw glfwTerminate(); } // 绑定window到上下文对象 创建完窗口我们就可以通知GLFW将我们窗口的上下文设置为当前线程的主上下文了 glfwMakeContextCurrent(window); glewExperimental = true; // GLEW_OK 0 //init GLEW if (glewInit() != GLEW_OK) { cout << "glew init failed." << endl; // 终止 glfw glfwTerminate(); 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); // 绑定 VAO glBindVertexArray(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字节 偏移为0 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *) 0); // 以顶点属性位置值作为参数,启用顶点属性;顶点属性默认是禁用的 //读取到0号栏位上 glEnableVertexAttribArray(0); // 读取颜色属性 从 1号栏位 开始 将数据每三个为一组 单位为float 每次跳6*float字节 偏移为3个float glVertexAttribPointer(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) 为true stbi_set_flip_vertically_on_load(true); //获取图片的rgb unsigned char *data1 = stbi_load("container.jpg", &width, &height, &nrchannels, 0); cout< <<" "< < 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); //解绑VAO glBindVertexArray(0); glfwSwapBuffers(window); glfwPollEvents(); } // 最后终止 glfw glfwTerminate(); 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);}
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年03月28日 09时52分58秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
监控264后缀文件播放
2019-03-03
Java并发编程笔记-思维导图
2019-03-03
网站在线偷拍照片源码
2019-03-03
养猫最新版小程序源码
2019-03-03
Thinkphp6.0+vue个人虚拟物品发卡网站源码
2019-03-03
游戏服务端框架之代码热部署(一)
2019-03-03
游戏服务端开发之基础概念扫盲篇
2019-03-03
手游服务端框架之关于玩家数据的解决方案
2019-03-03
游戏服务端框架之网关
2019-03-03
游戏服务端框架之模仿SpringMvc实现消息路由
2019-03-03
QQ微信头像自动采集网站PHP源码
2019-03-03
微擎微赞模块:柚子洗车V1.1.5完整版 小程序前端+后端
2019-03-03
动态摇动吊牌自适应网站404页面源码
2019-03-03
炫酷文字消失动画网站404页面源码
2019-03-03
EMLOG模板山河网站主题分享
2019-03-03
2020年,51Talk求一个盈利的机会
2019-03-03
2019数字音乐市场年度回顾,QQ音乐全面领先
2019-03-03
迅雷新财报背后:下载一哥到艰难求生
2019-03-03
腾讯终于要杀入电商直播了
2019-03-03
花1亿扶持优质红人,如涵推动网红经济出圈之路有何深意?
2019-03-03