PDA

View Full Version : Opengl3.x and Qt under Linux



icepic1984
03-14-2010, 05:34 AM
Hi!

I currently try too create a Opengl3.x compatible QWidget under Linux. I use some source from this post:

http://www.opengl.org/discussion_boards
/ubbthreads.php?ubb=showflat&Number=262519

The context opens without an error, but the window is not created on my MainWindow. Instead there is a new window next to my gui. Any idea how i can embed the context on my gui-window? Have anybody a working example?

Code looks like that:

main.cpp:



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

MainWindow mainwindow;
mainwindow.show();
return app.exec();
}


mainwindow.cpp



MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
connect(ui.mButtonTest,SIGNAL(clicked()),this,SLOT (printHello()));
}



The newly created QWidget with the gl3-context is set on the mainwindow with the qtdesigner and looks like that



GL3Widget::GL3Widget(QWidget *parent):
QWidget(parent)
{


initWindow();

}


Init Framebuffer:



void GL3Widget::initWindow()
{
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_NoSystemBackground);
setAutoFillBackground(true);

static int visual_attribs[] = {
GLX_X_RENDERABLE , True,
GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
GLX_RENDER_TYPE , GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
GLX_RED_SIZE , 8,
GLX_GREEN_SIZE , 8,
GLX_BLUE_SIZE , 8,
GLX_ALPHA_SIZE , 8,
GLX_DEPTH_SIZE , 24,
GLX_STENCIL_SIZE , 8,
GLX_DOUBLEBUFFER , True,
//GLX_SAMPLE_BUFFERS , 1,
//GLX_SAMPLES , 4,
None
};

const QX11Info &xinfo = x11Info();
Display *display = xinfo.display();

XVisualInfo *vi = NULL;
Window window = 0;
int fbcount = 0;

GLXFBConfig *fbc = glXChooseFBConfig( display, DefaultScreen( display ),
visual_attribs, &fbcount );
if ( !fbc ) {
printf( "Failed to retrieve a framebuffer config\n" );
exit(1);
}

mFBConfig = fbc[0];
XFree(fbc);

printf( "Found %d matching FB configs.\n", fbcount );


vi = glXGetVisualFromFBConfig( display, mFBConfig );
XSetWindowAttributes swa;
swa.colormap = XCreateColormap( display, RootWindow( display, vi->screen )
swa.background_pixmap = None ;
swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask;


printf( "Creating window\n" );
Window win = XCreateWindow( display, RootWindow( display, vi->screen ),
0, 0, 100, 100, 0, vi->depth, InputOutput,
vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &swa );
if ( !win ) {
printf( "Failed to create window.\n" );
exit(1);
}

std::cout << "QT" << std::endl;
create(win, true, true);

mGL3Context = 0;
initContext();
}


Create context:


void GL3Widget::initContext()
{
Display *display;
{
const QX11Info &amp;xinfo = x11Info();
display = xinfo.display();
}

XVisualInfo *vi = glXGetVisualFromFBConfig(display, mFBConfig);
GLXContext tempContext = glXCreateContext(display, vi, 0, True);

glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
glXGetProcAddress( (const GLubyte *) "glXCreateContextAttribsARB" );

glXMakeCurrent(display, 0, 0);
glXDestroyContext(display, tempContext);

int attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, 3/*requestedGLVersion.Major*/,
GLX_CONTEXT_MINOR_VERSION_ARB, 0/*requestedGLVersion.Minor*/,
None
};

mGL3Context = glXCreateContextAttribsARB(display, mFBConfig, 0, True, attribs);
if (mGL3Context == NULL) {
std::cout << "Context failed" << std::endl;
exit(1);
}

if (glXIsDirect(display, mGL3Context) != True) {
std::cout << "The gl context is not direct." << std::endl;
exit(1);
}

}




Thx for help!

Rosario Leonardi
03-18-2010, 04:17 PM
If you don't need the menu just do that:



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

GL3Widget mainwindow;
mainwindow.show();
return app.exec();
}

When you create a widget without a parent it become an indipendent window

Otherwise you can do


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), glContext(parent)
{
ui.setupUi(this);
connect(ui.mButtonTest,SIGNAL(clicked()),this,SLOT (printHello()));
}

icepic1984
03-20-2010, 09:49 AM
I know, but the problem is, when i choose your last method, 2 independent windows are created. But context-widget should placed on my MainWindow.

Rosario Leonardi
03-20-2010, 03:31 PM
ehm.. sorry, I didn't tested the second solution, I always use the first. :D

I imagine your MainWindow should have a private attribute like this


protected:
GL3Widget glWig_;

As I told you before you need to pass a correct parent to your widget.

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), glWig_(this)
{
ui.setupUi(this);
connect(ui.mButtonTest,SIGNAL(clicked()),this,SLOT (printHello()));
}

note the this pointer. In this case you have to manually resize the context every time the windows is resized.

Another (better solution) is to define a pointer to your widget and in the windows constructor call setCentralWidget like this.


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
glWig_ = new Gl3Widget();
this->setCentralWidget(glWig_);
//....
}

You can also use layout controller to use your openGL widget with other type of widget. Check the Qt example. :)

BTW: Did you try to redefine only the QGLContext class and use QGLWidget? I tried but I can't get the windows pointer and the frame buffer descriptor.. are both private. :(

icepic1984
03-21-2010, 08:15 AM
Ok i will test it. But as far as i understand the header files generated by the QtDesigner, your last method is automatically generated. I created the gui with the designer and placed my GL3Widget on it.



BTW: Did you try to redefine only the QGLContext class and use QGLWidget? I tried but I can't get the windows pointer and the frame buffer descriptor.. are both private.


I created the context on my own in a QWidget-Class. I still wonder, why there is no working solution for this problem around the inet. Nobody working with opengl 3.x and Qt here?

Rosario Leonardi
03-21-2010, 05:42 PM
I'm reading now the documentation of the new QT4.7 and it have openGl 3.2 support. Qt 4.6 support "only" ogl 3.0

http://doc.qt.nokia.com/4.7-snapshot/qglformat.html#OpenGLVersionFlag-enum

Also add the QGlBuffer to wrap VBO.
----
QTDesigner can create only standard widget, and is excellent to create dialog. To create custom object I prefer to write the code.