在QT中使用glew解析OpenGL函数

时间:2013-07-02 11:32:33

标签: qt opengl glew

已经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库,并且在我的程序开始时使用了#include 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公司的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);
}

3 个答案:

答案 0 :(得分:14)

现在所有问题都解决了。

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

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

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

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

答案 1 :(得分:4)

以下代码仅在MSVC2008 express上编译FINE,qt 4.8.1和glew version 1.7.0

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并使用扩展绘制任何你想要的东西。我附近没有代码片段。

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

  

根据一些人的说法

人们说很多东西,你不需要相信所有的东西。

答案 2 :(得分:0)

我想分享一下有关如何使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!