1

オープングルを始めるのは本当に難しいと思いました。Web 中のチュートリアルを探しました。Philips Rideout による無料の本を見つけ、いくつかの章を試してみましたが、優れた C++ スキルがないため、途中で残しました。その後、Ray Wenderlich のチュートリアルを試してみましたが、シェーダーに行き詰まり、非常に単純なチュートリアルを作成できませんでした。今、私は Jeff Lamarche の古いブログに長居しています。COCOS2D と呼ばれる非常に優れたオブジェクト指向フレームワークがあり、2D ゲームとグラフィックスに必要なほとんどすべてを実行できることは知っていますが、COCOS2D を実際に試す前に、優れた基盤を作ることを考えました。しかし、私はそこにたどり着くことができないようです。トラブルが相次ぎ、解決の糸口が見つからない。だから、誤解を解くために何度もスタックオーバーフローに来ます。

OpenGLES の非常に単純な三角形に問題があります。この例では、OpenGLES 1.0 を使用しています。私のビューでグラフィックスをレンダリングするためのコードは、次のようになります。

struct Vertex3D{
    GLfloat x;
    GLfloat y;
    GLfloat z;

};


struct Triangle3D{
    Vertex3D v1;
    Vertex3D v2;
    Vertex3D v3;

};


static inline Triangle3D Triangle3DMake(Vertex3D vertex1, Vertex3D vertex2, Vertex3D vertex3){
    Triangle3D triangle;
    triangle.v1 = vertex1;
    triangle.v2 = vertex2;
    triangle.v3 = vertex3;
    return triangle;
};

static inline Vertex3D vertex3DMake(GLfloat x, GLfloat y, GLfloat z){
    Vertex3D vertex;
    vertex.x = x;
    vertex.y = y;
    vertex.z = z;
    return vertex;
}


static inline GLfloat Vertex3DCalculateDistanceBetweemVertices(Vertex3D first, Vertex3D second){
    GLfloat deltaX = second.x - first.x;
    GLfloat deltaY = second.y - first.y;
    GLfloat deltaZ = second.z - first.z;
    return sqrtf(powf(deltaX, 2) + powf(deltaY, 2) + powf(deltaZ, 2));
}


@implementation GLView{
    GLuint renderbuffer;
    GLuint framebuffer;
    EAGLContext *_context;
    CAEAGLLayer *layer;
    GLuint depthbuffer;
}

+(Class)layerClass{
    return [CAEAGLLayer class];
}

-(void)setUpLayer{
    layer = (CAEAGLLayer*)super.layer;
}

-(void)setUpContext{
    EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES1;
    _context = [[EAGLContext alloc] initWithAPI:api];
    if(!_context){
        NSLog(@"Could not create context");
        abort();
    }

    if(![EAGLContext setCurrentContext:_context]){
        NSLog(@"Could not set current context");
        abort();
    }
}

-(void)setUpRenderBuffer{
    glGenRenderbuffersOES(1, &renderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, renderbuffer);

    glGenRenderbuffers(1, &depthbuffer);
    glBindRenderbufferOES(GL_DEPTH_COMPONENT16_OES, depthbuffer);
    [_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer];
    [_context renderbufferStorage:GL_DEPTH_COMPONENT16_OES fromDrawable:layer];
}

-(void)setUpFrameBuffer{
    glGenFramebuffersOES(1, &framebuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, renderbuffer);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_DEPTH_COMPONENT16_OES, depthbuffer);
}

-(void)render{
    Vertex3D    vertex1 = vertex3DMake(0,1,0);
    Vertex3D    vertex2 = vertex3DMake(1.0, 0.0, 0);
    Vertex3D    vertex3 = vertex3DMake(-1.0, 0.0, 0.);
    Triangle3D  triangle = Triangle3DMake(vertex1, vertex2, vertex3);
    glViewport(0, 0, self.bounds.size.width, self.bounds.size.height);
    glClearColor(0.7, 0.7, 0.7, 1.0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glEnableClientState(GL_VERTEX_ARRAY);
    glColor4f(1.0, 0.0, 0.0, 1.0);
    glVertexPointer(3, GL_FLOAT, 0, &triangle);
    glDrawArrays(GL_TRIANGLES, 0, 9);
    [_context presentRenderbuffer:GL_RENDERBUFFER_OES];
    glDisableClientState(GL_VERTEX_ARRAY);


}
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setUpLayer];
        [self setUpContext];
        [self setUpRenderBuffer];
        [self setUpFrameBuffer];

        [self render];
    }
    return self;
}

このコードが生成する図は、次の図のようになります。

ここに画像の説明を入力

(1,0)、(-1,0)、(1,0) の 2D 座標を使用しているため、次のような図が得られると想定しています。

ここに画像の説明を入力

私が間違ってやっている非常に小さなことがあると確信しています。誰かが私を指摘できれば、それは私にとって大きな助けになるでしょう。ありがとうございました。

4

1 に答える 1

2

あまりにも多くの頂点をレンダリングしているように見え、OpenGL は頂点配列の終わりを越えて初期化されていないメモリに読み込んでいます。この線

glDrawArrays(GL_TRIANGLES, 0, 9);

おそらくあるはずです

glDrawArrays(GL_TRIANGLES, 0, 3);

三角形を1つだけ描きたい場合。3 番目のパラメーターは、レンダリングする頂点の総数です。

于 2013-01-09T21:57:14.527 に答える