全屏拉伸对象

时间:2018-12-30 12:24:23

标签: c++ opengl glut

我遇到的问题是,当我使用全屏显示时,对象会被拉伸。我希望它适合全屏坐标,因此它看起来与图像A完全相同。我知道glViewport确定了OpenGL要绘制到的窗口部分,它可以帮助将对象设置为整个窗口。但是,我没有使用glViewport,而是我使用了gluOrtho2D

Click here to see the full code

图片A(屏幕尺寸:700、600)

Original screen size

图像B(全屏尺寸)

Full screen size

gluOrtho2D代码

// this is the initialisation function, called once only
void init() {
    glClearColor(0.0, 0.0, 0.0, 0.0); // set what colour you want the background to be
    glMatrixMode(GL_PROJECTION); // set the matrix mode
    gluOrtho2D(0.0, winWidth, 0.0, winHeight); // set the projection window size in x and y.
}

我最初使用的是gluOrtho2D,它用于设置二维正射影像查看区域。

1 个答案:

答案 0 :(得分:1)

glViewport定义了渲染到的(默认)帧缓冲区的区域。

如果您不想渲染到全屏,则可以将渲染的区域缩小glViewport。您可以在边框上留下一些黑色条纹。

您的应用程序的宽高比为winWidthwinHeight

使用glutGet,分别使用参数GLUT_WINDOW_WIDTH GLUT_WINDOW_HEIGHT,可以获取当前窗口的大小并可以计算当前的长宽比:

int currWidth = glutGet( GLUT_WINDOW_WIDTH );
int currHeight = glutGet( GLUT_WINDOW_HEIGHT );

float window_aspcet = (float)currWidth / (float)currHeight;

有了这些信息,视图就可以完美地位于视口的中心:

void display() {

    float app_aspcet = (float)winWidth / (float)winHeight;

    int currWidth = glutGet( GLUT_WINDOW_WIDTH );
    int currHeight = glutGet( GLUT_WINDOW_HEIGHT );

    float window_aspcet = (float)currWidth / (float)currHeight;

    if ( window_aspcet > app_aspcet )
    {
        int width = (int)((float)currWidth * app_aspcet / window_aspcet + 0.5f);
        glViewport((currWidth - width) / 2, 0, width, currHeight);
    }
    else
    {
        int height = (int)((float)currHeight * window_aspcet / app_aspcet + 0.5f);
        glViewport(0, (currHeight - height) / 2, currWidth, height);
    }

    // [...]

}

或者您可以熟练使用正射投影的纵横比和中心

void display() {

    float app_aspcet = (float)winWidth / (float)winHeight;

    int currWidth = glutGet( GLUT_WINDOW_WIDTH );
    int currHeight = glutGet( GLUT_WINDOW_HEIGHT );

    float window_aspcet = (float)currWidth / (float)currHeight;

    glViewport(0, 0, currWidth, currHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if ( window_aspcet > app_aspcet )
    {
        float delta_width = (float)currWidth * (float)winHeight / (float)currHeight - (float)winWidth;
        gluOrtho2D(-delta_width/2.0f, (float)winWidth + delta_width/2.0f, 0.0, (float)winHeight);    
    }
    else
    {
        float delta_height = (float)currHeight * (float)winWidth / (float)currWidth - (float)winHeight;
        gluOrtho2D(0.0, (float)winWidth, -delta_height/2.0f, (float)winHeight + delta_height/2.0f);
    }