Объект буфера вершин, мешающий текстуре в OpenGL ES 2.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) он по-прежнему не падает, но профилирование с помощью инструментов сообщает мне о вызове отрисовки текстуры «Превышены границы буфера массива» и используются «неинициализированные данные буфера», хотя текстура по-прежнему отлично рисуется. Добавление строки (3) приводит к сбою приложения, и инструменты сообщают мне об отсутствии данных GL.

Кто-нибудь знает, почему это происходит?


person Joseph Mark    schedule 13.07.2013    source источник


Ответы (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 не должно быть ни одной привязки.

person Joseph Mark    schedule 15.07.2013