7

必要な形状をほぼ表示するGLKViewがありますが、それでも希望どおりに機能しないことがいくつかあります。

      3_______________________2
      |\                     /|
      | \_ _ _ _ _ _ _ _ _ _/ |
      | /4                 5\ |
      |/_____________________\|
      0                       1
  • テクスチャマッピングは前面で機能していますが、他の2つの面は実際には機能せず、三角形が欠けています。

  • 色を使用すると、面は希望どおりに表示されますが、背面はポイント4と5によって形成されるエッジで結合しません(上記の図を参照してください)。
    (横から見れば)正三角形の形をしたいのですが。

必要に応じてテストできるように、コードのテクスチャマッピングセクションを一時的にコメントアウトしました。

ここでビューを設定します(ビューの寸法に注意してください。座標系は低い値をいじることなく正常に機能します。顔は見栄えがよく、後ろで結合すると言ったように、見栄えがよくありません):

    EAGLContext * context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    OpenGLShape *view = [[OpenGLShape alloc] initWithFrame:CGRectMake(0, 200, 320, 80) context:context];
    view.delegate = view;
    [view setupGL];
    [self.view addSubview:view];

- (void)setupGL {

    [EAGLContext setCurrentContext:self.myContext];

    //glEnable(GL_CULL_FACE);


    self.effect = [[GLKBaseEffect alloc] init];

    BOOL useTexture = NO;

    // Create default framebuffer object.
    glGenFramebuffers(1, &defaultFrameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFrameBuffer);

    if(useTexture){
        NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithBool:YES],
                              GLKTextureLoaderOriginBottomLeft,
                              nil];

        NSError * error;
        NSString *path = [[NSBundle mainBundle] pathForResource:@"blogcell@2x" ofType:@"png"];
        GLKTextureInfo * info = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
        if (info == nil) {
            NSLog(@"Error loading file: %@", [error localizedDescription]);
        }
        self.effect.texture2d0.name = info.name;
        self.effect.texture2d0.enabled = true;

        glGenBuffers(1, &texArray);
        glBindBuffer(GL_ARRAY_BUFFER, texArray);
        glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
        glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0,0);
        glBufferData(GL_ARRAY_BUFFER, sizeof(TexCoords), TexCoords, GL_STATIC_DRAW);


    }else{

        glGenBuffers(1, &colArray);
        glBindBuffer(GL_ARRAY_BUFFER, colArray);
        glEnableVertexAttribArray(GLKVertexAttribColor);
        glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, 0, 0);
        glBufferData(GL_ARRAY_BUFFER, sizeof(Color), Color, GL_STATIC_DRAW);
    }

    glGenRenderbuffers(1, &depthBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 320.0f, 80.0f);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);

    glEnable(GL_DEPTH_TEST);

    glGenBuffers(1, &vertexArray);
    glBindBuffer(GL_ARRAY_BUFFER, vertexArray);
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition,3,GL_FLOAT,GL_FALSE,0,0);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);




    self.effect.transform.projectionMatrix = GLKMatrix4MakePerspective(51.4f,4.0f, 0.1f, 10.75f);
   rotMatrix = GLKMatrix4Translate(self.effect.transform.modelviewMatrix,0, 0, -3);


}




- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {

    self.opaque = NO;
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    [self.effect prepareToDraw];

    glDrawArrays(GL_TRIANGLES, 0, sizeof(Vertices));
}

赤=前面(ポイント0123で構成)

青=背面(上面-ポイント4523で構成)

緑=背面(下-ポイント0154で構成)

白=背景

また、ブレンド/カリングなどを確認するために、面を半透明(アルファ= 0.5)にしました。

初期状態(回転なし)

x軸を中心にわずかに回転

x軸を中心にほぼ完全に回転

4

2 に答える 2

10

OpenGLでは、カメラは常に{0,0,0}にあり、位置を変更するのは3Dワールドです。

正射影の場合、射影行列は次の式で与えられます。

self.effect.transform.projectionMatrix = GLKMatrix4MakeOrtho(left, right, bottom, top, front, back);

ここに画像の説明を入力してください

正射影のオブジェクトは、カメラの近くまたは遠くに移動すると同じサイズに見えます。

透視投影のオブジェクトは、カメラから遠くに移動すると小さく見えます。

ここに画像の説明を入力してください

透視投影の場合、投影行列は次の式で与えられます。

self.effect.transform.projectionMatrix = GLKMatrix4 GLKMatrix4MakePerspective (fov, aspect, front, back);
);

透視投影の場合、視野(fov)は実際のカメラの場合と同じように機能します。値が小さい場合、遠近法はほとんど目立たなくなります。値が大きい場合、透視投影による歪みは大きくなります。

角度はfovラジアンであり、シーンがアプリケーションに適しているようになるまで微調整できます

aspectは、水平表示領域と垂直表示領域の間の画面アスペクト比です。

実用上の理由から、fovは度で指定されているため、次のように使用できます。

GLKMatrix4MakePerspective(fov * M_PI / 180.0f,
                                          screenWidth / screenHeight,
                                          front, back);

透視投影では、ニアクリッピングプレーンはゼロより大きくする必要があるため、モデルビューマトリックスに平行移動を追加して、世界をカマラから少し分離する必要があります。

この変換は、モデルビューマトリックスで指定されます

self.effect.transform.modelviewMatrix = GLKMatrix4MakeTranslation(0, 0, -frontClippingPlane);

アップデート

クリッピングボリュームには、フロントクリッピングプレーンとのZファイティングを回避するために、すべての頂点を含める必要があります。この場合、透視投影での最終的な移動は少し遠くなる必要があります。

self.effect.transform.modelviewMatrix = GLKMatrix4MakeTranslation(0, 0, -frontClippingPlane - 0.1f);

モデルを回転させて最終的な位置に変換するには、次のように2つの変換を組み合わせる必要があります。

GLKMatrix4 rotation = GLKMatrix4MakeRotation(angle*M_PI/180, 1, 0, 0); // angle in degrees and x,y, and z coordinates for the rotation axis
GLKMatrix4 translation = GLKMatrix4MakeTranslation( 0, 0, -front - 0.1f);
self.effect.transform.modelviewMatrix = GLKMatrix4Multiply(rotation, translation); // the order matters

以下は、右利きのOpenGLの回転軸と方向です。

ここに画像の説明を入力してください

これが最終的な効果です

ここに画像の説明を入力してください

于 2013-01-02T16:24:37.847 に答える
0

あなたのデータは正しいですか?Vertices配列がどのように埋められているのかわかりません。

データがリストどおりである場合、たとえば赤い前面0123がこの順序である場合、頂点の曲がりが問題になる可能性があります。

デフォルトの巻線は通常CCWであり、rectsを反時計回りとして記述しているため、GL_TRIANGLESに正しく分解する必要があります。たとえば、0123は013になり、123は123になります。

ただし、図が正しければ、他の図が外側を向いているのに対して、赤い長方形は3つの長方形の辺で形成された三角柱 に面しています。

私が何を意味するかを理解するには、三角柱を形成するために2つの水平方向の折り目で紙を折り、接合部に沿ってテープで留め、頂点に番号を付けます。

「テクスチャモード」に入るときに前面にテクスチャのみが定義されている場合、その面を失う可能性があります。

于 2013-01-05T14:00:36.603 に答える