深度测试:opengl的深度测试是指在片段着色器执行之后,利用深度缓冲所保存的深度值决定当前片段是否被丢弃的过程。
深度缓冲区和颜色缓冲区是差不多的,有相同的宽高度,并且一般在窗口系统自动创建的时候就将其深度值存储为16,24或32位的浮点数了。
当深度测试开启的时候,opengl才会去测试深度缓冲区的深度值Z,通过测试则会被赋值新的深度值,如果失败则丢弃该片段。
深度测试是在片段着色器运行之后在屏幕空间执行的。
对于屏幕空间坐标相关的视区是由OpenGL的视口设置函数glViewport 函数设定的,但是也可以在片段着色器中通过内置的gl_FragCoord 变量访问。gl_FragCoord 的XY就表示该片段的屏幕空间坐标(0,0在左下角),其取值范围由glViewport 函数决定,屏幕空间坐标原点在左下角。对于gl_FragCoord 还有一个z坐标,这个就是是片段的实际深度值了,此 z 坐标值是与深度缓冲区的内容进行比较的值,
深度缓冲区中包含深度值介于 0.0 和 1.0 之间,物体接近近平面的时候,深度值接近 0.0 ,物体接近远平面时,深度接近 1.0 。
可以直接在光照基础的工程基础上,只有在draw的时候有部分不同,从原来的一个立方体到现在的多个立方体。
需要新增多个立方体的差异数组,需要引入深度测试;
//多个立方体
glm::vec3 transPos[] = {
glm::vec3( 0.0f, 0.0f, 0.0f),
glm::vec3( 2.0f, 2.0f, -1.0f) * 1.6f,
glm::vec3(-1.5f, -2.2f, -1.5f) * 1.6f,
glm::vec3(-1.8f, -2.0f, 1.3f) * 1.6f,
glm::vec3( 1.4f, -1.4f, -1.5f) * 1.6f,
glm::vec3(-1.7f, 2.0f, -1.5f) * 1.6f,
glm::vec3( 1.3f, -2.0f, 2.5f) * 1.6f,
glm::vec3( 0.5f, 1.3f, -0.1f) * 1.6f,
glm::vec3( 1.5f, 2.2f, 1.5f) * 1.6f,
glm::vec3(-1.3f, 1.0f, -1.5f) * 1.6f,
glm::vec3(-1.3f, 0.0f, -1.5f) * 1.6f,
glm::vec3( 0.0f, -1.3f, -0.5f) * 1.6f,
glm::vec3( 0.0f, -1.5f, 1.5f) * 1.6f,
};
//坐标视角
void Basiclighting::UpdateMatrix(glm::mat4 &mvpMatrix, glm::mat4 &modelMatrix, int angleXRotate, int angleYRotate, float scale, glm::vec3 transVec3, float ratio)
{
LOGD("DepthTestingSample::UpdateMatrix angleX = %d, angleY = %d, ratio = %f", angleXRotate,
angleYRotate, ratio);
angleXRotate = angleXRotate % 360;
angleYRotate = angleYRotate % 360;
//转化为弧度角
float radiansX = static_cast(MATH_PI / 180.0f * angleXRotate);
float radiansY = static_cast(MATH_PI / 180.0f * angleYRotate);
// Projection matrix
//glm::mat4 Projection = glm::ortho(-ratio, ratio, -1.0f, 1.0f, 0.0f, 100.0f);
//glm::mat4 Projection = glm::frustum(-ratio, ratio, -1.0f, 1.0f, 4.0f, 100.0f);
glm::mat4 Projection = glm::perspective(45.0f, ratio, 0.1f, 100.f);
// View matrix
glm::mat4 View = glm::lookAt(
glm::vec3(0, 0, 3), // Camera is at (0,0,1), in World Space
glm::vec3(0, 0, 0), // and looks at the origin
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
);
// Model matrix
glm::mat4 Model = glm::mat4(1.0f);
Model = glm::scale(Model, glm::vec3(scale, scale, scale));
Model = glm::rotate(Model, radiansX, glm::vec3(1.0f, 0.0f, 0.0f));
Model = glm::rotate(Model, radiansY, glm::vec3(0.0f, 1.0f, 0.0f));
Model = glm::translate(Model, transVec3);
modelMatrix = Model;
mvpMatrix = Projection * View * Model;
}
//绘画
void Basiclighting::Draw() {
#ifndef DEPTH
....
#else
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glClearColor(0.2f, 0.9f, 0.3f, 1.0f);
// UpdateMVPMatrix(m_MVPMatrix, m_AngleX, m_AngleY, (float) srceenWidth / srceenHeight);
glEnable(GL_DEPTH_TEST);//启用深度测试,注意glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);也要进行清除
glUseProgram(program);
glBindVertexArray(m_VaoId);
//设置参数
//glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);
glUniformMatrix4fv(m_ModelMatrixLoc, 1, GL_FALSE, &m_ModelMatrix[0][0]);
glUniform3f(m_LightColorLoc, 1.0f, 1.0f, 1.0f);
glUniform3f(m_LightPosLoc, -2.0f, 0.0f, 2.0f);
glUniform3f(m_ViewPosLoc, -3.0f, 0.0f, 3.0f);
//绑定纹理
glBindTexture(GL_TEXTURE_2D, m_TextureId);
glUniform1i(m_SamplerLoc, 0);
float ratio = (float)srceenWidth / srceenHeight;
// 绘制多个立方体,不同的位移和旋转角度
for(int i = 0; i < sizeof(transPos)/ sizeof(transPos[0]); i++)
{
UpdateMatrix(m_MVPMatrix, m_ModelMatrix, m_AngleX + 10, m_AngleY + 10, 0.4, transPos[i], ratio);
glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
glBindVertexArray(0);
#endif
}