Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Solved] Multiple windows and pthreads  (Read 4882 times)

0 Members and 1 Guest are viewing this topic.

tmac

  • Guest
[Solved] Multiple windows and pthreads
« on: July 08, 2008, 11:38:01 pm »
Hello

This is related to my earlier post about OpenMP and SFML. I have tried to write a program which creates two windows, and starts two threads, one for each of the windows. Each thread then does some OpenGL rendering (a simple triangle) and displays it in its own window.
I have tried to be careful by using mutexes around the rendering and displaying commands.
The problem is that the result is wrong in one of the windows. In the first window, the triangle is placed near the middle as it should be, but in the other window the triangle is placed in the top right corner.
If I remove the OpenGL commands in main(), the results are both correct, but then I have no choices for the perspective and camera position.

Code: [Select]

#include <SFML/Window.hpp>

sf::Mutex globalMutex;

void* threadFunc(void* a)
{
sf::Window* Win = (sf::Window*)(a);

while(true) {
globalMutex.Lock();
Win->SetActive();
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_LOOP);
glVertex3f(0.0,0.0,0.0); glVertex3f(0.5,0.0,0.0); glVertex3f(0.5,0.5,0.0);
glEnd();
Win->Display();
globalMutex.Unlock();
sf::Sleep(1);
}

return(0);
}

int main()
{
sf::Window Win1(sf::VideoMode(200, 200, 32), "Window 1");
sf::Window Win2(sf::VideoMode(200, 200, 32), "Window 2");

glEnable(GL_DEPTH_TEST);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, 300, 300);
gluPerspective(45, 1, 1, 1000);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

pthread_t thread1, thread2;

pthread_create(&thread1, 0, threadFunc, (void*)(&Win1));
pthread_create(&thread2, 0, threadFunc, (void*)(&Win2));

pthread_join(thread1, 0); pthread_join(thread2, 0);

return(0);
}

Xylankant

  • Newbie
  • *
  • Posts: 32
    • View Profile
    • http://xylankant.xy.funpic.de
[Solved] Multiple windows and pthreads
« Reply #1 on: July 09, 2008, 12:15:16 am »
hi tmac,
have you tried using RenderWindow nad to protect OpenGL Settings for your windows by calling once sf::RenderWindow::PreserveOpenGLStats(true); ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
[Solved] Multiple windows and pthreads
« Reply #2 on: July 09, 2008, 02:52:58 am »
First : why don't you use sf::Thread ?

Second : you must unbind an OpenGL context from the thread is bound to, before binding it to another thread. In other words, use Win1/2.SetActive(false) just before entering the threads.
Laurent Gomila - SFML developer

tmac

  • Guest
[Solved] Multiple windows and pthreads
« Reply #3 on: July 09, 2008, 12:39:39 pm »
I think I have gotten this example to work now! I had forgotten to change a viewport parameter after I changed it another place...

Btw, I have used pthreads since I need to be able to easily remove all SFML dependence when I will run it on a computer without visualization and without SFML installed. Now I will try to convert this pthread program to OpenMP, and see if this works the way I need it in my simulation program.

Here is a code that seems to work:

Code: [Select]

#include <SFML/Window.hpp>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* threadFunc(void* a)
{
sf::Window* Win = (sf::Window*)(a);

pthread_mutex_lock(&mutex);
Win->SetActive(true);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, 200, 200);
gluPerspective(45, 1, 1, 1000);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
Win->SetActive(false);
pthread_mutex_unlock(&mutex);

while(true) {
pthread_mutex_lock(&mutex);
Win->SetActive(true);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_LOOP);
glVertex3f(0.0,0.0,0.0); glVertex3f(0.5,0.0,0.0); glVertex3f(0.5,0.5,0.0);
glEnd();
Win->Display();
Win->SetActive(false);
pthread_mutex_unlock(&mutex);
sf::Sleep(1);
}

return(0);
}

int main()
{
sf::Window Win1(sf::VideoMode(200, 200, 32), "Window 1");
sf::Window Win2(sf::VideoMode(200, 200, 32), "Window 2");
Win1.SetActive(false);
Win2.SetActive(false);

pthread_t thread1, thread2;

pthread_create(&thread1, 0, threadFunc, (void*)(&Win1));
pthread_create(&thread2, 0, threadFunc, (void*)(&Win2));

pthread_join(thread1, 0); pthread_join(thread2, 0);

return(0);
}