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

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 呼び出しが行われるときに 1 つのバインドが存在することはありません。

于 2013-07-15T00:11:27.320 に答える