Russian Qt Forum
Ноябрь 05, 2024, 22:03 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Доступ к VBO в шейдере  (Прочитано 5859 раз)
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 или типа того?

Спасибо за ответы и помощь!
Записан
Disa
Гость
« Ответ #1 : Май 13, 2013, 15:44 »

Ну и аналогично с текстурами. По дефолту как я понял для первого семплера берутся данные из GL_TEXTURE0 и так далее.

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


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

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Май 14, 2013, 08:32 »

Если "attrib" то вероятно Вы говорите о VAO (а не VBO). В любом случае неясно зачем заботиться о шейдере - ему ведь все равно откуда загружны данные - из CPU или GPU
Записан
Disa
Гость
« Ответ #3 : Май 14, 2013, 10:16 »

В смысле?

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

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Май 14, 2013, 10:52 »

В смысле?

Я могу пересылать переменные напрямую, через qglshaderprogramm->set..., а можно биндить буффер, потом указывать указатели(простите за каламбур) и обращаться через например layout. Я думал что второй вариант лучше или я ошибаюсь? То есть быстрее например отослать 1 буфер с вершинами, цветом, нормалями и указать потом смещения в glVertexAttribPointer, например, чем пересылать отдельно 3и массива через "setЧто-то"
Ну да, так это посылка геометрии (вертексов и.т.п.), шейдер-то тут причем?
Записан
Disa
Гость
« Ответ #5 : Май 14, 2013, 12:22 »

Вроде бы понял. В сухом остатке получается, что генерация VAO (или VBO) и посылка через BufferData с указанием вершин полностью аналогично посылки через QGLShaderProgramm::set...();

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

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

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

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Май 14, 2013, 12:42 »

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

В любом случае "в шейдер" Вы ничего не подаете - он использует данные текущего рендера, а откуда они взялись ему все равно (хоть через glBegin/glEnd)
Записан
Disa
Гость
« Ответ #7 : Май 14, 2013, 12:59 »

ладно, тогда два новых вопроса:
1). что лучше - генерить VAO и вызывать glVertexAttribPointer и  glEnableVertexAttribArray или посылать через QGLShaderProgramm->setAttribute? Или без разницы?

2). если шейдер использует данные текущего рендера, то получается мне не имеет смысл писать glEnableClientState для различных буфферов, если я явно указываю ссылки на них через glVertexAttribPointer?
« Последнее редактирование: Май 14, 2013, 13:07 от Disa » Записан
Disa
Гость
« Ответ #8 : Май 14, 2013, 13:33 »

Вопрос решен, спасибо. Загвоздка была в непонимании что работа с VAO на FFP и PP немного различается
Записан
Disa
Гость
« Ответ #9 : Май 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 (как делает аллокейт видеопамяти?)?
« Последнее редактирование: Май 17, 2013, 14:15 от Disa » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.297 секунд. Запросов: 23.