【OpenGL】VS2019使用QtOpenGL遇到LNK2019报错问题解决

文章讲述了作者在使用Qt的OpenGL库进行编程时,在VS2019环境中遇到链接错误,通过查找资料和分析,发现需要添加OpenGL32和GLU32的静态库到项目配置中才能解决问题的过程。
摘要由CSDN通过智能技术生成

问题描述

今天尝试使用 Qt 的OpenGL相关的函数进行编程,在编译链接的时候,遇到了链接错误:

在这里插入图片描述

编写代码的时候,我引入了这些库:

#include <QGLWidget>
#include <gl/gl.h>
#include <gl/GLU.h>

编写过程中,VS2019没有任何报错与提示,所使用的函数也都可以正常使用

由于我使用的是VS2019,并不是Qt Creator,在网上查了一些解决办法,大部分都是讲Qt Creator的解决方法,主要是修改pro文件,打开pro文件修改LIBS:

LIBS += -lopengl32 -lglu32

但我这个项目并没有pro文件,需要额外去生成。

搜了很久,也没找到太多相关的解决方法。只能从报错去分析,可能是缺少一些静态库,导致链接发生了问题

解决办法

既然感觉是缺少静态库,那就尝试添加一些静态库吧

根据我调用的库以及Qt Creator解决方法,我初步判定应该是需要下面两个静态库:

  • OpenGL32.Lib
  • GlU32.Lib

所以我就给项目配置了这两个静态库:

  1. 打开项目属性页–>链接器–>常规–>附加库目录,在这个里面添加两个文件所在的目录,一般在下面的路径下是可以找到的:C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64
  2. 链接器–>输入–>附近依赖项,输入:OpenGL32.Lib GLU32.Lib

完成上述配置以后,再次重新生成解决方案,可以看到成功生成,并且可以运行!

完整代码:

OpenGLTools.h

/// OpenGLTools.h
#ifndef OPENGL_TOOLS_H
#define OPENGL_TOOLS_H

#include <QGLWidget>
#include <QMouseEvent>
#include <QPoint>
#include <QColor>
#include <QColorDialog>
#include <gl/gl.h>
#include <gl/GLU.h>

// #include "ui_OpenGlTools.h"

class COpenGlTools : public QGLWidget
{
    Q_OBJECT

public:
    COpenGlTools(QWidget *parent = nullptr);
    ~COpenGlTools();

protected:
    // inherited by QGLWidget
    void initializeGL();
    void resizeGL(int width, int height);
    void paintGL();
    // inherited by QWidget
    void mousePressEvent(QMouseEvent* event);
    void mouseMoveEvent(QMouseEvent* event);
    void mouseDoubleEvent(QMouseEvent* event);

private:
    // Ui::COpenGlToolsClass ui;
    void draw();
    int faceAtPosition(const QPoint& pos);

    GLfloat rotationX;
    GLfloat rotationY;
    GLfloat rotationZ;
    QColor faceColors[4];
    QPoint lastPos;
};
#endif // OPENGL_TOOLS_H

OpenGLTools.cpp

#include "OpenGlTools.h"


COpenGlTools::COpenGlTools(QWidget *parent)
    : QGLWidget(parent)
{
    // ui.setupUi(this);
    
    // 显示描述表
    setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
    // 初始化私有变量
    rotationX = -21.0;
    rotationY = -57.0;
    rotationZ = 0.0;

    faceColors[0] = Qt::red;
    faceColors[1] = Qt::green;
    faceColors[2] = Qt::blue;
    faceColors[3] = Qt::yellow;
}

COpenGlTools::~COpenGlTools()
{}

// 在调用paintGL()之前只被调用一次
void COpenGlTools::initializeGL()
{
    // 定义显示列表以及其他初始化
    qglClearColor(Qt::black);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
}

// 窗口部件改变大小时,调用resizeGL
void COpenGlTools::resizeGL(int width, int height)
{
    // 设置视口
    glViewport(0, 0, width, height);
    // 设置投影
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    GLfloat x = GLfloat(width) / height;
    glFrustum(-x, x, -1.0, 1.0, 4.0, 15.0);
    glMatrixMode(GL_MODELVIEW);
}

// 需要重绘时调用paintGL,类似于paintEvent
void COpenGlTools::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 等价于QPainter
    draw(); // 实际的绘制
}

void COpenGlTools::mousePressEvent(QMouseEvent* event)
{
    lastPos = event->pos();
}

void COpenGlTools::mouseMoveEvent(QMouseEvent* event)
{
    GLfloat dx = GLfloat(event->x() - lastPos.x()) / width();
    GLfloat dy = GLfloat(event->y() - lastPos.y()) / height();

    // 左键沿着 x 和 y 轴旋转
    if (event->buttons() & Qt::LeftButton)
    {
        rotationX += 180 * dy;
        rotationY += 180 * dx;
        updateGL(); // 重绘场景
    }
    else if (event->buttons() & Qt::RightButton) // 右键沿着 x 和 y 轴旋转
    {
        rotationX += 180 * dy;
        rotationZ += 180 * dx;
        updateGL(); // 重绘场景
    }
    lastPos = event->pos();
}

void COpenGlTools::mouseDoubleEvent(QMouseEvent* event)
{
    int face = faceAtPosition(event->pos());    // 确定光标下的面
    if (face != -1)
    {
        QColor color = QColorDialog::getColor(faceColors[face], this);
        if (color.isValid()) 
        {
            faceColors[face] = color;
            updateGL();
        }
    }
}

void COpenGlTools::draw()
{
    static const GLfloat P1[3] = { 0.0, -1.0, 2.0 };
    static const GLfloat P2[3] = { 1.73205081 , -1.0, -1.0 };
    static const GLfloat P3[3] = { -1.73205081, -1.0, -1.0 };
    static const GLfloat P4[3] = { 0.0, 2.0, 0.0 };

    static const GLfloat* const coords[4][3] = {
        { P1, P2, P3 }, { P1, P3, P4 }, { P1, P4, P2 }, { P2, P4, P3 }
    };

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -10.0);
    glRotatef(rotationX, 1.0, 0.0, 0.0);
    glRotatef(rotationY, 0.0, 1.0, 0.0);
    glRotatef(rotationZ, 0.0, 0.0, 1.0);

    for (int i = 0; i < 4; i++)
    {
        glLoadName(i);
        glBegin(GL_TRIANGLES);
        qglColor(faceColors[i]);
        for (int j = 0; j < 3; j++)
        {
            glVertex3f(coords[i][j][0], coords[i][j][1],
                coords[i][j][2]);
        }
        glEnd();
    }
}

// 确定光标下的面,返回窗口部件某位置所处的面的编号,没有面就返回1
int COpenGlTools::faceAtPosition(const QPoint& pos)
{
    const int maxSize = 512;
    GLuint buffer[maxSize];
    GLint viewport[4];

    makeCurrent();  // 确保正确使用OpenGL描述表

    glGetIntegerv(GL_VIEWPORT, viewport);
    glSelectBuffer(maxSize, buffer);
    glRenderMode(GL_SELECT); // 以GL_SELECT模式绘制场景

    glInitNames();
    glPushName(0);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluPickMatrix(GLdouble(pos.x()), GLdouble(viewport[3] - pos.y()), 5.0, 5.0, viewport);
    GLfloat x = GLfloat(width() / height());
    glFrustum(-x, x, -1.0, 1.0, 4.0, 15.0);
    draw();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    if (!glRenderMode(GL_RENDER))   
        return -1;

    return buffer[3];
}

main.cpp

#include "OpenGlTools.h"
#include <QtWidgets/QApplication>
#include <iostream>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    if (!QGLFormat::hasOpenGL())
    {
        std::cerr << "This system has no OpenGL support" << std::endl;
        return 1;
    }
    COpenGlTools w;
    w.setWindowTitle(QObject::tr("Tetrahedron"));
    w.resize(300, 300);
    w.show();

    return app.exec();
}

运行结果:
在这里插入图片描述

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值