C / C ++ OpenGL Окклюзия Отбор

Я опробовал сырой OpenGL, поэтому я решил написать очень-очень простую игру, основанную на 3D-блоках, что-то вроде игры Minecraft, только для того, чтобы улучшить свои навыки.

Последними проблемами, с которыми я встречался, были выбраковки. Я наконец-то понял, как сделать 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 полезен для решения моей проблемы, но я безуспешно пытался использовать его с Google по-разному, во-первых, кубы не были нарисованы, во-вторых, игра была нарисована, как и раньше, также покрыты кубами.

1

Решение

Как правило, вы не должны ожидать, что графический API выполнит эту работу за вас — его работа заключается в рендеринге, а ваша задача — сделать так, чтобы у него было как можно меньше рендеринга.

Я рекомендую прочитать этот блог: http://www.sea-of-memes.com/summary/blog_parts.html

Речь идет о ком-то, кто разрабатывает движок для майнкрафта с нуля и охватывает все: от окклюзии до освещения и прозрачности. На самом деле, самая первая часть должна ответить на ваш вопрос довольно хорошо.

2

Другие решения

Других решений пока нет …