繁体   English   中英

OpenGL ES 2.0视口

[英]OpenGL ES 2.0 viewport

我在OpenGL ES 2.0和命令Viewport(x,y,width,height)时遇到问题。 我正在使用渲染功能在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进行设置并以横向模式旋转或从其开始时-纹理显示的宽度大于屏幕高度,而高度小于屏幕尺寸。 用“界限”代替“框架”不能解决问题。

不幸的是,涉及的不仅仅是glViewport将标准化的设备坐标映射到窗口坐标 )。 您可能需要更新投影矩阵以反映宽高比变化 (摄像头自上而下现在看到的更少,但左右角度更广(或相反,取决于设备方向)。

因此,基本上使用这些新设备值(纵横比已更改)重新计算投影矩阵。

发现2个错误:

1-为什么旋转后我的纹理得到奇怪的位置

问题在于,仅当纹理从纵向模式以window_width = 768,window_height = 1004.0启动时,纹理才能正常显示。 使用这种尺寸,旋转后可以正常工作。 当我根据window_width = self.frame.size.width和window_height = self.frame.size.height进行设置并以横向模式旋转或从其开始时-纹理显示的宽度大于屏幕高度,而高度小于屏幕尺寸。 用“界限”代替“框架”不能解决问题。

我通过覆盖设置框架方法中的更新上下文解决了它

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

得到归一化值后,我生成投影矩阵。

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;

现在一切正常。 感谢帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM