#c #opengl #shader
#c #opengl #шейдер
Вопрос:
Я знаю, что есть uniforms
способы решить эту проблему, но мне интересно, можно ли добавить значение, подобное int
использованию glVertexAttribPointer()
?
Шейдер:
#version 330 core
layout (location = 0) in vec3 aPosition;
layout (location = 1) in vec3 aColor;
layout (location = 2) in int aSize;
out vec3 vColor;
void main()
{
gl_Position = vec4(aPosition, 1.0f);
gl_PointSize = aSize;
vColor = aColor;
}
Код:
makeCurrent();
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, points.vbo.size() * sizeof(GLfloat), amp;points.vbo.front(), GL_STATIC_DRAW); //look below to the struct
glVertexAttribPointer(0, points.vertexAmount, GL_FLOAT, GL_FALSE, points.stride * sizeof(GLfloat), (GLvoid *)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, points.colorAmount, GL_FLOAT, GL_FALSE, points.stride * sizeof(GLfloat), (GLvoid *)(points.vertexAmount * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(/* ??? how to add simple int here ??? */);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
doneCurrent();
points
структура:
struct RenderedObjects
{
std::vector<float> vbo;
int vertexAmount = 3;
int colorAmount = 3;
int stride = vertexAmount colorAmount;
int size = 1;
} points;
Ответ №1:
glVertexAttribPointer
предназначен только для массивов данных. Когда вы выполняете вызов dasw, графический процессор извлекает i
-й элемент каждого массива атрибутов, который включен, и использует данные указателя атрибута вершины, чтобы найти этот элемент в VBO.
Для входных данных атрибута, для которых не включен массив атрибутов, вы можете установить значение как часть состояния GL. Семейство функций glVertexAttib...()
позволяет устанавливать значения для общего атрибута вершины.
Соглашения об именах OpenGL здесь могут немного запутать. По умолчанию атрибуты вершин всегда обрабатываются как с плавающей запятой, даже если вы указываете входные данные в виде целых чисел (то же самое с glVertexAttribPointer()
параметром типа s). Таким образом, даже если вы можете подумать glVertexAttrib1i()
, что можете установить значение скалярного целочисленного атрибута, на самом деле это связано с установкой float
атрибута, просто предоставляя целочисленное значение.
Целочисленные атрибуты добавляются позже в GL, и вы должны использовать glVertexAttribI()
/ glVertexAttribIPointer()
(обратите внимание на заглавную букву I) для них.
Итак, правильный способ указать один постоянный ввод для layout (location = 2) in int aSize;
:
glVertexAttribI1i(2, yourIntegerValue);
glDisableVertexAttribArray(2); // do NOT use an array for this attribute
(При создании VAO все массивы атрибутов изначально отключаются, поэтому вам может не понадобиться явно вызывать glDisableVertexAttribArray(2)
here .)
Комментарии:
1. ошибка: ‘glVertexAttribI1i’ не был объявлен в этой области; вы имели в виду ‘glVertexAttribP1ui’? Нужна ли мне какая-то конкретная версия или заголовок GL? Я установил для своих шейдеров и контекста значение 3.3 и вижу, что glVertexAttribI1i доступен даже для версии 2.0.
2. Я вижу, очевидно, что это не является частью QOpenGLFunctions_3_3_Core
3.
glVertexAttribI1i
был представлен с OpenGL 3.0 и является частью основного профиля, я понятия не имею, что делает Qt, если эта функция не является частьюQOpenGLFunctions_3_3_Core
, но официальная спецификация ядра OpenGL 3.3 включает эту функцию.4. Я также выяснил, что операции с шейдерами любого размера в точках доступны только после glEnable(GL_PROGRAM_POINT_SIZE);
5. «Я также выяснил, что операции с шейдерами любого размера по точкам доступны только после
glEnable(GL_PROGRAM_POINT_SIZE);
«, ну, это правильно. На рабочем столе GL есть этот параметр, GLES, с другой стороны, не имеет этого состояния и всегда ведет себя так, как будто включен программируемый размер точки.