Ответ 1
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
gl_Position = MVP2 * vec4(vertexPosition_modelspace2,1);
Это не то, как работает графический конвейер. Вы не можете рисовать два объекта одновременно. Только последняя запись в gl_Position
будет эффективной, и ваш первый объект будет полностью проигнорирован. В самом базовом варианте вы хотите нарисовать два полностью независимых объекта, и вам понадобятся два вызова для рисования - как вы делаете в своем коде.
Однако при этом вам не нужны два разных атрибута вершины. Ваш шейдер просто обрабатывает вершины, которые в вашем случае имеют verexPosition_modelspace
атрибут verexPosition_modelspace
. Таким образом, вы можете использовать этот атрибут для всех объектов, которые вы хотите нарисовать. Нет смысла использовать разные атрибуты для разных объектов, если атрибут означает одно и то же.
Давайте посмотрим на ваш код для рисования:
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
Здесь вы устанавливаете атрибут вершины 0, чтобы он указывал на данные вершины первого буфера, и вы включаете массив атрибутов. Таким образом, данные не будут использоваться в качестве источника для vertexPosition_modelspace
.
glDrawArrays(GL_TRIANGLES, 0, 12*3);
Теперь вы рисуете объект. Но, как мы уже видели, ваш шейдер действительно использует только vertexPosition_modelspace2
, для которого вы не установили указатель или не включили массив. Поскольку массив отключен, GL будет использовать текущее значение атрибута 2 - для всех вершин. Таким образом, в случае треугольников вы создаете треугольники со всеми одинаковыми точками - получаете треугольники с площадью поверхности 0 и в любом случае невидимы, независимо от того, какой атрибут фактического значения 2 имеет в настоящее время.
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
Теперь вы делаете странную вещь: вы включаете массив атрибута 2, но не устанавливаете для него указатель! Вы должны повторно указать указатель для атрибута 0, чтобы указать на вашу вторую модель.
glDrawArrays(GL_TRIANGLES, 0, 4*3);
Теперь вы рисуете с включенным атрибутом 0 и 2. Атрибут 0 будет содержать данные, которые вы хотите, но шейдер игнорирует. Атрибут 2 просто указывает куда-то, и вы получаете неопределенное поведение - оно может просто аварийно завершиться, но может также отображать странные вещи или вообще ничего.
Чтобы заставить это работать, просто полностью удалите vertexPosition_modelspace2
из шейдера. Используйте только одну матрицу MVP
также. При рисовании любого объекта вы должны:
- Установите унифицированную матрицу
MVP
для объекта - Установить указатель атрибута для атрибута 0
- Включите массив атрибутов для атрибута 0 (или убедитесь, что он уже включен)
- Выполнить розыгрыш
Вы можете сделать это с любым количеством объектов.