OpenGL ES 学习教程(十二) DEPTH_TEST(深度缓冲测试)
来源:互联网 发布:河南评书下载软件 编辑:程序博客网 时间:2024/05/22 18:25
接触到3D,就一定会接触到深度这个概念,最直接的就是看Z轴,两个人在场景中,你的Z轴是1,我的Z轴是2,摄像机位于Z -10的位置,那么我的深度比你的大。
在OpenGL中,默认是没有开启深度检测的,也就是说,后绘制的物体覆盖先绘制的物体(颜色缓冲区中,先绘制的物体 被 后绘制的物体 覆盖)。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
来看代码例子:
//重写Render;virtual void render(){ glClearColor(0, 0, 0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, m_width, m_height); { //model; glm::mat4 model = glm::mat4(1.0f); //View glm::mat4 view = glm::lookAt(glm::vec3(0, 0, -10.0f), glm::vec3(0, 0,0), glm::vec3(0, 1, 0)); //透视 注意近裁剪面 远裁剪面的值是相对于Camera Position的 这里Camera位于Z -10,那么近裁剪面是 0,远裁剪面是2. glm::mat4 proj = glm::perspective(glm::radians(60.0f), 1.0f, 10.0f, 12.0f); proj = proj*view*model; m_program.begin(); { //红色 { glm::vec4 pos[] = { glm::vec4(-2.0f, -2.0f, 1.5f, 1.0f), glm::vec4(2.0f, -2.0f, 1.5f, 1.0f), glm::vec4(0.0f, 2.0f, 1.5f, 1.0f), }; glm::vec4 color[] = { glm::vec4(1, 0, 0, 1), glm::vec4(1, 0, 0, 1), glm::vec4(1, 0, 0, 1), }; glUniformMatrix4fv(m_program.m_mvp, 1, false, &proj[0][0]); glVertexAttribPointer(m_program.m_position, 4, GL_FLOAT, false, sizeof(glm::vec4), pos); glVertexAttribPointer(m_program.m_color, 4, GL_FLOAT, false, sizeof(glm::vec4), color); glDrawArrays(GL_TRIANGLES, 0, 3); } //黄色 { glm::vec4 pos[] = { glm::vec4(0.0f, -2.0f, 1.7f, 1.0f), glm::vec4(4.0f, -2.0f, 1.7f, 1.0f), glm::vec4(2.0f, 2.0f, 1.7f, 1.0f), }; glm::vec4 color[] = { glm::vec4(1, 1, 0, 1), glm::vec4(1, 1, 0, 1), glm::vec4(1, 1, 0, 1), }; glUniformMatrix4fv(m_program.m_mvp, 1, false, &proj[0][0]); glVertexAttribPointer(m_program.m_position, 4, GL_FLOAT, false, sizeof(glm::vec4), pos); glVertexAttribPointer(m_program.m_color, 4, GL_FLOAT, false, sizeof(glm::vec4), color); glDrawArrays(GL_TRIANGLES, 0, 3); } } m_program.end(); } eglSwapBuffers(m_EGLDisplay, m_EGLSurface);}
在上面的例子中,先绘制了一个红色的三角形,再绘制了一个黄色三角形。注意 到黄色三角形的 Z 轴,是比红色三角形 大的,所以理论上黄色三角形应该在红色三角形后面。
但是实际上
然而实际上黄色三角形却到了红色三角形前面。
这是因为 OpenGL中默认没有开启深度缓冲测试,就是说,后绘制的物体覆盖先绘制的物体(颜色缓冲区中,先绘制的物体 被 后绘制的物体 覆盖)。
所以这里红色三角形 被 后绘制的黄色三角形盖住了。
下面来启用 深度缓冲测试。
首先在创建窗口的时候请求一个深度缓冲区
bool initDevice(){const EGLint attribs[] ={EGL_SURFACE_TYPE, EGL_WINDOW_BIT,EGL_BLUE_SIZE, 8,EGL_GREEN_SIZE, 8,EGL_RED_SIZE, 8,EGL_ALPHA_SIZE,8,EGL_DEPTH_SIZE, 24, //请求深度缓冲区EGL_NONE};EGLint format(0);EGLintnumConfigs(0);EGLint major;EGLint minor;//! 1m_EGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);//! 2initeglInitialize(m_EGLDisplay, &major, &minor);//! 3eglChooseConfig(m_EGLDisplay, attribs, &m_EGLConfig, 1, &numConfigs);eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_NATIVE_VISUAL_ID, &format);//! 4 m_EGLSurface = eglCreateWindowSurface(m_EGLDisplay, m_EGLConfig, m_hWnd, NULL);//! 5EGLint attr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };m_EGLContext = eglCreateContext(m_EGLDisplay, m_EGLConfig, 0, attr);//! 6if (eglMakeCurrent(m_EGLDisplay, m_EGLSurface, m_EGLSurface, m_EGLContext) == EGL_FALSE){return false;}eglQuerySurface(m_EGLDisplay, m_EGLSurface, EGL_WIDTH, &m_width);eglQuerySurface(m_EGLDisplay, m_EGLSurface, EGL_HEIGHT, &m_height);//! windows apiSendMessage(m_hWnd, WM_SIZE, 0, 0);return true;}
然后启用深度缓冲测试
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
//重写初始化函数;virtual void onInit(){Light3dWinAPP::onInit();m_program.Initialize();glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS); //基准设置为 1.0,那么GL_LESS 则深度小余 1.0 的通过测试}
glDepthFunc 用来修改深度比较运算符,参数枚举用来指定深度值比较函数。可能是 GL_LESS,GL_GREATER,GL_LEQUAL,GL_GEQUAL,GL_NOTEQUAL,GL_ALWAYS,GL_NEVER。
看英文就能看出来大概的意思,比如 GL_LESS 的意思就是说,比深度缓冲区中原来的深度值小,就通过测试。用新的值覆盖掉缓冲区中保存的值。深度值小,就是离摄像机近。
最后在绘制的时候,添加 glClearDepth
//重写Render;virtual void render(){glClearColor(0, 0, 0, 1.0);glClearDepthf(1.0f);//深度测试的基准,注意1.0代表从近裁剪面到远裁剪面 这一段范围!!并不是指Z轴的1个单位glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);glViewport(0, 0, m_width, m_height);............
glClearDepth(1.0f)
深度,是一个Normolized的值,范围是 0-1,对应Z轴是从近裁剪面到远裁剪面。
所以这里的 1.0f 指的是 ,深度缓冲区中默认值是远裁剪面。
启用深度缓冲测试后
当某些片段位于 近裁剪面与远裁剪面之外,就会被摄像机裁减掉。这是摄像机的功能。
m_program.begin();{{glm::vec4 pos[] ={glm::vec4(-2.0f, -2.0f, 1.5f, 1.0f),glm::vec4(2.0f, -2.0f, 1.5f, 1.0f),glm::vec4(0.0f, 2.0f, 2.5f, 1.0f), //这个点已经在远裁剪面之外了,所以被裁剪掉了。};............
红色三角形 底边深度比黄色三角形底边更小,所以红色三角形底边覆盖了黄色三角形底边。
红色三角形顶角深度比黄色三角形大,所以往上 是红色三角形被黄色三角形覆盖了。
而且由于红色三角形深度值大于1,也就是被远裁剪面裁剪了,所以上面缺了一个角。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
示例代码工程下载:
http://pan.baidu.com/s/1eRJF8Im
- OpenGL ES 学习教程(十二) DEPTH_TEST(深度缓冲测试)
- OpenGL ES 颜色缓冲 深度测试 表面剔除
- OpenGL ES学习系列教程
- 现代OpenGL教程 03 - 矩阵,深度缓冲,动画
- OpenGL入门学习[十二] 片断测试
- iPhone OpenGL ES教程
- OpenGL ES 教程 1
- iPhone OpenGL ES教程
- Android OpenGL ES 教程
- opengl es 简单教程
- OpenGL ES 简单教程
- OpenGL ES 简单教程
- OpenGL ES 简单教程
- OpenGL ES教程
- openGL ES教程
- 基于OpenGL ES 的深度学习框架编写
- 基于OpenGL ES 的深度学习框架编写
- OpenGL入门学习之十二——OpenGL片断测试
- Android常用调试命令
- Reproducible可重复性 研究论文必备属性
- 【struts2】Struts2的运行流程
- Linux驱动开发基础知识
- Windows7硬盘安装和授权文件的备份和恢复
- OpenGL ES 学习教程(十二) DEPTH_TEST(深度缓冲测试)
- 花椒 GPUImage 处理流程
- Unity——通过脚本给物体改变颜色
- bean的生命周期
- lightoj 1027 幼儿园概率...
- C中的volatile用法
- 微信小程序开发之本地图片上传(leancloud)
- APK进行二次签名
- ICML 2016 papers