2011-09-09 71 views
2

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番目に作成されたかのように、ほとんど空であったということです。

+2

私はコードを見る必要があると思います。 –

+0

GLUTはマルチスレッドをサポートしていますか? – hammar

+0

私も同様の問題があります。私は遺伝的アルゴリズムの反復を計算するスレッドを使って作業し、各繰り返しで "GL.postRedisplay(Just window)"と呼びますが、何も描画しません。 :/ –

答えて

0

私にも同様の問題がありました。私は遺伝的アルゴリズムの反復を計算するスレッドを使って作業し、各繰り返しで "GL.postRedisplay(Just window)"と呼びますが、何も描画しませんでした。

私はアイドル関数から「GL.postRedisplay(ジャスト・ウィンドウ)」を呼び出すことによって、私の問題を解決しました:

GL.idleCallback GL.$= Just (idle window) >> 

idle window = CC.threadDelay (1000*500) >> GL.postRedisplay (Just window) 

は、セットアップにこのようなあなたのアイドルコールバック関数を忘れてはいけません

CCとGLの意味:

import qualified Control.Concurrent as CC 
import qualified Graphics.UI.GLUT as GL 
+1

答えをありがとう、私は3年間待っている:)私は冗談だが、とにかくありがとう – modular

+0

あなたは大歓迎です。 :) –

関連する問題