0

我正在使用 IOS 6.1,尝试绘制纹理和顶点缓冲区对象。

我设置了这样的纹理:

typedef struct{
    CGPoint geometryVertex;
    CGPoint textureVertex;
} TexturedVertex;

typedef struct {
    TexturedVertex bl;
    TexturedVertex br;
    TexturedVertex tl;
    TexturedVertex tr;
} TexturedQuad;

NSError         *error;
NSString        *path = [[NSBundle mainBundle] pathForResource:@"img.png" ofType:nil];
NSDictionary    *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], GLKTextureLoaderOriginBottomLeft, nil];
self.textureInfo = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
TexturedQuad quad;
quad.bl.geometryVertex  = CGPointMake(0, 0);
quad.br.geometryVertex  = CGPointMake(self.textureInfo.width, 0);
quad.tl.geometryVertex  = CGPointMake(0, self.textureInfo.height);
quad.tr.geometryVertex  = CGPointMake(self.textureInfo.width, self.textureInfo.height);
quad.bl.textureVertex   = CGPointMake(0, 0);
quad.br.textureVertex   = CGPointMake(1, 0);
quad.tl.textureVertex   = CGPointMake(0, 1);
quad.tr.textureVertex   = CGPointMake(1, 1);
self.quad = quad;

glClearColor(0, 0, 0, 0.5);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

然后画成这样:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClear(GL_COLOR_BUFFER_BIT);
    self.baseEffect.texture2d0.name = self.textureInfo.name;
    self.baseEffect.transform.modelviewMatrix = [self modelMatrix];
    [self.baseEffect prepareToDraw];

    long offset = (long)&_quad;
    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *)(offset + offsetof(TexturedVertex, geometryVertex)));
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *)(offset + offsetof(TexturedVertex, textureVertex)));
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

一切正常,没问题。我接下来要做的是绘制另一个存储在不是纹理的顶点缓冲区对象中的对象。所以我将它添加到设置代码中:

typedef struct {
    float Position[3];
} Vertex;

const Vertex Vertices[] = {
    {100, -100, 0},
    {100, 100, 0},
    {-100, 100, 0},
    {-100, -100, 0}
};

GLuint _vertexBuffer;

glGenBuffers(1, &_vertexBuffer); // (1)
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); // (2)
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); // (3)

但即使没有尝试绘制新对象,这些行也会使我的应用程序崩溃。我发现只有第 (1) 行它不会崩溃。使用 (1) + (2) 它仍然不会崩溃,但使用 Instruments 进行分析告诉我纹理“超出数组缓冲区边界”的绘制调用并使用了“未初始化的缓冲区数据”,尽管它仍然可以很好地绘制纹理。添加第 (3) 行会导致应用程序崩溃,并且 Instruments 告诉我没有 GL 数据。

有谁知道为什么会这样?

4

1 回答 1

0

The VBO was apparently interfering with the call to glVertexAttribPointer. Unbinding it like so stopped the crash:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClear(GL_COLOR_BUFFER_BIT);
    self.baseEffect.texture2d0.name = self.textureInfo.name;
    self.baseEffect.transform.modelviewMatrix = [self modelMatrix];
    [self.baseEffect prepareToDraw];

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    long offset = (long)&_quad;
    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *)(offset + offsetof(TexturedVertex, geometryVertex)));
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *)(offset + offsetof(TexturedVertex, textureVertex)));
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

The texture as it is doesn't use a VBO so there shouldn't be one bound when the glVertexAttribPointer call is made.

于 2013-07-15T00:11:27.320 回答