我正在尝试遵循 Apple 的 OpenGL ES Programming Guide 部分中关于实例化绘图的建议:Use Instanced Drawing to Minimize Draw Calls。我从 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,
]
我使用与实例 id 技术相同的方式进行绘制:
glDrawArraysInstanced(GLenum(GL_TRIANGLES), 0, 36, 3)
但它似乎没有任何效果。我只得到了单个立方体,如果我删除缓冲区设置,它甚至似乎都不会失败,所以我怀疑我的设置丢失了一些东西。
编辑:通过从 init 中删除两条虚假行来修复代码。