我通过一个非常简单的OpenGL设置发生了一些可怕的闪烁。我正在使用GLFW进行窗口和上下文创建。我的理解是你应该清除框架,提交绘图调用,然后交换缓冲区。我试图在绘制调用中渲染一堆2D四边形和一些变换数据。这是我的实际渲染例程,每个模拟步骤调用一次:
glClear( GL_COLOR_BUFFER_BIT );
glUseProgram( m_shader );
// Retrieve shader uniforms
int pos = glGetAttribLocation( m_shader, "position" );
int texCoord = glGetAttribLocation( m_shader, "texCoord" );
int texture = glGetUniformLocation( m_shader, "texture" );
int transforms = glGetUniformLocation( m_shader, "transforms" );
// Bind the quad mesh
glBindBuffer( GL_ARRAY_BUFFER, m_quad );
// Setup the transforms texture
glActiveTexture( GL_TEXTURE0 + 1 );
glBindTexture( GL_TEXTURE_BUFFER, m_transformBufferTexture );
glTexBuffer( GL_TEXTURE_BUFFER, GL_RGBA32F, m_transformBuffer );
glUniform1i( transforms, 1 );
// Setup stride
glEnableVertexAttribArray( pos );
glEnableVertexAttribArray( texCoord );
glVertexAttribPointer( pos, 4, GL_FLOAT, false, sizeof( Vertex ), (void *)offsetof( Vertex, p ) );
glVertexAttribPointer( texCoord, 2, GL_FLOAT, false, sizeof( Vertex ), (void *)offsetof( Vertex, uv ) );
// Render each batch
for(unsigned i = 0; i < m_batches.Size( ); ++i)
{
SpriteBatch batch = m_batches[i];
unsigned count = batch.end - batch.begin + 1;
unsigned textureID = batch.begin->m_texture->ID( );
// Copy batch transforms into the transform buffer
int j = 0;
for(;;)
{
memcpy( m_transforms + j, &batch.begin->m_tx, sizeof( float ) * 6 );
++j;
if(batch.begin == batch.end)
break;
++batch.begin;
}
// Setup which texture to use
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, textureID );
glUniform1i( texture, 0 );
glBindBuffer( GL_TEXTURE_BUFFER, m_transformBuffer );
glBufferSubData( GL_TEXTURE_BUFFER, 0, sizeof( Transform ) * count, m_transforms );
glBindBuffer( GL_TEXTURE_BUFFER, 0 );
// Render
glDrawArraysInstanced( GL_TRIANGLES, 0, 6, count );
}
glDisableVertexAttribArray( texCoord );
glDisableVertexAttribArray( pos );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glUseProgram( 0 );
glfwSwapBuffers( ENGINE->Window( ) );
如果我将glBufferSubData
调用调用glBufferData
调用,则闪烁的问题就会消失,我的场景会按预期呈现。如果可能的话,我更愿意使用glBufferSubData
,但我只是不明白为什么会遇到这样的问题。
编辑:这对我来说就像一个奇怪的同步问题。我相信我的转换数据在某个时候被glBufferSubData
调用覆盖,而OpenGL并不期望数据被覆盖。我猜它是司机问题?我不知道。我在网上读到的每个地方都说glBufferSubData
应该是同步的。
编辑:我可能找到了重复:glBufferSubData between glDrawArrays calls mangling data
编辑:经过一些研究后,我发现this link关于使用缓冲区孤立的异步数据上传。我认为这应该解决我的问题,因为由于某种原因,glBufferSubData
不是隐式同步的。我将回过头来了解它是如何运作的。
修改:我使用this link中的解决方案作为替代方案,所有问题都已解决。