C/C++OpenGL遮挡消隐

C/C++ OpenGL Occlusion Culling

本文关键字:消隐 遮挡 C++OpenGL      更新时间:2023-10-16

我正在尝试原始OpenGL,所以我决定基于3d块编写非常非常简单的游戏,这是一款"我的世界"游戏,只是为了提高我的技能。

我遇到的最后一个问题是筛选。我终于找到了如何制作Frustum Culling和Backface Culling,它们都很好用,但不幸的是,我不知道如何对Occlusion Culling进行编码,使其不显示被靠近玩家的其他框覆盖的框。

只是为了在主绘制循环中进行测试,我正在循环所有框,稍后我会将其更改为更有效的方式,现在代码看起来是这样的:

for( std::map< std::string, Cube* >::iterator it = Cube::cubesMap.begin( ); it !=  Cube::cubesMap.end( ); it++ )
{
    cube = ( *it ).second;
    if( !cube )
        continue;
    (...)
    if( Camera::cubeInFrustum( cube->position.x, cube->position.y, cube->position.z, 0.5f ) && cube->isInRoundDistance( 80 ) )
        cube->draw( );
}

和立方体::绘制:

void Cube::draw( )
{
    glPushMatrix( );
    glTranslatef( position.x, position.y, position.z );
    if( showSide1 == false && showSide2 == false && showSide3 == false && showSide4 == false && showSide5 == false && showSide6 == false )
    {
        glPopMatrix( );
        return;
    }
    GLfloat cube[] = 
    {
        -0.5f, -0.5f,  0.5f,// Front face
         0.5f, -0.5f,  0.5f,
        -0.5f,  0.5f,  0.5f,
         0.5f,  0.5f,  0.5f,
        -0.5f, -0.5f, -0.5f,// Back face
        -0.5f,  0.5f, -0.5f,
         0.5f, -0.5f, -0.5f,
         0.5f,  0.5f, -0.5f,
        -0.5f, -0.5f,  0.5f,// Left face
        -0.5f,  0.5f,  0.5f,
        -0.5f, -0.5f, -0.5f,
        -0.5f,  0.5f, -0.5f,
         0.5f, -0.5f, -0.5f,// Right face
         0.5f,  0.5f, -0.5f,
         0.5f, -0.5f,  0.5f,
         0.5f,  0.5f,  0.5f,
        -0.5f,  0.5f,  0.5f,// Top face
         0.5f,  0.5f,  0.5f,
        -0.5f,  0.5f, -0.5f,
         0.5f,  0.5f, -0.5f,
        -0.5f, -0.5f,  0.5f,// Bottom face
        -0.5f, -0.5f, -0.5f,
         0.5f, -0.5f,  0.5f,
         0.5f, -0.5f, -0.5f 
    };
    float textures[] =
    {
        1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 
        0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 
        0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 
        0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 
        0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 
        0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f
    };
    //ss << position.x + 2 << ", " << position.y << ", " << position.z << std::endl;
    glVertexPointer(3, GL_FLOAT, 0, cube);
    glTexCoordPointer(2, GL_FLOAT, 0, textures);
    if( showSide1 || showSide2 || showSide3 || showSide4 )
        glBindTexture(GL_TEXTURE_2D, imageSides->texture);
    if( showSide1 )
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    if( showSide2 )
        glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
    if( showSide3 )
        glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
    if( showSide4 )
        glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
    if( showSide5 )
    {
        glBindTexture(GL_TEXTURE_2D, imageUp->texture);
        glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);
    }
    if( showSide6 )
    {
        glBindTexture(GL_TEXTURE_2D, imageDown->texture);
        glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);
    }
    glPopMatrix( );
}

我确信这是低效的,正如我之前所说的,这段代码很快就会得到优化。现在我正努力让它发挥作用。bool变量showSide用于检测,如果有一个盒子旁边有另一个盒子,则不会绘制它们之间的边。

我一直在寻找和谷歌搜索如何进行遮挡剔除,但我失败了,只有简洁的信息或理论。

我的问题是,有人能帮助我如何不画有盖的方块吗?我听说我编译并注入了GLEW,它有以下两行:glBeginQuery(GL_SAMPLES_PASSED_ARB,查询);glEndQuery(GL_SAMPLES_PASSED);

显然Query有助于解决我的问题,但我尝试在谷歌上使用它,但在很多方面都没有成功,首先没有绘制多维数据集,其次游戏是像以前一样绘制的,也有覆盖的多维数据集。

一般来说,您不应该期望图形化的API为您做这项工作——它的工作是渲染,您的工作是确保它有尽可能少的渲染。

我建议阅读这个博客:http://www.sea-of-memes.com/summary/blog_parts.html

这是关于某人从头开始开发minecraft风格的引擎,涵盖了从遮挡到照明再到透明度的所有内容。事实上,第一部分应该很好地回答了你的问题。