1

I am finally trying to wrap my head around shaders, using a tutorial I found. I decided to start with Qt5 (Windows) since I'm familiar with it and can focus on learning GLSL itself to start with. The only difference between what I'm doing and the tutorial is that I'm working with a QOpenGLWidget rather than a QOpenGLWindow (I just have a form with one widget on it, nothing special).

To get started with a fragment shader, in Qt I added a new desktop (not ES) fragment shader to my project, and Qt generates the following shader:

uniform sampler2D qt_Texture0;
varying vec4 qt_TexCoord0;

void main(void)
{
    gl_FragColor = texture2D(qt_Texture0, qt_TexCoord0.st);
}

However, when compiling this shader, it generates this error:

QOpenGLShader::compile(Fragment): ERROR: 0:2: '' : No precision specified for (float)

I did a little bit of searching around and found this answer which states:

No default precision exists for fp types in fragment shaders in OpenGL ES 2.0.

From this, my conclusion is that my application is using OpenGL ES and not Desktop (otherwise it wouldn't expect a precision to be defined).

The GL version string I'm seeing is OpenGL ES 2.0 (ANGLE 2.1.0.8613f4946861). Fwiw, in Qt4 on this same machine, the version string is 3.0.0 - Build 9.17.10.4229.

Assuming my conclusion is correct, my question is: How can I configure the application to use regular OpenGL instead of OpenGL ES?


The suggestion in the comments to set the surface format's renderable type to OpenGL seemed promising, but it isn't working. For example, if I change it in the widget's constructor:

View::View (QWidget *parent) :
    QOpenGLWidget(parent),
    ...
{

    QSurfaceFormat f = format();
    qDebug() << "type was" << f.renderableType();

    f.setRenderableType(QSurfaceFormat::OpenGL);
    qDebug() << "type set to" << f.renderableType();

    setFormat(f);
    qDebug() << "type is now" << format().renderableType();

}

void View::initializeGL () {

    qDebug() << __FUNCTION__ << "type is now" << this->format().renderableType();
    ...

}

The issue persists and the output is (0 = default, 1 = OpenGL, 2 = OpenGLES):

type was 0
type set to 1
type is now 1
initializeGL type is now 2

So it appears to be being forced back to OpenGLES at some point between the constructor and initializeGL.

I observed similar behavior when setting the default surface format before constructing any GUI objects (and before constructing the QApplication) as well.

Jason C
  • 34,234
  • 12
  • 103
  • 151
  • 1
    You probably have to set [`QSurface::RenderableType`](https://doc.qt.io/qt-5/qsurfaceformat.html#RenderableType-enum) to `OpenGL` for the `QOpenGLWidget` – dave Mar 28 '19 at 14:21
  • @dave Hm; so I tried setting it to `OpenGL` in the default surface format (it was originally `DefaultRenderableType`) before creating the UI objects, but the result is the same, and indeed by the time `initializeGL` is called the widget's format is `OpenGLES` again. That seems like it's on the right track, though. I'm going to investigate that more and try to figure out why it didn't work. – Jason C Mar 28 '19 at 14:28
  • I'm starting to wonder if this has something to do with my old laptop; context initialization completely fails if I attempt to require GL version 4 or later in the surface format. – Jason C Mar 28 '19 at 14:40
  • 1
    Did you try this from the Qt doc: _Calling QSurfaceFormat::setDefaultFormat() before constructing the QApplication instance is mandatory on some platforms (for example, macOS) when an OpenGL core profile context is requested._ It may also be that your hardware does not support that specific version of OpenGL. In that case, the Surface format you request may not be set accordingly. (See [QOpenGLWidget::format](https://doc.qt.io/qt-5/qopenglwidget.html#format) ) – dave Mar 28 '19 at 14:43
  • @dave Yeah, I did it before constructing the QApplication. I guess it's just not supported on this machine. Everything in your comments seems to make sense and the conclusion that it's not supported seems reasonable, if you feel like throwing it up as an answer, I think there's enough evidence that it's correct at this point. I'll see if I can find another way to verify this machine's capabilities. I don't have a newer computer to test with. – Jason C Mar 28 '19 at 14:51
  • I dunno. I'm giving up for now. The Geeks3D caps viewer says I have OpenGL 3.1 support max, the shader demos all work fine, it looks like I should have at least desktop OpenGL 3.1, but I don't understand the interrelation between all the OpenGL desktop and ES versions and features and hardware enough to draw a conclusion, so I'm satisfied for now to say that it's just something to do with this computer and not with Qt. Maybe I'll understand more as I progress through my shader quest. I'll use ES for now I guess and hope that I don't run into any showstopping problems with tutorials. – Jason C Mar 28 '19 at 15:04
  • Tbh, I'm not that versed with OpenGL ES either. On more thing you can check is putting `qDebug() << (const char*)glGetString(GL_VERSION);` in the `initializeGL` function which should print the version string for OpenGL from within Qt – dave Mar 28 '19 at 15:13
  • `OpenGL ES 2.0 (ANGLE 2.1.0.8613f4946861)`. In Qt4 on this same machine, from the older `QGLWidget`, it shows `3.0.0 - Build 9.17.10.4229`. The capability viewer shows `OpenGL 3.1`. – Jason C Mar 28 '19 at 15:22
  • So none of my stuff was working at all, really, and I ended up trying it on a different machine, Linux with some nvidia hardware, and it just worked no problem right away, version string "4.5.0 NVIDIA 384.130". I guess maybe some logic somewhere ran into some unsupported features on my laptop and fell back on OpenGL ES for some reason, which still didn't work. – Jason C Mar 28 '19 at 17:42

1 Answers1

2

Qt5 on Windows will use ANGLE as a fallback (emulating OpenGL ES 2.0 with Direct3D) if either the video card is blacklisted (in ANGLE configuration at the time Qt was compiled) or the video driver does not support modern OpenGL (i.e. if you have only the stock driver provided by Microsoft).

You can force the application to use OpenGL instead of angle by adding:

QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);

in your main.cpp file or by setting the environment variable QT_OPENGL to "desktop" (without quotes). You can find more details here: http://doc.qt.io/qt-5/windows-requirements.html

Sergio Monteleone
  • 2,477
  • 5
  • 18
  • Oh wow; that totally worked. The version string is "3.1.0 - Build 9.17.10.4229" now; and my shaders compile and run just fine. Awesome, thanks! – Jason C Mar 29 '19 at 20:07