.. :tocdepth:2 ============================ MoNo.OpenGL.MGL ============================ OpenGL のAPIを .NET (C#/F#) から利用しやすくするための薄いラッパーです。 OpenGL の関数はC言語形式なので、そのままでは .NET から利用しづらいと感じることがあります。より .NET から利用しやすくするため下記の点を改善するラッパーとして ``MGL`` を用意しました。 * MoNo.RAIL のデータ型の利用 ``Vector3d`` や ``HmMatrix3d`` といった MoNo.RAIL で用意されているプリミティブなデータ型に対応させました。これにより、例えば OpenGL では3次元ベクトルを長さ3の ``double`` / ``float`` 配列として入出力する仕様だが、ラッパーにより ``Vector3d`` などのデータ型で入出力できるようになりました。 * プロパティによる状態の get/set OpenGL では状態の取得と設定が別々の関数になっていますが(例えば ``glIsEnabled()`` と ``glEnable(), glDisable()`` など)、.NET では get と set はひとつのプロパティにまとめたほうが自然であり使いやすくなります。例えば ``GL_DEPTH_TEST`` の有効/無効状態を ``MGL.DepthTestEnabled`` というプロパティでラップすることによって使いやすくしました。 * 頂点配列の描画の簡略化 頂点配列に関する OpenGL のAPIは非常に柔軟性が高く設計されていますが、その分だけ利用にあたっては定型的なコードが増えてしまいがちで気軽に利用することが出来ません。MGL では例えば ``PointNormal3f`` などといった MoNo.RAIL で用意されているデータ型の配列を受け取るラッパー関数群 ``MGL.DrawArrays()`` を備えており、簡便に頂点配列を利用することができます。 * その他 テクスチャ、シェーダー、FBO、VBO といった機能もラップすることでより簡便に利用できるようになっています。 .. contents:: プロパティ ================================================================== .. table:: 有効/無効状態の取得と設定 ========================= ====================== MGL Property OpenGL constant ========================= ====================== LightingEnabled GL_LIGHTING DepthTestEnabled GL_DEPTH_TEST StencilTestEnabled GL_STENCIL_TEST AlphaTestEnabled GL_ALPHA_TEST CullFaceEnabled GL_CULL_FACE ColorMaterialEnabled GL_COLOR_MATERIAL LineStippleEnabled GL_LINE_STIPPLE PolygonOffsetFillEnabled GL_POLYGON_OFFSET_FILL PolygonOffsetLineEnabled GL_POLYGON_OFFSET_LINE PolygonOffsetPointEnabled GL_POLYGON_OFFSET_POINT NormalizeEnabled GL_NORMALIZE AutoNormalEnabled GL_AUTO_NORMAL ========================= ====================== | .. table:: 状態の取得と設定 ==================== ========================== ========================= MGL Property glGet constant OpenGL func. ==================== ========================== ========================= DepthMask GL_DEPTH_WRITEMASK glDepthMask StencilMask GL_STENCIL_WRITEMASK glStencilMask StencilMaskFront GL_STENCIL_WRITEMASK glStencilMaskSeparate StencilMaskBack GL_STENCIL_BACK_WRITEMASK glStencilMaskSeparate ColorMask GL_COLOR_WRITEMASK glColorMask DepthFunc GL_DEPTH_FUNC glDepthFunc Normal GL_CURRENT_NORMAL glNormal3d Color GL_CURRENT_COLOR glColor4f SrcBuffer GL_READ_BUFFER glReadBuffer DstBuffer GL_DRAW_BUFFER glDrawBuffer PolygonOffsetFactor GL_POLYGON_OFFSET_FACTOR glPolygonOffset PolygonOffsetUnits GL_POLYGON_OFFSET_UNITS glPolygonOffset FrontPolygonMode GL_POLYGONMODE glPolygonMode BackPolygonMode GL_POLYGONMODE glPolygonMode CullFace GL_CULL_FACE_MODE glCullFace LightingTwoSide GL_LIGHT_MODEL_TWO_SIDE glLightModeli LineStipplePattern GL_LINE_STIPPLE_PATTERN glLineStipple PointSize GL_POINT_SIZE glPointSize LineWidth GL_LINE_WIDTH glLineWidth Matrix GL_MODELVIEW_MATRIX glLoadMatrixf Viewport GL_VIEWPORT glViewport ColorClearValue GL_COLOR_CLEAR_VALUE glClearColor DepthClearValue GL_DEPTH_CLEAR_VALUE glClearDepth StencilClearValue GL_STENCIL_CLEAR_VALUE glClearStencil GLRenderMode RenderMode GL_RENDER_MODE glRenderMode ==================== ========================== ========================= 光源 ================================================================== .. code-block:: csharp static class MGL { public static readonly LightCollection Lights = new LightCollection(); public class Light { public bool IsEnabled { get; set; } public Color4f Ambient { get; set; } public Color4f Diffuse { get; set; } public Color4f Specular { get; set; } public HmCod3f Position { get; set; } public Vector3f SpotDirection { get; set; } public float SpotExponent { get; set; } public Angle SpotCutoff { get; set; } public float ConstantAttenuation { get; set; } public float LinearAttenuation { get; set; } public float QuadraticAttenuation { get; set; } } public class LightCollection : IEnumerable { public int Count { get; } public Light this[int i] { get; } } } 頂点配列 ================================================================== 頂点のデータ型として使えるものを下記に示します。 * Point3f * Point3d * PointNormal3f * PointNormal3d * PointNormalUV3f * PointUV3f * ColoredPoint3f * ColoredPointNormal3f OpenGL の頂点配列には、大きく分けて次の2種類があります。 * glDrawArrays() によるもの * glDrawElements() によるもの ``MGL.DrawArrays( GLPrimType type, 頂点データ型[] points )`` -------------------------------------------------------------------- ``glDrawArrays`` によって頂点配列を描画します。 「頂点データ型」として上記のデータ型が使えるようにオーバーロードされています。 ``MGL.DrawArrays( GLPrimType type, 頂点データ型[] points, int[] indices )`` ----------------------------------------------------------------------------- ``glDrawElements`` によって頂点配列を描画します。 ``MGL.DrawArrays( 頂点データ型[] points, params Array[] elements )`` ----------------------------------------------------------------------------- ``glDrawElements`` によって頂点配列を描画します。 ``MGL.Array`` は次のように定義されています。 .. code-block:: csharp static class MGL { public sealed class Array { public readonly GLPrimType Type; public readonly T[] Data; public Array( GLPrimType type, params T[] data ); } } Texture Mapping ================================================================== ``MGL.ITexture`` ------------------------------------------------------------------ ※ ほとんどの場合、次節の `MGL.ITextureObject` を利用するほうが適切です。 .. code-block:: csharp :caption: API public static class MGL { public interface ITexture : IContextual { GLTextureTarget Target { get; } uint Handle { get; } ITextureBinding Bind(); } public static ITexture GenTexture( Bitmap bmp ); ... } .. code-block:: csharp :caption: Usage var tex = MGL.GenTexture( bitmap ); using ( var binding = tex.Bind() ) { binding.SetTexFilterParams( ... ); // 必要ならこういった設定を行う ... // ここに描画処理を書く } ``ITexture`` はレンダリングコンテキストに依存しています。 ``GenTexture()`` を呼ぶと内部では ``glGenTextures()`` が呼び出され、そのとき有効なレンダリングコンテキストにテクスチャが生成されます。 そのテクスチャIDは ``Handle`` プロパティで取得できます。 `ITexture` のオブジェクトを使って複数のレンダリングコンテキストでテクスチャマッピングを行うことはできません。 3Dビューが複数あるアプリケーションの開発では注意して下さい。そういった場合は下記の ``ITextureObject`` を使用して下さい。 ``MGL.ITextureObject`` ------------------------------------------------------------------ .. code-block:: csharp :caption: API public static class MGL { public interface ITextureObject : IObject { new ITexture Current { get; } Size2i ImageSize { get; } ITextureBinding Bind(); } public static ITextureObject CreateTextureObject( Bitmap bitmap ); ... } .. code-block:: csharp :caption: Usage // 事前にテクスチャオブジェクトを生成しておく var tex = MGL.CreateTextureObject( bitmap ); // 描画処理において(IScene.Draw メソッドの中など)次のように書く using ( var binding = tex.Bind() ) { binding.SetTexFilterParams( ... ); // 必要ならこういった設定を行う ... // ここに描画処理を書く } ``ITextureObject`` は複数のレンダリングコンテキストにまたがって利用できます。 常に現在アクティブなレンダリングコンテキストを確認し、適切な ``ITexture`` を取得・生成してテクスチャマッピングを行います。 ``Current`` プロパティは、現在のレンダリングコンテキストに合わせた ``ITexture`` を返します。 Shader =================================================================== .. code-block:: csharp :caption: Usage using MoNo.OpenGL; string shadersrcV = ...; // source code of vertex shader string shadersrcF = ...; // source code of fragment shader var program = MGL.CreateProgramObject( shadersrcV, shadersrcF ); using ( var use = program.Use() ) { use.Uniform( "hoge", .. ); // pass uniform variables to shader program. ... // ここに描画処理を書く } - 代表的な使用例です。 - なお、このコードでは ``CreateProgramObject()`` の直後に描画処理に入っていますが、毎フレームの描画のたびに ``CreateProgramObject()`` を呼び出す必要はありません。 事前に ``CreateProgramObject()`` してそのオブジェクトを保持しておけば、描画の際には ``Use()`` するだけでOKです。 - シェーダーのソースコードは、DLLのリソースとして定義しておくのが良いでしょう。 各インターフェイス ----------------------------------------------------------------- ※ RC = Rendering Context ================== ============ ===================================== RC非依存 RC依存 説明 ================== ============ ===================================== ``IProgramObject`` ``IProgram`` 複数のシェーダーを束ねたもの。 ``IShaderObject`` ``IShader`` バーテックスシェーダー、フラグメントシェーダーなど ================== ============ ===================================== Example ----------------------------------------------------------------- .. code-block:: fsharp let vs = """ #version 120 void main(void){ gl_Position=gl_ModelViewProjectionMatrix* gl_Vertex; } """ let fs = """ #version 120 void main (void) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } """ let program = MGL.CreateProgramObject(vs,fs) let scene = GraphicsUT.CreateScene (fun sc -> use scope = sc.Push() use prog = program.Use() sc.DrawQuads (fun gl -> gl.Vertex( 0.0, 0.0, 0.0 ) gl.Vertex( 1.0, 0.0, 0.0 ) gl.Vertex( 1.0, 1.0, 0.0 ) gl.Vertex( 0.0, 1.0, 0.0 ))) 古いGLSL(version 120)で書いたほうがMVP行列の値が自動で受け継がれるので楽