PDA

View Full Version : Multiple thread using OpenGL



pchopra
12-19-2011, 04:23 AM
Hi friends..
i am new to opengl. i am having problem in using the opengl application in a multi thread programme.
here is sample of my programme:

void * PlotTringle(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread \n");
int argc;
char** argv;
int w=1362;
int h=688;
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (2000, 2000);
glutCreateWindow (argv[0]);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glShadeModel (GL_FLAT);
glClearColor (0.0, 0.0, 0.0, 0.0);
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
gluOrtho2D (0.0, 1.0, 0.0, 1.0*(GLfloat)h/(GLfloat)w);
else
gluOrtho2D (0.0, 1.0*(GLfloat)w/(GLfloat)h, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
drawLeftTriangle();
drawRightTriangle();
glFlush();
glutMainLoop();
return 0;
}

void * GetData(void *threadid)
{
long tid;
tid = (long)threadid;
printf("GetData \n");
/* code to get data */
}

int main(int argc, char** argv)
{

pthread_t thread1, thread2;
int rc1;
long t1;
printf("In main: creating thread %ld\n", t1);
rc1 = pthread_create(&amp;thread1, NULL, PlotTringle, (void *)t1);
if (rc1){
printf("ERROR; return code from pthread_create() is %d\n", rc1);
return(-1);
}

int rc2;
long t2;
printf("In main: creating thread %ld\n", t2);
rc2 = pthread_create(&amp;thread2, NULL, GetData, (void *)t2);
if (rc2)
{
printf("ERROR; return code from pthread_create() is %d\n", rc2);
return(-1);
}
return 0;
}
i this code the PlotTringle thread is not working, some where its hanging.
plz help me.
thanks

GuentherKrass
12-19-2011, 05:00 AM
OpenGL does not support multiple rendering threads. Try to keep all your GL code (context, textures, buffers, and so on) in a single thread and you'll be fine...

Your thread appears to hang since

glutMainLoop() - once called - will never return.

aqnuep
12-19-2011, 06:28 AM
OpenGL *does* support multiple rendering threads but only using different rendering contexts, i.e. you cannot draw to the same framebuffer from multiple threads, but you can fill a renderbuffer, texture or buffer object in one thread/context and use it in the other thread/context with proper synchronization.

But GuentherKrass is right that what you want to achieve won't work.

McLeary
12-19-2011, 08:19 AM
Try the method FloatArray.wrap()

http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/FloatBuffer.html#wrap(float[])

pchopra
12-19-2011, 09:23 PM
Hii...GuentherKrass,
thanks for reply..
My problem is not multi thread rendering. i want to do complete rendering by one single thread. i had put all my GL code in a single thread only(see the code), but still its not working.
I am not able to resolve the problem. plz help me. thanks

aqnuep
12-20-2011, 08:14 AM
This is really how your GetData function looks like? There is nothing done there for sure? I'm suspecting you are trying to call some GL functions from the second thread (which runs GetData) but there you don't have a GL rendering context.

pchopra
12-20-2011, 09:43 AM
Ya my Getdata function is like this only as of now. I am not using any GL function in the GetData function.
I tried this code with single thread of PlotTringle only (without GetData). But still its not working.
PlotTringle is the only function where i am using GL functions. If i am calling PlotTringle function without creating thread, its working. But my requirement is to call it with thread.

Vaaksiainen
12-21-2011, 01:19 AM
Hi,

Just reading this thread I became curious. I have a custom DirectShow renderer that uses OpenGL. The window, and its context are created on the application thread, passed to the filter, which then uses either of two methods for rendering (+ other stuff to load textures of course ):



void ViewportOpenGL::Render(void){
InvalidateRgn(m_hWnd, NULL, FALSE);
}


which obviously just posts WM_PAINT message to the window creator thread (= application thread).

Or a direct method, which works on (one of) streaming thread(s):



void ViewportOpenGL::RenderNow(void){
EnterCriticalSection( &amp;m_critSec );

HDC hDC = GetDC( m_hWnd );
if (wglMakeCurrent( hDC, m_hRC )){
this->_render();
SwapBuffers(hDC);
wglMakeCurrent( NULL, NULL );
}
ReleaseDC( m_hWnd, hDC );
LeaveCriticalSection( &amp;m_critSec );
}


"_render" holds all gl drawing functions. No "SendMessage"s there which might switch the thread.

Both work. My question is, am I using some by-coincidence-working-but-not-supported approach here? Obviously, only for windows.