专栏首页大壮OpenGL ES 3.0 深度测试(OC)(二)

OpenGL ES 3.0 深度测试(OC)(二)

先看最终的效果

WechatIMG6.jpeg

本文章是基于文章一,开始讲解的。 效果就是个3D的正方体的盒子。 如果实现这个效果需要的步骤: 1.创建窗口 2.初始化环境(Context) 3.申请缓存区(渲染缓存,深度测试,帧缓存) 4.加载着色器关联链接程序 5.设置顶点 6.加载纹理 7.渲染 其中,创建窗口,初始化环境(Context),申请缓存区(渲染缓存,帧缓存),加载着色器关联链接程序,设置顶点,加载纹理。 这几个步骤同文章一,下面主要讲解下申请缓存区(深度测试),和渲染的步骤。

1.申请缓存区(深度测试)

一般情况下我们要申请渲染缓存区,帧缓存区,如果使用深度测试也需要申请深度缓存区。 其中渲染缓存区

// 创建 绑定 渲染缓存
    glGenRenderbuffers(1, &_myColorRenderBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, _myColorRenderBuffer);

帧缓冲区

// 创建 绑定帧缓存
    glGenFramebuffers(1, &_myColorFrameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, _myColorFrameBuffer);

在创建和绑定好渲染缓存区和帧缓存区后,还需要绑定下

    // 在帧缓存 和 渲染缓存创建 和 绑定结束后需要
    // 渲染缓存作为帧缓存的某种(颜色、深度、模板)附件
    glFramebufferRenderbuffer(
                              //帧缓冲区类型
                              GL_FRAMEBUFFER,
                              //缓冲附件类型
                              GL_COLOR_ATTACHMENT0,
                              //渲染缓冲区类型
                              GL_RENDERBUFFER,
                              //渲染缓冲句柄
                              _myColorRenderBuffer);

下面需要开始创建深的缓存区

    // 深度缓存
    GLint width;
    GLint height;
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
    
    // 申请深度渲染缓存
    glGenRenderbuffers(1, &_depthRenderBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
    // 设置深度测试的存储信息
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
    // 关联深度缓冲到帧缓冲区
    // 将渲染缓存挂载到GL_DEPTH_ATTACHMENT这个挂载点上
    glFramebufferRenderbuffer(
                              GL_FRAMEBUFFER,
                              GL_DEPTH_ATTACHMENT,
                              GL_RENDERBUFFER,
                              _depthRenderBuffer);
    // GL_RENDERBUFFER绑定的是深度测试渲染缓存,所以要绑定回色彩渲染缓存
    glBindRenderbuffer(GL_RENDERBUFFER, _myColorRenderBuffer);

其中这次glFramebufferRenderbuffer,是将深度缓存区添加到帧缓存区的深度(GL_DEPTH_ATTACHMENT)附件中。并且还需要重新绑定一次渲染缓存区。

2.渲染

当申请好深度缓存区后,就可以通过glEnable(GL_DEPTH_TEST);开启深度测试。 最后在每次渲染的时候还需要执行glClear(GL_DEPTH_BUFFER_BIT);清除深度缓存区。整个深度测试流程就结束了。

3.什么是深度测试

  1. 深度测试的概念: 深度其实就是该像素点在3D世界中距离摄像机的距离Z值
  2. 什么是深度缓冲区? 深度缓存区,就是一块内存区域,专门储存着每个像素点(绘制在屏幕上的)深度值。深度值(Z值)越大,则离摄像机越远。
  3. 为什么需要缓冲区? 在不使用深度测试的时候,如果我们先绘制一个距离比较近的物理,再绘制距离较远的物理,则距离远的位图因为后绘制,会被距离近的物体覆盖掉。有了深度缓冲区后,绘制 物体的顺序就不那么重要的。实际上,只要存在深度缓冲区,OpenGL都会把像素的深度值写入到缓冲区中。除非调用glDepthMask(GL_FALSE)来禁止写入。
  4. 为什么每次渲染需要执行一次Clear 深度缓冲区原理就是把一个距离观察平面(近裁剪面)的深度值(或距离)与窗口中的每个像素相关联。 首先,使用glClear(GL_DEPTH_BUFFER_BIT),把所有像素的深度值设置为最大值(一般是远裁剪面)。然后,在场景中以任意次序绘制所有物体。硬件或者软件所执行的图形计算把每一个绘制表面转换为窗口上一些像素的集合,此时并不考虑是否被其他物体遮挡。其次,OpenGL会计算这些表面和观察平面的距离。如果启用了深度缓冲区,在绘制每个像素之前,OpenGL会把它的深度值和已经存储在这个像素的深度值进行比较。新像素深度值<原先像素深度值,则新像素值会取代原先的;反之,新像素值被遮挡,他颜色值和深度将被丢弃。为了启动深度缓冲区,必须先启动它,即glEnable(GL_DEPTH_TEST)。每次绘制场景之前,需要先清除深度缓冲区,即glClear(GL_DEPTH_BUFFER_BIT),然后以任意次序绘制场景中的物体。

代码: https://github.com/YBYHunter/OpenGL-ES-Demo/tree/master

记得Star!Star!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • iOS 自动打包 - fastlane

    1 本文只是fastlane的基本使用. 2 使用fastlane前,确保你已经可以使用Xcode手动打包成功(说明你已经配置好证书)

    大壮
  • iOS 相机实时美白,磨皮,双边滤波、Canny边缘检测和肤色检测(实战篇)

    大壮
  • iOS transform(2D仿射)

    大壮
  • 【redis】缓存穿透的解决方案

    解决方案:使用多个 Hash 算法为元素计算出多个 Hash 值,只有所有 Hash 值对应的数组中的值都为 1 时,才会认为这个元素在集合中。 2. 不支持...

    居士
  • 操作系统实验之多线程操作之读者优先与写者优先第二版

    之前作者做的那个实验有误,希望大家见谅,在室友的质疑之后觉得的确存在着很大的问题,所以自己今天又把一些逻辑上的漏洞又重新完善了一下。其实主要的逻辑漏洞又两个方面...

    萌萌哒的瓤瓤
  • App架构设计经验谈:数据层的设计

    一个App,从根本上来说,就是对数据的处理,包括数据从哪里来、数据如何组织、数据怎么展示,从职责上划分就是:数据管理、数据加工、数据展示。相对应的也就有了三层架...

    Keegan小钢
  • H5 缓存机制浅析 移动端 Web 加载性能优化

    1 H5 缓存机制介绍 H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性。离线存储(也可称为缓存机制)是其中一个非常重要的特性。H5 引入的离...

    腾讯Bugly
  • Redis升级

    定期删除:默认是每隔 100ms 就轮询各个库随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。每隔100ms就遍历所有的设置过期时间的 ke...

    晚上没宵夜
  • 学界 | 我们还缺多少基础理论,才能在高中开设深度学习课程?

    AI 科技评论按:这篇文章来自资深机器学习专家、NIPS 2017 「时间检验奖」( Test of Time Award ) 获得者 Ali Rahimi。上...

    AI科技评论
  • 腾讯云Redis混合存储版重磅推出,万字长文助你破解缓存难题!

    导语 | 缓存+存储的系统架构是目前常见的系统架构,缓存层负责加速访问,存储层负责存储数据。这样的架构需要业务层或者是中间件去实现缓存和存储的双写、冷热数据的...

    腾讯云数据库 TencentDB

扫码关注云+社区

领取腾讯云代金券