Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: Disa от Май 13, 2013, 13:59



Название: Доступ к VBO в шейдере
Отправлено: Disa от Май 13, 2013, 13:59
Добрый день.

Я нашел такое решение:
Код
C++ (Qt)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

и в шейдере:
Код
glSlang
layout(location = 0) in vec3 vertexMPS;

Я правильно понимаю что аналогом этого будет (абстрактно):

Код
C++ (Qt)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
QGLShaderProgram::bindAttributeLocation("vertexMPS", 0);
 

Код
glSlang
in vec3 vertexMPS;

И еще, с ходу не нашел, а есть ли обертка вокруг glVertexAttribPointer для QGLBuffer или типа того?

Спасибо за ответы и помощь!


Название: Re: Доступ к VBO в шейдере
Отправлено: Disa от Май 13, 2013, 15:44
Ну и аналогично с текстурами. По дефолту как я понял для первого семплера берутся данные из GL_TEXTURE0 и так далее.

Обычно делал вот так вот:
Код
C++ (Qt)
glActiveTexture(GL_TEXTURE0);
glBindTexture(textureID);
glUniform1i(shaderUniformID, 0);


В общем-то видимо компилятор дописывает что-то похожее, если это не писать. Вопрос в том же - есть ли обертки в qt? Я только знаю, что айдишник можно взять :) shaderUniformID = QGLShaderProgram::uniformLocation("SamplerName")


Название: Re: Доступ к VBO в шейдере
Отправлено: Igors от Май 14, 2013, 08:32
Если "attrib" то вероятно Вы говорите о VAO (а не VBO). В любом случае неясно зачем заботиться о шейдере - ему ведь все равно откуда загружны данные - из CPU или GPU


Название: Re: Доступ к VBO в шейдере
Отправлено: Disa от Май 14, 2013, 10:16
В смысле?

Я могу пересылать переменные напрямую, через qglshaderprogramm->set..., а можно биндить буффер, потом указывать указатели(простите за каламбур) и обращаться через например layout. Я думал что второй вариант лучше или я ошибаюсь? То есть быстрее например отослать 1 буфер с вершинами, цветом, нормалями и указать потом смещения в glVertexAttribPointer, например, чем пересылать отдельно 3и массива через "setЧто-то"


Название: Re: Доступ к VBO в шейдере
Отправлено: Igors от Май 14, 2013, 10:52
В смысле?

Я могу пересылать переменные напрямую, через qglshaderprogramm->set..., а можно биндить буффер, потом указывать указатели(простите за каламбур) и обращаться через например layout. Я думал что второй вариант лучше или я ошибаюсь? То есть быстрее например отослать 1 буфер с вершинами, цветом, нормалями и указать потом смещения в glVertexAttribPointer, например, чем пересылать отдельно 3и массива через "setЧто-то"
Ну да, так это посылка геометрии (вертексов и.т.п.), шейдер-то тут причем?


Название: Re: Доступ к VBO в шейдере
Отправлено: Disa от Май 14, 2013, 12:22
Вроде бы понял. В сухом остатке получается, что генерация VAO (или VBO) и посылка через BufferData с указанием вершин полностью аналогично посылки через QGLShaderProgramm::set...();

У меня появился вопрос касательно комментария, и я правда с этим сталкивался, но не задумывался.

Цитировать
Если "attrib" то вероятно Вы говорите о VAO (а не VBO)

И тут я уже запутался. С одной стороны VAO это набор VBO с заранее подготовленными glEnableClientState, с другой стороны через glVertexAttribPointer я могу напрямую указать к чему я это привязывают (к нормали, вершине и прочему), то есть получается что VAO это либо набор уже готовых атрибутов для отрисовки, либо же некая пустышка, в которой я сам заполняю память по своему разумению и передаю в шейдер? Просто шейдер наверное тоже как-то интерпретирует константы типа GL_VERTEX_ARRAY/GL_COLOR_ARRAY и прочее? Для текстуры по дефолту идет первое значение для переменной типа Sampler - это первая забиндиная текстура в памяти.


Название: Re: Доступ к VBO в шейдере
Отправлено: Igors от Май 14, 2013, 12:42
И тут я уже запутался. С одной стороны VAO это набор VBO с заранее подготовленными glEnableClientState, с другой стороны через glVertexAttribPointer я могу напрямую указать к чему я это привязывают (к нормали, вершине и прочему), то есть получается что VAO это либо набор уже готовых атрибутов для отрисовки, либо же некая пустышка, в которой я сам заполняю память по своему разумению и передаю в шейдер? Просто шейдер наверное тоже как-то интерпретирует константы типа GL_VERTEX_ARRAY/GL_COLOR_ARRAY и прочее? Для текстуры по дефолту идет первое значение для переменной типа Sampler - это первая забиндиная текстура в памяти.
VBO - засылка данных на видеокарту (кеш чтобы не грузить их всякий раз с клиента)
VAO - то же самое но вызова экономичнее (не надо мурцевать буфера)

В любом случае "в шейдер" Вы ничего не подаете - он использует данные текущего рендера, а откуда они взялись ему все равно (хоть через glBegin/glEnd)


Название: Re: Доступ к VBO в шейдере
Отправлено: Disa от Май 14, 2013, 12:59
ладно, тогда два новых вопроса:
1). что лучше - генерить VAO и вызывать glVertexAttribPointer и  glEnableVertexAttribArray или посылать через QGLShaderProgramm->setAttribute? Или без разницы?

2). если шейдер использует данные текущего рендера, то получается мне не имеет смысл писать glEnableClientState для различных буфферов, если я явно указываю ссылки на них через glVertexAttribPointer?


Название: Re: Доступ к VBO в шейдере
Отправлено: Disa от Май 14, 2013, 13:33
Вопрос решен, спасибо. Загвоздка была в непонимании что работа с VAO на FFP и PP немного различается


Название: Re: Доступ к VBO в шейдере
Отправлено: Disa от Май 17, 2013, 14:13
В продолжение темы - в чем разница между:

Код
C++ (Qt)
m_positionBuffer.create();
m_positionBuffer.setUsagePattern( QOpenGLBuffer::StreamDraw );
m_positionBuffer.bind();
m_positionBuffer.allocate( positionData,
                                             vertexCount * 3 * sizeof( float ) );
m_shaderProgram.enableAttributeArray( "vertexPosition" );
m_shaderProgram.setAttributeBuffer( "vertexPosition", GL_FLOAT, 0, 3 );

и

 
Код
C++ (Qt)
static GLfloat const triangleVertices[] = { ...}
 
int vertexLocation = m_shaderProgram.attributeLocation("vertex");
m_shaderProgram.enableAttributeArray(vertexLocation);
m_shaderProgram.setAttributeArray(vertexLocation, triangleVertices, 3);

или даже

Код
C++ (Qt)
QVector<QVector3D> ...;
m_shaderProgram.setAttributeArray("vertex", vertices.constData());
m_shaderProgram.enableAttributeArray("vertex");

PS: Я понимаю что разница в коде и я понимаю что делает каждая строка, мне важно понять рама разница в принципах? То есть будет ли первый вариант с посылкой через VBO на GPU быстрее, чем без этого и если этого не делать руками, как это делает m_shaderProgram (как делает аллокейт видеопамяти?)?