OpenGL glOrtho 设置匹配窗口大小

Posted

技术标签:

【中文标题】OpenGL glOrtho 设置匹配窗口大小【英文标题】:OpenGL glOrtho set up match the window size 【发布时间】:2016-03-05 10:22:36 【问题描述】:

我是 OpenGl 的初学者,我在设置 glOrtho 相机以匹配窗口大小以便我可以使用窗口的坐标绘制一条线时遇到了一些困难。例如,如果我想从坐标 0,10 (x,y) 到 600,10 画一条线。我设法在我当前的设置中绘制了这条线(这将是视口中的“分隔符”和带有按钮的工具栏),但它是通过“尝试结束错误”方法并且我需要放置的坐标不对我有任何意义。当我尝试使用上述坐标绘制一条线时,这条线根本没有出现。为了使用这些(1000x600)屏幕尺寸并绘制我的顶点而不是这些顶点,我需要在 glOrtho 设置中进行更改:

glVertex3f(-2.0, 11.0, 0.0);
glVertex3f(20.0, 11.0, 0.0);

注意,我当前的窗口大小是 1000x600(宽/高)

这是一条线(在顶部横穿整个屏幕):

这是我处理所有绘图的 OGWindow 类:

void OGWindow::MyReSizeGLScene(int fwidth, int fheight) 

// Store window size  in class variables so it can be accessed in myDrawGLScene() if necessary
wWidth = fwidth;
wHeight = fheight;

// Calculate aspect ration of the OpenGL window
aspect_ratio = (float) fwidth / fheight;

// Set camera so it can see a square area of space running from 0 to 10 
// in both X and Y directions, plus a bit of space around it.
Ymin = -1;
Ymax = 12;
Xmin = -1;

// Choose Xmax so that the aspect ration of the projection
// = the aspect ratio of the viewport
Xmax = (aspect_ratio * (Ymax -Ymin)) + Xmin;

glMatrixMode(GL_PROJECTION);        // Select The Projection Stack
glLoadIdentity();
glOrtho(Xmin, Xmax, Ymin, Ymax, -1.0, 1.0);

glViewport(0, 0, wWidth, wHeight);      // Viewport fills the window


void OGWindow::myDrawGLScene(GLvoid)        // Here's Where We Do All The Drawing

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the drawing area

OGWindow::myDrawModel();
drawToolbar();

glutSwapBuffers(); // Needed if we're running an animation
glFlush();




void OGWindow::myDrawModel(GLvoid)

switch ( squareColour ) 
case RED:
        glColor3f(1.0, 0.0, 0.0);
    break;
case BLUE:
        glColor3f(0.0, 0.0, 1.0);
    break;


glBegin( GL_QUADS );
    glVertex3f( squareX, squareY, 0.0 ); // Coordinates of bottom-left corner of square
    glVertex3f( squareX + squareWidth, squareY, 0.0 );
    glVertex3f( squareX + squareWidth, squareY + squareHeight, 0.0 );
    glVertex3f( squareX, squareY + squareHeight, 0.0 );
glEnd();



// Convert from screen coords returned by mouse
// to world coordinates.
// Return result in worldX, worldY
void OGWindow::screen2World(int screenX, int screenY, double & worldX, double & worldY)

// Dimensions of rectangle viewed by camera projection
double projWidth = Xmax -Xmin;
double projHeight = Ymax - Ymin;

// Screen coords with origin at bottom left
int screenLeft = screenX;
int screenUp = wHeight - screenY; 

worldX = Xmin + screenLeft * projWidth / wWidth ;
worldY = Ymin + screenUp *  projHeight / wHeight ;


//Method to draw the toolbar separator line
void OGWindow::drawToolbar(GLvoid) 
//draw toolbar line separator
glColor3f(0.0,0.0,0.0);
glBegin(GL_LINES);
    glVertex3f(-2.0, 11.0, 0.0);
    glVertex3f(20.0, 11.0, 0.0);
glEnd();
//draw create button

glPushMatrix();
    glTranslatef(2.0, 10.0, 0.0);

    glutSolidCube(2.0);
glPopMatrix();


这是我从 OGWindow 调用方法的主要课程:

int main(int argc, char **argv) 

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);   
glutInitWindowSize( 1000, 600 );
glutInitWindowPosition(0, 0);
glutCreateWindow("OpenGL Demo");
glEnable(GL_DEPTH_TEST);    // enable the depth buffer test

glutDisplayFunc(DrawGLScene);
glutReshapeFunc(ReSizeGLScene);
glutMouseFunc(mouseClick);
glutMotionFunc(mouseMotion);
glutPassiveMotionFunc(mousePassiveMotion);
glutIdleFunc(Idle);
theWindow.initGL(); 

glutMainLoop();

【问题讨论】:

您是否使用glLoadIdentity 初始化了GL_MODELVIEW 矩阵?此外,您不要在调整大小后将glMatrixMode 换回GL_MODELVIEW 【参考方案1】:

查看documentation of glOrtho 函数。如您所见,有 6 个参数:left、right、bottom、top、near、far。您将窗口宽度设置为 top 而不是 bottom 参数时犯了错误。下面是函数的正确使用:

glOrtho (0, 1000, 600, 0, -1.0, 1.0)

【讨论】:

您好,感谢您的建议。我会仔细查看文档,回家后会尝试您的建议。吸引你的帮助。 非常感谢。这正是我需要的场景。 :)【参考方案2】:

所以,首先您的正交设置。如果您希望您的相机与屏幕尺寸匹配,glOrtho 必须使用相同的尺寸。

// This will anchor the camera to the center of the screen
// Camera will be centered on (0,0)
glOrtho( -screenWidth/2.f, screenWidth/2.f, -screenHeight/2.f, screenHeight/2.f, -1, 1 );

// This will anchor the camera to the lower left corner of the screen
// Camera will be centered on (screenWidth/2, screenHeight/2)
glOrtho( 0, screenWidth, 0, screenHeight, -1, 1 );

两者都试一下,看看有什么不同。虽然如果您正在制作某种编辑器,而您的相机不会移动,您可能正在寻找第二个正射设置。

第二,你只使用过(显然)GL_PROJECTION 矩阵模式。您必须使用此模式设置相机投影,并使用GL_MODELVIEW 将变换应用于相机或对象。

因此,当您调用 resize 并且不将矩阵模式改回 GL_MODELVIEW 时,您将对投影矩阵应用平移。

如果您确实忘记初始化模型视图矩阵,它可能包含垃圾值并产生意外结果。

【讨论】:

我测试了这些建议,它们正在按照您在此处提到的那样工作。感谢您对我的问题的详细解释。

以上是关于OpenGL glOrtho 设置匹配窗口大小的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 中的可视化问题(glOrtho 和投影)

OpenGL窗口大小渲染问题

在OpenGL中撕裂?

0、800、600、0 与 0、800、0、600 OpenGL

OpenGL 防止在调整窗口大小时拉伸

调整 OpenGL 窗口的大小会导致它崩溃