【问题标题】:OpenGL showing more/less of the world through resizeOpenGL 通过调整大小显示更多/更少的世界
【发布时间】:2017-04-14 23:48:09
【问题描述】:

所以网上很多关于调整大小的问题都是关于保持正确的比率和避免拉伸等。据我了解,这可以通过使用gluOrtho2D 设置新的比率来完成。

但是,我不确定如何在调整大小时显示 MORE 和 LESS 世界。例如。你有一个可以沿 x 轴从 0 到 100 的平面。调整大小后,它现在应该(仍然是相同的大小)从 0 移动到 200。

编辑:所以我的意思是,我希望我的游戏中的所有东西都保持与以前一样的大小,但是如果你愿意的话,“天空”在调整大小时应该更大,我的飞机应该能够飞入那片天空(因为目前我有将其限制在屏幕内的代码)。

同样的,如果我的屏幕更小,那么飞机应该再也无法飞到不再存在的“天空”部分

最初,我使用以下几行设置我的程序,其中有关游戏的所有内容都存储在“游戏”中,并且 XSize、YSize 返回屏幕的大小。

void init(void) {
    glClearColor(0.0, 0.0, 0.3, 0.0); /* set background color to a dark blue */
    glColor3f(1.0, 1.0, 1.0); /* set drawing color to white */
    glMatrixMode(GL_PROJECTION);
    glEnable (GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glLoadIdentity();
    gluOrtho2D(0, game.getXSize()*game.getAspect(), 0, game.getYSize() / game.getAspect()); /* defines world window */
}    

int main(int argc, char *argv[]) {
    game = GameManager(GAMENAME, 1000, 750, 60);

    /*SETUP*/
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(game.getXSize(), game.getYSize());
    glutCreateWindow(GAMENAME);
    /*Other GLUT main function lines here */
    glutReshapeFunc(resize);
}

但是,当我尝试在调整大小中设置 gluOrtho2D 时,程序会设置背景并停止绘制任何内容。

void resize(int w, int h){
    game.setScreenSize(w,h);
    glViewport(0,0,width,height) 
    const GLfloat aspectRatio = (GLfloat)game.getXSize() / (GLfloat)game.getYSize();
    gluOrtho2D(0, game.getXSize()*game.getAspect(), 0, game.getYSize() / game.getAspect());
}    

当然,我自己设法只使用 glViewport(0,0,w,h),但这与根本不做任何事情几乎相同(图形只是拉伸,而我正在使用的功能将对象移动到鼠标位置不再正常工作),因为如果我不创建 Reshape 函数,则默认调用 glViewport。

【问题讨论】:

  • 我不确定您的具体意思。您提到或多或少地显示,但也提到在视口缩放的地方显示相同的内容。哪一个?能具体一点吗?
  • 我会更新我的问题以更清楚,对不起
  • 如果我理解正确的话。您希望根据视口的大小改变游戏中的距离。因此,不只是缩放视口以正确适合屏幕吗?听起来有点奇怪。最终目标是什么?
  • 我只是想绘制一个在初始窗口设置中可能不完全可见的场景。当我调整窗口大小时,我希望能够看到更多(或更少)该场景,而无需拉伸或调整场景大小

标签: opengl viewport


【解决方案1】:

世界坐标在 OpenGL 中映射到屏幕的一般方式是:

世界坐标 --> 剪辑空间坐标 --> 设备坐标

“世界坐标”就是您作为顶点数据提供给 OpenGL 的任何内容。它们可以是任何你想要的,没有规则。

顶点着色器(或矩阵堆栈,如果您穿越到 1990 年代)是将世界坐标转换为剪辑空间坐标的工具。

剪辑空间坐标从 –1…+1 开始。所以 (–1,–1) 是窗口的左下角, (–1,+1) 是左上角, (+1,+1) 是右上角,依此类推。无论如何都一样你的窗户是多大的。因此,如果您的窗口变大,图片也会变大,除非您同时缩小剪辑空间坐标。

因此,如果您想保持相同的世界坐标并保持相同的像素大小,则必须更改世界坐标转换为剪辑空间的方式。一般来说,这意味着如果您的窗口变大两倍,则剪辑空间坐标应该变大一半,以保持所有内容的大小相同。

通常,要实现这一点,您最终会在一个看起来像这样的矩阵中相乘:

int windowWidth = ..., windowHeight = ...;
double matrix[2][2] = {
    { 1.0 / windowWidth,                0.0 },
    {               0.0, 1.0 / windowHeight },
};

如果您使用的是 2D 矩阵。如果您使用glOrtho 或您的特定顶点着色器,请适当更改此设置。或者只是阅读glOrtho 的手册。

【讨论】:

    【解决方案2】:

    通过使用:

    gluOrtho2D(-1.0f, 1.0f, -1.0f, 1.0f);
    

    与以下内容相同:

    glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
    

    那么我假设你的问题是when you scale a scene like this,那么它最终看起来像这样:

    正如您所说,这可以通过考虑纵横比来解决。给定屏幕的widthheight。然后你可以计算纵横比并设置正确的正交投影:

    const GLfloat aspectRatio = (GLfloat)width / (GLfloat)height;
    
    gluOrtho2D(-aspectRatio, aspectRatio, -1.0f, 1.0f);
    

    这会导致所有内容都相对于纵横比进行缩放,并随后让您查看更多

    由于上面实际上是一个 3D 球体,所以还需要设置 nearfar 的值:

    glOrtho(-aspectRatio, aspectRatio, -1.0f, 1.0f, 1.0f, 100.0f);
    

    【讨论】:

    • 您是否假设程序从某个负值变为同样大的正值?我只是问,因为在我的情况下,我的程序默认从 0 到某个值 x,从 0 到某个值 y。然而,当我尝试使用 gluOrtho2D 时,游戏不再绘制任何东西。 (我正在传递它的值(0,宽度,0,高度)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多