当前位置: 首页 > news >正文

LearnOpenGL-入门-着色器

本人刚学OpenGL不久且自学,文中定有代码、术语等错误,欢迎指正

我写的项目地址:https://github.com/liujianjie/LearnOpenGLProject

LearnOpenGL中文官网:https://learnopengl-cn.github.io/

文章目录

  • 着色器
  • GLSL
    • 数据类型
    • 输入与输出
    • Uniform
    • 更多属性
  • 我们自己的着色器类

着色器

  • 简介
    • 着色器(Shader)是运行在GPU上的小程序,分别对应渲染管理不同阶段。
    • 着色器是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通只有通过输入和输出。

GLSL

  • 简介

    • 着色器是GLSL的类C语言写成的
    • 着色器的开头总是要声明版本,接着是输入和输出变量、uniform和main函数。每个着色器的入口点都是main函数。
    • main函数:在这个函数中我们处理所有的输入变量,并将结果输出到输出变量中
  • 结构

    #version version_number
    in type in_variable_name;
    in type in_variable_name;out type out_variable_name;uniform type uniform_name;int main()
    {// 处理输入并进行一些图形操作...// 输出处理过的结果到输出变量out_variable_name = weird_stuff_we_processed;
    }
    

    说明:

    • 当我们特别谈论到顶点着色器的时候,每个输入变量也叫顶点属性

    • 我们能声明的顶点属性是有上限的,它一般由硬件来决定。

    • OpenGL确保至少有16个包含4分量的顶点属性可用,但是有些硬件或许允许更多的顶点属性,你可以查询GL_MAX_VERTEX_ATTRIBS来获取具体的上限

      xint nrAttributes;glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl;
      

数据类型

类型含义
vecn包含n个float分量的默认向量
bvecn包含n个bool分量的向量
ivecn包含n个int分量的向量
uvecn包含n个unsigned int分量的向量
dvecn包含n个double分量的向量

输入与输出

  • 输入与输出

    in和out:类型和名称要对得上

  • 特殊的顶点着色器阶段

    需要用layout (location = 0)指定输入变量,来源于顶点数据(疑问:这个顶点数据在cpu还是gpu,应该是GPU,因为用了glBufferData从CPU拷贝到GPU上了)

  • 例子

    顶点着色器

    #version 330 core
    layout (location = 0) in vec3 aPos; // 位置变量的属性位置值为0out vec4 vertexColor; // 为片段着色器指定一个颜色输出void main()
    {gl_Position = vec4(aPos, 1.0); // 注意我们如何把一个vec3作为vec4的构造器的参数vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // 把输出变量设置为暗红色
    }
    

    片段着色器

    #version 330 core
    out vec4 FragColor;in vec4 vertexColor; // 从顶点着色器传来的输入变量(名称相同、类型相同)void main()
    {FragColor = vertexColor;
    }
    

Uniform

  • 简介

    是一种从CPU中的应用向GPU中的着色器发送数据的方式

  • 与顶点属性不同

    • uniform是全局的(Global),可以被着色器程序的任意着色器在任意阶段访问
    • 无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新
  • 使用例子

    #version 330 core
    out vec4 FragColor;uniform vec4 ourColor; // 在OpenGL程序代码中设定这个变量void main()
    {FragColor = ourColor;
    }
    
    float timeValue = glfwGetTime();
    float greenValue = (sin(timeValue) / 2.0f) + 0.5f;
    int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
    glUseProgram(shaderProgram);
    // 发送数据
    glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
    

    关键代码

    glGetUniformLocation(); 通过名称查询uniform ourColor的位置值

  • 细节

    OpenGL在其核心是一个C库,所以无法重载,所以每个上传数据给Uniform的函数都不一样

    f函数需要一个float作为它的值
    i函数需要一个int作为它的值
    ui函数需要一个unsigned int作为它的值
    3f函数需要3个float作为它的值
    fv函数需要一个float向量/数组作为它的值

    glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);

    在vertexColorLocation位置上上传4个float

更多属性

  • 顶点数据

    float vertices[] = {// 位置              // 颜色0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,   // 右下-0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,   // 左下0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f    // 顶部
    };
    
  • glsl

    #version 330 core
    layout (location = 0) in vec3 aPos;   // 位置变量的属性位置值为 0 
    layout (location = 1) in vec3 aColor; // 颜色变量的属性位置值为 1out vec3 ourColor; // 向片段着色器输出一个颜色void main()
    {gl_Position = vec4(aPos, 1.0);ourColor = aColor; // 将ourColor设置为我们从顶点数据那里得到的输入颜色
    }
    
    #version 330 core
    out vec4 FragColor;  
    in vec3 ourColor;void main()
    {FragColor = vec4(ourColor, 1.0);
    }
    
  • 告诉OpenGL如何解读顶点缓冲中的顶点数据

    // 位置属性
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // 颜色属性
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float)));
    glEnableVertexAttribArray(1);
    
  • 图示

我们自己的着色器类

我只关心读取这段代码

Shader(const char* vertexPath, const char* fragmentPath)
{// 1. 从文件路径中获取顶点/片段着色器std::string vertexCode;std::string fragmentCode;std::ifstream vShaderFile;std::ifstream fShaderFile;// 保证ifstream对象可以抛出异常:vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);try {// 打开文件vShaderFile.open(vertexPath);fShaderFile.open(fragmentPath);std::stringstream vShaderStream, fShaderStream;// 读取文件的缓冲内容到数据流中vShaderStream << vShaderFile.rdbuf();fShaderStream << fShaderFile.rdbuf();       // 关闭文件处理器vShaderFile.close();fShaderFile.close();// 转换数据流到stringvertexCode   = vShaderStream.str();fragmentCode = fShaderStream.str();     }catch(std::ifstream::failure e){std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;}const char* vShaderCode = vertexCode.c_str();const char* fShaderCode = fragmentCode.c_str();[...]
  • 代码流程
    • 用了文件输入流:ifstream
    • 打开文件读取数据vShaderStream << vShaderFile.rdbuf();
    • 保存在stringstream类型对象中
    • 然后再转为string,再转为字符数组

相关文章:

LearnOpenGL-入门-着色器

本人刚学OpenGL不久且自学&#xff0c;文中定有代码、术语等错误&#xff0c;欢迎指正 我写的项目地址&#xff1a;https://github.com/liujianjie/LearnOpenGLProject LearnOpenGL中文官网&#xff1a;https://learnopengl-cn.github.io/ 文章目录着色器GLSL数据类型输入与输…...

【谷粒学院】vue、axios、element-ui、node.js(44~58)

44.前端技术-vue入门 &#x1f9e8;Vue.js 是什么 Vue (读音 /vjuː/&#xff0c;类似于 view) 是一套用于构建用户界面的渐进式框架。 Vue 的核心库只关注视图层&#xff0c;不仅易于上手&#xff0c;还便于与第三方库或既有项目整合。另一方面&#xff0c;当与现代化的工具…...

【一些回忆】2022.02.26-2023.02.26 一个普通男孩的365天

&#x1f483;&#x1f3fc; 本人简介&#xff1a;男 &#x1f476;&#x1f3fc; 年龄&#xff1a;18 &#x1f91e; 作者&#xff1a;那就叫我亮亮叭 &#x1f4d5; 专栏&#xff1a;一些回忆 为什么选择在这个时间节点回忆一下呢&#xff1f; 一是因为今天距离2023高考仅剩1…...

OSPF的多区域特性 (电子科技大学TCP/IP实验三)

一&#xff0e;实验目的 1、掌握OSPF 协议中区域的类型、特征和作用 2、掌握OSPF 路由器的类型、特征和作用 3、掌握OSPF LSA 分组的类型、特征和作用 4、理解OSPF 区域类型、路由器类型和OSPF LSA 分组类型间的相互关系 二&#xff0e;预备知识 1、静态路由选择和动态路…...

(四十四)多个事务更新同一行数据时,是如何加锁避免脏写的?

之前我们已经用很多篇幅给大家讲解了多个事务并发运行的时候&#xff0c;如果同时要读写一批数据&#xff0c;此时读和写时间的关系是如何协调的&#xff0c;毕竟要是你不协调好的话&#xff0c;可能就会有脏读、不可重复读、幻读等一系列的问题。 简单来说&#xff0c;脏读、…...

【数据库】第十二章 数据库管理

第12章 数据库管理 数据库的物理存储 关于内存、外存、磁盘、硬盘、软盘、光盘的区别_Allenzyg的博客-CSDN博客_磁盘和硬盘的区别 数据库记录在磁盘上的存储 定长&#xff0c;变长跨块&#xff0c;非跨快 文件的组织方方法&#xff1a; 无序记录文件(堆文件heap或pile file…...

Redis源码---整体架构

目录 前言 Redis目录结构 前言 deps目录 src 目录 tests 目录 utils 目录 重要的配置文件 Redis 功能模块与源码对应 前言 服务器实例 数据库数据类型与操作 高可靠性和高可扩展性 辅助功能 前言 以先面后点的方法推进无特殊说明&#xff0c;都是基于 Redis 5.0.…...

基于springboot+vue的校园招聘系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...

SAP MM学习笔记1-SAP中扩张的概念,如何将一个物料从工厂A扩张到工厂B

MM中在创建物料的时候&#xff0c;最低也得创建如下5个view。 基本数据1 基本数据2 购买管理 会计1 会计2 1&#xff0c;扩张是什么 有时候&#xff0c;你想增加其他的View&#xff0c;比如保管场所 等&#xff0c;你不能用MM02来做编辑&#xff0c;要用MM01来做扩张。这就是扩…...

【Python】Numpy数组的切片、索引详解:取数组的特定行列

【Python】Numpy数组的切片、索引详解&#xff1a;取数组的特定行列 文章目录【Python】Numpy数组的切片、索引详解&#xff1a;取数组的特定行列1. 介绍2. 切片索引2.1 切片索引先验知识2.1 一维数组的切片索引2.3 多维数组的切片索引3. 数组索引&#xff08;副本&#xff09;…...

2023年全国最新交安安全员精选真题及答案6

百分百题库提供交安安全员考试试题、交安安全员考试预测题、交安安全员考试真题、交安安全员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 51.安全生产资金保障制度建立后关键在于落实&#xff0c;各施工企业在落实安全生…...

JavaScript 闭包【自留】

闭包的概念理解 闭包的定义 ✅ 这里先来看一下闭包的定义&#xff0c;分成两个:在计算机科学中和在JavaScript中。 ✅ 在计算机科学中对闭包的定义(维基百科): 闭包(英语:Closure)&#xff0c;又称词法闭包(Lexical Closure)或函数闭包(function closures);是在支持头等函数…...

【MySQL】什么是意向锁 IS IX 及值得学习的思想

文章目录前言行锁和表锁使用意向锁意向锁的算法意向锁的思想JDK 中相似的思想前言 之前看 MySQL 都刻意忽略掉了 IS 和 IX 锁&#xff0c;今天看 《MySQL 是怎样运行的》&#xff0c;把意向锁讲的很通透&#xff0c;本篇博文提炼一下思想。 I: Intention Lock&#xff08;意向…...

python多线程实现

用于线程实现的Python模块 Python线程有时称为轻量级进程&#xff0c;因为线程比进程占用的内存少得多。 线程允许一次执行多个任务。 在Python中&#xff0c;以下两个模块在一个程序中实现线程 - _thread模块threading模块 这两个模块之间的主要区别在于_thread模块将线程视…...

macOS使用CodeRunner快速配置fortran环境

个人网站:xzajyjs.cn 由于一些项目的缘故&#xff0c;需要有fortran的需求&#xff0c;但由于是M1 mac的缘故&#xff0c;不能像windows那样直接使用vsivf这种经典配置。搜了一下网上主流的跨平台方案&#xff0c;主要是gfortran&#xff0c;最近用Coderunner&#xff08;主要…...

【云原生】k8s 离线部署讲解和实战操作

文章目录一、概述二、前期准备1&#xff09;节点信息2&#xff09;修改主机名和配置hosts3&#xff09;配置ssh互信4&#xff09;时间同步5&#xff09;关闭防火墙6&#xff09;关闭 swap7&#xff09;禁用SELinux8&#xff09;允许 iptables 检查桥接流量三、开始部署1&#x…...

【Kubernetes】第十一篇 - 滚动发布的介绍与实现

一&#xff0c;前言 上一篇&#xff0c;介绍了灰度发布和流量切分的集中方式&#xff0c;以及如何实现 k8s 的灰度发布&#xff1b; 本篇&#xff0c;介绍滚动发布的实现&#xff1b; 二&#xff0c;滚动发布简介 滚动发布 滚动发布&#xff0c;则是我们一般所说的无宕机发…...

【尊享版】如何系统构建你的思维认知模型?

超友们&#xff0c;早上好&#xff0c;国庆节快乐&#xff5e; 今天为你带来的分享是《如何系统构建你的思维认知模型&#xff1f;》&#xff0c;主要分为三个部分&#xff1a; 第一部分&#xff1a;【实现爆发式成长的 10 个思维模型】 第二部分&#xff1a;【6 个不可不知的…...

urho3D编码约定

缩进样式类似于Allman&#xff08;BSD&#xff09;&#xff0c;即在控制语句的下一行使用大括号&#xff0c;在同一级别缩进。在switch-case语句中&#xff0c;case与switch语句处于相同的缩进级别。 缩进使用4个空格而不是制表符。不应保留空行上的缩进。 类和结构名称以大写…...

Overleaf推广奖励:增加合作者的数量、解锁Dropbox同步和项目修改历史

Overleaf推广奖励 Overleaf是一个LaTeX\LaTeXLATE​X在线编译器&#xff0c;它可以让你与合作者共同在线编辑文档。但是默认的免费账号仅能邀请一个合作者。那么如何增加合作者的数量呢&#xff1f; Overleaf推出了一个奖励计划&#xff0c;你邀请其他人注册Overleaf&#xf…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...