2012-06-12 13 views
9

Estoy tratando de usar QGLWidget en Qt 4.8.2. Noté que el contexto predeterminado que crea QGLWidget no muestra ningún resultado para OpenGL por encima de 3.1. The Qt wiki has a tutorial que demuestra el uso de OpenGL 3.3 para dibujar un triángulo simple. Cuando intento ejecutar el tutorial, aparece una pantalla en blanco. Si cambio la versión de OpenGL a 3.1, obtengo el resultado esperado (un triángulo rojo).No se puede establecer la versión de OpenGL deseada en QGLWidget

Mi tarjeta de video admite OpenGL 4.2 y llamando al QGLFormat::openGLVersionFlags() antes de crear el QGLWidget muestra que Qt detecta OpenGL 4.2 y todas las versiones de escritorio anteriores.

Aquí hay otro ejemplo mínimo:

#include <QApplication> 
#include <QGLWidget> 
#include <QDebug> 
#include <QtDeclarative/qdeclarativeview.h> 

int main(int argc, char * argv[]) 
{ 
    QApplication app(argc, argv); 

    qDebug() << "OpenGL Versions Supported: " << QGLFormat::openGLVersionFlags(); 

    QGLFormat qglFormat; 
    qglFormat.setVersion(4,2); // get expected output with (3,1) and below, else blank window 
    qglFormat.setProfile(QGLFormat::CoreProfile); 
    qglFormat.setSampleBuffers(true); 

    QGLWidget* qglWidget = new QGLWidget(qglFormat); 

    QString versionString(QLatin1String(reinterpret_cast<const char*>(glGetString(GL_VERSION)))); 
    qDebug() << "Driver Version String:" << versionString; 
    qDebug() << "Current Context:" << qglWidget->format(); 

    QDeclarativeView mainView; 
    mainView.setViewport(qglWidget); 
    mainView.setSource(QString("helloworld.qml")); 
    mainView.show(); 

    return app.exec(); 
} 

Aquí está la salida:

OpenGL Versions Supported: QFlags(0x1|0x2|0x4|0x8|0x10|0x20|0x40|0x1000|0x2000|0x4000|0x8000|0x10000) 
Driver Version String: "4.2.0 NVIDIA 295.53" 
Current Context: QGLFormat(options QFlags(0x1|0x2|0x4|0x10|0x20|0x80|0x200|0x400) , plane 0 , depthBufferSize 24 , accumBufferSize 16 , stencilBufferSize 8 , redBufferSize 8 , greenBufferSize 8 , blueBufferSize 8 , alphaBufferSize -1 , samples 4 , swapInterval 0 , majorVersion 4 , minorVersion 2 , profile 1) 

La lista enum QFlags() en la primera línea describe las versiones de OpenGL compatibles. La lista muestra que soporto todas las variantes excepto las versiones de OpenGL/ES. QFlags() en la tercera línea describe las opciones de formato (canal alfa, memoria intermedia de esténcil, etc.).

¿Alguien sabe por qué QGLWidget no funciona con nada> = 3.1? Estoy en Linux, tengo una Nvidia GT440 y glxinfo muestra que admite OpenGL 4.2.0. La versión del controlador se imprime en la salida de muestra anterior. No estoy muy seguro de qué más probar.

Editar: He cometido algunos errores/suposiciones muy malas con mi explicación del problema antes de esta edición. El problema sigue siendo similar, pero ojalá tenga más sentido ahora. Perdón por cualquier confusión.

+0

¿Están compilando/vinculando sus sombreadores? Si está utilizando un contexto 4.2 y sombreadores incompatibles/incorrectos, esa es una de las causas de una ventana en blanco. –

+0

No he llegado tan lejos aún (shaders). Quería usar QGLWidget como una ventana gráfica para QDeclarativeView y luego agregar algo de contenido en 3D que usaba shaders. Pero incluso un archivo simple con componentes predeterminados como un Rectangle {} no representa nada.Aparecerá como se espera si no configuro la versión de QGLFormat, pero el objetivo de esta pregunta es averiguar por qué no puedo configurarlo en primer lugar. Además, obtendría errores si yo (o Qt internamente) estuviera usando sombreadores incompatibles. El único resultado es lo que pegué en mi pregunta. – Prismatic

+0

Hmm, la única razón por la que sugiero consultar el registro de sombreado es que OpenGL 3.0 + requiere que se compilen y carguen sus propios sombreadores, mientras que OpenGL 2.0 y versiones posteriores no lo hacen. No tengo experiencia con el uso de OpenGL a través de QT, así que no sé cuánto se maneja para usted. Sin embargo, en el ejemplo que vinculó, el autor prepara sus propios sombreadores. Si no proporciona sombreadores a la tarjeta gráfica utilizando el perfil central, no renderizará nada. –

Respuesta

4

Debe mover las consultas de OpenGL después de mainView.show();. Antes de show(), el contexto OpenGL no se ha inicializado.

2

Versión corta: actualización a Qt5, se arregló allí.

P.S Y si puede usar 5.4, probablemente debería utilizar clases QtOpenGL ... en lugar de QGL ... ones.

Versión larga: Entonces, en caso de que alguien se encuentre con un problema como este.

Intenté crear el contexto NO OpenGL 3.0 con mi Intel HD3000 en ubuntu 14.04 y Qt 4.8.6. Se me ocurrió este código de prueba proporcionado al final de la respuesta. Intentó crear contextos 3.1, 1.2, 2.1 .. etc. Core Compatible ... pero siempre termina con context->format().majorVersion() mostrando la versión solicitada, y glGetString(GL_VERSION) mostrando 3.0.

Después de aproximadamente 3 horas me di cuenta de que de forma predeterminada Qt Creator usa Qt4 en lugar de Qt 5 reciente, instalado en mi sistema. Y después de recompilar el proyecto con Qt 5.2.1 exactamente el mismo código comenzó a funcionar como se esperaba.

Espero que esto ayude a alguien.

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 

    MainWindow w; 
    w.show(); 

    QGLFormat glFormat; 
    glFormat.setVersion(3, 1); 
    glFormat.setProfile(QGLFormat::NoProfile); 
    glFormat.setSampleBuffers(true); 
    glFormat.setDefaultFormat(glFormat); 
    glFormat.setSwapInterval(1); 
    QGLWidget widget(glFormat); 
    widget.makeCurrent(); 

    const QGLContext *context = widget.context(); 

    glewExperimental = GL_TRUE; 
    if (glewInit() != GLEW_OK) { 
     qWarning("Failed to initialize GLEW\n"); 
    } 
    qDebug() << "Context valid: " << context->isValid(); 
    qDebug() << "Really used OpenGl: " << context->format().majorVersion() << "." << context->format().minorVersion(); 
    qDebug() << "OpenGl information: VENDOR:  " << (const char*)glGetString(GL_VENDOR); 
    qDebug() << "     RENDERDER: " << (const char*)glGetString(GL_RENDERER); 
    qDebug() << "     VERSION:  " << (const char*)glGetString(GL_VERSION); 
    qDebug() << "     GLSL VERSION: " << (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION); 
    qDebug() << "endstuff\n"; 

    return a.exec(); 
} 
Cuestiones relacionadas