PDA

View Full Version : opengl and read serial with thread



ncn213
11-22-2008, 11:49 PM
Hi,all
I'm using glut and read from serial port(RS232) with a thread, when I receive a special frame redraw window with glutPostRedisplay function.
My code work correctly in windows but in linux (fedora core 8) doesn't work correctly.
My code is similar this :
---->main
glutinitialize.
create serial read thread.
glutMainLoop();
---->serial read thread
while(1)
{
readSerial();**1**
if(DataChanged())
glutPostRedisplay();
}

This code work in windows, but in linux redisplay doesn't happen until I press a key or move or click the mouse.

when I replace **1** with sleep(1) and set random data it's similar above but if I remove **1** and set random data the display redraw about evry 300 mili second.

If you know the problem or mistake please help me.
thanks
ncn213

mfort
11-23-2008, 04:42 AM
GLUT is not multi-threading ready. You can only call the API from one thread. Everything else is undefined.

Check the serial port status in glutTimerFunc callback and call glutPostRedisplay when you have new data from there.

This should be enough for your prototype app.

ncn213
11-23-2008, 11:29 PM
Hi, mfort
If GLUT isn't multi threading ready, why is it working in windows?

Are there another way except timer?

mfort
11-24-2008, 01:18 AM
If GLUT isn't multi threading ready, why is it working in windows?

You are lucky for now. But do not bet on it. It is not supported.
If you do it, the app can crash even on Windows. The GLUT code is not thread safe.



Are there another way except timer?

GLUT does not have any functionality to wakeup the main GUI thread. Probably the only way would be to send message (win32) / x-event (linux) to repaint the window.

Or maybe Idle callback. But this could be even worse. (higher CPU load).

ncn213
11-24-2008, 04:22 AM
Hi,mfort
Thanks for your help, but I have another questions:

I have a window with more 10 shape on it, in every serial read I read value for 1 shape, and redraw the window to show new value of shape, in this case which way is better:

1- I redisplay hole of window.
2- Or create 10 subwindow and in any value receive I redisplay a subwindow.

mfort
11-24-2008, 05:14 AM
It depends on complexity of the objects. I'd redisplay the whole window.
I do not know what the subwindow is. Usually one OpenGL context is faster then using and switching more contexts.
Updating only part of the window makes troubles in SLI.

thibault
11-25-2008, 01:54 PM
I'm not sure about creating a new post, because my issue is kind of related to this topic.
My C main process spawns a GLUT window, but this C process retrieves textures that are updated 30 times a second, that I would like to display on the shapes inside the GLUT window. Obvioulsy the glutMainLoop() stops my C process, so, instead of reading data from the serial port, how is it possible to read from another c function that should be executed "in parallel" with all the GLUT process ?

Tell me if this post is misplaced...

Thanks!

ZbuffeR
11-25-2008, 04:12 PM
With glut, use a glutTimerFunc( 30 * 1000, retrieveTextures,0);

with properly written retrieveTextures(int value); containing the code from your C process to update the textures.

http://www.opengl.org/resources/libraries/glut/spec3/node64.html
http://www.opengl.org/resources/faq/technical/glut.htm#glot0027

thibault
11-25-2008, 10:08 PM
Ok, so if I am right, this means that the glut main loop should spawn the c children processes, and not the contrary (which is the way it is currently working).
I guess it can be possible, but that way I should reorganize the whole project architecture.
So have I understood well what you meant?

ZbuffeR
11-26-2008, 02:51 AM
Yes.

GLUT is quite limited for this, so if you have other uses for more fine grained multitasking within your GL program, I suggest looking for GLFW, cross-platform toolkit to create fullscreen/windowed rendering, event driven or not, with threads, fancy inputs, etc. Very simple to use, yet powerful. However not built-in menus like glut.

thibault
11-26-2008, 02:38 PM
I've been reading the GLFW user guide, it seems indeed powerful and easy to use. Before I try to go any further, since yo seems aware, in my case (triggering the GLFW loop from my C process), can I still have my C process running in parallel (which updates the textures notably)?

ZbuffeR
11-26-2008, 03:25 PM
One thing to note is that the OpenGL context can only be current to one thread at a time.
Rough pseudocode for your case :


////// opengl rendering thread
// init gl stuff
glfwSwapInterval(1); // to calm down the rendering loop
// etc
while(1) {
drawstuff();
glfwSwapBuffers();
//aquire 'texture' mutex
glfwLockMutex(newtexturelock);
if(newtextureavailable) {
glTexSubImage(newtexture);
}
//release 'texture' mutex
glfwUnlockMutex(newtexturelock);
}




////// serial read thread
while(1)
{
readSerial();**1**
if(DataChanged()) {
//acquire 'texture' mutex
glfwLockMutex(newtexturelock);
newtextureavailable=true;
copyData(data,newtexture);
//release 'texture' mutex
glfwUnlockMutex(newtexturelock);
}
}


If you need more parallelism of the texture upload, see the PBO (pixel buffer object) extension.
A tutorial here : http://www.songho.ca/opengl/gl_pbo.html

thibault
11-26-2008, 04:42 PM
Okay, to make sure that I got it:
I include my whole main process, called once, in an OpenGL context. I modify this c main process so that it checks/outputs some way the textures data, say 30 times a second (this ckecking/returning operation would be the readSerial() you mentioned above).
And then follows the opengl rendering loop, which reads from the readSerial() (that actually reads, and writes the data to the shared object "newtexture")thread.
Am I still on the right thinking way?

As for the pixel buffer object, it is very possible that I use this extension, since I "constantly" need to read/write from the c classes/subclasses to my opengl interface.

Cheers,

Thibault.

thibault
11-27-2008, 05:59 PM
Just following my post to tell that I got it working! Temporarily, what I did is :
from my main process, create a thread that contains my glut main loop, so both can run at the same time. But I am going to switch to glfw... Thanks for your help !