opengl日记10-opengl使用多个纹理示例

文章目录

  • 环境
  • 代码
    • CMakeLists.txt文件内容不变。
    • fragmentShaderSource.fs
    • vertexShaderSource.vs
    • main.cpp
  • 总结

在这里插入图片描述

环境

  • 系统:ubuntu20.04
  • opengl版本:4.6
  • glfw版本:3.3
  • glad版本:4.6
  • cmake版本:3.16.3
  • gcc版本:10.3.0

在<opengl学习日记9-opengl使用纹理示例>的基础上,拓展使用多个纹理。

代码

CMakeLists.txt文件内容不变。

fragmentShaderSource.fs

#version 330 core
out vec4 FragColor;in vec3 ourColor;
in vec2 TexCoord;uniform sampler2D texture1;
uniform sampler2D texture2;void main()
{FragColor = mix(texture(texture1,TexCoord),texture(texture2,TexCoord),0.2) ;
}

vertexShaderSource.vs

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;out vec3 ourColor;
out vec2 TexCoord;void main()
{gl_Position = vec4(aPos, 1.0);ourColor = aColor;TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

main.cpp

#include <glad/glad.h>
#include <GLFW/glfw3.h>#include "stbimage.h"//#include <glm/glm.hpp>
//#include <glm/gtc/matrix_transform.hpp>
//#include <glm/gtc/type_ptr.hpp>#include <iostream>
#include <fstream>
#include <iosfwd>
#include <sstream>
#include <string>//定义窗口大小
int SCR_WIDTH = 800;
int SCR_HEIGHT = 600;std::string readFile(const std::string filename)
{std::string data;data = readFile(filename.c_str());return data;
}std::string readFile(const char* filename)
{std::string data;std::ifstream infile;infile.open(filename);std::stringstream neirong;neirong << infile.rdbuf();infile.close();data = neirong.str();return data;
}int main()
{std::cout << "Hello World!" << std::endl;std::cout << "初始化" << std::endl;glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "transformtions", NULL, NULL);if (window == NULL) {std::cout << "创建窗口失败" << std::endl;return -1;}glfwMakeContextCurrent(window);if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "初始化glad失败" << std::endl;return -1;}std::cout << "顶点定义,VAO,VBO,EBO" << std::endl;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, 3,1, 2, 3};unsigned int VAO, VBO, EBO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glGenBuffers(1, &EBO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//定位点关系glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *) 0);glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *) (3 * sizeof(float)));glEnableVertexAttribArray(1);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *) (6 * sizeof(float)));glEnableVertexAttribArray(2);std::cout << "着色器定义" << std::endl;std::cout << "着色器定义:顶点着色器" << std::endl;std::string vertexShaderSource = readFile("vertexShaderSource.vs");const char *vertexShaderSourceCtr = vertexShaderSource.c_str();unsigned int vertexShader;vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSourceCtr, NULL);glCompileShader(vertexShader);int success;char infolog[512] = {0};glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertexShader, 512, NULL, infolog);std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infolog << std::endl;}std::cout << "着色器定义:片段着色器" << std::endl;std::string fragmentShaderSource = readFile("fragmentShaderSource.fs");const char *fragmentShaderSourceCtr = fragmentShaderSource.c_str();unsigned int fragmentShader;fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSourceCtr, NULL);glCompileShader(fragmentShader);glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(fragmentShader, 512, NULL, infolog);std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infolog << std::endl;}std::cout << "着色器定义:启用着色器程序" << std::endl;unsigned int shaderProgram;shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infolog);std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infolog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);std::cout << "纹理定义" << std::endl;unsigned int texture1;glGenTextures(1, &texture1);glBindTexture(GL_TEXTURE_2D, texture1);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_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);stbi_set_flip_vertically_on_load(true);std::cout << "读取纹理图片" << std::endl;int width, height, nrChannels;unsigned char* texturesData = stbi_load("container.jpg", &width, &height, &nrChannels, 0);if (texturesData) {//绑定和纹理图片数据结合glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0,GL_RGB,GL_UNSIGNED_BYTE,texturesData);glGenerateMipmap(GL_TEXTURE_2D);} else {std::cout << "读取图片数据错误" << std::endl;}stbi_image_free(texturesData);std::cout << "纹理定义2" << std::endl;unsigned int texture2;glGenTextures(1, &texture2);glBindTexture(GL_TEXTURE_2D, texture2);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_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);std::cout << "读取纹理图片" << std::endl;//        int width, height, nrChannels;texturesData = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);if (texturesData) {//绑定和纹理图片数据结合glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,texturesData);glGenerateMipmap(GL_TEXTURE_2D);} else {std::cout << "读取图片数据错误" << std::endl;}stbi_image_free(texturesData);glUseProgram(shaderProgram);glUniform1i(glGetUniformLocation((GLuint)shaderProgram,"texture1"),0);glUniform1i(glGetUniformLocation((GLuint)shaderProgram,"texture2"),1);std::cout << "绘制" << std::endl;while (!glfwWindowShouldClose(window)) {glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, texture1);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, texture2);glUseProgram(shaderProgram);glBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (const GLvoid *) 0);glfwSwapBuffers(window);glfwPollEvents();}std::cout << "内存释放" << std::endl;glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);glDeleteProgram(shaderProgram);glfwTerminate();return 0;
}

总结

  1. 使用多个纹理,则需要定义多个纹理,读取多个图片数据
std::cout << "纹理定义" << std::endl;unsigned int texture1;glGenTextures(1, &texture1);glBindTexture(GL_TEXTURE_2D, texture1);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_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);stbi_set_flip_vertically_on_load(true);std::cout << "读取纹理图片" << std::endl;int width, height, nrChannels;unsigned char* texturesData = stbi_load("container.jpg", &width, &height, &nrChannels, 0);if (texturesData) {//绑定和纹理图片数据结合glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0,GL_RGB,GL_UNSIGNED_BYTE,texturesData);glGenerateMipmap(GL_TEXTURE_2D);} else {std::cout << "读取图片数据错误" << std::endl;}stbi_image_free(texturesData);std::cout << "纹理定义2" << std::endl;unsigned int texture2;glGenTextures(1, &texture2);glBindTexture(GL_TEXTURE_2D, texture2);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_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);std::cout << "读取纹理图片" << std::endl;//        int width, height, nrChannels;texturesData = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);if (texturesData) {//绑定和纹理图片数据结合glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,texturesData);glGenerateMipmap(GL_TEXTURE_2D);} else {std::cout << "读取图片数据错误" << std::endl;}stbi_image_free(texturesData);
  1. 一张图片纹理叠加在另一张图片纹理上,需要有透明通道,图片格式是png,所以在绑定png纹理图片是需要注意参数变化
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,texturesData);

注意第三个参数和第七个参数,由GL_RGB变为GL_RGBA
3. 在绘制之前需要手动设置一次纹理对应的采样器

glUseProgram(shaderProgram);
glUniform1i(glGetUniformLocation((GLuint)shaderProgram,"texture1"),0);
glUniform1i(glGetUniformLocation((GLuint)shaderProgram,"texture2"),1);

这里需要注意,glUniform1i函数的书写是数字1,不是字母l
4. 在读取纹理之前,设置一下,可保持加载图像不上下颠倒

stbi_set_flip_vertically_on_load(true);

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

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

相关文章

设计模式之工厂方法模式解析

工厂方法模式 1&#xff09;问题 简单工厂模式 当需要引入新产品时&#xff0c;由于静态工厂方法通过所传入参数的不同来创建不同的产品&#xff0c;需要修改工厂类的源代码。 2&#xff09;概述 针对不同的产品提供不同的工厂&#xff0c;系统提供一个与产品等级结构对应…

我的保研材料全部损坏了!这个压缩包文件格式未知或数据已经被损坏不可预料的压缩文件末端

求助各位友友&#xff0c;我的保研材料全部没了&#xff01; 之前为了清理D盘&#xff0c;把之前保研期间准备的几个G的材料全部压缩放在了U盘&#xff0c;但是现在却损坏打不开了&#xff0c;之前为了省事也没有添加过“恢复记录”&#xff01;&#xff01;&#xff01; 先声…

阿赵UE学习笔记——20、角色蓝图和动画蓝图

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   继续学习虚幻引擎的使用。这次来看看角色控制动画相关的东西&#xff0c;主要用到了动画蓝图和角色蓝图。 一、动画蓝图 之前分析过&#xff0c;蓝图对于虚幻引擎来说&#xff0c;是存在于各个系统里面的&#xff0c;相当…

智慧公厕:卫生、便捷、安全的新时代厕所变革

在城市快速发展的背景下&#xff0c;公共厕所的建设和管理变得越来越重要。智慧公厕作为厕所变革的一项全新举措&#xff0c;通过建立公共厕所全面感知监测系统&#xff0c;以物联网、互联网、大数据、云计算、自动化控制技术为支撑&#xff0c;实现对公共厕所的智能化管理和运…

FPGA学习_时序约束以及VIVADO时序报告

文章目录 前言时序约束的目的一、时序约束种类1、约束主时钟2、约束衍生时钟3、约束虚拟时钟4、input delay5、output delay6、约束异步时钟组7、约束互斥时钟8、假路径约束9、多周期约束 二、VIVADO时序报告三、从时序的角度看为什么寄存器赋值慢一拍 前言 一边学习一边补充当…

容器中的大模型(三)| 利用大语言模型:容器化高效地部署 PDF 解析器实践...

作者&#xff1a;宋文欣&#xff0c;智领云科技联合创始人兼CTO 01 简介 大语言模型&#xff08;LLMs&#xff09;正逐渐成为人工智能领域的一颗璀璨明星&#xff0c;它们的强大之处在于能够理解和生成自然语言&#xff0c;为各种应用提供了无限可能。为了让这些模型更好地服务…

【Hadoop】Hadoop 编译源码

目录 为什么要源码编译Hadoop 编译源码1前期工作准备2jar 包安装2.1安装 Maven2.2安装 ant2.3安装 glibc-headers 和 g2.4安装 make 和 cmake2.5安装 protobuf2.6安装 openssl 库2.7安装 ncurses-devel 库 3编译源码3.1解压源码到 /opt/ 目录3.2 进入到 hadoop 源码主目录 /opt…

AI时代Python金融大数据分析实战:ChatGPT让金融大数据分析插上翅膀

❤️作者主页&#xff1a;小虚竹 ❤️作者简介&#xff1a;大家好,我是小虚竹。2022年度博客之星评选TOP 10&#x1f3c6;&#xff0c;Java领域优质创作者&#x1f3c6;&#xff0c;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;掘金年度人气作…

UniTask 异步任务

文章目录 前言一、UniTask是什么&#xff1f;二、使用步骤三、常用的UniTask API和示例1.编写异步方法2.处理异常3.延迟执行4.等待多个UniTask或者一个UniTas完成5.异步加载资源示例6.手动控制UniTask的完成状态7.UniTask.Lazy延迟任务的创建8.后台线程切换Unity主线程9.不要返…

第二证券|热度飙升,出境游人数有望破亿,这些概念股被机构盯上

在免签和航班批量康复的方针利好下&#xff0c;本年出境游商场迎来炽热升温。 清明出境游有望爆火 3月20日&#xff0c;Airbnb爱彼迎在北京举行春季出境游趋势发布会举行。 爱彼迎中国数据显示&#xff0c;本年清明节期间的出境游查找热度已经超出2023年同期的2.5倍&#xf…

计算机网络面经-什么是IPv4和IPv6?

前言 Internet协议&#xff08;IP&#xff09;是为连接到Internet网络的每个设备分配的数字地址。它类似于电话号码&#xff0c;是一种独特的数字组合&#xff0c;允许用户与他人通信。IP地址主要有两个主要功能。首先&#xff0c;有了IP&#xff0c;用户能够在Internet上被识别…

Redis 安装(二)

Redis安装说明 大多数企业都是基于Linux服务器部署项目&#xff0c;而且Redis官网也没有提供Windows版本的安装包&#xff0c;因此课程中我们会基于Linux系统来安装Redis。 此处选择Linux版本为Centos7。 Redis的官方网站地址&#xff1a;https://redis.io/ Redis的安装 切换…

TCP协议中的传输控制机制图文详解「重传机制」「流量控制」「拥塞控制」

目录 TCP重传机制 超时重传 快速重传 SACK 方法 Duplicate SACK TCP 流量控制 滑动窗口 累积确认 窗口大小由哪一方决定&#xff1f; 接收窗口和发送窗口的大小是相等的吗&#xff1f; 流量控制 窗口关闭的后果 糊涂窗口综合症 TCP拥塞处理 为什么要有拥塞控制呀&#xff0c;不…

如何在WSL中的ubuntu编译Linux内核并且安装使用ebpf?

如何在WSL中的ubuntu编译Linux内核并且安装使用ebpf? 步骤1 编译安装内核获取源码修改配置编译编译成功后配置重启WSL测试 步骤2 安装bcc安装依赖下载bcc&#xff0c;编译测试 环境: wsl2windows 11 步骤1 编译安装内核 去https://kernel.org/找你想要的版本&#xff0c; …

119.设计链表(力扣)

代码解决 class MyLinkedList { public:// 定义链表节点结构体struct LinkedNode {int val;LinkedNode* next;LinkedNode(int val):val(val), next(nullptr){}};MyLinkedList() {dummyhead new LinkedNode(0);size0;}int get(int index) {if (index > (size - 1) || index…

从点云创建 DSM:网格化和可视化实用指南

今天我将向您展示如何从点云创建数字表面模型&#xff08;DSM&#xff09;。首先&#xff0c;我们将尝试了解 DSM 是什么&#xff0c;然后我们将进入讨论的更实际部分。 什么是 DSM&#xff1f; DSM 是一个描述表面及其表面所有内容的模型。现在&#xff0c;为了更清楚地了解…

学习JavaEE的日子 Day28 异常,多线程

Day28 1.异常机制 1.1 异常概念 异常是程序在运行期发生的不正常的事件&#xff0c;它会打断指令的正常执行流程。 设计良好的程序应该在异常发生时提供处理这些不正常事件的方法&#xff0c;使程序不会因为异常的发生而阻断或产生不可预见的结果。 ​ Java语言使用异常处理机…

LabVIEW柴油机安保监控系统

LabVIEW柴油机安保监控系统 随着航运业的快速发展&#xff0c;确保船舶柴油机的安全稳定运行变得尤为重要。船舶柴油机故障不仅会导致重大的经济损失&#xff0c;还可能危及人员安全和环境。设计并开发了一套基于LabVIEW平台的柴油机安保监控系统&#xff0c;旨在通过实时监控…

Python数学建模-2.9Matplotlib库

Matplotlib库是Python中一个非常流行的绘图库&#xff0c;它提供了大量的绘图工具&#xff0c;可以生成各种类型的静态、动态、交互式的图表。Matplotlib的设计初衷是为了与NumPy配合使用&#xff0c;从而提供一个强大的数学绘图工具。 1.Matplotlib的主要特点 丰富的图表类型…

Ubuntu18.04显示--有线连接未托管

引用: Ubuntu18.04连不网 报"有线连接未托管"_ubuntu20.04以太网未托管-CSDN博客 正文 虚拟机环境配置&#xff1a; VirtaualBox Ubuntu18.04桌面版 问题现象&#xff1a; Ubuntu18.04虚拟机的桌面上提示“有线连接未托管”&#xff0c;虚拟机不能上网&#xf…