经过一些调试,我得出了几个结论:
面部剔除(照片中已关闭)似乎会让情况变得更糟。
深度缓冲(在照片中打开)似乎没有什么帮助。
面部剔除使用
glFrontFace( GL_CW ) | glFrontFace( GL_CCW )
与 glCullFace( GL_BACK_FACE )
结合使用。
这是 Need4Sleep 提供的代码片段的结果:
(注意:GL_LESS 深度比较本身似乎没有改变任何东西)
顶点和颜色在结构体中按顶点、颜色排序,称为
simdColorVertex_t
,其中结构体的颜色和顶点分量由 4 个浮点数组成,每个浮点数位于各自的数组中:
typedef float simdVec4_t[ 4 ];
typedef struct simdColorVert4_s
{
simdVec4_t position;
simdVec4_t color;
}
simdColorVert4_t;
构造函数创建其各自的程序。然后指定顶点和索引数据,并将其绑定到各自的缓冲区:
(为简洁起见,省略了着色器程序的创建)
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(...)
函数之前清除深度缓冲区。
我认为很明显我在这里做错了什么,但我不确定它可能是什么。在搞乱了背面剔除并在正面的逆时针和顺时针缠绕顺序之间移动之后,这只会让事情变得更糟。有什么想法吗?
尝试将这段代码添加到程序的顶部
//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)
根据@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
};
如果将上述指标与问题中提到的原始指标进行比较,就不难发现人为错误的缺陷之美!
(不用说,立方体现在可以正确渲染)