2つのウィンドウを作成し、2つの異なるスレッド(ウィンドウごとに1つ)に再描画すると、すべての描画が最初に作成されたウィンドウに移動するようです。両方のウィンドウに何を表示するかを常に切り替えます。もう1つはほとんど黒いままです。GLUTで複数のウィンドウで同時に描画する
コードは1つのウィンドウでうまくいき、コールバックと呼び出しのレンダリング方法を設定する関数の先頭にcurrentWindow $= Just glWindow
を挿入して更新しました。
問題の原因は何だと思いますか?
EDIT:
コードスケルトン:
module Chart.Window where
import Graphics.UI.GLUT hiding (Window, postRedisplay, <etc>)
import qualified Graphics.UI.GLUT as GLUT
import qualified Graphics.Rendering.OpenGL as GL
data Window = Window
{ glWindow :: GLUT.Window
, viewListRef :: IORef [Line]
}
main = do
forkOS start <params1>
forkOS start <params2>
start <params> = do
win <- new <params>
run win
mainLoop
new :: Strict -> (Int, Int) -> (Int, Int) -> IO Window
new name (posx, posy) (w, h) = do
initGLUT
glWindow <- createWindow name
currentWindow $= Just glWindow
windowSize $= Size (fromIntegral w) (fromIntegral h)
windowPosition $= Position (fromIntegral posx) (fromIntegral posy)
return Window {..}
initGLUT :: IO()
initGLUT = do
beenInit <- get initState
unless beenInit $ void getArgsAndInitialize
initialDisplayMode $= [WithDepthBuffer, DoubleBuffered, RGBAMode]
initialWindowSize $= Size 100 100
initialWindowPosition $= Position 100 100
actionOnWindowClose $= ContinueExectuion
run :: Window -> IO()
run [email protected]{..} = do
-- this will fork (with forkIO) threads
-- which will call "repaint" when chart needs to be updated
initListeners repaint
initCallbacks win
where
repaint :: [Line] -> IO()
repaint viewList = do
writeIORef viewListRef viewList
postRedisplay win
postRedisplay Window{..} = GLUT.postRedisplay $ Just glWindow
initCallbacks [email protected]{..} = do
currentWindow $= Just glWindow
GLUT.displayCallback $= display win
GLUT.idleCallback $= Just (postRedisplay win)
display Window{..} = do
currentWindow $= Just glWindow
Size w h <- get windowSize
viewList <- readIORef viewListRef
drawChart viewList otherOptions
reshapeCallback :: Window -> GLUT.ReshapeCallback
reshapeCallback [email protected]{..} [email protected](Size w h) = do
currentWindow $= Just glWindow
GL.viewport $= (Position 0 0, size)
GL.matrixMode $= GL.Projection
GL.loadIdentity
GL.ortho2D 0 (fromIntegral w) 0 (fromIntegral h)
GL.matrixMode $= GL.Modelview 0
GL.loadIdentity
... -- send command for listener thread to change internal state and postRedisplay
drawChart viewList otherOptions = do
...
-- chart consists of several horizontal panels. Call this for each panel:
glViewport 0 panelYPosition width winHeight
glScissor 0 panelYPosition (fromIntegral width) (fromIntegral panelHeight)
GL.clear [GL.ColorBuffer]
...
-- and then for each line=(Vertex2 v1 v2) from viewList
GL.renderPrimitive GL.Lines $ do
GL.vertex v1
GL.vertex v2
...
私はreshapeCallbackを設定する行をコメント(とウィンドウが最初に再形成される)と、一つのウィンドウのみをグラフ化する起動するとところで、私は正確になりましたマルチウィンドウの起動と同じ効果が得られます。つまり、(唯一の)ウィンドウは、2番目に作成されたかのように、ほとんど空であったということです。
私はコードを見る必要があると思います。 –
GLUTはマルチスレッドをサポートしていますか? – hammar
私も同様の問題があります。私は遺伝的アルゴリズムの反復を計算するスレッドを使って作業し、各繰り返しで "GL.postRedisplay(Just window)"と呼びますが、何も描画しません。 :/ –