OpenGL通过调整大小来显示更多/更少的世界

时间:2017-04-14 23:48:09

标签: opengl viewport

因此,网上有很多关于调整大小的问题一直是关于保持正确的比例并避免拉伸等。据我所知,这可以通过设置gluOrtho2D的新比率来完成。

但是,我不确定如何在调整大小时显示更多和更少的世界。例如。你有一个可以沿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),但这几乎完全没有做任何事情(图形只是拉伸,功能我用来将对象移动到鼠标位置不再正常工作),因为如果我不创建重塑函数,默认情况下会调用glViewport。

2 个答案:

答案 0 :(得分:0)

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

  

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

"世界坐标"只是你作为顶点数据提供给OpenGL的任何东西。它们可以是你想要的任何东西,没有规则。

顶点着色器(或矩阵堆栈,如果你是时间旅行到20世纪90年代)是将世界坐标转换为剪辑空间坐标。

剪辑空间坐标从-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手册。

答案 1 :(得分:0)

使用:

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);