我从Xcode中的Apple-spupplied iOS OpenGL游戏模板开始,我有一个结构数组(更多的结构结构数组,如果你愿意的话),我正在尝试使用OpenGL VBO 。但是,虽然我没有错误,但屏幕上没有任何内容。
首先,我创建并填充这个VecAttributeType类型的数组,这个结构又有3个其他结构:vPosition,vTCoordinates和vNormal。 然后我尝试将数组复制到VBO并通过glVertexAttribPointer将位置和法线(意味着VecAttributeType.vPosition和VecAttributeType.vNormal在偏移方面)绑定到顶点着色器中的相应in / attributes。 然后我尝试渲染。
没有画出任何内容:/
请注意,arrayOfStructs包含绘制模型所需的所有顶点。也就是说,我没有使用索引到顶点。相反,对于这个测试,我将浏览obj中的面部定义和每个索引,检索适当的顶点,纹理,法线并在arraOfStructures中复制它。
因此,例如,对于obj格式的经典立方体,该文件列出了8个顶点,但我的最终arrayOfStructs长度为12,其中有12个VecAttributeType结构,每个结构都有正确的位置,纹理坐标和该顶点的法线,派生来自obj文件的面部定义中的索引。是的,我将f定义中的索引偏移-1,以解释obj文件索引从1开始的事实。
我的猜测是,我只是计算位置和法线错误的VBO偏移量。我想是的,因为我已经尝试在arrayOfStructures中的第一个VecAttributeType中打印第一个位置x坐标,如下所示:
NSLog(@"\nTEST:\nfirst vertex X = %f", arrayOfStructs[0].vPosition.x);
我得到了预期值,同时尝试打印:
char* address = (char*)arrayOfStructs+offsetof(VecAttributeType, vPosition.x);
float b = *address;
NSLog(@"\nTEST:\nfirst vertex X = %f", b);
代替打印0(正确的值应为1);
以下是相关的代码部分:
//Inside a c++ class I'm parsing an Obj and creating the vertex attribute array:
typedef struct
{
float x;
float y;
float z;
} Vec3fType;
typedef struct
{
float s;
float t;
} Vec2fType;
typedef struct
{
int p;
int n;
int t;
} Vec3iType;
typedef struct
{
Vec3fType vPosition;
Vec3fType vNormal;
Vec2fType vTCoordinates;
} VecAttributeType;
int arrayLength = // Some number;
VecAttributeType* arrayOfStructs = new VecAttributeType[arrayLength];
// Populate the array.
// . . .
// Then, in the ViewController (Objective-C) class, I try binding to the VBO and getting the offsets right:
[EAGLContext setCurrentContext:self.context];
[self loadShaders];
glEnable(GL_DEPTH_TEST);
GLuint _vertexBuffer;
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(VecAttributeType)*arrayLength, arrayOfStructs, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType), BUFFER_OFFSET(0) + offsetof(VecAttributeType, vPosition) + offsetof(Vec3fType, x));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType), BUFFER_OFFSET(0) + offsetof(VecAttributeType, vNormal) + offsetof(Vec3fType, x));
最后,绘图代码是:
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(1.f, 0.f, 0.f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArrayOES(_vertexArray);
// Render the object again with ES2
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, arrayLength);
}
有什么想法吗?
答案 0 :(得分:0)
好的我明白了......
事实证明,我忘记了我使用的是 VAO 扩展程序(glBindVertexArrayOES
),并且在VBO设置结束后禁用它后,我忘记在{{1}中启用它}
我上面的代码显示它已启用,但只是因为我创建了一个新项目,以便在发布到SO之前复制相关的代码部分。
此外,glkView:draInRect:
行可以更紧凑地重写,如下所示:
glVertexAttribPointer