Почему некоторые из моих кубических граней не воспроизводят так, как мне бы хотелось?

Лицевая сторона слева; правое лицо справа

Cube Front

Задняя сторона слева; левое лицо справа

Куб обратно

После некоторой отладки я пришел к нескольким выводам:

  • Отбраковка лица (на фотографиях отключена), кажется, усугубляет ситуацию.

  • Глубокая буферизация (включена на фотографиях), кажется, мало что помогает.

Используются лицевые клетки glFrontFace( GL_CW ) | glFrontFace( GL_CCW ) в комбинации с glCullFace( GL_BACK_FACE ),

Вот результат из фрагмента кода, предлагаемого Need4Sleep:

(примечание: сравнение глубины GL_LESS, похоже, ничего не меняет само по себе)

Передняя сторона слева; правое лицо справа — выбраковка лица включена

withCulling


Обзор кода

Вершины и цвета упорядочены как вершины, цвета в структуре, известной как simdColorVertex_tгде компоненты color и vertex структуры состоят из 4-х float, каждый в своих соответствующих массивах:

typedef float simdVec4_t[ 4 ];

typedef struct simdColorVert4_s
{
simdVec4_t position;
simdVec4_t color;
}
simdColorVert4_t;

Класс ColorCube

Конструктор создает свою соответствующую программу. Затем указываются данные вершины и индекса и привязываются к их соответствующим буферам:

(создание шейдерной программы для краткости опущено)

    const float S = 0.5f;

const simdColorVert4_t vertices[] =
{
/*! Positions */                    /*! Colors */           /*! Indices */
{ {  S,  S,  S, 1.0f },     { 0.0f, 0.0f, 1.0f, 1.0f } },   //! 0

{ { -S,  S,  S, 1.0f },     { 1.0f, 0.0f, 0.0f, 1.0f } },   //! 1

{ { -S, -S,  S, 1.0f },     { 0.0f, 1.0f, 0.0f, 1.0f } },   //! 2

{ {  S, -S,  S, 1.0f },     { 1.0f, 1.0f, 0.0f, 1.0f } },   //! 3

{ {  S,  S, -S, 1.0f },     { 1.0f, 1.0f, 1.0f, 1.0f } },   //! 4

{ { -S,  S, -S, 1.0f },     { 1.0f, 0.0f, 0.0f, 1.0f } },   //! 5

{ { -S, -S, -S, 1.0f },     { 1.0f, 0.0f, 1.0f, 1.0f } },   //! 6

{ {  S, -S, -S, 1.0f },     { 0.0f, 0.0f, 1.0f, 1.0f } }    //! 7
};const GLubyte indices[] =
{
1, 0, 2,    2, 0, 3,    //! Front Face

3, 6, 4,    4, 0, 3,    //! Right Face

3, 6, 2,    2, 6, 7,    //! Bottom Face

7, 6, 4,    4, 5, 7,    //! Back Face

7, 5, 2,    2, 1, 5,    //! Left Face

5, 1, 4,    4, 0, 1,    //! Top Face
};

//! The prefix BI_* denotes an enum, standing for "Buffer Index"
{
glBindBuffer( GL_ARRAY_BUFFER, mBuffers[ BI_ARRAY_BUFFER ] );
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_DYNAMIC_DRAW );
glBindBuffer( GL_ARRAY_BUFFER, 0 );

glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mBuffers[ BI_ELEMENT_BUFFER ] );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), indices, GL_DYNAMIC_DRAW );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
}

Оттуда (все еще в конструкторе) создается и связывается массив вершин вместе с соответствующим атрибутом и данными буфера:

    glBindVertexArray( mVertexArray );

glBindBuffer( GL_ARRAY_BUFFER, mBuffers[ BI_ARRAY_BUFFER ] );

glEnableVertexAttribArray( 0 );
glEnableVertexAttribArray( 1 );

glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, sizeof( float ) * 8, ( void* ) offsetof( simdColorVert4_t, simdColorVert4_t::position ) );
glVertexAttribPointer( 1, 4, GL_FLOAT, GL_FALSE, sizeof( float ) * 8, ( void* ) offsetof( simdColorVert4_t, simdColorVert4_t::color ) );

glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mBuffers[ BI_ELEMENT_BUFFER ] );

glBindVertexArray( 0 );

Разное

Перед инициализацией куба эта функция вызывается:

void MainScene::setupGL( void )
{
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glDepthRange( 0.0f, 1.0f );

glClearDepth( 1.0f );

int width, height;

gvGetWindowSize( &width, &height );

glViewport( 0, 0, width, height );
}

И буфер глубины очищается перед mCube->draw(...) функция называется.

Я думаю, очевидно, что я делаю что-то не так, но я не уверен, что это может быть. После того, как он возился с отбраковкой задней поверхности и перемещением между командами намотки против часовой стрелки и по часовой стрелке для передней поверхности, это только ухудшило ситуацию. Есть идеи?

3

Решение

Попробуйте добавить этот кусок кода в начало вашей программы

//screen cleared as blue
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);

это из текстурированной кубической программы, которую я написал, возможно, у вас уже реализованы некоторые из этих функций, но из того, что я вижу, вы можете отсутствовать glDepthFunc(GL_LESS)

1

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

Согласно замечанию @ JasonD о некорректном порядке индексирования, индексы редактировались следующим образом:

const GLubyte indices[] =
{
1, 0, 2,    2, 0, 3,    //! Front Face

3, 7, 4,    4, 0, 3,    //! Right Face (edited)

3, 7, 2,    2, 6, 7,    //! Bottom Face (edited)

7, 6, 4,    4, 5, 6,    //! Back Face

6, 5, 2,    2, 1, 5,    //! Left Face (edited)

5, 1, 4,    4, 0, 1,    //! Top Face
};

Если сравнить вышеуказанные показатели с оригиналом, упомянутым в вопросе, нетрудно заметить ущербную красоту человеческой ошибки!

(само собой разумеется, куб теперь рендерится правильно)

1

По вопросам рекламы [email protected]