十三、输出多个立方体并深度测试

第一部分概念

1)由来:

深度测试:opengl的深度测试是指在片段着色器执行之后,利用深度缓冲所保存的深度值决定当前片段是否被丢弃的过程。

深度缓冲区和颜色缓冲区是差不多的,有相同的宽高度,并且一般在窗口系统自动创建的时候就将其深度值存储为16,24或32位的浮点数了。

当深度测试开启的时候,opengl才会去测试深度缓冲区的深度值Z,通过测试则会被赋值新的深度值,如果失败则丢弃该片段。

深度测试是在片段着色器运行之后在屏幕空间执行的。

2) 定义:

对于屏幕空间坐标相关的视区是由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<float>(MATH_PI / 180.0f * angleXRotate);
    float radiansY = static_cast<float>(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
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值