OpenGL glOrtho 设置匹配 window 大小

OpenGL glOrtho set up match the window size

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

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

请注意,我当前的 window 尺寸是 1000x600 (width/height)

这是一行(在横跨整个屏幕的顶部):

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

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

}

这是我的主要 class 调用 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();
}

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

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

所以,首先您的正射设置。如果您希望相机与屏幕尺寸匹配,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 );

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

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

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

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