iDISS 2 + WebGL、一部残高13


私の最後のdevログからの進捗状況はかなりイライラしています.IDRISとWebGLの間の結婚についてのいくつかの厄介な障害物があります
本当に乗り越えられる.
最初に、iDrisの限られたFCIとの私の決して終わらない戦いが、あります.私は私の最初のdevログエントリに戻ってそれについて不平を言いました、そして、それはまだ私を悩まします.要するに、サポートされているタイプは限られていますが、まだ偏っていて、FFIの線形値を扱うことは不必要に複雑です.しかし、私は少しだけ物事を改善するために管理しています.
むしろAnyPtr すべてのffiで、隠しコンストラクタを持つ抽象データ型を使用するAnyPtr :
export
WebGLRenderingContext : Type
WebGLRenderingContext = AnyPtr

export
WebGLProgram : Type
WebGLProgram = AnyPtr

export
%foreign "browser:lambda: (rtype, gl, cbk) => cbk(gl.createProgram())(gl)"
prim__createProgram : (1 _ : WebGLRenderingContext) -> (1 _ : (1 _ : WebGLProgram) -> (1 _ : WebGLRenderingContext) -> rtype) -> rtype
すべてのデータ型がexport , ないpublic export , 他のモジュールは知らないWebGLProgram = AnyPtr , ジャストザットサムWebGLProgram が存在し、prim__createProgram . これはまだ抽象的なデータ型ですが、もう少し効率的なものですnewtype ).
残念ながら、私はこのトリックを実際にファントム型と組み合わせることはできません.例えば、宣言したい場合は
export
WebGLProgram : ProgramStatus -> Type
WebGLProgram status = AnyPtr
の値を指定しなければならないstatus 至る所に.何が原因かわからない.一方で、以下のようになります.
export
data WebGLProgram : ProgramStatus -> Type where
  MkWebGLProgram : AnyPtr -> WebGLProgram status
それで、私は結局少し余分なデータ建設者を使用しています.少なくとも、これはおそらく私が交換可能な高速で安全なモジュールを持つことを可能にするでしょう.
まだFFIの主題で、私は部分的に私が持っていた問題を解決しましたglenum s.
WebGL/OpenGL仕様ではglenum sはちょうどint s、特定の名前が特定の値に結び付けられてWebGL constants on MDN ). この問題に対処できるいくつかの方法があります.
抽象データを他の型と同様に使用します.
-- shaders
export
ShaderType : Type
ShaderType = AnyPtr

export
%foreign "browser:lambda: () => 0x8B30"
GL_FRAGMENT_SHADER : ShaderType
しかし、私がこれまでのように、グレンムにマッチする必要があるならば、これは壊れますgetProgramParameterもう一つの解決策はInt s
export
ShaderType : Type
ShaderType = Int

export
GL_FRAGMENT_SHADER : ShaderType
GL_FRAGMENT_SHADER = 0x8B30
これは私が現在持っているものですが、もし私がケースマッチをしたいなら、私は値を作る必要がありますpublic export , これは抽象データ型を通して型安全性を中断します.
洗練されたタイプは、ここで全く素晴らしいです.しましょう.
public export
GLEnum = Int

public export
GL_FRAGMENT_SHADER : GLEnum
GL_FRAGMENT_SHADER = 0x8B30


export
%foreign "browser:lambda: (aType, gl, type, callback) => callback(gl.createShader(Number(type)))(gl)"
prim__createShader : IsElem shaderType [GL_VERTEX_SHADER, GL_FRAGMENT_SHADER] => (1 _ : WebGLRenderingContext) -> (shaderType : GLEnum) -> (1 _ : (1 _ : WebGLShader) -> (1 _ : WebGLRenderingContext) -> a) -> a
And while you can express refinements in a dependently typed language, the result is verbose , そして、エンドユーザーに証明を渡す必要があります.私は、それが許容できるとわかりません.私はライブラリの内部の作業を複雑にするようになるが、APIはきれいでなければならない.それはこの実験のポイントです.例えば、上記のような場合、エンドユーザは以下のように書く必要があります.
createShader (There Here) gl GL_FRAGMENT_SHADER
The There Here 証明されてグラント値のリストと一緒に長くなる証明の一部.
私が考えることができる最後のオプションは、私がおそらく行くだろう1つは、基本に戻って、パフォーマンスヒットを取ることです:和タイプを使用して、AnyPtrまたはIntへの変換機能を作成してください.
data ShaderType
  = GL_VERTEX_SHADER
  | GL_FRAGMENT_SHADER

toShaderType : Int -> Maybe ShaderType
toShaderType i = case i of
  0x8B30 => Just GL_FRAGMENT_SHADER
  0x8B31 => Just GL_VERTEX_SHADER
  _ => Nothing
FFIの世界から踏み出すと、線形型に関するWebGL APIのデザインにおいて、興味深いものであり、煩わしい問題があります.
例えば、これは関数bindVertexArray . 一般的にWebGLVertexArrayObject , しかし、“default”頂点配列オブジェクトを結びつける値としてNULLを受け入れるでしょう.NULLを渡すことさえ勧められますbindVertexArray , それがデフォルトのものが束縛されると仮定するならば、特定のVAOを上書きすることからスコープから外れているコードを防ぎます.今のところ、その勧告がタイプセーフティであるべきもののための弱い解決であるならば、私は質問を無視します.
ポイント、通過null が有効であるが、WebGLVertexArrayObjectnull また、線形であるbindVertexArray それは私たちに返す!私たちはそれからパスしなければならないだろうnull to deleteVertexArray . 機能を作成することによって他の何もないならば、私はこれが解決可能であるとかなり確信していますunbindVertexArray , しかし、それは面白いデザイン問題です.私は、彼らがお互いに影響を及ぼすかもしれないと思うので、今、私はこれについて調べる前に、私がVAOSに持っている他のタイプ安全性懸念に取り組むことを望みます.
より詳細には、VAOSによる他のタイプ安全性問題は、それがプログラムにマッチすることを確実とします.頂点属性で、私はちょうど特定のプログラムから得られる属性を必要として、プログラムIDを幻影タイプに入れます.プログラマが属性の場所を手動で指定することができ、プログラムが同じ場所を使用していることを保証し、静的な位置に属性をバインドすることができたので、これは完全に正確な解決策ではありませんでした.VAOSで、VAOが必ずしもどんな特定のプログラムにもマッチしないので、この問題はより大きくなります.ないgetAttribLocation VAOのバリアント、それだけですcreateVertexArray . 私はVAOに特定のプログラムに合致するために人工的な制限を加えることができました、しかし、私はそれが欲しくありません、それはプログラムがあるように多くのvaosとして作成することを必要とします.
代わりに、おそらくプログラムIDを使用して、プログラムの種類にすべての属性を置くように切り替えます.これは最初はもっと詳細に見えます.
Program Linked pid

Program Linked [attributeType0, attributeType1, attributeType2...] [uniformType0, uniformType1, uniformType2]
しかし、私はこれらのプログラムタイプがユーザー最終コードで制限されると思っています.
BlinnPhongProgram : Type
BlinnPhongProgram = Program Linked [...] [...]
このアプローチの欠点としては、getAttribLocation . どうやってenableVertexAttribArray and vertexAttribPointer コンパイル時に渡された場所変数がプログラムに有効であることを知っていますか?それは、VAOSを使うことがWebGLプログラムを書く好ましい方法であると言いました.
すべてのすべての私は私の前に多くの仕事を持って、それは簡単です.