PDA

View Full Version : How to use QOpenGLFunctions_2_1 properly



jshafferman
22nd March 2014, 01:24
I am trying to use raw OpenGL with Qt and I am trying to strictly use the Qt API to do so. I am using OpenGL 2.1 because that is our hardware limitation. I am able to build without any errors but the first instance of a gl* fails. The first opengl function is glGetIntergv(GL_ENUM, int*) and through the debugger I am able to see that is where I crash first. I am just curious if anyone can see what I am missing because my guess is I have to do something special to initialize these functions (which I thought initializeOpenGLFunctions() accomplished). Any help or direction would be great!!

I am subclassing with QOpenGLFunctions_2_1 like so:


class GLWidget : public QGLWidget, protected QOpenGLFunctions_2_1


These are the relevant source file functions


GLWidget::GLWidget(QWidget *parent) :
QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::Rgba | QGL::DepthBuffer),parent)
{
createActions();
createMenus();
}

void GLWidget::initializeGL()
{
initializeOpenGLFunctions();

pixels[0] = pixels[1] = pixels[2] = NULL;
frameGood[0] = frameGood[1] = frameGood[2] = GL_FALSE;

qDebug() << "Pixel Buffer Object Demo";

QGLFunctions funcs(QGLContext::currentContext());
bool isNonPowerTwo = funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures) ;

// // Make sure required functionality is available!
// if (!GLEE_VERSION_2_1 && !GLEE_ARB_pixel_buffer_object)
// {
// qDebug() << "PBO extension is not available!";
//// fprintf(stderr, "PBO extension is not available!\n");
// Sleep(2000);
// exit(0);
// }

if (isNonPowerTwo)
{
npotTexturesAvailable = GL_TRUE;
}
else
{
qDebug() << "GL_ARB_texture_non_power_of_two extension is not available!";
qDebug() << "Only portion of window will be used for rendering";
}

// Check for minimum resources
GLint intVal = 0;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &intVal);

if (intVal < 3)
{
qDebug() << "Fewer than 3 texture units available!";
Sleep(2000);
exit(0);
}
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &intVal);
if (intVal < 1024)
{
qDebug() << "1024x1024 texture not supported!";
Sleep(2000);
exit(0);
}

qDebug() << "Controls:";
qDebug() << "\tRight-click for menu";
qDebug() << "\tb\tToggle motion blur";
qDebug() << "\tp\tToggle PBO usage";
qDebug() << "\tarrows\t+/- rotation speed";
qDebug() << "\tq\t\tExit demo";

// Colors
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
glColor4f(0.0f, 0.0f, 0.0f, 1.0f );

// Texture matrix is the only one we'll change
glMatrixMode(GL_TEXTURE);

// Set up textures
SetupTextures();
}


And as stated above the first call to glGetIntergv is what fails :(. Any ideas?

ChrisW67
23rd March 2014, 23:36
Has initializeOpenGLFunctions() returned true or failed (false)?

jshafferman
25th March 2014, 11:51
I haven't had a chance to check it yet, but if it is returning false why would that happen?

jshafferman
26th March 2014, 02:21
So it is turning out that my initializeOpenGLFunctions() is returning false. What would cause this to happen? I have already double checked to make sure that my graphics card is capable of supporting OpenGL 2.1 so I know that it isn't hardware related. Any ideas?

ChrisW67
26th March 2014, 05:39
Well, the QOpenGLFunctions example sets a surface type and creates a GL context in the class constructor and makes that current before calling initializeOpenGLFunctions.

jshafferman
26th March 2014, 11:25
Isn't the SetSurfaceType specific to a QWindow not a QWidget? I have seen that example but I didn't think it applied to the QGLWidget.

ChrisW67
27th March 2014, 00:21
This is where my broken link should have been pointing http://qt-project.org/doc/qt-5.0/qtgui/qopenglfunctions.html#details

Yes it is QWindow but there could be a clue in the setup to use the inherited functions. I do not know from first hand use of it.

jshafferman
27th March 2014, 18:50
I investigated trying to use the QWindow version and I don't see how that can be applied to the QGLWidget. The QOpenGLContext takes a QSurfaceType (if I remember right) which I don't know if it makes sense to create a QSurfaceType inside of QGLWidget. Anyhow I don't see how I can piggy back off of that example. Do you have any ideas? According to the documentation for QGLWidget context should be set when calling the paintgl and initializeGL functions.

ChrisW67
28th March 2014, 05:34
OK. This code works for me (Linux 64-bit, Qt 5.2.0, nVidia proprietary drivers):


#include <QtWidgets>
#include <QtOpenGL>
#include <QOpenGLFunctions_2_1>

class GLWidget : public QGLWidget, protected QOpenGLFunctions_2_1
{
Q_OBJECT
public:
GLWidget(QWidget *parent = 0) :
QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::Rgba | QGL::DepthBuffer),parent)
{
}
protected:
void initializeGL()
{
bool ok = initializeOpenGLFunctions();

// Check for minimum resources
GLint intVal = 0;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &intVal);
qDebug() << ok << intVal; // true, 4 on my machine
}
};

int main(int argc, char **argv) {
QApplication app(argc, argv);
GLWidget w;
w.show();
return app.exec();
}
#include "main.moc"


Your initializeOpenGLFunctions() returning false would indicate that there is no OpenGL support on your system.

jshafferman
28th March 2014, 12:55
Well I'll be... It appears that the laptop I am using to work with 'says' it has OpenGL support for 2.1 however if I change the QOpenGLFunction_2_1 to 2_0 or 1_* it appears to start working! So I am glad to learn that if initializeOpenGLFunctions fails it is because that particular version of OpenGL is not supported on your system. I wish the Qt doucmentation just said that :(, however thank you very much for your help! I am sure I will have more questions about Qt and OpenGL as get more involved with the process. Thanks!

ChrisW67
28th March 2014, 21:11
It is not ideal documentation, but see the second last paragraph in the detailed description of QAbstractOpenGLFunctions.