Я пытаюсь следовать предложению в разделе Руководства по программированию Apple OpenGL ES по экземплярному рисованию: Используйте Instance Drawing для минимизации вызовов Draw. Я начал с примера проекта, который XCode генерирует для игрового приложения с OpenGL и Swift, и преобразовал его в OpenGL ES 3.0, добавив некоторый экземпляр рисунка для дублирования куба.
Это прекрасно работает, когда я использую технику gl_InstanceID
и просто генерирую смещение от нее. Но когда я пытаюсь использовать метод «экземплярных массивов» для передачи данных через буфер, я не вижу никаких результатов.
Мой обновленный вершинный шейдер выглядит так:
#version 300 es
in vec4 position;
in vec3 normal;
layout(location = 5) in vec2 instOffset;
out lowp vec4 colorVarying;
uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;
void main()
{
vec3 eyeNormal = normalize(normalMatrix * normal);
vec3 lightPosition = vec3(0.0, 0.0, 1.0);
vec4 diffuseColor = vec4(0.4, 0.4, 1.0, 1.0);
float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));
colorVarying = diffuseColor * nDotVP;
// gl_Position = modelViewProjectionMatrix * position + vec4( float(gl_InstanceID)*1.5, float(gl_InstanceID)*1.5, 1.0,1.0);
gl_Position = modelViewProjectionMatrix * position + vec4(instOffset, 1.0, 1.0);
}
и в моем методе setupGL() я добавил следующее:
//glGenVertexArraysOES(1, &instArray) // EDIT: WRONG
//glBindVertexArrayOES(instArray) // EDIT: WRONG
let kMyInstanceDataAttrib = 5
glGenBuffers(1, &instBuffer)
glBindBuffer(GLenum(GL_ARRAY_BUFFER), instBuffer)
glBufferData(GLenum(GL_ARRAY_BUFFER), GLsizeiptr(sizeof(GLfloat) * instData.count), &instData, GLenum(GL_STATIC_DRAW))
glEnableVertexAttribArray(GLuint(kMyInstanceDataAttrib))
glVertexAttribPointer(GLuint(kMyInstanceDataAttrib), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 0/*or 8?*/, BUFFER_OFFSET(0))
glVertexAttribDivisor(GLuint(kMyInstanceDataAttrib), 1);
вместе с некоторыми простыми данными смещения экземпляра:
var instData: [GLfloat] = [
1.5, 1.5,
2.5, 2.5,
3.5, 3.5,
]
Я рисую так же, как и с техникой идентификатора экземпляра:
glDrawArraysInstanced(GLenum(GL_TRIANGLES), 0, 36, 3)
Но, похоже, это не имеет никакого эффекта. Я просто получаю один куб, и кажется, что он даже не выходит из строя, если я удаляю настройку буфера, поэтому я подозреваю, что в моей настройке чего-то не хватает.
РЕДАКТИРОВАТЬ: Исправлен код, удалив две фиктивные строки из файла init.