使用freeglut维护纵横比和与窗口大小无关的比例

时间:2014-03-29 18:30:36

标签: c++ opengl freeglut

我一直想用freeglut试验平台物理,但在我允许自己开始之前,我有一个老问题需要处理。

你知道,我想写一个整形处理程序,它不仅可以保持比例并消除视图的任何失真,而且即使在窗口太小而无法容纳它们时,也允许所有屏幕上的形状保持其大小(即让它们被修剪。)

我几乎已经完成了所有三个部分的解决,但是当我缩放窗口时,我绘制的圆圈会缩小稍微。否则,我得到了剪辑,我已经消除了失真。 更新:我想要实现的是一个保持比例和宽高比独立于窗口大小的程序。

这是我的代码:

void reshape(int nwidth,int nheight)
{
    glViewport(0,0,nwidth,nheight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    //here begins the code
    double bound = 1.5;
    double aspect = double(nwidth)/nheight;

    //so far, I get the best results by normalizing the dimensions
    double norm = sqrt(bound*bound+aspect*aspect);
    double invnorm = sqrt(bound*bound+(1/aspect)*(1/aspect));

    if(nwidth <= nheight)
        glOrtho(-bound/invnorm,bound/invnorm,-bound/aspect/invnorm,bound/aspect/invnorm,-1,1);
    else
        glOrtho(-bound*aspect/norm,bound*aspect/norm,-bound/norm,bound/norm,-1,1);

    //without setting the modelview matrix to the identity form,
    //the circle becomes an oval, and does not clip when nheight > nwidth
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

更新:根据科尔曼先生的建议,我尝试将单精度切换为双精度。缩放问题沿垂直轴有所改善,但每当我在任一方向上拖动水平轴时,形状仍然会显着缩放。它始终保持相同的形状,但是视觉检查告诉我,当窗口为150x300时,形状不是相同的大小,就像窗口是600x800时一样,无论哪个glOrtho正在执行。

1 个答案:

答案 0 :(得分:1)

我知道了。这是我改变代码的方式:

//at the top of the source file, in global scope:
int init_width;//the initial width
int init_height;//the initial height
void reshape(int new_width, int new_height)
{
    //moved the glViewport call further down (it was part of an earlier idea that didn't work out)
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();//these two lines are unchanged

    double bound = 1.0; //I reduced the edge distance to make the shape larger in the window
    double scaleX = double(new_width)/init_width;
    double scaleY = double(new_height)/init_height;

    glOrtho( -bound*scaleX/2, bound*scaleX/2, //these are halved in order to un-squash the shape
        -bound*scaleY, bound*scaleY, -1,1 );

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glViewport(0,0,new_width,new_height);
}

这就是我现在的代码。它保持了我在屏幕上的比例和形状,并允许它在窗口太小而无法包含整个形状时离屏。