在Haskell中,如何为此函数提供正确的数字?

时间:2016-12-20 23:16:14

标签: haskell

我是Haskell的初学者,试用GPipe。

以下代码运行良好:

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?

2 个答案:

答案 0 :(得分:5)

VFloatS V Float的同义词。 Several lines above the VFloat entry GPipe 文档解释了:

  

类型S x a是一个opaque类型,表示着色器阶段a中类型x的值,例如S F Float表示片段流中的浮点值

它还通过下面的实例列表告诉我们,NumFractionalS whatever Float的实例。 Num实例解释了为什么您可以将文字1作为S V Float参数传递。这也意味着您可以使用fromIntegral创建S V Float值,因此以下内容应该可以解决问题:

fromIntegral windowWidth / fromIntegral windowHeight

(我使用过它而不仅仅是fromIntegral (windowWidth / windowHeight),因为正如crockeea指出的那样,(/)Int一起使用Int,因为Fractional没有{ {1}}实例。)

答案 1 :(得分:2)

fromIntegral确实会将积分转换为S V Float,但会在编辑着色器时执行此操作。如果您希望它能够在渲染每个帧时动态使用当前窗口宽度和高度,则需要在着色器环境中通过统一传递它(然后将Float转换为{{1 s和S V FloatInt s)。

然后,您将使用S V Int将窗口宽度转换为Float,然后再将其发送到fromIntegral - 值的GPU世界中,或者使用S toFloat 1}}(不是S V Int,因此没有Integral

您可以在part 3 of the tutorial

中详细了解GPipe中的制服