Opengl es 将结构数组传递给GLVertexAttribute指针

Opengl es 将结构数组传递给GLVertexAttribute指针,opengl-es,Opengl Es,我从Xcode中的Apple spupplied iOS OpenGL游戏模板开始,我有一个结构数组(如果你愿意的话,更多的是结构数组),我试图与OpenGL VBO一起使用。然而,虽然我没有收到任何错误,但屏幕上没有任何内容 首先,我创建并填充VecAttributeType类型的数组,这是一个结构,它又有3个其他结构:vPosition、vTCoordinates和vNormal。 然后,我尝试将数组复制到VBO,并通过GLVertexAttributePointer将位置和法线绑定到顶点着

我从Xcode中的Apple spupplied iOS OpenGL游戏模板开始,我有一个结构数组(如果你愿意的话,更多的是结构数组),我试图与OpenGL VBO一起使用。然而,虽然我没有收到任何错误,但屏幕上没有任何内容

首先,我创建并填充VecAttributeType类型的数组,这是一个结构,它又有3个其他结构:vPosition、vTCoordinates和vNormal。 然后,我尝试将数组复制到VBO,并通过GLVertexAttributePointer将位置和法线绑定到顶点着色器中相应的in/属性(表示偏移量方面的VecAttributeType.vpPosition和VecAttributeType.vNormal)。 然后我尝试渲染

没有画任何东西:/

请注意,arrayOfStructs包含绘制模型所需的所有顶点。也就是说,我没有使用顶点的索引。相反,在这个测试中,我将检查obj和每个索引中的面定义,检索适当的顶点、纹理、法线并将其复制到arraOfStructures中

例如,对于obj格式的经典立方体,该文件列出了8个顶点,但我的最终arrayOfStructs长度为12,其中有12个VecAttributeType结构,每个结构都具有该顶点的正确位置、纹理坐标和法线,这些都是从obj文件的面定义中的索引派生的。是的,我用-1抵消了f定义中的索引,以解释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);
}
有什么想法吗?

好的,我知道了。。。 事实证明,在某个时刻,我忘记了我使用的是VAO扩展(
glbinvertexarrayoes
),在VBO设置结束时禁用它之后,我忘记了在
glkView:draInRect:

我上面的代码显示它已启用,但这只是因为我创建了一个新项目,以便在发布之前将代码的相关部分复制到

另外,
glvertexattributepointer
行可以像这样重写得更紧凑一些:

glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType),(void*)offsetof(VecAttributeType, vPosition.x));
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType), (void*)offsetof(VecAttributeType, vNormal.x));