【问题标题】:Resolving OpenGL functions using glew in QT在 QT 中使用 glew 解析 OpenGL 函数
【发布时间】:2013-06-29 18:08:12
【问题描述】:

已经 17 天了 我正在努力使用 QT 在 OpenGL 中编写一个简单的程序,但是在 Google 上搜索的所有教程都失败了。 我已经使用 msvc2010 编译了带有 -opengl 桌面的 QT 5.0.1 以使桌面 opengl 成为默认值。

我读过 Sean Harmer 的教程,但它依赖于 QT 来解析 opengl 函数。

根据某些人的说法,不可能在 QT 中使用 glew,因为 QT 的内置库阻止 glew 包含其标题,但根据 Sean Harmer HERE ,这是可能的(但没有解释如何)。

即使使用 QGLWidget,我也无法使用 OpenGL 扩展。

现在我只想单独使用所有 OpenGL 函数和 QT 中的所有窗口函数,即 QT 不会干扰 OpenGL。

如果有人用简单的三角形示例并使用任何扩展名向我解释该过程,我将非常感激..

我在我的项目中使用了 glew 库,并在我的程序开始时使用了 #included glew.h,但是在编译时它给出了错误: glwidget.obj:-1:错误:LNK2001:未解析的外部符号 imp__glewGenVertexArrays

我的 .pro 文件

QT       += core gui opengl

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Trial
TEMPLATE = app

SOURCES += main.cpp\
        mainwindow.cpp \
    glwidget.cpp

HEADERS  += mainwindow.h \
    glwidget.h

FORMS    += mainwindow.ui

RESOURCES += \
    resources.qrc
win32: LIBS += -L$$PWD/../../../../../OpenGL/glew-1.9.0/lib/ -lglew32s

INCLUDEPATH += $$PWD/../../../../../OpenGL/glew-1.9.0/include
DEPENDPATH += $$PWD/../../../../../OpenGL/glew-1.9.0/include

win32: PRE_TARGETDEPS += $$PWD/../../../../../OpenGL/glew-1.9.0/lib/glew32s.lib

glewInfo 的输出: GLEW 版本 1.9.0 pixelformat 1 的报告功能 在 NVIDIA Corporation 的 GeForce GT 540M/PCIe/SSE2 上运行 支持 OpenGL 4.3.0 版本

void GLWidget::initializeGL()
{
    GLenum err = glewInit();
    if(err != GLEW_OK)
    {
        printf("%s",glewGetErrorString(err));
    }

    glEnable(GL_DEPTH_TEST);
    qglClearColor(QColor(Qt::red));

    shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertexShader.vsh");
    shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragmentShader.fsh");
    shaderProgram.link();
    shaderProgram.bind();

    const GLubyte *oglVersion = glGetString(GL_VERSION);
    printf( "%s\n",oglVersion );

    GLfloat vertices[3][3] ={{ -0.5, -0.5, -1 },
                { 0,    0.5,    -1},
                    { 0.5,  -0.5,   -1}};
    vertexArray.create();
    vertexArray.setUsagePattern(QOpenGLBuffer::StaticDraw);
    vertexArray.allocate( vertices, 3 * 3 * sizeof( GLfloat ) );
    vertexArray.bind();
    shaderProgram.setAttributeBuffer( "vVertex", GL_FLOAT, 0, 3 );
    shaderProgram.enableAttributeArray( "vVertex" );

    GLuint arr[5];
    glGenBuffers(5,arr);
}

【问题讨论】:

  • "根据某些人的说法,在 QT 中不能使用 glew" 错误。大多数在 Qt 应用程序中使用 OpenGL 的人使用 GLEW 配置扩展,并从 QGLWidgets 内部调用原始 OpenGL 函数。但是如果没有具体的错误信息,你使用过的.pro文件等等,我们帮不了你。
  • 错误“无法解析的外部符号 imp__glew”是在 glew32s.lib 添加静态标记时出现的,当 glew32.lib 添加动态标记时它们会消失。虽然我的程序意外终止,但在调试模式下运行时,问题出在 glDrawArrays...
  • 如果您尝试在 Windows 上进行静态链接,您需要定义 GLEW_STATIC 令牌。一旦你有有效的上下文,大概你也会调用glewInit()
  • 是的 Iv glewInit() 在 initialiseGL() 中。正如你所说,我在#include glew.h 之前添加了 GLEW_STATIC,但它给出了警告::-1: warning: LNK4098: defaultlib 'LIBCMT' conflict with use of other libs;使用 /NODEFAULTLIB:library glew32s.lib(glew.obj):-1: 警告:LNK4099: 在 'glew32s.lib(glew.obj)' 或'D:\Dexter\Softwares 中找不到 PDB'vc100.pdb' \Programming stuff\QT Projects\Trial-build-Desktop_Qt_5_0_1_MSVC2010_32bit-Debug\debug\vc100.pdb';链接对象好像没有调试信息
  • 只是为了确定,您的 GPU 支持什么版本的 OpenGL(由 glewinfo 返回)?另外,发布您的 initializeGL() 方法。

标签: qt opengl glew


【解决方案1】:

我想分享我关于如何使 Qt 和 glew 在(当前)最新的 Windows 环境(Qt 5.15.1 + QMake + MSVC 2019 + glew 2.1.0)上协同工作的最新发现。希望其他人避免像我一样在这上面花费无数时间。以下是我所做的:

  1. 将 glew32.dll 和 glew32.lib 复制到项目目录中的某个位置。确保 glew 的位数与您告诉 Qt 构建的可执行文件的位数相匹配。我没有使用库的静态版本,因为我没能成功。
  2. 在您的 .pro (QMake) 文件中,编写如下内容:
GLEW_INCLUDE_PATH = "$$PWD/ext/glew/include" # put glew headers here
GLEW_LIB_PATH = "$$PWD/ext/glew/x64"         # put glew32.dll and glew32.lib here

LIBS += -L$$GLEW_LIB_PATH -lglew32 -lglu32 -lopengl32

DEPENDPATH += .
INCLUDEPATH += $$GLEW_INCLUDE_PATH

与之前的答案相比,我所做的唯一区别是我在链接参数中添加了 -lglu32-lopengl32。似乎它们在 Windows 上是强制性的,否则 MSVC 会抱怨 OpenGL API 函数的一些链接错误。

  1. 此外,请尝试使用QOpenGLWidget 而不是QGLWidgetQGLWidget 当我的程序退出并试图破坏 OpenGL 句柄(如析构函数中的缓冲区和纹理句柄)时,导致了一些奇怪的 OpenGL“无效操作”错误。 glIntercept 告诉我这是因为 wgl 上下文在句柄被释放之前被破坏了。改用 QOpenGLWidget 彻底解决了这个问题。

希望您现在可以享受在 Qt 中使用 glew 的乐趣!

【讨论】:

    【解决方案2】:

    现在所有问题都解决了。

    第一个问题是:QT 5.0.1 默认不支持 opengl。 您必须使用 -opengl desktop 编译它。 Here 是关于如何使用 vs2010 编译 QT 的教程。 或者你可以从 QT 下载新的 opengl 构建。

    将 glew 库添加到项目的第二个问题。 如果添加 glew32s.lib(静态),则必须在“#include”之前添加“#define GLEW_STATIC” 建议使用glew32.lib(动态)。

    第三个问题是某些 opengl 函数的段错误,即使您的 GPU 支持 4.3 版。 GLEW 从图形驱动程序获取有关支持的扩展的信息。然而,实验性或预发布驱动程序可能不会通过标准机制报告每个可用的扩展,在这种情况下,GLEW 将报告它不受支持。为了规避这种情况,可以通过在调用 glewInit() 之前将 glewExperimental 全局开关设置为 GL_TRUE 来打开它,这样可以确保所有具有有效入口点的扩展都将被公开。

    花了18天解决这些问题,很高兴现在可以开始实际编程了。

    【讨论】:

      【解决方案3】:

      以下代码仅在 MSVC2008 express、qt 4.8.1 和 glew 版本 1.7.0 上编译 FINE

      main.cpp:

      #include <GL/glew.h>
      #include <QApplication>
      #include <QGLWidget>
      
      int main(int argc, char** argv){
          glewInit();//<<-- glew function
          QApplication app(argc, argv);
          QGLWidget widget;
      
          GLuint arr;
          glGenVertexArrays(1, &arr);//<--no linker error (added just for testing, most likely won't gen arrays)
      
          widget.show();
          return app.exec();
      }
      

      gltest.pro:

      TEMPLATE = app
      TARGET = 
      DEPENDPATH += .
      INCLUDEPATH += . d:/c++/libs/include
      LIBS += -L"d:/c++/libs/lib" -lglew32
      
      CONFIG += console
      QT += opengl
      
      # Input
      SOURCES += main.cpp
      

      我认为使用 Qt 5 情况不会有任何不同。

      随意覆盖 QGLWidget 的 paintGL 并使用扩展绘制任何你想要的东西。我附近没有用于此的代码 sn-p。

      建议:
      1. 使用预编译的二进制文件。
      2. 使用 glew 的动态链接版本可能有意义。
      3. 注意标题包含顺序。

      有人说

      人们说的很多,你不必全都相信。

      【讨论】:

        猜你喜欢
        • 2012-02-29
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多