c++ - OpenGL Multithreaded sample in Ubuntu virtualbox -


i facing weird problem opengl sample on vbox 3d acceleration enabled

  • guest: ubuntu 12.04
  • host: windows 7, nvidia graphics
  • vbox version 4.3.6 guest additions installed

this application runs on vbox when 3d acceleration disabled , have checked on stand alone linux pc well. when same run 3d acceleration enabled, not able gl function pointers giving errors - function no-op


the app simple, main thread creates 2 threads.

  • main thread - create thread 1, create thread 2
  • thread 1 - create x-window rendering
  • thread 2 - create render thread (draw opengl quad on x-window).

here code sample app.

#include<stdio.h> #include<stdlib.h> #include<x11/x.h> #include<x11/xlib.h> #include<gl/gl.h> #include<gl/glx.h> //#include<gl/glu.h> #include <dlfcn.h> /*dlopen*/ #include <pthread.h> #include <unistd.h> /*sleep*/  display                 *dpy; display                 *dpy2; window                  root; glint                   att[] = { glx_rgba, glx_depth_size, 24, glx_doublebuffer, none }; xvisualinfo             *vi; xvisualinfo             *vi2; colormap                cmap; xsetwindowattributes    swa; window                  win; glxcontext              glc; xwindowattributes       gwa; xevent                  xev; bool            render;   void drawaquad()  {     glclearcolor(1.0, 1.0, 1.0, 1.0);     glclear(gl_color_buffer_bit | gl_depth_buffer_bit);      glmatrixmode(gl_projection);     glloadidentity();     glortho(-1., 1., -1., 1., 1., 20.);      glmatrixmode(gl_modelview);     glloadidentity();     //glulookat(0., 0., 10., 0., 0., 0., 0., 1., 0.);     gltranslatef(0.0, 0.0, -10.0);      glbegin(gl_quads);      glcolor3f(1., 0., 0.); glvertex3f(-.75, -.75, 0.);      glcolor3f(0., 1., 0.); glvertex3f( .75, -.75, 0.);      glcolor3f(0., 0., 1.); glvertex3f( .75,  .75, 0.);      glcolor3f(1., 1., 0.); glvertex3f(-.75,  .75, 0.);     glend(); }  void *createmainwindow(void* threadid) {     dpy = xopendisplay(null);     if(dpy == null)      {         printf("\n\twindow thread: cannot connect x server\n\n");         exit(0);     }      root = defaultrootwindow(dpy);     printf("\n *** createwindow: xopendisplay on *** \n");      vi = (xvisualinfo*)glxchoosevisual(dpy, 0, att);     if(vi == null)      {         printf("\n\twindow thread: no appropriate visual found\n\n");         exit(0);     }      else      {         printf("\n\twindow thread: visual %p selected\n", (void *)vi->visualid);     }      cmap = xcreatecolormap(dpy, root, vi->visual, allocnone);     swa.colormap = cmap;     swa.event_mask = exposuremask | keypressmask;      win = xcreatewindow(dpy, root, 0, 0, 600, 600, 0, vi->depth, inputoutput, vi->visual, cwcolormap | cweventmask, &swa);     xmapwindow(dpy, win);     xstorename(dpy, win, "very simple application");      while(1)      {         xnextevent(dpy, &xev);         printf("\nxevent\n");         if(xev.type == expose)         {             render = true;         }         else if(xev.type == keypress)         {             xdestroywindow(dpy, win);             xclosedisplay(dpy);             render = false;             break;             //exit(0);         }     } }  void *renderthread(void* threadid) {     vi2 = (xvisualinfo*)glxchoosevisual(dpy2, 0, att);     printf("\n\trenderthread : visual %p selected\n", (void *)vi2->visualid);      glc = (glxcontext)glxcreatecontext(dpy2, vi2, null, gl_true);     glxmakecurrent(dpy2, win, glc);      glenable(gl_depth_test);       while(render)      {         //xgetwindowattributes(dpy, win, &gwa);         glviewport(0, 0, 600, 600);         drawaquad();          glxswapbuffers(dpy2, win);     } /* closes while(render) */      glxmakecurrent(dpy2, none, null);     glxdestroycontext(dpy2, glc);     xclosedisplay(dpy2); }  int main(int argc, char *argv[])  {     render = true;     pthread_t thread1;     pthread_t thread2;     char *temp1;     char *temp2;      //for async issue     if(!xinitthreads())     {         fprintf(stderr, "xinitthread failed\n");         return 0;     }      //create main window     int err = pthread_create(&thread1, null, createmainwindow, (void*)temp1);     if (err != 0)         printf("\n error::can't create thread1 :[%d]", err);     else         printf("\n thread1 created successfully\n");      sleep(1); // wait thread 1 complete      dpy2 = xopendisplay(null);     if(dpy2 == null)      {         printf("\n\tmain : cannot connect x server\n\n");         exit(0);     }      //create render thread     err = pthread_create(&thread2, null, renderthread, (void*)temp2);     if (err != 0)         printf("\n error::can't create thread2 :[%d]", err);     else         printf("\n thread2 created successfully\n");      pthread_join( thread1, null);     pthread_join( thread2, null);  } /* } closes int main(int argc, char *argv[]) { */ 

and compile code -

g++ -o quad quad.cpp -lgl -lx11 -lxmu -lxi -lpthread -lm 

help me understand issue lies

whatever thick you're doing, stop!

multithreading + x11 + opengl tricky thing right. , it's impossible correct if you're using xlib. xlib never thread safe.

anyway, first , foremost program lacks call xinitthreads make @ least safe use in multithreaded programs. it's still unsafe spread out xlib calls on multiple threads. important: whatever do, keep xlib calls 1 thread only.

opengl not tricky. because opengl needs context created glx, in turn builds on xlib. usual approach create opengl context in xlib thread, later on make current in renderer thread. advised if got indirect rendering context opengl calls go through x11 , may mean through xlib , things going unstable again.

because of mess simplest solution is: keep graphics , windowing related 1 thread. there's nothing gained if put opengl operations thread separate rest of gui operations (technically opengl gui operations well). if want use multithreading, use if thing make sense executed concurrently, audio, physics simulation , such.


Comments

Popular posts from this blog

python - Subclassed QStyledItemDelegate ignores Stylesheet -

java - HttpClient 3.1 Connection pooling vs HttpClient 4.3.2 -

SQL: Divide the sum of values in one table with the count of rows in another -