Cherno OpenGL(18 ~ 24)

混合

默认情况下 OpenGL 不执行任何混合,它只需要你们渲染的东西,然后把它渲染成不透明的东西。

之前我们渲染了红色方块,在它上面我们以某种形式渲染了一个半透明的蓝色方块(不透明的蓝色方块会直接覆盖红色方块),我们期望得到这两种颜色的组合:紫色。如果我们现实生活中拿红玻璃和蓝玻璃然后把它们像这样叠在一起,我们会看到穿过的光实际上是紫色的,那就是我们用眼睛所看到的。

  • 所以混合只决定了我们如何将输出颜色与目标缓冲区中已经存在的颜色结合起来
  • 我们的输出颜色为片段着色器中输出的颜色,也被称为 source
  • 在这个例子中我们把它画到一个已经存在的缓冲区上,也就是我们的目标 destination:红色方块
混合控制

那么我们如何控制这两种颜色混合的方式呢? 我们在 OpenGL 在有三种不同的方法,他们做的事情非常不同:

  • 首先,启用和禁用 glEnable(GL_BLEND),gl_Disable(GL_BLEND),参数 GL_BLEND。默认情况下不会启用混合
  • gl_BlendFuc(src,dest) 指定如何将两种颜色混合在一起(传参1,0 表示丢掉 dest 并用 src 覆盖),其中 RGB 因子将乘以所有颜色通道,所以 src 默认为 1 而 dest 默认为 0
  • gl_BlendEquation(mode)混合不等式,参数 mode  为组合方式(默认为 GL_FUNC_ADD)

数学库

GLM 库

glm 是一个只包含头文件的库,这意味着没有 cpp 文件不需要编译它,所以我们不需要链接到库直接使用。

投影矩阵

投影矩阵是我们告诉窗口的一种方式,告诉它我们想要如何将所有不同的顶点映射到它。所以我们有一个填充了顶点位置顶点缓冲区这样的概念,但是我们需要把它转换到 2D 平面,因为当我们把它绘制在笔记本电脑屏幕或电脑显示器上时需要以 2D 的方式绘制出来。

那么想象一个 3D 世界,我们有一个 3D 世界的数学表示,但我们需要把它绘制在 2D 表面上。数学上我们如何从 3D 几何图形到 2D 平面图形的?那就是投影矩阵的用处。

投影矩阵的实际变换就是把所有那些位置转换成所谓的标准坐标,也就是某种标准化空间,然后映射到我们的窗口。标准空间意味着在每个 xyz 轴上都有一个 -1 和 1 之间的坐标系统,所以我想说的是一个窗口的图像分辨率在点上无关紧要。

MVP 是我们的模型 (Model) 视图 (View) 投影 (Projection) 矩阵

接着在顶点着色器用这个矩阵乘以我的顶点位置,每个顶点运行一次基于我们提供的正交矩阵将它移到合适的空间。

void main()
{gl_Position = u_MVP * position;v_TexCoord = texCoord;
}

关于模型视图投影矩阵

在我们的着色器代码中或者在 C++ 的 glm 代码中,它可以是 pvm:投影 x 视图 x 模型。而像 Direct3D 和 DirectX 因为它们确实处理的矩阵是行主序的,那么就是 mvp:模型 x 视图 x 投影。

视图矩阵

OpenGL 中没有相机这个东西,我们能做的就是移动几何体和顶点。所以为了模拟相机向左移动,我们需要做的是将所有东西向右移动,可以算一种逆向运算。

glm::mat4 proj = glm::ortho(0.0f, 960.0f, 0.0f, 540.0f, -1.0f, 1.0f);glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(-100, 0, 0));glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(200, 200, 0));//glm::translate(view, glm::vec3(-100, 0, 0));glm::mat4 mvp = proj * view;mvp = mvp * model;

 像这样,图形先左移后 右上移

关于 ImGui

今天我们会整合一些 ImGui 的东西,它本质上是一个我们可以在 OpenGL、DirectX 以及任何渲染接口中使用的 GUI 图形用户接口库。 它的大多数接口是独立的,这是我们在屏幕上绘制 UI 界面的一种方式。

/* Setup Dear ImGui context */const char* glsl_version = "#version 130";IMGUI_CHECKVERSION();ImGui::CreateContext();ImGui_ImplGlfw_InitForOpenGL(window, true);ImGui_ImplOpenGL3_Init(glsl_version);ImGui::StyleColorsDark();glm::vec3 translation(200, 200, 0);float r = 0.0f;float increment = 0.05f;/* Loop until the user closes the window */while (!glfwWindowShouldClose(window)){render.Clear();// Start the Dear ImGui frameImGui_ImplOpenGL3_NewFrame();ImGui_ImplGlfw_NewFrame();ImGui::NewFrame();glm::mat4 model = glm::translate(glm::mat4(1.0f), translation);glm::mat4 mvp = proj * view * model;shader.SetUniformMat4f("u_MVP", mvp);render.Draw(va, ib, shader);if (r > 1.0f) {increment = -0.0001f;}else if (r <= 0.0f) {increment = 0.0001f;}r += increment;{static float f = 0.0f;ImGui::Begin("Hello, world!");                          // Create a window called "Hello, world!" and append into it.ImGui::SliderFloat3("translation", &translation.x, 0.0f, 960.0f);            // Edit 1 float using a slider from 0.0f to 1.0fImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);ImGui::End();}ImGui::Render();ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());/* Swap front and back buffers */glfwSwapBuffers(window);/* Poll for and process events */glfwPollEvents();}
}ImGui_ImplOpenGL3_Shutdown();ImGui_ImplGlfw_Shutdown();ImGui::DestroyContext();glfwTerminate();return 0;
}

可以实现鼠标控制图片位移,利用 model 矩阵

批量渲染对象

两种方式:一种是再弄一块 vertex buffer ,一种是再传入其他的 MVP 矩阵(instance实例化技术?)

这里选择第二种方式,代码如下:

绘制代码:
{glm::mat4 model = glm::translate(glm::mat4(1.0f), translationA);glm::mat4 mvp = proj * view * model;shader.Bind();shader.SetUniformMat4f("u_MVP", mvp);renderer.Draw(va, ib, shader);
}{glm::mat4 model = glm::translate(glm::mat4(1.0f), translationB);glm::mat4 mvp = proj * view * model;shader.Bind();shader.SetUniformMat4f("u_MVP", mvp);renderer.Draw(va, ib, shader);
}ImGui的代码:
{ImGui::SliderFloat3("Translation A", &translationA.x, 0.0f, 960.0f); ImGui::SliderFloat3("Translation B", &translationB.x, 0.0f, 960.0f); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
}

调用了两次 drawcall,费性能。真正要用在项目里头应该会弄个材质类出来。

设置一个测试框架

参考博文:Cherno OpenGL 教程 | Fl0w3r

视频地址:S17.关于纹理_哔哩哔哩_bilibili

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

HashMap源码分析下

HashMap 环境 JDK11 HashMap是用哈希表结构&#xff08;链表散列&#xff1a;数组链表&#xff09;实现&#xff0c;结合数组和链表的优点。扩容时当链表长度超过 6 时&#xff0c;链表转换为红黑树。 public class HashMap<K,V> extends AbstractMap<K,V>impleme…

【Golang】——Gin 框架简介与安装

文章目录 1. Gin 框架概述1.1 什么是 Gin 框架&#xff1f;1.2 为什么选择 Gin&#xff1f;1.3 使用场景 2. 安装 Go 与 Gin 框架2.1 安装 Go 语言环境2.2 初始化 Go 项目2.3 安装 Gin 框架 3. 编写第一个 Gin 应用3.1 Gin 最小化示例代码代码解读3.2 运行程序3.3 测试服务 4. …

南京邮电大学《智能控制技术》期末抢救(上)

一、智能控制的提出 传统控制方法包括经典控制和现代控制——基于被控对象精确模型的控制方式&#xff0c;缺乏灵活性和应变能力&#xff0c;适于解决线性、时不变性等相对简单的控制问题。传统控制方法在实际应用中遇到很多难解决的问题&#xff0c;主要表现以下几点&#xff…

系统设计-系统回调通知设计

系统回调通知设计 消息类型容错机制消息协议负载均衡监控&告警很多公司的架构都存在与外界系统有交互,交互难免会有一些同步请求、回调通知等。且公司一般网络的出入口都是只有一个,而各个业务条线只要存在和外界系统有业务往来,都会存在回调通知,所以可以设计一个公司…

Seatunnel2.3.5的FTP无法读取中文路径的问题

问题原因 Seatunnel的connector-file下的ftp包中关于读取文件的路径没有对路径进行编码导致当有中文的时候会出现乱码 修改源码 我们需要修改两处位置 一处是判断路径是否存在的方法 一处是读取文件的流的地方 修改判断文件是否存在的地方 这个文件的路径是org/apache/sea…

基于java的果蔬种植销售一体化服务平台

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

【云岚到家】-day10-1-状态机增删查

【云岚到家】-day10-1-状态机增删查 1 订单管理1&#xff09;订单管理管什么&#xff1f; 2 基础设计2.1 订单状态流转1&#xff09;订单状态流转图2&#xff09;订单状态3&#xff09;服务单状态 2.2 数据库设计1&#xff09;表设计2&#xff09;分库分表 2.3 状态机设计1&…

ICML24|通用时间序列预测大模型思路

论文标题&#xff1a;Unified Training of Universal Time Series Forecasting Transformers GitHub链接&#xff1a;https://github. com/SalesforceAIResearch/uni2ts 论文链接&#xff1a;https://arxiv.org/pdf/2402.02592 前言 普适预测器是一个能够处理任何时间序列预…

LRU(Least Recently Used,最近未使用)

一、LRU的由来 lru的引入主要是和内存回收有关。 属于内核的大部分page是不能够进行回收的&#xff0c;比如内核栈、内核代码段、内核数据段以及大部分内核使用的page&#xff0c;它们都是不能够进行回收的&#xff1b; 相反&#xff0c;进程使用的page&#xff0c;比如进程…

网盘聚合搜索项目Aipan(爱盼)

本文软件由网友 刘源 推荐&#xff1b; 简介 什么是 Aipan&#xff08;爱盼&#xff09; ? Aipan&#xff08;爱盼&#xff09;是一个基于 Vue 和 Nuxt.js 技术构建的开源网盘搜索项目。其主要目标是为用户提供一个能够自主拥有和管理的网盘搜索网站。该项目持续维护和更新&a…

i春秋-Hash(__wakeup沉默、序列化)

练习平台地址 竞赛中心 题目描述 题目内容 啥也没有就一个标签跳转 点击后的确发生了跳转 观察到url中有key和hash两个值&#xff0c;猜测hash是key的hash 查看源代码发现确实是 $hashmd5($sign.$key);the length of $sign is 8 解密得到$sign应该为kkkkkk01 构造122的hash i…

【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的智能蒙绮英语学习系统设计与实现

开题报告 随着全球化的不断深入&#xff0c;英语作为国际通用语言&#xff0c;其重要性日益凸显。掌握英语不仅可以拓宽个人的视野和知识面&#xff0c;还可以增强个人竞争力&#xff0c;为个人职业发展带来更多机会。因此&#xff0c;开发一款能够帮助用户更高效地学习英文单…

Blender vs 3dMax谁才是3D软件的未来?

在探讨Blender与3ds Max谁才是3D软件的未来时&#xff0c;我们需要从多个维度对这两款软件进行详细分析。 Blender的优势 开源免费&#xff1a;Blender是一款完全免费的开源3D创作套件&#xff0c;这使得它成为独立艺术家、业余爱好者和小型工作室的首选。用户无需承担巨额的…

ubuntu安装cuda、cudnn和TensoRT【分步安装】

我说实话&#xff0c;这个环境安装真的要了老命&#xff0c;太tm恶心了。 因为遇到了很多问题&#xff0c;非常之恶心 问题一&#xff1a;版本对应 问题二&#xff1a;下载具慢 问题三&#xff1a;上NVIDIA有时候上不去 问题四&#xff1a;找到对应版本点不了 问题五&…

基于树莓派的边缘端 AI 目标检测、目标跟踪、姿态估计 视频分析推理 加速方案:Hailo with ultralytics YOLOv8 YOLOv11

文件大纲 加速原理硬件安装软件安装基本设置系统升级docker 方案Demo 测试目标检测姿态估计视频分析参考文献前序树莓派文章hailo加速原理 Hailo 发布的 Raspberry Pi AI kit 加速原理,有几篇文章介绍的不错 https://ubuntu.com/blog/hackers-guide-to-the-raspberry-pi-ai-ki…

网络工程实验一:静态路由的配置

#实验仅供参考&#xff0c;勿直接粘贴复制&#xff0c;用以学习交流# 1、实验目的&#xff1a; 熟悉eNSP网络仿真工具平台。 掌握静态路由配置方法。 能够配置路由器接口地址。 2、实验内容&#xff1a; 2.1、安装对应的软件&#xff1a; &#xff08;1&#xff09;Virtual …

基于java的宠物用品交易平台

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

华为VPN技术

1.启动设备 2.配置IP地址 [FW1]int g1/0/0 [FW1-GigabitEthernet1/0/0]ip add 192.168.1.254 24 [FW1-GigabitEthernet1/0/0]int g1/0/1 [FW1-GigabitEthernet1/0/1]ip add 100.1.1.1 24 [FW1-GigabitEthernet1/0/1]service-manage ping permit [FW2]int g1/0/0 [FW2-Gi…

鸿蒙进阶篇-数组常用方法(一)

大家好&#xff0c;这里是鸿蒙开天组&#xff0c;今天咱们来学习一下数组的常用方法。 数组在编程中是非常常见的数据类型&#xff0c;毕竟需要用到的场合太多了&#xff0c;所以我们今天来使劲学习一下常用方法&#xff0c;在这里也没法一一列全&#xff0c;但是大家也可以根…