1

OpenGL ES 2.0 とコマンド Viewport(x,y,width,height) で問題が発生しました。render 関数を使用して UIView に texture(WxH) を表示しています

- (void)render
{
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glViewport(0,0,window_width,window_height);
    _openglViewer.render();
    [_context presentRenderbuffer:GL_RENDERBUFFER];
}

問題は、window_width = 768、window_height = 1004.0 のポートレート モードから開始した場合にのみ、テクスチャが正常に表示されることです。このようなサイズでは、回転後に正常に動作します。window_width = self.frame.size.width および window_height = self.frame.size.height のように依存して設定し、横向きモードで回転するか、それから開始すると、画面サイズよりも幅が大きく、高さが小さく表示されるテクスチャ。「フレーム」を「境界」に置き換えても問題は解決しません。

4

2 に答える 2

1

glViewport残念ながら、 (正規化されたデバイス座標をウィンドウ座標にマップする)よりも多くのことが関係しています。アスペクト比の変更を反映するために、おそらく射影行列を更新する必要があります(カメラは上から見下ろすことが少なくなりますが、左右の角度が広がります (デバイスの向きによっては逆になります)。

したがって、基本的にこれらの新しいデバイス値で射影行列を再計算します (アスペクト比が変更されました)。

于 2013-05-15T19:47:50.107 に答える
1

2 つのバグが見つかりました:

1 - 回転後のテクスチャが奇妙な位置になる理由

問題は、window_width = 768、window_height = 1004.0 のポートレート モードから開始した場合にのみ、テクスチャが正常に表示されることです。このようなサイズでは、回転後に正常に動作します。window_width = self.frame.size.width および window_height = self.frame.size.height のように依存して設定し、横向きモードで回転するか、それから開始すると、画面サイズよりも幅が大きく、高さが小さく表示されるテクスチャ。「フレーム」を「境界」に置き換えても問題は解決しません。

オーバーライドされた set frame メソッドでコンテキストを更新することで解決しました

- (void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
    _openglViewer.setWindowSize(frame.size.width, frame.size.height);
    [_context renderbufferStorage:GL_RENDERBUFFER
                     fromDrawable:(CAEAGLLayer *)self.layer];
    _openglViewer.setupVBOs();
    _openglViewer.compileShaders();
}

2 - 比率を保存せずにテクスチャが表示される理由

Trax に感謝します。あなたのアドバイスを聞いて、射影行列を再計算しました。

void calculateRatio (GLsizei &width, GLsizei &height, GLfloat &w, GLfloat &h)
{
    // The bigger side returns 1.0,
    // smaller - percentage value of bigger side
    GLfloat ratio = (GLfloat)width/(GLfloat)height;

    if(ratio < 1.0) {
        w = ratio;
        h = 1.0;
    } else {
        w = 1.0;
        h = 1.0/ratio;
    }
}

このメソッドを 2 回呼び出します。1) テクスチャの比率を取得するため、2) ウィンドウの比率を取得するためです。この値を取得した後、確認します

if(winW > winH) {
        w = texW*winH;
        h = texH;
    } else {
        w = texW;
        h = texH*winW;
    }

今、私は最終的な比率を持っています。私の仕事は - 画面サイズに合わせて調整された最大サイズでテクスチャをレンダリングすることでした。そのため、この比率を正規化します normalizeSizes(w,h);

void normalizeSizes(GLfloat &w, GLfloat &h)
{
    // the smaller size get 1.0 value,
    // bigger - times it is bigger than smaller;
    bool isWider = false;
    GLfloat maxSize;
    if(w > h) {
        isWider = true;
        maxSize = w;
    } else {
       maxSize = h;
    }
    if(maxSize != 1.0) {
        if(isWider) {
            w = 1.0;
            h = h/maxSize;
        } else {
            h = 1.0;
            w = w/maxSize ;
        }
    }
    w = 1.0/w;
    h = 1.0/h;
}

正規化された値を取得した後、射影行列を生成します。

projectMatrix = tmp.genOrthoProjMatrix(-1.0, 1.0, -w, w, -h, h);

//genOrthoProjMatrix(float near ,float far ,float left, float right, float bottom, float top)
    // First Column
    res.p[0][0] = 2.0 / (right - left);
    res.p[1][0] = 0.0;
    res.p[2][0] = 0.0;
    res.p[3][0] = 0.0;

    // Second Column
    res.p[0][1] = 0.0;
    res.p[1][1] = 2.0 / (top - bottom);
    res.p[2][1] = 0.0;
    res.p[3][1] = 0.0;

    // Third Column
    res.p[0][2] = 0.0;
    res.p[1][2] = 0.0;
    res.p[2][2] = -2.0 / (far - near);
    res.p[3][2] = 0.0;

    // Fourth Column
    res.p[0][3] = -(right + left) / (right - left);
    res.p[1][3] = -(top + bottom) / (top - bottom);
    res.p[2][3] = -(far + near) / (far - near);
    res.p[3][3] = 1;

すべてが機能しています。手伝ってくれてありがとう!

于 2013-05-17T14:09:18.147 に答える