learnOpenGL-深度测试
深度测试:OpenGL将一个片段的深度值与深度缓冲的内容进行对比。执行一个深度测试,测试通过则深度缓冲将会更新为新的深度值。测试失败则片段被丢弃。
深度测试片段着色器及模版测试之后执行。
片段着色器中内置变量gl_FragCoord的z值即为深度值。
提前深度测试:允许深度测试在片段着色器之前运行。片段着色器通常开销很大。使用提前深度测试时,片段着色器不可写入深度值,因为OpenGl不能提前知道深度值。
默认禁用,glEnable(GL_DEPTH_TEST);启用
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);清楚上一帧深度缓冲
实际运用的深度缓冲是非线性的
深度冲突:两个平面或三角形z值一样,两个形状会不断切换前后顺序
防止深度冲突:
1.不要把多个物体放的太近,导致它们的一些三角形重叠
2.将进平面设置远一些,因为精度在靠近进平面时较高。(注意,进平面太远会导致近处的一些物体被裁减掉)
3.牺牲一些性能,使用更高精度的深度缓冲。大部分深度缓冲的精度都是24位,但现在大部分显卡支持32位
main.cpp
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "shader.h"
#include "stb_image.h"
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>
#include "Camera.h"
#include "Model.h"Camera* myCamera = new Camera(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f));void mouse_callback(GLFWwindow* window, double xpos, double ypos) {myCamera->mouseCb(xpos, ypos);
};void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{myCamera->scrollCb(xoffset, yoffset);
}GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;void processInput(GLFWwindow* window) {GLfloat currentFrame = glfwGetTime();deltaTime = currentFrame - lastFrame;lastFrame = currentFrame;if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {myCamera->pressKeyW(deltaTime);}if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {myCamera->pressKeyS(deltaTime);}if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {myCamera->pressKeyA(deltaTime);}if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {myCamera->pressKeyD(deltaTime);}
}glm::vec3 pointLightPositions[] = {glm::vec3(2.0f, 10.2f, 2.0f),glm::vec3(-2.3f, 7.3f, -4.0f)
};float cubeVertices[] = {// positions // texture Coords-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 1.0f,0.5f, 0.5f, -0.5f, 1.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 1.0f,0.5f, 0.5f, 0.5f, 1.0f, 1.0f,-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 1.0f,0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.5f, -0.5f, 0.5f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,0.5f, -0.5f, -0.5f, 1.0f, 1.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.5f, 0.5f, -0.5f, 1.0f, 1.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
float planeVertices[] = {// positions // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat)5.0f, -0.5f, 5.0f, 2.0f, 0.0f,-5.0f, -0.5f, 5.0f, 0.0f, 0.0f,-5.0f, -0.5f, -5.0f, 0.0f, 2.0f,5.0f, -0.5f, 5.0f, 2.0f, 0.0f,-5.0f, -0.5f, -5.0f, 0.0f, 2.0f,5.0f, -0.5f, -5.0f, 2.0f, 2.0f
};int main()
{glfwInit();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", nullptr, nullptr);if (window == nullptr){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);//glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);glfwSetCursorPosCallback(window, mouse_callback);glfwSetScrollCallback(window, scroll_callback);glewExperimental = GL_TRUE;if (glewInit() != GLEW_OK){std::cout << "Failed to initialize GLEW" << std::endl;glfwTerminate();return -1;}glViewport(0, 0, 800, 600);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));glEnableVertexAttribArray(1);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));glEnableVertexAttribArray(2);glEnableVertexAttribArray(0);glBindVertexArray(0);GLuint cubeVAO, cubeVBO;glGenVertexArrays(1, &cubeVAO);glBindVertexArray(cubeVAO);glGenBuffers(1, &cubeVBO);glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));glBindVertexArray(0);unsigned int planeVAO, planeVBO;glGenVertexArrays(1, &planeVAO);glGenBuffers(1, &planeVBO);glBindVertexArray(planeVAO);glBindBuffer(GL_ARRAY_BUFFER, planeVBO);glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), &planeVertices, GL_STATIC_DRAW);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));glBindVertexArray(0);GLuint tex;glGenTextures(1, &tex);int width, height, nrComponents;unsigned char* image = stbi_load("container.jpg", &width, &height, &nrComponents, 0);if (image) {GLenum format;if (nrComponents == 1)format = GL_RED;else if (nrComponents == 3)format = GL_RGB;else if (nrComponents == 4)format = GL_RGBA;glBindTexture(GL_TEXTURE_2D, tex);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, image);glGenerateMipmap(GL_TEXTURE_2D);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_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);stbi_image_free(image);}glm::mat4 model;glm::mat4 view;glm::mat4 projection;glEnable(GL_DEPTH_TEST);//深度测试函数glDepthFunc(GL_LESS);/** GL_ALWAYS 永远通过深度测试* GL_NEVER 永远不通过深度测试* GL_LESS 在片段深度值小于缓冲的深度值时通过测试* GL_EQUAL 在片段深度值等于缓冲区的深度值时通过测试* GL_LEQUAL 在片段深度值小于等于缓冲区的深度值时通过测试* GL_GREATER 在片段深度值大于缓冲区的深度值时通过测试* GL_NOTEQUAL 在片段深度值不等于缓冲区的深度值时通过测试* GL_GEQUAL 在片段深度值大于等于缓冲区的深度值时通过测试*/Shader* testShader = new Shader("test.vert", "test.frag");Shader* lightShader = new Shader("test.vert", "light.frag");while (!glfwWindowShouldClose(window)){processInput(window);glfwPollEvents();glClearColor(0.1f, 0.1f, 0.1f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);testShader->Use();glUniform1i(glGetUniformLocation(testShader->getProgram(), "texture1"), 0);glBindVertexArray(cubeVAO);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, tex);view = myCamera->getViewMat4();glUniformMatrix4fv(glGetUniformLocation(testShader->getProgram(), "view"), 1, GL_FALSE, glm::value_ptr(view));projection = glm::perspective(glm::radians(myCamera->getFov()), 800.0f / 600.0f, 0.1f, 100.0f);glUniformMatrix4fv(glGetUniformLocation(testShader->getProgram(), "projection"), 1, GL_FALSE, glm::value_ptr(projection));model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));glUniformMatrix4fv(glGetUniformLocation(testShader->getProgram(), "model"), 1, GL_FALSE, glm::value_ptr(model));glDrawArrays(GL_TRIANGLES, 0, 36);model = glm::mat4(1.0f);model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));glUniformMatrix4fv(glGetUniformLocation(testShader->getProgram(), "model"), 1, GL_FALSE, glm::value_ptr(model));glDrawArrays(GL_TRIANGLES, 0, 36);glBindVertexArray(planeVAO);glUniformMatrix4fv(glGetUniformLocation(testShader->getProgram(), "model"), 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f)));glDrawArrays(GL_TRIANGLES, 0, 6);glBindVertexArray(0);glfwSwapBuffers(window);}glfwTerminate();return 0;
}
顶点着色器
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoords;out vec2 TexCoords;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main()
{TexCoords = aTexCoords; gl_Position = projection * view * model * vec4(aPos, 1.0);
}
片段着色器
#version 330 core
out vec4 FragColor;in vec2 TexCoords;uniform sampler2D texture1;float near = 0.1;
float far = 100.0; float LinearizeDepth(float depth)
{float z = depth * 2.0 - 1.0; // back to NDC [0,1]变换到[-1,1](标准化设备坐标/裁剪空间)return (2.0 * near * far) / (far + near - z * (far - near));
}void main()
{ FragColor = texture(texture1, TexCoords);//FragColor = vec4(vec3(gl_FragCoord.z), 1.0);//float depth = LinearizeDepth(gl_FragCoord.z) / far; // 为了演示除以 far//FragColor = vec4(vec3(depth), 1.0);
}
相关文章:
learnOpenGL-深度测试
深度测试:OpenGL将一个片段的深度值与深度缓冲的内容进行对比。执行一个深度测试,测试通过则深度缓冲将会更新为新的深度值。测试失败则片段被丢弃。 深度测试片段着色器及模版测试之后执行。 片段着色器中内置变量gl_FragCoord的z值即为深度值。 提前深…...
阿里云服务器数据盘是什么?系统盘和数据盘区别
阿里云服务器系统盘和数据盘有什么区别?系统盘类似Windows电脑的C盘,数据盘相当于其他盘符,数据盘可以有多个而系统盘只能有一个,数据盘可有可无而云服务器系统盘是必须要有的。阿里云服务器网来详细说下阿里云服务器数据盘和系统…...
linux常用命令精选
参考文章: Top 60 Linux Interview Questions and Answers - howtouselinux 在管理和维护Linux系统时,有一些常用的命令可以帮助您进行系统初始化和配置。这些命令涵盖了各种任务,包括系统设置、用户管理、软件安装和网络配置等。 本文将为…...
人体行为足力特征分析及其应用研究_kaic
第一章 绪论 随着社会现代化的发展和科技的不断进步,我国航天事业蓬勃发展,与此同时产生了很多亟待解决的难题,康复医疗成为航天医学和康复领域的重要课题之一。载人航天实践证明,失重对航天员生理功能有很大影响,这不…...
javascript基础二十七:说说 JavaScript 数字精度丢失的问题,解决方案?
一、场景复现 一个经典的面试题 0.1 0.2 0.3 // false 为什么是false呢? 先看下面这个比喻 比如一个数 130.33333333… 这是一个除不尽的运算,3会一直无限循环,数学可以表示,但是计算机要存储,方便下次再使用,但…...
重塑工作场所:后疫情时代组织韧性的8个策略
经济寒冬来临,倒挂的收益率曲线、持续上升的利率以及层出不穷的裁员公告等等,让经济学家们得出一个结论:全球经济正在衰退。然而,经济下行周期可能是卓越公司改变其命运的最佳时机。有研究表明,相对于非经济衰退时期&a…...
TCP协议为什么要三次握手而不是两次?
TCP(Transmission Control Protocol,传输控制协议)的历史可以追溯到1970年代初期,最初的版本是RFC 793,后来经过多次更新和改进,包括RFC 1122、RFC 1323、RFC 2018、RFC 2581、RFC 2873、RFC 3168和RFC 461…...
使用Vuex进行状态管理
在Vue.js应用程序中,状态管理是一个重要的主题。当应用程序变得复杂,组件之间的状态共享和通信变得困难,这时候使用Vuex就会变得十分有用。Vuex是一个专门为Vue.js设计的状态管理库,它提供了一个集中式的状态管理方案,…...
【优化调度】基于改进遗传算法的公交车调度排班优化的研究与实现(Matlab代码实现)
目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 1 概述 本文对当前公交企业调度系统进行了分析,建立了公交排班的数学模型。本文基于数据挖掘分析的结果上,使用截面客流量数据对模型进行约束,得出了公交客流出行的空间分布规律。再以…...
IMX6ULL裸机篇之I2C实验-硬件原理图
一. I2C 实验简介 I2C实验,我们就来学习如何使用 I.MX6U 的 I2C 接口来驱动 AP3216C,读取 AP3216C 的传感器数据。 AP3216C是一个三合一的环境光传感器,ALSPSIRLED,ALS是环境光,PS是接近传感器,IR是红外L…...
华为OD机试真题 Java 实现【获取字符串中连续出现次数第k多的字母的次数】【2023Q1 100分】,附详细解题思路
一、题目描述 给定一个字符串,只包含大写字母,求在包含同一字母的子串中,长度第 k 长的子串的长度,相同字母只取最长的那个子串。 二、输入描述 第一行有一个子串(1<长度<100),只包含大写字母;第二…...
充分统计量和因子分解定理
充分统计量 定义: 设样本 X X X的服从分布 f ( X ∣ θ ) f(X|\theta) f(X∣θ), θ ∈ Θ \theta\in\Theta θ∈Θ,设 T T ( X ) TT(X) TT(X)为一统计量,若在已知 T T T的条件下,样本 X X X的条件分布与参数 θ \the…...
M1 PD安装arm ubuntu及Docker
M1 PD安装arm ubuntu 下载 Ubuntu 22.04.2 LTS https://cn.ubuntu.com/download/server/arm 参考视频安装 https://www.bilibili.com/video/BV1Mu4y1f74v/?spm_id_from333.999.0.0&vd_source9056c6d3c91a117baaceb663957daa08 PD Ubuntu安装docker 删除现有的docker安装…...
TCP协议的RST标志
下文中的内容多数来自【参考】中的文章,这边进行一个整理和总结,后续会慢慢增加出现各个 RST 包的测试代码,便于理解。 TCP的 “断开连接” 标志 RST 标志 Reset,复位标志,用于非正常地关闭连接。它是 TCP 协议首部里…...
【软件质量与软件测试 白盒测试与黑盒测试】
第十章 黑盒测试 10.1 等价类划分: 10.1.1 划分等价类 等价类是指所有数据中的一组,它们具有相同的测试结果或相同的响应。等价类划分是将输入数据分为多个等价类的过程。 10.1.2 划分等价类的方法 划分等价类方法主要包括以下几种: 特…...
JavaScript教程(高级)
面向对象编程介绍 两大编程思想 (1)、 面向过程编程: (缩写 POP)( Process-oriented programming)面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现&am…...
C++进阶 —— 范围for(C++11新特性)
目录 一,范围for介绍 二,范围for注意事项 一,范围for介绍 范围for(range-based for loop)是C11新引入的特性,可遍历各种序列结构的容器(如数组、vector、list等);每次循…...
ELK +Filebeat日志分析系统
一、 ELK日志分析系统概述 1、ELK简介 ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。新增了一个FileBeat,它是一个轻量级的日志收集处理工具(Agent),Filebeat占用资源少,…...
万字解析PELT算法!
Linux是一个通用操作系统的内核,她的目标是星辰大海,上到网络服务器,下至嵌入式设备都能运行良好。做一款好的linux进程调度器是一项非常具有挑战性的任务,因为设计约束太多了: 它必须是公平的快速响应系统的throughp…...
腾讯云服务器端口怎么全开?教程来了
腾讯云服务器端口怎么全开?云服务器CVM在安全组中设置开通,轻量应用服务器在防火墙中设置,腾讯云百科来详细说下腾讯云服务器端口全开放教程: 目录 腾讯云服务器端口全部开通教程 云服务器CVM端口全开放教程 轻量应用服务器开…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
