【问题标题】:Vertex buffer object interfering with texture in OpenGL ES 2.0顶点缓冲区对象在 OpenGL ES 2.0 中干扰纹理
【发布时间】:2013-07-13 05:18:58
【问题描述】:

我正在使用 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 数据。

有人知道为什么会这样吗?

【问题讨论】:

    标签: ios opengl-es-2.0 glkit


    【解决方案1】:

    VBO 显然干扰了对 glVertexAttribPointer 的调用。像这样解开它停止了崩溃:

    - (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);
    }
    

    纹理本身不使用 VBO,因此在调用 glVertexAttribPointer 时不应有一个绑定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      • 2011-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-04
      • 1970-01-01
      相关资源
      最近更新 更多