2013-05-15 217 views
1

我遇到了OpenGL ES 2.0和命令視口(x,y,寬度,高度)的問題。 我使用渲染功能OpenGL ES 2.0視口

- (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]; 
} 

顯示紋理(寬x高)中的UIView的問題是,紋理顯示正常,只有當它從肖像模式開始與 window_width = 768,window_height = 1004.0。使用這種尺寸後,它在旋轉後正常工作。 當我設置取決於像window_width = self.frame.size.width和window_height = self.frame.size.height並在橫向模式旋轉或從它開始 - 紋理顯示寬度和高度小於屏幕尺寸。 用「範圍」代替「框架」並不能解決問題。

回答

1

找到2個錯誤投影矩陣:

1 - 爲什麼旋轉後我的質地得到奇怪位置

問題是,紋理僅在從縱向模式(window_width = 768,window_height = 1004.0)開始顯示時才顯示。使用這種尺寸後,它在旋轉後正常工作。當我設置取決於像window_width = self.frame.size.width和window_height = self.frame.size.height並在橫向模式下旋轉或從它開始 - 紋理顯示寬度和高度小於屏幕尺寸。用「邊界」代替「框架」並不能解決問題。

我解決它通過更新上下文overrided組框架方法

- (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 - 爲什麼紋理顯示,不保存率

感謝特里克斯,我聽你的建議,並重新計算我的投影矩陣。

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; 
} 

獲得標準化值後,我生成投影矩陣。

projectionMatrix = 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; 

一切工作。感謝幫助!

1

不幸的是,涉及的不僅僅是glViewport,它將歸一化的設備座標映射到窗口座標)。您可能需要更新您投影矩陣反映寬高比(相機現在看到少自上而下的,但有一個更廣泛的角度右 - 左(或相反,這取決於設備的方向)的變化。

所以基本上重新計算與這些新設備的值(縱橫比已經改變)