OpenGL纵横比问题

时间:2013-05-01 14:45:18

标签: opengl

我正在使用Qt + OpenGl进行2D渲染。 我是OpenGL的初学者,对于我的生活,我无法弄清楚这个长宽比问题。每次我认为我已经理解了glOrtho和gViewPort,但下一次我与他们进入另一个问题。如果坐标是对称的,如-1和1之间,我的代码工作,否则它没有。我真的想要一次性完成这些。我搜索和应用的所有建议对我来说都没有结果。

我的问题陈述:

我正在渲染一个正方形和一个三角形,然后用键击“R”在它们之间切换。我也在放大和缩小。正方形保持纵横比,而三角形不是。形状的坐标是:

方形:( - 10,-250),(500,-250),(500,-260),( - 10,-260);

三角形:(250,0),(310,0),(280,30)

基本上我无法渲染三角形以上。这是相同的代码:

我的代码

#include <QtGui/QMouseEvent>
#include <qdebug.h>
#include "GLWidget.h"
#include "stdio.h"
#include "qgl.h"
#include "qimage.h"

GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent)
{
    setMouseTracking(true);
}

void GLWidget::initializeGL()
{
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_COLOR_MATERIAL);
    glEnable(GL_BLEND);
    glEnable(GL_POLYGON_SMOOTH);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(1, 1, 1, 0);
    glEnable( GL_POINT_SMOOTH ); // For Circular Points
}

void GLWidget::resizeGL(int w, int h)
{
    canvas_width = (double)w;
    canvas_height = (double)h;
    aspect_ratio = canvas_width/canvas_height;

    left_plane  = 250;
    right_plane = 310;
    bottom_plane  = 0;
    top_plane  = 60;
    z_near_plane = 1;
    z_far_plane  = -1;

    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    if( canvas_width > canvas_height ){ 
        glOrtho(left_plane*aspect_ratio, right_plane*aspect_ratio, bottom_plane, top_plane, z_near_plane, z_far_plane);
    }else{
        glOrtho(left_plane, right_plane, bottom_plane/aspect_ratio, top_plane/aspect_ratio, z_near_plane, z_far_plane);
    }

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void GLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1,0,0); // red

    glBegin(GL_POLYGON);
        //glVertex2f(-30,0);
        //glVertex2f(30,0);
        //glVertex2f(0,60);
        glVertex2f(250,0);
        glVertex2f(310,0);
        glVertex2f(280,60);
    glEnd();
}

我没有看到任何traint,因为left_plane * aspect_ratio剪辑我的绘图(250是最小X,250 * 1.4&gt; 310,310是最大X)。

我希望自己清楚明白。

我也会尝试放置图像(我想我必须将图像上传到其他网站并将它们链接到这里?)。

1 个答案:

答案 0 :(得分:1)

您的问题是边界框(分配给左/右/顶部/底部平面的值)与视口的宽高比不同。如果您有对象的边界框,则需要找到具有正确宽高比(w / h)的视口坐标。视口需要以边界框中心为中心,并且足够大以适合边界框。但是视口的宽高比与边界框的大小无关。

一般来说,你有一个3D边界框(8个角点)。您可以将每个角投影到屏幕上,然后使用min / max来获得需要在屏幕上居中的矩形。然后,检查该矩形的纵横比ar = wr / hr与视口a = w / r的纵横比。如果&lt; ar,你需要适应w到w,否则hr适合h。

void GLWidget::resizeGL(int w, int h)
{
  // First set up the projection.
  double canvas_width = (double)w;
  double canvas_height = (double)h;
  double a = canvas_width / canvas_height;

  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-a, +a, -1, +1, -1, +1);

  // Now set up the view matrix.
  double leftBoundingRectangle  = 250;
  double rightBoundingRectangle = 310;
  double bottomBoundingRectangle  = 0;
  double topBoundingRectangle  = 60;

  double widthBoundingRectangle = rightBoundingRectangle - leftBoundingRectangle;
  double heightBoundingRectangle = topBoundingRectangle - bottomBoundingRectangle;

  double ar = widthBoundingRectangle / heightBoundingRectangle;

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  // Center on bounding rectangle center.
  double tx = (leftBoundingRectangle + rightBoundingRectangle)/2.0, ty = (topBoundingRectangle + bottomBoundingRectangle)/2.0;
  glTranslated(tx, ty, 0.0); // or is it -tx, -ty?

  // Scale to fit bounding box.
  double s;
  if (ar > a)
  {
    s = ... // sorry, but you have to figure this one out for yourself. :)
  }
  else
  {
    s = ...
  }
  glScaled(s,s,s);
}