glOrtho不会在2D窗口中更改坐标系吗?

时间:2019-02-22 17:37:26

标签: c++ qt opengl

因此,除非我理解此错误,否则默认情况下,OpenGL窗口坐标(0,0)位于屏幕中心。我使用glOrtho / glViewport设置了以下调整大小功能,以将左上角设置为(0,0)。但是由于某种原因,在(0,0)处绘制一个点仍会显示在屏幕中心(并且仍在-1/1范围内)。

主要

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.setTitle("OpenGL");
    w.resize(500,500);
    w.show();
    return a.exec();
}

Mainwindow.cpp

MainWindow::MainWindow(QWidget *parent)
{
    setSurfaceType(QWindow::OpenGLSurface);
    QSurfaceFormat format;
    format.setProfile(QSurfaceFormat::CompatibilityProfile);
    format.setVersion(2,1);

    setFormat(format);
    context =new QOpenGLContext;
    context->setFormat(format);
    context->makeCurrent(this);

    openGLFuncions = context->functions();

}
void MainWindow::resizeGL(int w, int h)
{
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0,w,h,0.0,-1.0,1.0);
    glMatrixMode(GL_MODELVIEW);
}

void MainWindow::paintGL()
{
    glClearColor(0.0f,0.0f,0.0f,0.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glPointSize(10.0f);
    glBegin(GL_POINTS);
        glVertex2f(0.5f,0);
    glEnd();

    glFlush();
}

MainWidow.h

class MainWindow : public QOpenGLWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void updateAnim();
protected:
    virtual void initilizeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();
    void resizeEvent(QResizeEvent *event);
    void paintEvent(QPaintEvent *event);
private:
    QOpenGLContext *context;
    QOpenGLFunctions *openGLFuncions;
};

1 个答案:

答案 0 :(得分:1)

除了MainWindow::initilizeGLMainWindow::paintGL中,我建议不要进行任何OpenGL调用。

将状态成员(_vp_valid)添加到类MainWindow中,以指示视口和投影矩阵是否已正确设置并初始化false

class MainWindow : public QOpenGLWindow
{

    // [...]

private:

   bool _vp_valid = false;

   // [...]
};

如果状态无效,则更新视口矩形并在MainWindow::paintGL中设置投影矩阵:

void MainWindow::paintGL()
{
    if ( !_vp_valid )
    {
        _vp_valid = true;
        int w = this->width();
        int h = this->height();

        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0.0,w,h,0.0,-1.0,1.0);
        glMatrixMode(GL_MODELVIEW);
    }

    glClearColor(0.0f,0.0f,0.0f,0.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glPointSize(10.0f);
    glBegin(GL_POINTS);
        glVertex2f(0.5f,0);
    glEnd();

    glFlush();
}

MainWindow::resizeGL中,使状态无效就足够了:

void MainWindow::resizeGL(int w, int h)
{
    _vp_valid = false;
}