2016-12-20 22 views
1

我是Haskell的初學者,嘗試了GPipe。在Haskell中,如何爲這個函數提供正確的編號?

下面的代碼罰款運行:

shader <- compileShader $ do 
    primitiveStream <- toPrimitiveStream id 
    let transPrims = fmap 
     (\(pos,col) -> (perspective (pi/3) 1 1 100 !* pos, col)) 
     primitiveStream 
    fragmentStream <- rasterize 
     (const (FrontAndBack, ViewPort (V2 0 0) (V2 500 500), DepthRange 0 1)) 
     transPrims 
    drawContextColor (const (ContextColorOption NoBlending (V3 True True True))) 
        fragmentStream 

不過,我有2個變量WINDOWWIDTH和WINDOWHEIGHT(包括類型爲int),當我嘗試這樣做:

shader <- compileShader $ do 
    primitiveStream <- toPrimitiveStream id 
    let transPrims = fmap 
     (\(pos,col) 
     -> (perspective (pi/3) (windowWidth/windowHeight) 1 100 !* pos, col)) 
     primitiveStream 
    fragmentStream <- rasterize 
     (const (FrontAndBack, ViewPort (V2 0 0) (V2 500 500), DepthRange 0 1)) 
     transPrims 
    drawContextColor (const (ContextColorOption NoBlending (V3 True True True))) 
        fragmentStream 

我得到編譯錯誤:

Couldn't match type ‘S V Float’ with ‘Int’ 
     Expected type: Shader 
         os 
         (ContextFormat RGBFloat()) 
         (PrimitiveArray Triangles (B4 Float, B3 Float)) 

         (PrimitiveStream Triangles (V4 Int, V3 VFloat)) 
     Actual type: Shader 
         os 
         (ContextFormat RGBFloat()) 
         (PrimitiveArray Triangles (B4 Float, B3 Float)) 
         (PrimitiveStream Triangles (VertexFormat (B4 Float, B3 Float))) 

想到它可能想要一個浮點數,我做(toFloat $ windowWidth/windowHeight)

Couldn't match type ‘Float’ with ‘S V Float’ 
     Expected type: VFloat 

如何獲得VFloat?

+1

'(WINDOWWIDTH ::智力)/(WINDOWHEIGHT ::智力)'是一種錯誤。這不是報告的錯誤,但它是一個錯誤。 – crockeea

回答

5

VFloatS V Float的同義詞。 Several lines above the VFloat entry,該GPipe文件解釋說:

The type S x a is an opaque type that represents a value of type a in a shader stage x , eg S F Float means a floating point value in a fragment stream.

這也告訴我們,通過略低於實例的列表,有兩個NumFractionalS whatever Float的實例。 Num實例解釋了爲什麼您可以傳遞1作爲S V Float參數。這也意味着你可以使用fromIntegral創建S V Float值,所以下面應該做的伎倆:

fromIntegral windowWidth/fromIntegral windowHeight 

(我已經使用了而不是簡單地fromIntegral (windowWidth/windowHeight)因爲,crockeea指出,你不能使用(/)Int S,因爲Int沒有Fractional實例。)

+0

Aaand ....三角形不再被拉伸!但那麼浮動呢?該文件說「轉換爲浮點數。」。這與「S V Float」有什麼不同? – user1582024

+0

@ user1582024 [1/2]'toFloat :: Convert a => a - > ConvertFloat a'是'Convert'類的一個方法,而'ConvertFloat'是該類的關聯類型族,這意味着每個帶有'Convert'實例的'a'類型有一個相應的'ConvertFloat a'類型。查看這些實例,可以看出'toFloat'可用於將例如'Int'轉換爲'Float'(在這種情況下,它相當於'fromIntegral')或'SV Int'轉換爲'SV Float '。 – duplode

+0

@ user1582024 [2/2]我不完全確定何時需要使用'toFloat'而不是'fromIntegral',但如果沒有其他任何事情,它會使GPipe的DSL內的轉換看起來更加一致。 *使用[本教程](http://tobbebex.blogspot.com.br/2015/10/gpu-programming-in-haskell-using-gpipe.html)的提升的S值*部分,我發現通過GitHub包的自述文件,還有更多關於'Convert'和類似類的動機的文字。 – duplode

2

fromIntegral的確會轉化不可或缺的S V Float,但將在着色器編譯的時間做到這一點。如果您希望它能夠在渲染每個幀時動態使用當前窗口寬度和高度,則需要在着色器環境中通過統一傳遞它(然後將其轉換爲Float s到S V Float s和Int s到S V Int S)。

那麼你要麼窗口寬度轉換爲使用fromIntegralFloat發送它變成S - 值的GPU世人面前,或在S V Int使用toFloat(這是不是一個Integral,因此沒有fromIntegral

用`Int`你不能使用`(/)`:

你可以閱讀更多關於GPipe制服在part 3 of the tutorial

相關問題