简体   繁体   English

C / C ++ OpenGL遮挡剔除

[英]C/C++ OpenGL Occlusion Culling

I'm trying out raw OpenGL, so I decided to code very, very simple game based on 3d blocks, something a'la retarded Minecraft game, just to improve my skills. 我正在尝试原始OpenGL,所以我决定编写基于3d块的非常非常简单的游戏,这是Minecraft游戏中的一种“智障”游戏,目的只是为了提高我的技能。

Last problems I've met with were cullings. 我遇到的最后一个问题是剔除。 I've finally figured out how to make Frustum Culling and Backface Culling, and they both work well, but unfortunatelly I have no idea how to code Occlusion Culling to not display boxes that are covered by other boxes that are closer to player. 我终于弄清楚了如何制作“平截头体剔除”和“背面剔除”,它们都工作良好,但是不幸的是,我不知道如何编写“遮挡剔除”的代码,以不显示被其他更靠近玩家的盒子所覆盖的盒子。

Just for test in main draw loop I'm looping through all boxes, later I'll change it to a more efficient way, now this is how the code looks like: 只是为了在主绘制循环中进行测试,我将遍历所有框,稍后将其更改为更有效的方式,现在代码如下所示:

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( );
}

And Cube::Draw: 和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( );
}

I'm pretty sure it's inefficient, as I said earlier, this code will be optimized soon. 我可以肯定它的效率很低,正如我之前所说的,此代码将很快进行优化。 Now I'm trying to make it working. 现在,我正在尝试使其正常运行。 The bool variables showSide are made for detection, if there is box with other box next to it, the sides between them won't be drawn. 布尔变量showSide用于检测,如果旁边有一个带有其他框的框,则不会绘制它们之间的边。

I've been looking and googling how to make the occlusion culling, but I failed, there are only laconic informations or theory. 我一直在寻找和搜寻如何进行遮挡剔除,但是我失败了,只有简单的信息或理论。

My question is, could anyone help me how to not draw covered blocks? 我的问题是,有人可以帮助我如何不绘制遮盖的方块吗? I heard there is GLEW which I've compiled and injected, it has two following lines: glBeginQuery(GL_SAMPLES_PASSED_ARB, query); 我听说有我编译和注入的GLEW,它有两行:glBeginQuery(GL_SAMPLES_PASSED_ARB,query); glEndQuery(GL_SAMPLES_PASSED); glEndQuery(GL_SAMPLES_PASSED);

Apparently Query is helpful to solve my problem, but I unsuccessfully tried to use it with Google on many ways, firstly no cubes were drawn, secondly game was drawn as earlier, covered cubes also. 显然Query可以帮助解决我的问题,但是我尝试通过多种方式与Google一起使用均未成功,首先没有绘制任何多维数据集,其次像以前绘制游戏一样,也覆盖了多维数据集。

Generally, you shouldn't expect a graphical API to do the work for you - its job is rendering, and your job is making sure it has as little to render as possible. 通常,您不应该期望图形API为您完成工作-它的工作是呈现,而您的工作是确保尽可能少地呈现。

I recommend reading this blog: http://www.sea-of-memes.com/summary/blog_parts.html 我建议阅读此博客: http : //www.sea-of-memes.com/summary/blog_parts.html

It is about someone developing a minecraft-ish engine from scratch, and goes over everything from occlusion to lighting to transparency. 它是关于某人从零开始开发类似于Minecraft的引擎,并且涉及从遮挡,照明到透明度的所有内容。 In fact, the very first part should answer your question pretty well. 实际上,第一部分应该很好地回答您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM