Отношение смещения в glMapBufferRange (...) и сначала в glDrawArraysInstanced (...) - PullRequest
0 голосов
/ 09 сентября 2018

Я пытаюсь понять связь между переменными смещения в двух функциях и тем, как значение смещения влияет на переменные gl_VertexID и gl_InstanceID в шейдере.

При чтении документации по функциям, я думаю, glMapBufferRange ожидает, что offset будет числом байтов от начала буфера, тогда как glDrawArraysInstanced ожидает, что first будет числом шагов, как определено glVertexAttribPointer.

Однако, похоже, это не так, поскольку приведенный ниже код не работает, если offsetVerts имеет значение, отличное от 0. Для 0 он отображает 3 квадрата на экране, как я и ожидал.

Другим возможным источником ошибок будет значение gl_VertexID. Я ожидал бы, что он будет 0,1,2,3 для 4 вызовов вершинных шейдеров на экземпляр, независимо от значения смещения. Просто чтобы убедиться, что я также попытался использовать первое значение, кратное 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 голосов
/ 09 сентября 2018

Другим возможным источником ошибки будет значение gl_VertexID. Я ожидаю, что он будет 0,1,2,3 для 4 вызовов вершинных шейдеров на экземпляр, независимо от значения offset.

Существует нет offset значение в glDrawArrays*

Базовая функция для этого glDrawArrays(type, first, count), и это просто сгенерирует примитивы из последовательного подмассива указанных массивов атрибутов вершин от индекса frist до frist+count-1. Следовательно, gl_VertexID будет в диапазоне first, first+count-1.

Вы фактически не используете какой-либо массив атрибутов вершин, вы превратили свой атрибут в атрибут на экземпляр . Но параметр first будет , а не вводить смещение в них. Вы можете настроить указатель атрибута так, чтобы он включал смещение, или вы можете использовать glDrawArraysInstancedBaseInstance, чтобы указать необходимое смещение.

Обратите внимание, что gl_InstanceID не будет отражать базовый экземпляр, который вы там установили, он все равно будет отсчитываться от 0 относительно начала вызова отрисовки. Но значения экземпляра actall, извлеченные из массива, будут использовать смещение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...