【问题标题】:OpenGL ES 2.0 viewportOpenGL ES 2.0 视口
【发布时间】:2013-05-15 17:26:06
【问题描述】:

我遇到了 OpenGL ES 2.0 和命令 Viewport(x,y,width,height) 的问题。 我正在使用渲染功能在 UIView 中显示纹理(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];
}

问题是纹理只有在从纵向模式开始时才能正常显示 窗口宽度 = 768,窗口高度 = 1004.0。有了这样的尺寸,它在旋转后可以正常工作。 当我设置取决于 window_width = self.frame.size.width 和 window_height = self.frame.size.height 并以横向模式旋转或从它开始时 - 纹理显示的宽度和高度比屏幕尺寸大。 用“bounds”替换“frame”并不能解决问题。

【问题讨论】:

    标签: ios rendering opengl-es-2.0


    【解决方案1】:

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

    所以基本上用这些新的设备值重新计算投影矩阵(纵横比已经改变)。

    【讨论】:

      【解决方案2】:

      发现 2 个错误:

      1 - 为什么我的纹理在旋转后会出现奇怪的位置

      问题是纹理只有在window_width = 768,window_height = 1004.0的纵向模式下才能正常显示。有了这样的尺寸,它在旋转后可以正常工作。当我设置取决于 window_width = self.frame.size.width 和 window_height = self.frame.size.height 并以横向模式旋转或从它开始时 - 纹理显示的宽度和高度比屏幕尺寸大。用“bounds”替换“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;
          }
      

      现在我有了最终比例。我的任务是 - 以调整到屏幕尺寸的最大可能尺寸渲染纹理。这就是为什么我将这个比率标准化 归一化尺寸(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;
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-30
        • 2015-08-08
        • 1970-01-01
        • 2011-06-14
        • 1970-01-01
        • 1970-01-01
        • 2011-05-19
        • 1970-01-01
        相关资源
        最近更新 更多