使用glBufferSubData的OpenGL闪烁

时间:2013-12-19 17:43:06

标签: c++ opengl

我通过一个非常简单的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中的解决方案作为替代方案,所有问题都已解决。

0 个答案:

没有答案