我试图让 iOS 上的 OpenGL ES 在超过 2 个属性下正常工作,但由于某种原因,它似乎是在绘制法线而不是实际对象。
我的顶点着色器:
attribute vec4 position;
attribute vec3 tc;
attribute vec3 normal;
uniform vec3 color;
uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;
varying lowp vec3 Color;
void main()
{
vec3 eyeNormal = normalize(normalMatrix * normal);
vec3 lightDirection = vec3(0.0, 0.0, 1.0);
float nDot = max(0.0, dot(eyeNormal, normalize(lightDirection)));
Color = tc * nDot;
gl_Position = modelViewProjectionMatrix * position;
}
我像您期望的那样获取对属性的引用:
glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
glBindAttribLocation(_program, GLKVertexAttribTexCoord0, "tc");
glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
我使用一个 NSMutableArray 容器来存储 Vector 对象,第一个 Vector 对象代表位置,后面的代表纹理数据,后面的代表法线。这样重复,数组中通常有大约 5000 个 Vector 对象。使用以下代码将该数组的内容读入缓冲区:
float *buffer = (float*) calloc(vBuffer.count * 3, sizeof(float));
int bufferIndex = 0;
for(int i =0; i < [vBuffer count]; i++) {
vector3 *vec = (vector3*) vBuffer[i];
buffer[bufferIndex] = vec.x;
buffer[bufferIndex+1] = vec.y;
buffer[bufferIndex+2] = vec.z;
bufferIndex += 3;
}
然后我像你期望的那样设置 glVertexAttribPointer 的东西:
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(12));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(24));
我编译并绘制了这个:http: //i.imgur.com/Q0QLsHd.png。如果我没有将表示法线的 Vector 对象包含到我的 NSMutableArray 中,我会得到预期的结果(虽然颜色很奇怪,但那是因为我正在读取纹理坐标作为颜色,忽略它):http://i. imgur.com/DOFZxaq.png。
为什么当我将第三个属性添加到缓冲区时一切都搞砸了?
以下是基于解析 .obj 文件中的面部语句向数组添加位置、纹理和法线的代码:
if(v < INT32_MAX && v != 0) {
vector3 *position = (vector3*) _vertices[v-1];
[vBuffer addObject:position];
}
if(vt < INT32_MAX && vt != 0) {
vector3 *texture = (vector3*) _textures[vt-1];
[vBuffer addObject:texture];
}
if(vn < INT32_MAX && vn != 0) {
vector3 *normal = (vector3*) _normals[vn-1];
[vBuffer addObject:normal];
}
我基于 XCode 的 OpenGL 模板创建了一个新的测试项目,并添加了第三个属性,它工作正常,所以不确定是什么导致了这个特定项目的问题。是缓冲区的大小吗?里面存储了大约 15,000 个花车。