glMapBufferRange(...)中的偏移量与glDrawArraysInstanced(...)中的first的关系

时间:2018-09-09 16:38:29

标签: c++ opengl

我正在努力了解这两个函数中的偏移量变量之间的关系以及偏移值如何影响着色器中的gl_VertexIDgl_InstanceID变量。

通过阅读函数文档,我认为glMapBufferRange期望offset是从缓冲区开始的字节数,而glDrawArraysInstanced期望firstglVertexAttribPointer指定的步幅数。

但是,情况似乎并非如此,因为如果offsetVerts的值不同于0,下面的代码将不起作用。对于0,它会在屏幕上渲染3个正方形,这与我预期的一样。

另一个可能的错误源将是gl_VertexID的值。我希望每个实例的4个顶点着色器调用为0、1、2、3,而不管偏移值如何。 只是为了确保我也尝试将4和vertices[int(mod(gl_VertexID,4))]的第一个值用于位置查找,但没有成功。

如何替换代码以使其与非0的偏移量一起使用?

在这里省略了

glGetError()调用以缩短代码,在整个过程中它为0。 GL版本是3.3。

初始化代码:

GLuint buff_id, v_id;
GLint bytesPerVertex = 2*sizeof(GLfloat); //8

glGenBuffers( 1, &buff_id );
glBindBuffer( GL_ARRAY_BUFFER, buff_id );
glGenVertexArrays( 1, &v_id );
glBufferData( GL_ARRAY_BUFFER, 1024, NULL, GL_STREAM_DRAW );

glBindVertexArray( v_id );
glEnableVertexAttribArray( posLoc );
glVertexAttribPointer( posLoc, 2, GL_FLOAT, GL_FALSE, bytesPerVertex, (void *)0 );
glVertexAttribDivisor( posLoc, 1 );
glBindVertexArray( 0 );

glBindBuffer( GL_ARRAY_BUFFER, 0 );
float *data_ptr = nullptr;

int numVerts = 3;
int offsetVerts = 0;

渲染代码:

glBindBuffer( GL_ARRAY_BUFFER, buff_id );
data_ptr = (float *)glMapBufferRange( GL_ARRAY_BUFFER, 
    bytesPerVertex * offsetVerts, 
    bytesPerVertex * numVerts,
    GL_MAP_WRITE_BIT );

data_ptr[0] = 50;
data_ptr[1] = 50;
data_ptr[2] = 150;
data_ptr[3] = 50;
data_ptr[4] = 250;
data_ptr[5] = 50;

glUnmapBuffer( GL_ARRAY_BUFFER );
glBindBuffer( GL_ARRAY_BUFFER, 0 );

glBindVertexArray( v_id );
glDrawArraysInstanced( GL_TRIANGLE_STRIP, offsetVerts, 4, 3 );
glBindVertexArray( 0 );

顶点着色器:

#version 330
uniform mat4 proj;
in vec2 pos;

void main() {

  vec2 vertices[4]= vec2[4](
    vec2(pos.x,         pos.y),
    vec2(pos.x + 10.0f, pos.y),
    vec2(pos.x,         pos.y + 10.0f ),
    vec2(pos.x + 10.0f, pos.y + 10.0f )
    );

  gl_Position = proj * vec4(vertices[gl_VertexID], 1, 1);
}

片段着色器:

#version 330
out vec4 LFragment;
void main() {
  LFragment = vec4( 1.0f, 1.0f, 1.0f, 1.0f ); 
}

1 个答案:

答案 0 :(得分:2)

  

另一个可能的错误源将是gl_VertexID的值。我希望每个实例进行4个顶点着色器调用时,其值分别为0、1、2、3,而不考虑offset的值。

offset中没有没有 glDrawArrays*

此的基本功能是 glDrawArrays(type, first, count),这将从指定的顶点属性数组的连续子数组(从索引fristfrist+count-1)生成图元。因此,gl_VertexID将在firstfirst+count-1范围内。

您实际上没有使用任何顶点属性数组,而是将您的属性变成了 per-instance 属性。但是first参数将引入偏移量。您可以调整属性指针以包括偏移量,也可以使用glDrawArraysInstancedBaseInstance指定所需的偏移量。

请注意,gl_InstanceID不会反映您在此处设置的基本实例,相对于绘图调用的开始,它仍将从0开始计数。但是从数组中获取的实际实例值将使用偏移量。