]> O.S.I.I.S - jp/crow.git/commitdiff
glbackend tests, copy first try from hg repos glbackend
authorjpbruyere <jp.bruyere@hotmail.com>
Wed, 21 Oct 2015 20:00:20 +0000 (22:00 +0200)
committerjpbruyere <jp.bruyere@hotmail.com>
Wed, 21 Oct 2015 20:00:20 +0000 (22:00 +0200)
25 files changed:
GOLib.csproj
GOLib.sln
Tests/Tests.csproj
Tests/testGLBackend (copier).cs [new file with mode: 0644]
Tests/testGLBackend.cs [new file with mode: 0644]
src/Font.cs
src/Interface.cs
src/OpenGL/GLBackend/ClipShader.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Context.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/Font.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/FontExtents.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/FontFace.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/FontFlag.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/FontShader (copier).cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/FontShader.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/FontSlant.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/FontStyle.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/FontWeight.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/TextExtents.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/glFont.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Font/glGlyph.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Path.cs [new file with mode: 0644]
src/OpenGL/GLBackend/Shader (copier).cs [new file with mode: 0644]
src/OpenGL/GLBackend/Surface.cs [new file with mode: 0644]
src/OpenTKGameWindow.cs

index 652fccc8eedeff13be4c6411d2b5e5c2968d04ad..ffffd6c8cbce3367dbeca24c1edf09e867bf8d75 100644 (file)
     <Compile Include="src\SelectionChangeEventArgs.cs" />\r
     <Compile Include="src\ValueChangeEventArgs.cs" />\r
     <Compile Include="src\GraphicObjects\FileDialog.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\ClipShader.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Context.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Path.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Shader %28copier%29.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Surface.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Font\Font.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Font\FontExtents.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Font\FontFace.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Font\FontFlag.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Font\FontShader.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Font\FontSlant.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Font\FontWeight.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Font\glFont.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Font\glGlyph.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Font\TextExtents.cs" />\r
+    <Compile Include="src\OpenGL\GLBackend\Font\FontStyle.cs" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Reference Include="System" />\r
     <Folder Include="Images\Icons\" />\r
     <Folder Include="src\CompilerServices\" />\r
     <Folder Include="src\OpenGL\" />\r
+    <Folder Include="src\OpenGL\GLBackend\" />\r
+    <Folder Include="src\OpenGL\GLBackend\Font\" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <EmbeddedResource Include="Images\Icons\updown.svg" />\r
     <None Include="Images\Icons\Cursors\move" />\r
     <None Include="README.md" />\r
   </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="..\SharpFont-2.5.0.1\SharpFont\SharpFont.csproj">\r
+      <Project>{C293DB32-FA42-486D-B128-5A12522FAE4E}</Project>\r
+      <Name>SharpFont</Name>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
 </Project>\r
index 03d54156c94ae45ae34be7d7e09ee8b41a10091f..9d5b1f2a6b7770a36b180d76dc2155d603072353 100644 (file)
--- a/GOLib.sln
+++ b/GOLib.sln
@@ -9,24 +9,52 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.GOLib", "MonoDe
 EndProject\r
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.Diagram", "..\MonoDevelop.Diagram\MonoDevelop.Diagram.csproj", "{232716B4-D19D-4FD7-B310-94A98FD926F0}"\r
 EndProject\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpFont", "..\SharpFont-2.5.0.1\SharpFont\SharpFont.csproj", "{C293DB32-FA42-486D-B128-5A12522FAE4E}"\r
+EndProject\r
 Global\r
        GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
                Debug|Linux_x86 = Debug|Linux_x86\r
                Release|Linux_x86 = Release|Linux_x86\r
+               Debug WIN64|Any CPU = Debug WIN64|Any CPU\r
+               Release WIN64|Any CPU = Release WIN64|Any CPU\r
        EndGlobalSection\r
        GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {232716B4-D19D-4FD7-B310-94A98FD926F0}.Debug WIN64|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {232716B4-D19D-4FD7-B310-94A98FD926F0}.Debug WIN64|Any CPU.Build.0 = Debug|Any CPU\r
                {232716B4-D19D-4FD7-B310-94A98FD926F0}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU\r
+               {232716B4-D19D-4FD7-B310-94A98FD926F0}.Release WIN64|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {232716B4-D19D-4FD7-B310-94A98FD926F0}.Release WIN64|Any CPU.Build.0 = Debug|Any CPU\r
                {232716B4-D19D-4FD7-B310-94A98FD926F0}.Release|Linux_x86.ActiveCfg = Debug|Any CPU\r
+               {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Debug WIN64|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Debug WIN64|Any CPU.Build.0 = Debug|Any CPU\r
                {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU\r
                {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Debug|Linux_x86.Build.0 = Debug|Any CPU\r
+               {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release WIN64|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release WIN64|Any CPU.Build.0 = Debug|Any CPU\r
                {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Linux_x86.ActiveCfg = Release|Any CPU\r
                {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Linux_x86.Build.0 = Release|Any CPU\r
+               {C293DB32-FA42-486D-B128-5A12522FAE4E}.Debug WIN64|Any CPU.ActiveCfg = Debug WIN64|Any CPU\r
+               {C293DB32-FA42-486D-B128-5A12522FAE4E}.Debug WIN64|Any CPU.Build.0 = Debug WIN64|Any CPU\r
+               {C293DB32-FA42-486D-B128-5A12522FAE4E}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU\r
+               {C293DB32-FA42-486D-B128-5A12522FAE4E}.Debug|Linux_x86.Build.0 = Debug|Any CPU\r
+               {C293DB32-FA42-486D-B128-5A12522FAE4E}.Release WIN64|Any CPU.ActiveCfg = Release WIN64|Any CPU\r
+               {C293DB32-FA42-486D-B128-5A12522FAE4E}.Release WIN64|Any CPU.Build.0 = Release WIN64|Any CPU\r
+               {C293DB32-FA42-486D-B128-5A12522FAE4E}.Release|Linux_x86.ActiveCfg = Release|Any CPU\r
+               {C293DB32-FA42-486D-B128-5A12522FAE4E}.Release|Linux_x86.Build.0 = Release|Any CPU\r
+               {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Debug WIN64|Any CPU.ActiveCfg = Release|Any CPU\r
+               {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Debug WIN64|Any CPU.Build.0 = Release|Any CPU\r
                {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU\r
                {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Debug|Linux_x86.Build.0 = Debug|Any CPU\r
+               {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release WIN64|Any CPU.ActiveCfg = Release|Any CPU\r
+               {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release WIN64|Any CPU.Build.0 = Release|Any CPU\r
                {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release|Linux_x86.ActiveCfg = Release|Any CPU\r
                {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release|Linux_x86.Build.0 = Release|Any CPU\r
+               {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Debug WIN64|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Debug WIN64|Any CPU.Build.0 = Debug|Any CPU\r
                {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU\r
                {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Debug|Linux_x86.Build.0 = Debug|Any CPU\r
+               {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Release WIN64|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Release WIN64|Any CPU.Build.0 = Debug|Any CPU\r
                {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Release|Linux_x86.ActiveCfg = Release|Any CPU\r
        EndGlobalSection\r
        GlobalSection(MonoDevelopProperties) = preSolution\r
index e9eccb48ecc0139711f51acb9f4b463fb9611463..8967bdd9a2f8b705804765f841c519f2adc1b392 100644 (file)
@@ -8,7 +8,7 @@
     <OutputType>Exe</OutputType>
     <RootNamespace>Tests</RootNamespace>
     <AssemblyName>Tests</AssemblyName>
-    <StartupObject>test2.GOLIBTest_DirViewer</StartupObject>
+    <StartupObject>testGLBackend.GOLIBTestglb</StartupObject>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <OutputPath>..\bin\$(configuration)</OutputPath>
     <IntermediateOutputPath>obj\$(configuration)</IntermediateOutputPath>
@@ -42,6 +42,9 @@
       <HintPath>..\..\opentk\Binaries\OpenTK\Release\OpenTK.dll</HintPath>
     </Reference>
     <Reference Include="Mono.Cairo" />
+    <Reference Include="GGL">
+      <HintPath>..\..\GGL\bin\GGL.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="GOLIBTest_5.cs" />
@@ -61,6 +64,8 @@
     <Compile Include="..\bin\Debug\Interfaces\test4.goml.cs">
       <Link>Interfaces\test4.goml.cs</Link>
     </Compile>
+    <Compile Include="testGLBackend.cs" />
+    <Compile Include="testGLBackend %28copier%29.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="image\u.svg">
       <Project>{C2980F9B-4798-4C05-99E2-E174810F7C7B}</Project>
       <Name>GOLib</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\SharpFont-2.5.0.1\SharpFont\SharpFont.csproj">
+      <Project>{C293DB32-FA42-486D-B128-5A12522FAE4E}</Project>
+      <Name>SharpFont</Name>
+    </ProjectReference>
   </ItemGroup>
 </Project>
diff --git a/Tests/testGLBackend (copier).cs b/Tests/testGLBackend (copier).cs
new file mode 100644 (file)
index 0000000..0381d0d
--- /dev/null
@@ -0,0 +1,384 @@
+#define MONO_CAIRO_DEBUG_DISPOSE
+
+
+using System;
+using System.Runtime.InteropServices;
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+using OpenTK.Input;
+
+using System.Diagnostics;
+
+using go;
+using System.Threading;
+using GGL;
+//using Cairo;
+using go.GLBackend;
+
+namespace testGLBackend2
+{
+       class GOLIBTestglb : OpenTKGameWindow
+       {
+               #region FPS
+               static int _fps = 0;
+
+               public static int fps {
+                       get { return _fps; }
+                       set {
+                               _fps = value;
+                               if (_fps > fpsMax)
+                                       fpsMax = _fps;
+                               else if (_fps < fpsMin)
+                                       fpsMin = _fps;
+                       }
+
+               }
+
+               public static int fpsMin = int.MaxValue;
+               public static int fpsMax = 0;
+
+               static void resetFps ()
+               {
+                       fpsMin = int.MaxValue;
+                       fpsMax = 0;
+                       _fps = 0;
+               }
+               #endregion
+
+               public GOLIBTestglb ()
+                       : base(1024, 800)
+               {
+                       VSync = VSyncMode.Off;
+               }
+
+               #region  scene matrix and vectors
+               public static Matrix4 modelview;
+               public static Matrix4 projection;
+
+               public static Vector3 vEye = new Vector3(5.0f, 5.0f, 5.0f);    // Camera Position
+               public static Vector3 vEyeTarget = Vector3.Zero;
+               public static Vector3 vLook = new Vector3(0f, 1f, -0.7f);  // Camera vLook Vector
+
+               float _zFar = 6400.0f;
+
+               public float zFar {
+                       get { return _zFar; }
+                       set {
+                               _zFar = value;
+                       }
+               }
+
+               public float zNear = 0.1f;
+               public float fovY = (float)Math.PI / 4;
+
+               float MoveSpeed = 0.5f;
+               float RotationSpeed = 0.02f;
+               #endregion
+
+               Context ctx;
+               Surface surf;
+
+               QuadVAO testQuad;
+               go.GLBackend.Shader shad;
+               Matrix4 projectionMatrix, 
+               modelviewMatrix;
+               Texture testTex;
+
+               void drawScene()
+               {
+                       //shad.Enable ();
+                       //shader.LineWidth = lineWidth;
+                       shad.ProjectionMatrix = projectionMatrix;
+                       shad.ModelViewMatrix = modelviewMatrix;
+                       shad.Color = new Vector4(1f,1f,1f,1f);
+
+                       GL.ActiveTexture (TextureUnit.Texture0);
+                       GL.BindTexture(TextureTarget.Texture2D, surf.texId);
+
+                       testQuad.Render (PrimitiveType.TriangleStrip);
+
+                       GL.BindTexture(TextureTarget.Texture2D, 0);
+
+                       //shad.Disable ();
+               }
+
+               protected override void OnLoad (EventArgs e)
+               {
+                       base.OnLoad (e);
+
+
+                       Mouse.WheelChanged += new EventHandler<MouseWheelEventArgs>(Mouse_WheelChanged);
+                       Mouse.Move += new EventHandler<MouseMoveEventArgs>(Mouse_Move);
+
+                       GL.Viewport (0, 0, ClientRectangle.Width, ClientRectangle.Height);
+                       GL.ClearColor(0.0f, 0.0f, 0.2f, 1.0f);
+
+//                     GL.Enable(EnableCap.DepthTest);
+//                     GL.DepthFunc(DepthFunction.Less);
+                       //GL.Enable(EnableCap.CullFace);
+                       //GL.Enable(EnableCap.Texture2D);
+
+                       GL.Enable (EnableCap.Blend);
+                       GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
+
+                       //GL.FrontFace(FrontFaceDirection.Ccw);
+
+                       //GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
+                       //GL.ShadeModel(ShadingModel.Smooth);
+                       //GL.Hint (HintTarget.LineSmoothHint, HintMode.Nicest);
+                       ErrorCode err = GL.GetError ();
+                       Debug.Assert (err == ErrorCode.NoError, "OpenGL Error");
+
+                       surf = new Surface (Format.Argb32, 600, 600);
+
+                       testQuad = new QuadVAO (100, 100, 600, 600);
+                       shad = new TexturedShader ();
+
+                       projectionMatrix = Matrix4.CreateOrthographicOffCenter 
+                               (0, ClientRectangle.Width, ClientRectangle.Height, 0, 0, 1);
+                       modelviewMatrix = Matrix4.Identity;
+
+                       testTex = new Texture (rootDir + @"Images/texture/structures/639-diffuse.jpg");
+                       //string[] extensions = GL.GetString(StringName.Version).Split(' ');
+                       LoadInterface("Interfaces/test0.goml");
+
+               }
+               public static void DrawRoundedRectangle(Context gr, double x, double y, double width, double height, double radius)
+               {
+
+                       if ((radius > height / 2) || (radius > width / 2))
+                               radius = Math.Min(height / 2, width / 2);
+
+                       gr.MoveTo(x, y + radius);
+                       gr.Arc(x + radius, y + radius, radius, Math.PI, -Math.PI / 2);
+                       gr.LineTo(x + width - radius, y);
+                       gr.Arc(x + width - radius, y + radius, radius, -Math.PI / 2, 0);
+                       gr.LineTo(x + width, y + height - radius);
+                       gr.Arc(x + width - radius, y + height - radius, radius, 0, Math.PI / 2);
+                       gr.LineTo(x + radius, y + height);
+                       gr.Arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI);
+                       gr.ClosePath();
+               }
+               double angle;
+               public override void GLClear ()
+               {
+                       GL.ClearColor(0.0f, 0.0f, 0.2f, 1.0f);
+                       GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
+               }
+               public override void OnRender (FrameEventArgs e)
+               {
+                       drawScene ();
+               }
+
+               protected override void OnUpdateFrame (FrameEventArgs e)
+               {
+                       base.OnUpdateFrame (e);
+
+                       fps = (int)RenderFrequency;
+
+                       using (Context ctx = new Context (surf)) {
+                               ctx.LineWidth = 1.0;
+                               ctx.Rectangle (new Rectangle (0, 0, 600, 600));
+                               DrawRoundedRectangle (ctx, 100, 100, 70, 70, 10);
+                               ctx.Color = go.Color.Green;
+                               ctx.FillPreserve ();
+
+                               for (int i = 0; i < 5; i++) {
+                                       
+                                       
+                                       angle += Math.PI / 1000;
+                                       if (angle > Math.PI * 2)
+                                               angle = 0;
+                                                                                       
+                                       ctx.Translate (-200, -200);
+                                       ctx.Rotate (angle);
+                                       ctx.Translate (200, 200);
+
+                                       //ctx.FillPreserve ();
+                                       ctx.Color = go.Color.White;
+                                       //ctx.Color.AdjustAlpha (1.0 / i);
+                                       ctx.StrokePreserve ();
+                               }
+                       }
+                       //surf.Save (@"/home/jp/test.png");
+                       //Debug.WriteLine (fps);
+                       this.Title = fps.ToString ();
+               }
+               protected override void OnResize (EventArgs e)
+               {
+                       base.OnResize (e);
+                       UpdateViewMatrix();
+               }
+
+               #region Mouse Handling
+               void Object_Mouse_Move(object sender, MouseMoveEventArgs e){
+                       if (activeWidget == null)
+                               return;
+
+                       activeWidget.registerClipRect ();
+                       if (activeWidget!=null) {
+                               activeWidget.Left += e.XDelta;
+                               activeWidget.Top += e.YDelta;
+                       }
+               }
+               void Mouse_Move(object sender, MouseMoveEventArgs e)
+               {
+                       if (e.XDelta != 0 || e.YDelta != 0)
+                       {
+                               if (e.Mouse.MiddleButton == OpenTK.Input.ButtonState.Pressed)
+                               {
+                                       Matrix4 m = Matrix4.CreateRotationZ(-e.XDelta * RotationSpeed);
+                                       m *= Matrix4.CreateFromAxisAngle(-vLookPerpendicularOnXYPlane, -e.YDelta * RotationSpeed);
+                                       vEyeTarget = Vector3.Zero;
+                                       vEye = Vector3.Transform(vEye, Matrix4.CreateTranslation(-vEyeTarget) * m * Matrix4.CreateTranslation(vEyeTarget));
+                                       UpdateViewMatrix();
+                               }
+                               if (e.Mouse.RightButton == ButtonState.Pressed)
+                               {
+
+                                       Matrix4 m = Matrix4.CreateRotationZ(-e.XDelta * RotationSpeed);
+                                       Matrix4 m2 = Matrix4.Rotate(vLookPerpendicularOnXYPlane, e.YDelta * RotationSpeed);
+
+                                       vEyeTarget = Vector3.Transform(vEyeTarget, Matrix4.CreateTranslation(-vEye) * m * m2 * Matrix4.CreateTranslation(vEye));
+
+                                       //vLook = Vector3.Transform(vLook, m2);
+                                       UpdateViewMatrix();
+
+                               }
+                       }
+               }                       
+               void Mouse_WheelChanged(object sender, MouseWheelEventArgs e)
+               {
+                       float speed = MoveSpeed;
+                       if (Keyboard[Key.ShiftLeft])
+                               speed *= 0.1f;
+                       else if (Keyboard[Key.ControlLeft])
+                               speed *= 20.0f;
+
+                       vLook = Vector3.NormalizeFast(vEye - vEyeTarget);
+                       vEye -= vLook * e.Delta * speed;
+                       UpdateViewMatrix();
+               }
+               #endregion
+
+               #region vLookCalculations
+               Vector3 vLookDirOnXYPlane
+               {
+                       get
+                       {
+                               Vector3 v = Vector3.NormalizeFast(vEye - vEyeTarget);
+                               v.Z = 0;
+                               return v;
+                       }
+               }
+               public Vector3 vLookPerpendicularOnXYPlane
+               {
+                       get
+                       {
+                               Vector3 vLook = Vector3.NormalizeFast(vEye - vEyeTarget);
+                               vLook.Z = 0;
+
+                               Vector3 vHorizDir = Vector3.Cross(vLook, Vector3.UnitZ);
+                               return vHorizDir;
+                       }
+               }
+
+               void moveCamera(Vector3 v)
+               {
+                       vEye += v;
+                       vEyeTarget += v;
+               }
+               #endregion
+
+               public void UpdateViewMatrix()
+               {
+//                     Rectangle r = this.ClientRectangle;
+//                     GL.Viewport( r.X, r.Y, r.Width, r.Height);
+//                     projection = Matrix4.CreatePerspectiveFieldOfView(fovY, r.Width / (float)r.Height, zNear, zFar);
+//                     GL.MatrixMode(MatrixMode.Projection);
+//                     GL.LoadIdentity();
+//
+//                     GL.LoadMatrix(ref projection);
+//
+//                     modelview = Matrix4.LookAt(vEye, vEyeTarget, Vector3.UnitZ);
+//                     GL.MatrixMode(MatrixMode.Modelview);
+//                     GL.LoadIdentity();
+//                     GL.LoadMatrix(ref modelview);
+               }
+               [STAThread]
+               static void Main ()
+               {
+                       Console.WriteLine ("starting example");
+
+                       using (GOLIBTestglb win = new GOLIBTestglb( )) {
+                               win.Run (30.0);
+                       }
+               }
+       }
+}
+//using (Context ctx = new Context (surf)) {
+//     //for (int i = 0; i < 150; i++) {
+//
+//
+//     //                                      angle += Math.PI / 100000;
+//     //                                      if (angle > Math.PI * 2)
+//     //                                              angle = 0;
+//     //GL.
+//     //drawScene();
+//
+//     //                                      ctx.Color = new Color (1.0/i, 1, 0, 1);
+//     //                              ctx.Translate (-512, -400);
+//     //                              ctx.Rotate (angle);
+//     //                              ctx.Translate (512, 400);
+//     ctx.LineWidth = 1.0;
+//     ctx.Color = go.Color.LightBlue.AdjustAlpha(0.2);                        
+//     //                              ctx.MoveTo (100, 100);
+//     //                              ctx.LineTo (150, 150);
+//     //                              ctx.LineTo (300, 100);
+//     //                              ctx.LineTo (150, 200);
+//     //                              ctx.LineTo (500, 200);
+//     //                              ctx.LineTo (400, 100);
+//     //                              ctx.LineTo (600, 100);
+//     //                              ctx.LineTo (600, 600);
+//     //                              ctx.LineTo (200, 600);
+//     //                              ctx.LineTo (300, 300);
+//     //                              ctx.LineTo (100, 300);
+//     //                              //ctx.ClosePath ();
+//     //ctx.Rectangle(new go.Rectangle(100,600,60,80));
+//
+//     DrawRoundedRectangle (ctx, 200, 200, 70, 70,10);
+//     //                                      DrawRoundedRectangle (ctx, 300, 300, 70, 70,5);
+//     //                                      DrawRoundedRectangle (ctx, 400, 400, 70, 70,25);
+//     //                                      DrawRoundedRectangle (ctx, 500, 500, 70, 70,25);
+//     //                                      DrawRoundedRectangle (ctx, 600, 600, 100, 100,25);
+//
+//
+//     //**** concave shape
+//
+//     //                              ctx.LineTo (110, 200);
+//     //                              ctx.LineTo (400, 200);
+//     //                              ctx.LineTo (400, 100);
+//     //                              ctx.LineTo (200, 100);
+//     //                              ctx.LineTo (200, 50);
+//     //                              ctx.LineTo (500, 50);
+//     //                              ctx.LineTo (500, 200);
+//     //                              ctx.LineTo (400, 300);
+//     //                              ctx.LineTo (100, 300);
+//     //                              ctx.LineTo (50, 200);
+//     ctx.FillPreserve ();
+//     //*****************************
+//
+//     ctx.Color = go.Color.White;
+//     //ctx.Stroke ();
+//     //                                      ctx.LineTo (500, 50);
+//     //                                      ctx.LineTo (750, 500);
+//     //                                      ctx.LineTo (750, 50);
+//     //                                      ctx.MoveTo (100, 100);
+//     //                                      ctx.LineTo (200, 200);
+//     //                                      ctx.LineTo (100, 400);
+//     //                                      ctx.LineTo (300, 400);
+//     //                                      //ctx.LineTo (250, 300);
+//     //                                      ctx.Arc (300, 600, 100, 0, Math.PI);
+//     ctx.Stroke ();
+//}
+////}
diff --git a/Tests/testGLBackend.cs b/Tests/testGLBackend.cs
new file mode 100644 (file)
index 0000000..da51053
--- /dev/null
@@ -0,0 +1,494 @@
+#define MONO_CAIRO_DEBUG_DISPOSE
+
+
+using System;
+using System.Runtime.InteropServices;
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+using OpenTK.Input;
+
+using System.Diagnostics;
+
+using go;
+using System.Threading;
+using GGL;
+//using Cairo;
+using go.GLBackend;
+
+namespace testGLBackend
+{
+       class GOLIBTestglb : OpenTKGameWindow
+       {
+               #region FPS
+               static int _fps = 0;
+
+               public static int fps {
+                       get { return _fps; }
+                       set {
+                               _fps = value;
+                               if (_fps > fpsMax)
+                                       fpsMax = _fps;
+                               else if (_fps < fpsMin)
+                                       fpsMin = _fps;
+                       }
+
+               }
+
+               public static int fpsMin = int.MaxValue;
+               public static int fpsMax = 0;
+
+               static void resetFps ()
+               {
+                       fpsMin = int.MaxValue;
+                       fpsMax = 0;
+                       _fps = 0;
+               }
+               #endregion
+
+               public float coef1 = 1.0f;
+               public float coef2 = 0.5f;
+               public float coef3 = 0.0f;
+               public float coefA = 1.0f;
+
+               Color foreground = Color.Black;
+               Color background = Color.White;
+
+               public GOLIBTestglb ()
+                       : base(1024, 800)
+               {
+                       VSync = VSyncMode.Off;
+               }
+
+               #region  scene matrix and vectors
+               public static Matrix4 modelview;
+               public static Matrix4 projection;
+
+               public static Vector3 vEye = new Vector3(5.0f, 5.0f, 5.0f);    // Camera Position
+               public static Vector3 vEyeTarget = Vector3.Zero;
+               public static Vector3 vLook = new Vector3(0f, 1f, -0.7f);  // Camera vLook Vector
+
+               float _zFar = 6400.0f;
+
+               public float zFar {
+                       get { return _zFar; }
+                       set {
+                               _zFar = value;
+                       }
+               }
+
+               public float zNear = 0.1f;
+               public float fovY = (float)Math.PI / 4;
+
+               float MoveSpeed = 0.5f;
+               float RotationSpeed = 0.02f;
+               #endregion
+
+               Context ctx;
+               Surface surf;
+
+               QuadVAO testQuad;
+               QuadVAO magnifierQuad;
+               int magTex;     //mignified texture
+               go.GLBackend.Shader shade;
+               Matrix4 projectionMatrix, 
+               modelviewMatrix;
+               Texture testTex;
+
+
+               void drawScene()
+               {
+                       shade.Enable ();
+                       //shader.LineWidth = lineWidth;
+                       shade.ProjectionMatrix = projectionMatrix;
+                       shade.ModelViewMatrix = modelviewMatrix;
+                       shade.Color = new Vector4(1f,1f,1f,1f);
+
+                       GL.ActiveTexture (TextureUnit.Texture0);
+                       GL.BindTexture(TextureTarget.Texture2D, surf.texId);
+                       //GL.BindTexture(TextureTarget.Texture2D, FontFace.testTexture);
+
+                       testQuad.Render (PrimitiveType.TriangleStrip);
+
+                       GL.BindTexture(TextureTarget.Texture2D, magTex);
+                       magnifierQuad.Render (PrimitiveType.TriangleStrip);
+
+                       GL.BindTexture(TextureTarget.Texture2D, 0);
+
+                       //shader.Disable ();
+               }
+               glFont testFont;
+
+               protected override void OnLoad (EventArgs e)
+               {
+                       base.OnLoad (e);
+
+
+                       Mouse.WheelChanged += new EventHandler<MouseWheelEventArgs>(Mouse_WheelChanged);
+                       Mouse.Move += new EventHandler<MouseMoveEventArgs>(Mouse_Move);
+
+                       GL.Viewport (0, 0, ClientRectangle.Width, ClientRectangle.Height);
+                       GL.ClearColor(0.0f, 0.0f, 0.2f, 1.0f);
+
+                       //GL.Enable(EnableCap.DepthTest);
+                       //GL.DepthFunc(DepthFunction.Less);
+                       //GL.Enable(EnableCap.CullFace);
+                       //GL.Enable(EnableCap.Texture2D);
+
+
+
+                       //GL.FrontFace(FrontFaceDirection.Ccw);
+
+                       //GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
+                       //GL.ShadeModel(ShadingModel.Smooth);
+                       //GL.Hint (HintTarget.LineSmoothHint, HintMode.Nicest);
+                       ErrorCode err = GL.GetError ();
+                       Debug.Assert (err == ErrorCode.NoError, "OpenGL Error");
+
+                       surf = new Surface (Format.Argb32, 512, 512);
+
+                       testQuad = new QuadVAO (0, 0, 512, 512);
+                       magnifierQuad = new QuadVAO (150, 300, 400, 400,1.1f,0.73f,0.05f,0.05f);
+
+                       shade = new TexturedShader ();
+
+                       projectionMatrix = Matrix4.CreateOrthographicOffCenter 
+                               (0, ClientRectangle.Width, ClientRectangle.Height, 0, 0, 1);
+                       modelviewMatrix = Matrix4.Identity;
+
+                       testTex = new Texture (rootDir + @"Images/texture/structures/639-diffuse.jpg");
+                       //string[] extensions = GL.GetString(StringName.Version).Split(' ');
+                       FontFace.BuildFontsList(@"/usr/share/fonts/truetype/");
+                       //glFont.dumpFontsDirectories (@"/usr/share/fonts/");
+                       //glFont.dumpFontsDirectories (@"/usr/share/fonts/opentype");
+                       LoadInterface("Interfaces/test0.goml");
+
+                       //testFont = new glFont (@"/usr/share/fonts/truetype/droid/DroidSans-Bold.ttf");
+               }
+
+               public static void DrawRoundedRectangle(Context gr, double x, double y, double width, double height, double radius)
+               {
+
+                       if ((radius > height / 2) || (radius > width / 2))
+                               radius = Math.Min(height / 2, width / 2);
+
+                       gr.MoveTo(x, y + radius);
+                       gr.Arc(x + radius, y + radius, radius, Math.PI, -Math.PI / 2);
+                       gr.LineTo(x + width - radius, y);
+                       gr.Arc(x + width - radius, y + radius, radius, -Math.PI / 2, 0);
+                       gr.LineTo(x + width, y + height - radius);
+                       gr.Arc(x + width - radius, y + height - radius, radius, 0, Math.PI / 2);
+                       gr.LineTo(x + radius, y + height);
+                       gr.Arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI);
+                       gr.ClosePath();
+               }
+               double angle;
+               public override void GLClear ()
+               {
+                       GL.ClearColor(1.0f, 0.0f, 0.2f, 1.0f);
+                       GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
+               }
+               public override void OnRender (FrameEventArgs e)
+               {
+                       drawScene ();
+               }
+               protected override void OnUpdateFrame (FrameEventArgs e)
+               {
+                       base.OnUpdateFrame (e);
+
+                       fps = (int)RenderFrequency;
+
+                       using (Context ctx = new Context (surf)) {
+                               ctx.coef1 = coef1;
+                               ctx.coef2 = coef2;
+                               ctx.coef3 = coef3;
+                               ctx.coefA = coefA;
+
+                               ctx.Rectangle(new Rectangle(0,0,512,512));
+                               ctx.Color = background;//new Color(1.0,0.1,0.2,1);
+                               ctx.Fill ();
+                               ctx.LineWidth = 1.0;
+                               ctx.Color = foreground;
+                               ctx.SelectFontFace ("courier new", FontSlant.Normal, FontWeight.Normal);
+                               ctx.SetFontSize (6);
+                               ctx.FillText ("Test d'une string a petite échelle", new Point (50, 50));
+                               ctx.SetFontSize (8);
+                               ctx.FillText ("Test d'une string a petite échelle", new Point (50, 60));
+                               ctx.SetFontSize (10);
+                               ctx.FillText ("Test d'une string a petite échelle", new Point (50, 70));
+                               ctx.SetFontSize (12);
+                               ctx.FillText ("Test d'une string a petite échelle", new Point (50, 85));
+                               ctx.SetFontSize (14);
+                               ctx.FillText ("Test d'une string a petite échelle", new Point (50, 100));
+
+                               ctx.FillText ("c1: " + string.Format("{0:##.000}",coef1), new Point (300, 100));
+                               ctx.FillText ("c2: " + string.Format("{0:##.000}",coef2), new Point (300, 120));
+                               ctx.FillText ("c3: " + string.Format("{0:##.000}",coef3), new Point (300, 140));
+                               ctx.FillText ("cA: " + string.Format("{0:##.000}",coefA), new Point (300, 160));
+
+                               ctx.Rectangle(new Rectangle(10,10,40,100));
+                               ctx.Stroke ();
+                               ctx.SetFontSize (40);
+                               ctx.FillText ("ceci est un test de string", new Point (2, 200));
+                               ctx.Fill ();
+//                             ctx.LineWidth = 1.0;
+//                             ctx.MoveTo (300, 10);
+//                             ctx.LineTo (300, 350);
+//                             ctx.Color = new Color (1.0, 0.5, 0.0, 1.0);
+//                             ctx.Stroke ();
+//                             ctx.MoveTo (301, 10);
+//                             ctx.LineTo (301, 350);
+//                             ctx.Color = new Color (0.0, 0.5, 1.0, 1.0);
+//                             ctx.Stroke ();
+//                             ctx.Rectangle(new Rectangle(100,100,200,200));
+                               //ctx.Clip ();
+//                             for (int i = 0; i < 25; i++) {
+//                                     
+//                                     
+//                                     angle += Math.PI / 10000;
+//                                     if (angle > Math.PI * 2)
+//                                             angle = 0;
+//
+//                                     
+//                                     ctx.Color = new Color (1.0 / i, 1, 0, 0.1);
+//                                     ctx.Translate (-200, -200);
+//                                     ctx.Rotate (angle);
+//                                     ctx.Translate (200, 200);
+//                                     
+//                                     
+//                                     ctx.Rectangle (new Rectangle (0, 0, 400, 400));
+//                                     DrawRoundedRectangle (ctx, 100, 100, 70, 70, 10);
+//                                     ctx.FillPreserve ();
+//                                     ctx.Color = go.Color.White;
+//                                     ctx.Stroke ();
+//                             }
+                               surf.Save (@"/home/jp/surf.png");
+
+                               if (GL.IsTexture(magTex))
+                                       GL.DeleteTexture(magTex);
+
+                               magTex = ctx.copyCurentSurfaceToTexture ();
+
+//                             GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
+//                             GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+//
+                       }
+
+                       float inc = 0.01f;
+                       if (Keyboard [Key.ShiftLeft])
+                               inc = 0.1f;
+                       if (Keyboard[Key.Keypad1])
+                               coef1 -= inc;
+                       if (Keyboard[Key.Keypad2])
+                               coef2 -= inc;
+                       if (Keyboard[Key.Keypad3])
+                               coef3 -= inc;
+                       if (Keyboard[Key.Keypad4])
+                               coef1 = 0f;
+                       if (Keyboard[Key.Keypad5])
+                               coef2 = 0f;
+                       if (Keyboard[Key.Keypad6])
+                               coef3 = 0f;
+                       if (Keyboard[Key.Keypad7])
+                               coef1 += inc;
+                       if (Keyboard[Key.Keypad8])
+                               coef2 += inc;
+                       if (Keyboard[Key.Keypad9])
+                               coef3 += inc;
+                       if (Keyboard[Key.KeypadAdd])
+                               coefA += inc;
+                       if (Keyboard[Key.KeypadSubtract])
+                               coefA -= inc;
+                       //Debug.WriteLine (fps);
+
+               }
+               protected override void OnKeyPress (KeyPressEventArgs e)
+               {
+                       base.OnKeyPress (e);
+                       if (e.KeyChar == 'c') {
+                               if (background == Color.Black) {
+                                       background = Color.White;
+                                       foreground = Color.Black;
+                               } else {
+                                       background = Color.Black;
+                                       foreground = Color.White;
+                               }
+                       }
+               }
+               protected override void OnResize (EventArgs e)
+               {
+                       base.OnResize (e);
+                       UpdateViewMatrix();
+               }
+
+               #region Mouse Handling
+               void Object_Mouse_Move(object sender, MouseMoveEventArgs e){
+                       if (activeWidget == null)
+                               return;
+
+                       activeWidget.registerClipRect ();
+                       if (activeWidget!=null) {
+                               activeWidget.Left += e.XDelta;
+                               activeWidget.Top += e.YDelta;
+                       }
+               }
+               void Mouse_Move(object sender, MouseMoveEventArgs e)
+               {
+                       if (e.XDelta != 0 || e.YDelta != 0)
+                       {
+                               if (e.Mouse.MiddleButton == OpenTK.Input.ButtonState.Pressed)
+                               {
+                                       Matrix4 m = Matrix4.CreateRotationZ(-e.XDelta * RotationSpeed);
+                                       m *= Matrix4.CreateFromAxisAngle(-vLookPerpendicularOnXYPlane, -e.YDelta * RotationSpeed);
+                                       vEyeTarget = Vector3.Zero;
+                                       vEye = Vector3.Transform(vEye, Matrix4.CreateTranslation(-vEyeTarget) * m * Matrix4.CreateTranslation(vEyeTarget));
+                                       UpdateViewMatrix();
+                               }
+                               if (e.Mouse.RightButton == ButtonState.Pressed)
+                               {
+
+                                       Matrix4 m = Matrix4.CreateRotationZ(-e.XDelta * RotationSpeed);
+                                       Matrix4 m2 = Matrix4.Rotate(vLookPerpendicularOnXYPlane, e.YDelta * RotationSpeed);
+
+                                       vEyeTarget = Vector3.Transform(vEyeTarget, Matrix4.CreateTranslation(-vEye) * m * m2 * Matrix4.CreateTranslation(vEye));
+
+                                       //vLook = Vector3.Transform(vLook, m2);
+                                       UpdateViewMatrix();
+
+                               }
+                       }
+               }                       
+               void Mouse_WheelChanged(object sender, MouseWheelEventArgs e)
+               {
+                       float speed = MoveSpeed;
+                       if (Keyboard[Key.ShiftLeft])
+                               speed *= 0.1f;
+                       else if (Keyboard[Key.ControlLeft])
+                               speed *= 20.0f;
+
+                       vLook = Vector3.NormalizeFast(vEye - vEyeTarget);
+                       vEye -= vLook * e.Delta * speed;
+                       UpdateViewMatrix();
+               }
+               #endregion
+
+               #region vLookCalculations
+               Vector3 vLookDirOnXYPlane
+               {
+                       get
+                       {
+                               Vector3 v = Vector3.NormalizeFast(vEye - vEyeTarget);
+                               v.Z = 0;
+                               return v;
+                       }
+               }
+               public Vector3 vLookPerpendicularOnXYPlane
+               {
+                       get
+                       {
+                               Vector3 vLook = Vector3.NormalizeFast(vEye - vEyeTarget);
+                               vLook.Z = 0;
+
+                               Vector3 vHorizDir = Vector3.Cross(vLook, Vector3.UnitZ);
+                               return vHorizDir;
+                       }
+               }
+
+               void moveCamera(Vector3 v)
+               {
+                       vEye += v;
+                       vEyeTarget += v;
+               }
+               #endregion
+
+               public void UpdateViewMatrix()
+               {
+//                     Rectangle r = this.ClientRectangle;
+//                     GL.Viewport( r.X, r.Y, r.Width, r.Height);
+//                     projection = Matrix4.CreatePerspectiveFieldOfView(fovY, r.Width / (float)r.Height, zNear, zFar);
+//                     GL.MatrixMode(MatrixMode.Projection);
+//                     GL.LoadIdentity();
+//
+//                     GL.LoadMatrix(ref projection);
+//
+//                     modelview = Matrix4.LookAt(vEye, vEyeTarget, Vector3.UnitZ);
+//                     GL.MatrixMode(MatrixMode.Modelview);
+//                     GL.LoadIdentity();
+//                     GL.LoadMatrix(ref modelview);
+               }
+               [STAThread]
+               static void Main ()
+               {
+                       Console.WriteLine ("starting example");
+
+                       using (GOLIBTestglb win = new GOLIBTestglb( )) {
+                               win.Run (30.0);
+                       }
+               }
+       }
+}
+//using (Context ctx = new Context (surf)) {
+//     //for (int i = 0; i < 150; i++) {
+//
+//
+//     //                                      angle += Math.PI / 100000;
+//     //                                      if (angle > Math.PI * 2)
+//     //                                              angle = 0;
+//     //GL.
+//     //drawScene();
+//
+//     //                                      ctx.Color = new Color (1.0/i, 1, 0, 1);
+//     //                              ctx.Translate (-512, -400);
+//     //                              ctx.Rotate (angle);
+//     //                              ctx.Translate (512, 400);
+//     ctx.LineWidth = 1.0;
+//     ctx.Color = go.Color.LightBlue.AdjustAlpha(0.2);                        
+//     //                              ctx.MoveTo (100, 100);
+//     //                              ctx.LineTo (150, 150);
+//     //                              ctx.LineTo (300, 100);
+//     //                              ctx.LineTo (150, 200);
+//     //                              ctx.LineTo (500, 200);
+//     //                              ctx.LineTo (400, 100);
+//     //                              ctx.LineTo (600, 100);
+//     //                              ctx.LineTo (600, 600);
+//     //                              ctx.LineTo (200, 600);
+//     //                              ctx.LineTo (300, 300);
+//     //                              ctx.LineTo (100, 300);
+//     //                              //ctx.ClosePath ();
+//     //ctx.Rectangle(new go.Rectangle(100,600,60,80));
+//
+//     DrawRoundedRectangle (ctx, 200, 200, 70, 70,10);
+//     //                                      DrawRoundedRectangle (ctx, 300, 300, 70, 70,5);
+//     //                                      DrawRoundedRectangle (ctx, 400, 400, 70, 70,25);
+//     //                                      DrawRoundedRectangle (ctx, 500, 500, 70, 70,25);
+//     //                                      DrawRoundedRectangle (ctx, 600, 600, 100, 100,25);
+//
+//
+//     //**** concave shape
+//
+//     //                              ctx.LineTo (110, 200);
+//     //                              ctx.LineTo (400, 200);
+//     //                              ctx.LineTo (400, 100);
+//     //                              ctx.LineTo (200, 100);
+//     //                              ctx.LineTo (200, 50);
+//     //                              ctx.LineTo (500, 50);
+//     //                              ctx.LineTo (500, 200);
+//     //                              ctx.LineTo (400, 300);
+//     //                              ctx.LineTo (100, 300);
+//     //                              ctx.LineTo (50, 200);
+//     ctx.FillPreserve ();
+//     //*****************************
+//
+//     ctx.Color = go.Color.White;
+//     //ctx.Stroke ();
+//     //                                      ctx.LineTo (500, 50);
+//     //                                      ctx.LineTo (750, 500);
+//     //                                      ctx.LineTo (750, 50);
+//     //                                      ctx.MoveTo (100, 100);
+//     //                                      ctx.LineTo (200, 200);
+//     //                                      ctx.LineTo (100, 400);
+//     //                                      ctx.LineTo (300, 400);
+//     //                                      //ctx.LineTo (250, 300);
+//     //                                      ctx.Arc (300, 600, 100, 0, Math.PI);
+//     ctx.Stroke ();
+//}
+////}
index 9b4285a476cf817f633e15dda7121d6b252363e9..7588eff9d8cf026fff4d26a3cec1063aa9595a7c 100644 (file)
@@ -3,13 +3,6 @@ using Cairo;
 
 namespace go
 {
-       public enum FontStyle
-       {
-               Normal,
-               Bold,
-               Italic,
-               Underlined
-       }
        public class Font
        {
                #region CTOR
index 1b6f24374948ef21de2647f652f1520e4da446fa..aa3720fbb2375b3548067fb445c7f010860f0967 100644 (file)
@@ -139,9 +139,9 @@ namespace go
                                                if (!string.IsNullOrEmpty (ClassName))
                                                        break;
                                                if (CurrentGOMLPath.StartsWith ("#"))
-                                                       ClassName = Path.GetFileNameWithoutExtension (CurrentGOMLPath.Substring (1));
+                                                       ClassName = System.IO.Path.GetFileNameWithoutExtension (CurrentGOMLPath.Substring (1));
                                                else
-                                                       ClassName = Path.GetFileNameWithoutExtension (CurrentGOMLPath);
+                                                       ClassName = System.IO.Path.GetFileNameWithoutExtension (CurrentGOMLPath);
                                                break;
                                        }
                                }
@@ -228,9 +228,9 @@ namespace go
                                                                newClassName = reader.GetAttribute ("Class");
                                                                if (string.IsNullOrEmpty (newClassName)) {
                                                                        if (path.StartsWith ("#"))
-                                                                               newClassName = Path.GetFileNameWithoutExtension (path.Substring (1));
+                                                                               newClassName = System.IO.Path.GetFileNameWithoutExtension (path.Substring (1));
                                                                        else
-                                                                               newClassName = Path.GetFileNameWithoutExtension (path);
+                                                                               newClassName = System.IO.Path.GetFileNameWithoutExtension (path);
                                                                }
                                                                curType = Type.GetType ("go." + root);
 
diff --git a/src/OpenGL/GLBackend/ClipShader.cs b/src/OpenGL/GLBackend/ClipShader.cs
new file mode 100644 (file)
index 0000000..a805716
--- /dev/null
@@ -0,0 +1,40 @@
+using System;
+using OpenTK.Graphics.OpenGL;
+
+namespace go.GLBackend
+{
+       public class ClipShader : Shader
+       {
+               public ClipShader ()
+               {
+                       vertSource = @"
+                               #version 130
+
+                               precision highp float;
+
+                               uniform mat4 projection_matrix;
+                               uniform mat4 modelview_matrix;
+
+                               in vec2 in_position;
+
+                               void main(void)
+                               {
+                                       gl_Position = projection_matrix * modelview_matrix * vec4(in_position,0, 1);
+                               }";
+
+                       fragSource = @"
+                               #version 130
+                               precision highp float;
+
+                               out vec4 out_frag_color;
+
+                               void main(void)
+                               {
+                                       out_frag_color = vec4(1.0,1.0,1.0,1.0);
+                               }";
+
+                       Compile ();
+               }
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Context.cs b/src/OpenGL/GLBackend/Context.cs
new file mode 100644 (file)
index 0000000..51d5d86
--- /dev/null
@@ -0,0 +1,887 @@
+#define     MPERF
+//#define GPU_TIME_MSR
+
+using System;
+using OpenTK.Graphics.OpenGL;
+using OpenTK;
+using System.Collections.Generic;
+using System.Linq;
+using System.Diagnostics;
+using System.Drawing.Imaging;
+
+
+
+namespace go.GLBackend
+{
+       public class Context : IDisposable
+       {
+               #region CTOR
+               public Context (Surface _surf)
+               {
+                       surf = _surf;
+
+                       saveGLConfig ();
+
+                       createStencilTexture ();
+
+                       fboId = createFbo (surf.texId);
+                               
+                       projectionMatrix = Matrix4.CreateOrthographicOffCenter 
+                               (0, surf.width, surf.height, 0, 0, 1);
+                       modelviewMatrix = Matrix4.Identity;
+
+                       if (shader == null)
+                               shader = new Shader ();
+                       if (texturedShader == null)
+                               texturedShader = new TexturedShader ();
+                       if (clipShader == null)
+                               clipShader = new ClipShader ();
+                       if (fontShader == null)
+                               fontShader = new FontShader ();
+
+
+                       GL.Viewport (0, 0, surf.width, surf.height);
+                       GL.PrimitiveRestartIndex (int.MaxValue);
+                       GL.Enable (EnableCap.PrimitiveRestart);
+                       GL.Enable (EnableCap.Blend);
+                       GL.BlendFunc (BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
+
+                       //GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboId);
+
+                       //                      GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+                       //                      GL.Clear(ClearBufferMask.ColorBufferBit);
+               }
+               #endregion
+
+               #if (DEBUG && MPERF)
+               Stopwatch sw_fill = new Stopwatch ();
+               Stopwatch sw_stroke = new Stopwatch ();
+               #endif
+
+               #if GPU_TIME_MSR
+               ulong gpuTime = 0;
+               ulong gpuTimeCpt = 0;
+               #endif
+
+               public float coef1 = 1.0f;
+               public float coef2 = 0.5f;
+               public float coef3 = 0.0f;
+               public float coefA = 1.0f;
+
+               static Shader shader;
+               static Shader clipShader;
+               static Shader texturedShader;
+               static FontShader fontShader;
+
+               static List<glFont> fontsCache = new List<glFont>();
+
+               #region Private Fields
+               Surface surf;
+               Surface sourceSurface;//should be a pattern object from which surf would be derrived
+
+               double lineWidth = 1.0;
+               Color color = Color.White;
+               LineCap lineCap = LineCap.Butt;
+               LineJoin lineJoint = LineJoin.Miter;
+
+               FontFace fontFace;
+               uint fontSize = 10;
+               //path building temp fields
+               Vector2 curPos = new Vector2(0f,0f);
+               List<Path> pathes = new List<Path> ();
+               Path cpath;//current path
+
+               int fboId;
+               int stencilTexId;
+               VertexArrayObject vao;
+
+               Matrix4 projectionMatrix, 
+                               modelviewMatrix;
+
+               bool stencilTest = false;
+
+               VertexArrayObject paint_vao; //quad used to paint source on context
+
+               //path limits used in fill
+               float   minX,maxX,minY,maxY,
+                               polyWidth, polyHeight;
+
+               #endregion
+
+               #region Public properties
+               public double LineWidth {
+                       get { return lineWidth; }
+                       set { lineWidth = value; }
+               }
+               public Color Color {
+                       get { return color; }
+                       set { color = value; }
+               }
+               public LineCap LineCap {
+                       get { return lineCap;}
+                       set {lineCap = value;}
+               }
+               public LineJoin LineJoint {
+                       get {return lineJoint;}
+                       set {lineJoint = value;}
+               }
+               #endregion
+
+               #region Private functions
+               int createFbo(int texID)
+               {
+                       //GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
+                       int fbo;
+                       GL.GenFramebuffers(1,out fbo);
+                       GL.BindFramebuffer(FramebufferTarget.Framebuffer, fbo);
+                       GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, 
+                               FramebufferAttachment.ColorAttachment0,
+                               TextureTarget.Texture2D,texID,0);
+
+                       //GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
+                       FramebufferErrorCode fbErr = GL.CheckFramebufferStatus (FramebufferTarget.Framebuffer);
+
+                       switch (fbErr) {
+                       case FramebufferErrorCode.FramebufferUndefined:
+                               break;
+                       case FramebufferErrorCode.FramebufferComplete:
+                               //Debug.WriteLine ("FBO complete");
+                               break;
+                       case FramebufferErrorCode.FramebufferIncompleteAttachment:
+                               Debug.WriteLine ("FBO incomplete attachment");
+                               break;
+                       case FramebufferErrorCode.FramebufferIncompleteMissingAttachment:
+                               Debug.WriteLine ("FBO missing attachment");
+                               break;
+                       default:
+                               Debug.WriteLine ("FBO error");
+                               break;
+                       }
+                       return fbo;
+               }
+               public int copyCurentSurfaceToTexture()
+               {
+                       //create a new fbo to blit to with an empty texture
+                       Surface tmp = surf.CreateSimilar ();
+                       int dstFbo = createFbo (tmp.texId);//we are binded to new fbo (read&write)
+                       //bind read to Context fbo;
+                       GL.BindFramebuffer (FramebufferTarget.ReadFramebuffer, fboId);
+                       GL.BindFramebuffer (FramebufferTarget.DrawFramebuffer, dstFbo);
+
+                       GL.BlitFramebuffer (0, 0, surf.width, surf.height, 0, 0, surf.width, surf.height,
+                               ClearBufferMask.ColorBufferBit,BlitFramebufferFilter.Nearest);
+
+                       //bind write fbo to Context
+                       GL.BindFramebuffer (FramebufferTarget.Framebuffer, fboId);
+                       //delete temp fbo
+                       GL.DeleteFramebuffer (dstFbo);
+                       return tmp.texId;
+               }
+               void createStencilTexture(){
+                       stencilTexId = GL.GenTexture();
+                       GL.BindTexture(TextureTarget.Texture2D, stencilTexId);
+                       GL.TexImage2D(TextureTarget.Texture2D,0,
+                               PixelInternalFormat.R8, surf.width, surf.height,0,
+                               OpenTK.Graphics.OpenGL.PixelFormat.Red, PixelType.UnsignedByte,IntPtr.Zero);
+
+                       GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
+                       GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+                       GL.BindTexture(TextureTarget.Texture2D, 0);
+               }
+               void clear_path()
+               {
+                       pathes.Clear ();
+                       curPos = new Vector2 (0f, 0f);
+                       cpath = null;
+               }
+               void addPath(Path _path){
+                       if (_path == null)
+                               return;
+                       if (_path.Count > 1)
+                               pathes.Add (_path);
+               }
+               //TODO: 360° will fail
+               double NormalizeAngle(double a)
+               {
+                       double res = a % (2*Math.PI);
+                       return res < 0 ? res + 2*Math.PI : res;
+               }
+               #endregion
+
+               #region Public functions
+               #region Main drawing functions
+               public void Stroke()
+               {
+                       stroke_internal ();
+                       clear_path ();
+               }
+               public void StrokePreserve()
+               {
+                       stroke_internal ();
+               }
+               public void Fill()
+               {
+                       fill_internal ();
+                       clear_path ();
+               }
+               public void FillPreserve()
+               {
+                       fill_internal ();
+               }
+               public void Paint()
+               {
+                       if (paint_vao == null)
+                               return;
+                       texturedShader.Enable ();
+                       //shader.LineWidth = lineWidth;
+                       texturedShader.ProjectionMatrix = projectionMatrix;
+                       texturedShader.ModelViewMatrix = modelviewMatrix;
+                       texturedShader.Color = new Vector4(1f,1f,1f,1f);
+
+                       GL.ActiveTexture (TextureUnit.Texture0);
+                       GL.BindTexture (TextureTarget.Texture2D, sourceSurface.texId);
+
+                       paint_vao.Render (PrimitiveType.TriangleStrip);
+
+                       GL.BindTexture (TextureTarget.Texture2D, 0);
+
+                       texturedShader.Disable ();
+               }
+               public void SetSourceSurface (Surface _source, int x, int y)
+               {
+                       sourceSurface = _source;
+
+                       if (paint_vao != null)
+                               paint_vao.Dispose ();
+
+
+                       paint_vao = new QuadVAO (x,y,sourceSurface.width,sourceSurface.height);
+               }
+               #region Clipping
+               public void Clip()
+               {
+                       clip_internal ();
+                       clear_path ();
+               }
+               public void ClipPreserve()
+               {
+                       clip_internal ();
+                       clear_path ();
+               }
+               public void ResetClip()
+               {
+                       stencilTest = false;
+
+                       GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, 
+                               FramebufferAttachment.ColorAttachment0,
+                               TextureTarget.Texture2D,stencilTexId,0);
+
+
+                       GL.Clear (ClearBufferMask.ColorBufferBit);
+
+                       GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, 
+                               FramebufferAttachment.ColorAttachment0,
+                               TextureTarget.Texture2D,surf.texId,0);
+               }
+               #endregion
+
+               #region Fonts & text handling
+               public void SelectFontFace(string _fontName, FontSlant _slant, FontWeight _weight){
+                       Font tmp = _fontName;
+                       switch (_slant) {
+                       case FontSlant.Italic:
+                               tmp.Style |= FontStyle.Italic;
+                               break;
+                       case FontSlant.Oblique:
+                               tmp.Style |= FontStyle.Oblique;
+                               break;
+                       }
+                       if (_weight == FontWeight.Bold)
+                               tmp.Style |= FontStyle.Bold;
+
+                       fontFace = FontFace.SearchFont (tmp);
+               }
+               public void SetFontSize(uint _fontSize){
+                       fontSize = _fontSize;
+                       if (!fontFace.glyphesCache.ContainsKey(fontSize))
+                               fontFace.buildGlyphesTextures (fontSize, 0, 0xFF);
+               }
+               public FontExtents FontExtents {
+                       get {
+                               return fontFace.originalFontExtents;
+                       }
+               }
+               public TextExtents TextExtents(string s)
+               {
+                       TextExtents te = new go.GLBackend.TextExtents ();
+
+                       int penX = 0,
+                               penY = 0;
+
+                       for (int i = 0; i < s.Length; i++) {
+                               uint c = (uint)s [i];
+                               glGlyph g = fontFace.glyphesCache [fontSize] [c];
+                               penX += (int)g.advanceX;
+                               penY += (int)g.advanceY;
+                       }
+
+                       te.XAdvance = penX;
+                       te.YAdvance = penY;
+                       return te;
+               }
+               public void FillText(string text, Point _pt)
+               {
+                       buildTextVAO (text,_pt);
+
+                       int backTex = copyCurentSurfaceToTexture ();
+
+                       fontShader.Enable ();
+                       //shader.LineWidth = lineWidth;
+                       fontShader.ProjectionMatrix = projectionMatrix;
+                       fontShader.ModelViewMatrix = modelviewMatrix;
+                       fontShader.Color = new Vector4(
+                               (float)color.R,
+                               (float)color.G,
+                               (float)color.B,
+                               (float)color.A);
+                       fontShader.Resolution = new Vector2 (surf.width, surf.height);
+                       fontShader.coef1 = coef1;
+                       fontShader.coef2 = coef2;
+                       fontShader.coef3 = coef3;
+                       fontShader.coefA = coefA;
+//                     shader.StencilTest = stencilTest;
+//
+//                     if (stencilTest) {
+//                                     shader.Resolution = new Vector2 (surf.width, surf.height);
+//                             GL.ActiveTexture (TextureUnit.Texture0);
+//                             GL.BindTexture (TextureTarget.Texture2D, stencilTexId);
+//                     }
+
+                       GL.ActiveTexture (TextureUnit.Texture0);
+                       GL.BindTexture (TextureTarget.Texture2D, curFontTex);
+                       GL.ActiveTexture (TextureUnit.Texture1);
+                       GL.BindTexture (TextureTarget.Texture2D, backTex);
+
+                       vao.Render (PrimitiveType.TriangleStrip);
+                       vao.Dispose ();
+
+                       //                      #if DEBUG
+                       //                      ErrorCode err = GL.GetError ();
+                       //                      if (err != ErrorCode.NoError)
+                       //                              Debug.WriteLine ("Stroke_internal error: " + err.ToString ());
+                       //                      #endif
+
+                       fontShader.Disable ();
+
+                       GL.BindTexture (TextureTarget.Texture2D, 0);
+                       GL.ActiveTexture (TextureUnit.Texture0);
+                       GL.BindTexture (TextureTarget.Texture2D, 0);
+
+                       //destroy background texture
+                       GL.DeleteTexture (backTex);
+                       //GL.Enable (EnableCap.Blend);
+               }
+               #endregion
+
+               #endregion
+
+
+
+               #region Path handling functions
+               public void MoveTo(double x, double y)
+               {
+                       addPath (cpath);
+                       cpath = new Path ();
+                       curPos = new Vector2 ((float)x, (float)y);
+               }
+               public void LineTo(double x, double y)
+               {
+                       if (cpath==null)
+                               cpath = new Path ();
+                       if (cpath.Count == 0)
+                               cpath.Add (curPos);
+                       curPos = new Vector2 ((float)x, (float)y);
+                       cpath.Add (curPos);
+               }
+               public void Rectangle(Rectangle r)
+               {
+                       MoveTo (r.X, r.Y);
+                       LineTo (r.Right, r.Y);
+                       LineTo (r.Right, r.Bottom);
+                       LineTo (r.X, r.Bottom);
+                       ClosePath ();
+               }
+               public void Arc(double xc, double yc, double radius, double angle1, double angle2)
+               {
+                       angle1 = NormalizeAngle (angle1);
+                       angle2 = NormalizeAngle (angle2);
+
+                       if (angle1 > angle2)
+                               angle2 += Math.PI * 2.0;
+                       double  a = angle1,
+                       //step = Math.PI/16;
+                       step =Math.PI * 2/(radius+20);
+
+                       Vector2 v = new Vector2 ((float)(Math.Cos (a) * radius + xc), (float)(Math.Sin (a) * radius + yc));
+                       if (v!=curPos)
+                               cpath.Add (v);
+                       int cpt = 0;
+                       while(true){
+                               if (a<angle2){
+                                       a+=step;
+                                       if (a > angle2)
+                                               break;
+                                               //a = angle2;
+                               }else
+                                       break;
+                               cpt++;
+//                             if (a == angle2) {//add a point very close to a to get good termination angle
+//                                     v = new Vector2 ((float)(Math.Cos (a-0.001) * radius + xc), (float)(Math.Sin (a-0.001) * radius + yc));
+//                                     cpath.Add (v);
+//                             }
+
+                               v = new Vector2 ((float)(Math.Cos (a) * radius + xc), (float)(Math.Sin (a) * radius + yc));
+                               cpath.Add (v);
+
+                       }
+                       curPos = cpath [cpath.Count - 1];
+               }
+               public void ClosePath()
+               {
+                       if (cpath == null)
+                               return;
+                       if (cpath.Count < 3)//cannot close path with less than 3 points
+                               return;
+                               
+                       cpath.IsClosed = true;
+
+                       MoveTo (cpath [0].X, cpath [0].Y);
+               }
+               #endregion
+
+               #region Transformations
+               public void Translate(double tx, double ty)
+               {
+                       modelviewMatrix *= Matrix4.CreateTranslation ((float)tx, (float)ty, 0f);
+               }
+               public void Scale(double sx, double sy)
+               {
+                       modelviewMatrix *= Matrix4.CreateScale ((float)sx, (float)sy, 0f);
+               }
+               public void Rotate(double angle){
+                       modelviewMatrix *= Matrix4.CreateRotationZ ((float)angle);
+               }
+               #endregion
+               #endregion
+
+               //temp Lists used to build arrays for vao
+               List<Vector2> vertices = new List<Vector2> ();
+               List<int> indices = new List<int> ();
+               List<Vector2> texCoords = new List<Vector2> ();
+               int idxOffset = 0;      //offset in vertices array between pathes
+
+
+               void initVAOsCache()
+               {
+                       if (vertices != null)
+                               return;
+                       vertices = new List<Vector2> ();
+                       indices = new List<int> ();
+                       texCoords = new List<Vector2> ();
+                       idxOffset = 0;
+               }
+               void flush(){
+                       vao = new VertexArrayObject (
+                               vertices.ToArray (),
+                               texCoords.ToArray (), 
+                               indices.ToArray ());
+
+                       vertices = null;
+                       indices = null;
+                       texCoords = null;
+               }
+
+               void stroke_internal()
+               {
+                       buildStrokeVAOs ();
+
+                       #if GPU_TIME_MSR
+                       ulong gpuTimeStart, gpuTimeStop;
+                       gpuTimeStart = (ulong)GL.GetInteger64 (GetPName.Timestamp);
+                       #endif
+
+                       shader.Enable ();
+                       //shader.LineWidth = lineWidth;
+                       shader.ProjectionMatrix = projectionMatrix;
+                       shader.ModelViewMatrix = modelviewMatrix;
+                       shader.Color = new Vector4(
+                               (float)color.R,
+                               (float)color.G,
+                               (float)color.B,
+                               (float)color.A);
+                       shader.StencilTest = stencilTest;
+                               
+                       if (stencilTest) {
+                               shader.Resolution = new Vector2 (surf.width, surf.height);
+                               GL.ActiveTexture (TextureUnit.Texture0);
+                               GL.BindTexture (TextureTarget.Texture2D, stencilTexId);
+                       }
+
+                       vao.Render (PrimitiveType.TriangleStrip);
+                       vao.Dispose ();
+
+//                     #if DEBUG
+//                     ErrorCode err = GL.GetError ();
+//                     if (err != ErrorCode.NoError)
+//                             Debug.WriteLine ("Stroke_internal error: " + err.ToString ());
+//                     #endif
+
+                       shader.Disable ();
+
+                       GL.BindTexture (TextureTarget.Texture2D, 0);
+
+                       #if GPU_TIME_MSR
+                       gpuTimeStop = (ulong)GL.GetInteger64 (GetPName.Timestamp);
+                       Debug.WriteLine(gpuTimeStop - gpuTimeStart);
+                       #endif
+               }
+               void fill_internal()
+               {
+                       buildFillVAOs ();
+
+                       shader.Enable ();
+                       //shader.LineWidth = lineWidth;
+                       shader.ProjectionMatrix = projectionMatrix;
+                       shader.ModelViewMatrix = modelviewMatrix;
+                       shader.Color = new Vector4(
+                               (float)color.R,
+                               (float)color.G,
+                               (float)color.B,
+                               (float)color.A);
+                       shader.StencilTest = stencilTest;
+
+                       if (stencilTest) {
+                               shader.Resolution = new Vector2 (surf.width, surf.height);
+                               GL.ActiveTexture (TextureUnit.Texture0);
+                               GL.BindTexture (TextureTarget.Texture2D, stencilTexId);
+                       }
+
+                       vao.Render (PrimitiveType.Triangles);
+                       vao.Dispose ();
+
+                       shader.Disable ();
+
+                       GL.BindTexture (TextureTarget.Texture2D, 0);
+               }
+               void clip_internal()
+               {
+                       GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, 
+                               FramebufferAttachment.ColorAttachment0,
+                               TextureTarget.Texture2D,stencilTexId,0);
+
+                       if (!stencilTest)
+                               GL.Clear (ClearBufferMask.ColorBufferBit);
+                       stencilTest = true;
+
+                       buildFillVAOs ();
+
+                       clipShader.Enable ();
+                       //shader.LineWidth = lineWidth;
+                       clipShader.ProjectionMatrix = projectionMatrix;
+                       clipShader.ModelViewMatrix = modelviewMatrix;
+
+                       vao.Render (PrimitiveType.Triangles);
+                       vao.Dispose ();
+
+                       clipShader.Disable ();
+
+                       GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, 
+                               FramebufferAttachment.ColorAttachment0,
+                               TextureTarget.Texture2D,surf.texId,0);
+               }
+
+               void buildFillVAOs()
+               {
+                       #if (DEBUG && MPERF)
+                       sw_fill.Start();
+                       #endif
+
+                       addPath (cpath);
+
+                       initVAOsCache ();
+
+                       float hlw = (float)lineWidth / 2.0f;//half line width
+
+                       Vector2 vDir,vDir2;
+                       bool genTexCoords = false;
+
+                       for (int j = 0; j < pathes.Count; j++) {
+                               Path path = new Path(pathes[j]);
+                               //keep an array containing real vertex indice
+                               List<int> vertIdx = new List<int> (Enumerable.Range(0,path.Count));
+
+                               #region get polygon bounds for texture mapping
+                               if (genTexCoords){
+                                       minX = float.MaxValue;
+                                       maxX = float.MinValue;
+                                       minY = float.MaxValue;
+                                       maxY = float.MinValue;
+
+                                       foreach (Vector2 p in path) {
+                                               if (p.X < minX)
+                                                       minX = p.X;
+                                               if (p.Y < minY)
+                                                       minY = p.Y;
+                                               if (p.X > maxX)
+                                                       maxX = p.X;
+                                               if (p.Y > maxY)
+                                                       maxY = p.Y;
+                                       }
+                                       polyWidth = maxX - minX;
+                                       polyHeight = maxY - minY;
+                               }
+                               #endregion
+
+                               vertices.AddRange (path);//we only play on indices
+                               int ptrS = 0, ptrS1, ptrS2; //index du sommet dans le path
+                               while (path.Count > 3) {
+                                       if (ptrS == path.Count)
+                                               ptrS = 0;
+
+                                       if (ptrS < path.Count - 2) {
+                                               ptrS1 = ptrS + 1;
+                                               ptrS2 = ptrS + 2;
+                                       } else if (ptrS < path.Count - 1) {
+                                               ptrS1 = ptrS + 1;
+                                               ptrS2 = 0;
+                                       } else {
+                                               ptrS1 = 0;
+                                               ptrS2 = 1;
+                                       }
+
+                                       //should test only concavity points if any
+                                       vDir = Vector2.NormalizeFast (path [ptrS1] - path [ptrS]);
+                                       vDir2 = Vector2.NormalizeFast (path [ptrS2] - path [ptrS]);
+
+                                       float dotP = Vector2.Dot (vDir.PerpendicularLeft, vDir2);
+                                       //double angle = Math.Acos((double)dotP);
+//
+//                                     Debug.WriteLine (dotP);
+//                                     Debug.WriteLine (angle);
+
+                                       if (dotP <= 0) {
+                                               //triangle is invalid
+                                               ptrS++;
+                                               continue;
+                                       }
+                                               
+                                       //check if no other points of path is inside tri
+//                                     bool triangleIsValid = true;
+//                                     int i = ptrS + 3;
+//                                     if (i >= path.Count)
+//                                             i -= path.Count;
+//                                     while (i != ptrS) {
+//                                             if (PointInTriangle (path [i],path [ptrS] , path [ptrS1], path [ptrS2])) {
+//                                                     ptrS++;
+//                                                     triangleIsValid = false;
+//                                                     break;
+//                                             }
+//                                             i++;
+//                                             if (i == path.Count)
+//                                                     i = 0;
+//                                     }
+//                                     if (!triangleIsValid)
+//                                             continue;
+                                       //triangle is valid, add tri to primitive to draw
+                                       //and remove middle sommet from path[];
+                                       addFillTriangle (j, vertIdx [ptrS], vertIdx [ptrS1], vertIdx [ptrS2]);
+
+                                       path.RemoveAt (ptrS1);
+                                       vertIdx.RemoveAt (ptrS1);
+                               }
+                               if (path.Count == 3)
+                                       addFillTriangle (j, vertIdx [0], vertIdx [1], vertIdx [2]);
+
+                               if (j < pathes.Count - 1) {                             
+                                       idxOffset += pathes[j].Count;
+                               }
+                       }
+                       flush ();
+
+                       #if (DEBUG && MPERF)
+                       sw_fill.Stop();
+                       #endif
+               }
+
+               int curFontTex;
+               void buildTextVAO(string text, Point pt)
+               {
+                       initVAOsCache ();
+
+                       int penX = pt.X,
+                       penY = pt.Y + (int)fontFace.originalFontExtents.Ascent;
+
+                       for (int i = 0; i < text.Length; i++) {
+                               uint c = (uint)text [i];
+                               glGlyph g = fontFace.glyphesCache [fontSize] [c];
+                               curFontTex = g.texId;
+                               vertices.Add (new Vector2(penX + g.bmpLeft, penY - g.bmpTop));
+                               vertices.Add (new Vector2(penX + g.bmpLeft, penY - g.bmpTop + g.dims.Height));
+                               vertices.Add (new Vector2(penX + g.bmpLeft + g.dims.Width, penY - g.bmpTop));
+                               vertices.Add (new Vector2(penX + g.bmpLeft + g.dims.Width, penY - g.bmpTop + g.dims.Height));
+                               indices.Add (int.MaxValue);//primitive restart
+                               indices.Add (i*4);
+                               indices.Add (i*4 + 1);
+                               indices.Add (i*4 + 2);
+                               indices.Add (i*4 + 3);
+                               texCoords.Add (new Vector2(g.texX,g.texY));
+                               texCoords.Add (new Vector2(g.texX,g.texY + g.texHeight));
+                               texCoords.Add (new Vector2(g.texX + g.texWidth,g.texY));
+                               texCoords.Add (new Vector2(g.texX + g.texWidth,g.texY + g.texHeight));
+
+                               penX += (int)g.advanceX;
+                               penY += (int)g.advanceY;
+                       }
+
+                       flush ();
+               }
+               void buildStrokeVAOs()
+               {
+                       addPath (cpath);
+
+                       initVAOsCache ();
+
+                       float hlw = (float)lineWidth / 2.0f;//half line width
+
+                       Vector2 vDir,vDir2, vPerp;
+                       float lPerp;
+                       int i;
+                       //current offset in index
+                       for (int j = 0; j < pathes.Count; j++) {
+                               Path path = pathes[j];  
+                               for (i = 0; i < path.Count; i++) {
+                                       lPerp = hlw;
+                                       vDir2 = Vector2.Zero;
+
+                                       if (i < path.Count - 1) {
+                                               vDir = Vector2.Normalize (path [i + 1] - path [i]);
+                                               if (i > 0) {
+                                                       vDir2 = Vector2.Normalize (path [i] - path [i - 1]);
+                                               } else if (path.IsClosed)
+                                                       vDir2 = Vector2.Normalize (path [0] - path [path.Count - 1]);
+                                       } else {
+                                               vDir = Vector2.Normalize (path [i] - path [i - 1]);
+                                               if (path.IsClosed)
+                                                       vDir2 = Vector2.Normalize (path [0]-path [i]);
+                                       }
+
+                                       vPerp = Vector2.Normalize(vDir+vDir2).PerpendicularLeft;
+
+                                       if (vDir2 != Vector2.Zero) {
+                                               double dotP = Vector2.Dot (vDir.PerpendicularLeft, vPerp);
+                                               double angle = Math.Acos(dotP);
+                                               double x = Math.Tan (angle) * hlw;
+
+                                               if (dotP == 0)
+                                                       lPerp = hlw;
+                                               else
+                                                       lPerp = (float)Math.Sqrt (Math.Pow (x, 2) + Math.Pow (hlw, 2));
+                                       }
+
+                                       vertices.Add (path [i] + vPerp * (float)lPerp);
+                                       vertices.Add (path [i] - vPerp * (float)lPerp);
+                                       indices.Add (idxOffset + i*2);
+                                       indices.Add (idxOffset + i*2 + 1);
+                                       texCoords.Add (Vector2.Zero);
+                                       texCoords.Add (Vector2.One);
+                               }
+                               if (path.IsClosed) {
+                                       indices.Add (idxOffset);
+                                       indices.Add (idxOffset+1);
+                                       texCoords.Add (Vector2.Zero);
+                                       texCoords.Add (Vector2.One);
+                               }
+                               if (j < pathes.Count - 1) {
+                                       indices.Add (int.MaxValue);     //restart primitive idex
+                                       idxOffset += path.Count * 2;
+                               }
+                       }
+                       flush ();
+               }
+                       
+               void addFillTriangle(int pathIdx, int vx1, int vx2, int vx3){
+                       addFillVertex (pathIdx, vx1);
+                       addFillVertex (pathIdx, vx2);
+                       addFillVertex (pathIdx, vx3);
+               }
+
+               void addFillVertex(int pathIdx, int vx){
+                       Vector2 p = pathes [pathIdx] [vx];
+                       indices.Add (idxOffset + vx);
+                       //texCoords.Add (new Vector2(1.0f/polyWidth*(p.X-minX),1.0f/polyHeight*(p.Y-minY)));
+               }
+
+               float sign (Vector2 p1, Vector2 p2, Vector2 p3)
+               {
+                       return (p1.X - p3.X) * (p2.Y - p3.Y) - (p2.X - p3.X) * (p1.Y - p3.Y);
+               }
+               bool PointInTriangle (Vector2 pt, Vector2 v1, Vector2 v2, Vector2 v3)
+               {
+                       bool b1, b2, b3;
+
+                       b1 = sign(pt, v1, v2) < 0.0f;
+                       b2 = sign(pt, v2, v3) < 0.0f;
+                       b3 = sign(pt, v3, v1) < 0.0f;
+
+                       return ((b1 == b2) && (b2 == b3));
+               }
+
+               #region GL Ctx Save and restore
+               int savedFbo,
+               savedPriRstIdx,
+               savedBlendSrc,
+               savedBlendDst;
+               int[] viewport = new int[4];
+               float[] savedClsColor = new float[4];
+               bool savedBlend,savedPriRstCap;
+               void saveGLConfig(){
+                       GL.GetInteger (GetPName.FramebufferBinding, out savedFbo);
+                       GL.GetInteger ((GetPName)All.PrimitiveRestartIndex, out savedPriRstIdx);
+                       GL.GetBoolean ((GetPName)All.PrimitiveRestart, out savedPriRstCap);
+                       GL.GetInteger(GetPName.Viewport, viewport);
+                       GL.GetFloat (GetPName.ColorClearValue, savedClsColor);
+                       GL.GetBoolean (GetPName.Blend, out savedBlend);
+                       GL.GetInteger (GetPName.BlendSrc, out savedBlendSrc);
+                       GL.GetInteger (GetPName.BlendDst, out savedBlendDst);
+               }
+               void restoreGLConfig(){
+                       GL.BindFramebuffer(FramebufferTarget.Framebuffer, savedFbo);
+
+                       GL.Viewport (viewport[0],viewport[1],viewport[2],viewport[3]);
+                       GL.PrimitiveRestartIndex (savedPriRstIdx);
+                       GL.ClearColor (savedClsColor [0], savedClsColor [1], savedClsColor [2], savedClsColor [3]);
+                       if (!savedBlend)
+                               GL.Disable (EnableCap.Blend);
+                       if (!savedPriRstCap)
+                               GL.Disable (EnableCap.PrimitiveRestart);
+                       GL.BlendFunc ((BlendingFactorSrc) savedBlendSrc,(BlendingFactorDest)savedBlendDst);
+               }
+               #endregion
+
+               #region IDisposable implementation
+
+               public void Dispose ()
+               {
+                       restoreGLConfig ();
+
+                       if (GL.IsFramebuffer (fboId))
+                               GL.DeleteFramebuffer (fboId);
+                       if (GL.IsTexture(stencilTexId))
+                               GL.DeleteTexture(stencilTexId);
+               }
+
+               #endregion
+
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Font/Font.cs b/src/OpenGL/GLBackend/Font/Font.cs
new file mode 100644 (file)
index 0000000..4ff3bb1
--- /dev/null
@@ -0,0 +1,115 @@
+using System;
+
+
+namespace go.GLBackend
+{
+       public class Font
+       {
+               public Font ()
+               {
+               }
+
+               public Font (string name, FontSlant fs, FontWeight fw)
+               {
+                       _name = name;
+                       switch (fs) {
+                       case FontSlant.Italic:
+                               Style |= FontStyle.Italic;
+                               break;
+                       case FontSlant.Oblique:
+                               Style |= FontStyle.Oblique;
+                               break;
+                       }
+                       if (fw == FontWeight.Bold)
+                               Style |= FontStyle.Bold;
+               }
+
+               string _name = "droid";
+               FontStyle _style = FontStyle.Normal;
+               FontFlag _flags = FontFlag.None;
+
+               int _size = 10;
+
+               public string Name {
+                       get { return _name; }
+                       set { _name = value; }
+               }
+               public FontStyle Style {
+                       get { return _style; }
+                       set { _style = value; }
+               }
+               public FontFlag Flags {
+                       get { return _flags; }
+                       set { _flags = value; }
+               }
+               public FontSlant Slant {
+                       get{ 
+                               if ((Style & FontStyle.Italic) == FontStyle.Italic)
+                                       return FontSlant.Italic;
+                               if ((Style & FontStyle.Oblique) == FontStyle.Oblique)
+                                       return FontSlant.Oblique;
+                               return FontSlant.Normal;
+                       }
+               }
+               public FontWeight Wheight {
+                       get{ return (Style & FontStyle.Bold) == FontStyle.Bold ? FontWeight.Bold : FontWeight.Normal; }
+               }
+               public int Size {
+                       get { return _size; }
+                       set { _size = value; }
+               }
+
+               #region Operators
+               public static implicit operator string(Font c)
+               {
+                       return c.ToString();
+               }
+               public static implicit operator Font(string s)
+               {
+                       Font f = new Font ();
+
+                       if (!string.IsNullOrEmpty (s)) {
+                               f.Name = "";
+                               string[] attribs = s.TrimStart().TrimEnd().Split(',');
+                               for (int i = 0; i < attribs.Length; i++) {
+                                       FontFlag fl;
+                                       FontStyle fs;
+                                       int sz;
+                                       if (Enum.TryParse<FontFlag> (attribs [i], true, out fl))
+                                               f.Flags |= fl;
+                                       else if (Enum.TryParse<FontStyle> (attribs [i], true, out fs))
+                                               f.Style |= fs;
+                                       else if (int.TryParse (attribs [i], out sz))
+                                               f.Size = sz;
+                                       else
+                                               f.Name += attribs[i] + " ";
+                               }
+                               f.Name = f.Name.Trim();
+                       }
+
+                       return f;
+               }
+               #endregion
+               public string FontFaceString
+               {
+                       get {
+                               string tmp = Name;
+                               if (Style != FontStyle.Normal)
+                                       tmp += "," + Style.ToString ();
+                               if (Flags != FontFlag.None)
+                                       tmp += "," + Flags.ToString ();
+                               return tmp;
+                       }
+               }
+               public override string ToString()
+               {
+                       return string.Format("{0},{1}", FontFaceString, _size);
+               }
+
+               public static object Parse(string s)
+               {
+                       return (Font)s;
+               }
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Font/FontExtents.cs b/src/OpenGL/GLBackend/Font/FontExtents.cs
new file mode 100644 (file)
index 0000000..f880244
--- /dev/null
@@ -0,0 +1,39 @@
+using System;
+
+namespace go.GLBackend
+{
+       public class FontExtents
+       {
+               double ascent;
+               double descent;
+               double height;
+               double maxXAdvance;
+               double maxYAdvance;
+
+               public double Ascent {
+                       get { return ascent; }
+                       set { ascent = value; }
+               }
+               public double Descent {
+                       get { return descent; }
+                       set { descent = value; }
+               }
+               public double Height {
+                       get { return height; }
+                       set { height = value; }
+               }
+               public double MaxXAdvance {
+                       get { return maxXAdvance; }
+                       set { maxXAdvance = value; }
+               }
+               public double MaxYAdvance {
+                       get { return maxYAdvance; }
+                       set { maxYAdvance = value; }
+               }
+
+               public FontExtents ()
+               {
+               }
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Font/FontFace.cs b/src/OpenGL/GLBackend/Font/FontFace.cs
new file mode 100644 (file)
index 0000000..0fe7523
--- /dev/null
@@ -0,0 +1,307 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using SharpFont;
+using System.Diagnostics;
+using System.Linq;
+using System.Text.RegularExpressions;
+using OpenTK.Graphics.OpenGL;
+
+namespace go.GLBackend
+{
+       public class FontFace
+       {
+               public static int testTexture;
+
+               static List<FontFace> fonts = new List<FontFace>();
+               public Dictionary<uint,Dictionary<uint, glGlyph>> glyphesCache = new Dictionary<uint, Dictionary<uint, glGlyph>>();
+
+               #region CTOR
+               public FontFace ()
+               {
+               }
+               #endregion
+
+               string _name = "droid";
+               string _family;
+               string _fontPath;
+               public FontExtents originalFontExtents;
+
+               FontStyle _style = FontStyle.Normal;
+               FontFlag _flags = FontFlag.None;
+
+               public string Name {
+                       get { return _name; }
+                       set { _name = value; }
+               }
+               public string Family {
+                       get {return _family;}
+                       set {_family = value;}
+               }
+               public string FontPath {
+                       get { return _fontPath; }
+                       set { _fontPath = value; }
+               }
+                       
+               public FontStyle Style {
+                       get { return _style; }
+                       set { _style = value; }
+               }
+               public FontFlag Flags {
+                       get { return _flags; }
+                       set { _flags = value; }
+               }
+
+               public FontSlant Slant {
+                       get{ 
+                               if ((Style & FontStyle.Italic) == FontStyle.Italic)
+                                       return FontSlant.Italic;
+                               if ((Style & FontStyle.Oblique) == FontStyle.Oblique)
+                                       return FontSlant.Oblique;
+                               return FontSlant.Normal;
+                       }
+               }
+               public FontWeight Wheight {
+                       get{ return (Style & FontStyle.Bold) == FontStyle.Bold ? FontWeight.Bold : FontWeight.Normal; }
+               }
+
+               public static FontFace SearchFont(Font font)
+               {
+                       FontFace[] tmp = fonts.Where (f =>
+                               (string.Compare(f.Name,font.Name,true)==0 && f.Style == font.Style)).ToArray();
+
+                       tmp = tmp.Where (f => (f.Flags & font.Flags) == font.Flags).OrderBy(f=>f.Flags).ToArray();
+
+                       return tmp.FirstOrDefault();
+               }
+
+               public static void BuildFontsList(string _path)
+               {
+                       DirectoryInfo dir = new DirectoryInfo (_path);
+                       try
+                       {
+                               using (Library lib = new Library())
+                               {
+                                       foreach (FileInfo f in dir.GetFiles("*.ttf",SearchOption.AllDirectories)) {
+                                               try {
+
+                                                       Face face = new Face(lib,f.FullName, 0);
+                                                       FontFace font = new FontFace();
+
+                                                       //TODO:test if font is scalable, if not=>continue
+                                                       font.Family = face.FamilyName;
+                                                       font.FontPath = f.FullName;
+                                                                                       
+                                                       //check if no particularities hidde in family name
+                                                       font.Name = "";
+                                                       string[] styles = face.FamilyName.Split(' ');
+                                                       for (int i = 0; i < styles.Length; i++) {
+                                                               FontFlag fl;
+                                                               FontStyle fs;
+                                                               if (Enum.TryParse<FontFlag> (styles [i], true, out fl))
+                                                                       font.Flags |= fl;
+                                                               else if (Enum.TryParse<FontStyle> (styles [i], true, out fs))
+                                                                       font.Style |= fs;
+                                                               else//add only unknown word to create shortest possible name
+                                                                       font.Name += styles[i] + " ";
+                                                       }
+                                                       font.Name = font.Name.Trim();
+
+                                                       styles = face.StyleName.Split(' ');
+                                                       for (int i = 0; i < styles.Length; i++) {
+                                                               switch (styles[i].ToLowerInvariant()) {
+                                                               case "regular":
+                                                               case "normal":
+                                                                       break;
+                                                               case "bold":
+                                                                       font.Style |= FontStyle.Bold;
+                                                                       break;
+                                                               case "italic":
+                                                                       font.Style |= FontStyle.Italic;
+                                                                       break;
+                                                               case "oblique":
+                                                                       font.Style |= FontStyle.Oblique;
+                                                                       break;
+                                                               default:
+                                                                       FontFlag fl;
+                                                                       if (Enum.TryParse<FontFlag>(styles[i], true, out fl))
+                                                                               font.Flags |= fl;
+                                                                       break;
+                                                               }
+
+                                                       }                                                               
+                                                       fonts.Add(font);
+                                                       face.Dispose();
+                                               }
+                                               catch (FreeTypeException ee)
+                                               { Console.Write(ee.Error.ToString() + ": " + f.FullName); }
+                                       }
+                               }
+                       }
+                       catch (FreeTypeException e)
+                       { Console.Write(e.Error.ToString()); }
+               }
+
+               const int FONT_TEX_SIZE = 1024;
+
+               public void buildGlyphesTextures(uint activeSize, uint startChar, uint endChar){
+                       try
+                       {
+                               using (Library lib = new Library())
+                               {
+                                       Face face = new Face(lib,_fontPath, 0);
+
+                                       face.SetPixelSizes(0,activeSize);
+
+                                       //face.SetCharSize(0, 32 * 64, 0, 96);
+
+                                       originalFontExtents = new FontExtents();
+                                       originalFontExtents.Ascent = face.Size.Metrics.Ascender >> 6;
+                                       originalFontExtents.Descent = face.Size.Metrics.Descender >> 6;
+                                       originalFontExtents.Height = face.Size.Metrics.Height >> 6;
+                                       originalFontExtents.MaxXAdvance = face.Size.Metrics.MaxAdvance >> 6;
+                                       originalFontExtents.MaxYAdvance = face.MaxAdvanceHeight >> 6;
+
+                                       if (!glyphesCache.ContainsKey(activeSize))
+                                               glyphesCache [activeSize] = new Dictionary<uint, glGlyph>();
+
+                                       buildTexture(ref face,activeSize,startChar,endChar);
+
+                                       face.Dispose();
+                               }
+                       }
+                       catch (FreeTypeException e)
+                       { Console.Write(e.Error.ToString()); }
+               }
+                       
+               void setTextureData(int tex, byte[] _buffer)
+               {
+                       GL.BindTexture(TextureTarget.Texture2D, tex);
+                       GL.TexImage2D(TextureTarget.Texture2D,0,
+                               PixelInternalFormat.R8, FONT_TEX_SIZE, FONT_TEX_SIZE,0,
+                               OpenTK.Graphics.OpenGL.PixelFormat.Red, PixelType.UnsignedByte,_buffer);
+
+                       GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
+                       GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+                       GL.BindTexture(TextureTarget.Texture2D, 0);
+
+                       byte[] pixels = new byte[FONT_TEX_SIZE * FONT_TEX_SIZE * 4];
+
+                       for (int x = 0; x < FONT_TEX_SIZE; x++)
+                       {
+                               for (int y = 0; y < FONT_TEX_SIZE; y++)
+                               {
+                                       byte v = _buffer[x + y * FONT_TEX_SIZE];
+
+                                       pixels[(x + y * FONT_TEX_SIZE) * 4] = v;
+                                       pixels[(x + y * FONT_TEX_SIZE) * 4 + 1] = v;
+                                       pixels[(x + y * FONT_TEX_SIZE) * 4 + 2] = v;
+                                       pixels[(x + y * FONT_TEX_SIZE) * 4 + 3] = 255;
+                               }
+                       }
+                       System.Drawing.Bitmap bmp;
+                       unsafe
+                       {
+                               bmp = new System.Drawing.Bitmap(FONT_TEX_SIZE, FONT_TEX_SIZE, System.Drawing.Imaging.PixelFormat.Format32bppArgb);//, ptr);
+                               System.Drawing.Imaging.BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(0, 0, FONT_TEX_SIZE, FONT_TEX_SIZE),
+                                       System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+
+                               System.Runtime.InteropServices.Marshal.Copy(pixels, 0, data.Scan0, FONT_TEX_SIZE * FONT_TEX_SIZE * 4);
+
+                               bmp.UnlockBits(data);
+                       }
+
+                       bmp.Save(@"/home/jp/fonttex.png");
+
+
+               }
+
+
+               void buildTexture(ref Face face,uint activeSize, uint startChar, uint endChar){
+                       int texPage = GL.GenTexture ();
+                       byte[] buffer = new byte[FONT_TEX_SIZE*FONT_TEX_SIZE];
+
+                       int penX = 0,
+                               penY = 0;
+
+                       int maxBmpHeight = 0;
+
+                       for(uint c=startChar;c<endChar;c++)
+                       {
+                               uint glyphIndex = face.GetCharIndex((uint)c);
+                               if (glyphIndex==0)
+                                       continue;
+                               //face.LoadChar((uint)c, LoadFlags.Render, LoadTarget.Normal);
+                               face.LoadGlyph(glyphIndex, LoadFlags.Render, LoadTarget.Normal);
+                               testTexture = texPage;
+
+                               GlyphSlot slot = face.Glyph;
+                               FTBitmap bmp = slot.Bitmap;
+
+                               if (penX+bmp.Width > FONT_TEX_SIZE){
+                                       penX = 0;
+                                       penY += maxBmpHeight;
+                                       maxBmpHeight = 0;
+                               }
+
+                               if (penY+bmp.Rows > FONT_TEX_SIZE)
+                               {
+                                       //glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+                                       setTextureData (texPage, buffer);
+                                       texPage = GL.GenTexture ();
+                                       buffer = new byte[FONT_TEX_SIZE*FONT_TEX_SIZE];
+                                       penX = 0;
+                                       penY = 0;
+                                       maxBmpHeight = 0;
+                               }
+
+                               Rectangle tmp = new Rectangle (
+                                       penX,
+                                       penY,
+                                       bmp.Width, bmp.Rows);
+
+                               for(int y=0; y<bmp.Rows; y++)
+                               {
+                                       for(int x=0; x<bmp.Width; x++)
+                                               buffer[ penX + x + (penY + y)* FONT_TEX_SIZE ] =
+                                                       bmp.BufferData[x + y * bmp.Width];
+                               }
+                               glyphesCache [activeSize][c] = new glGlyph() 
+                               {
+                                       texId = texPage,
+                                       texX = (float)penX / FONT_TEX_SIZE,
+                                       texY = (float)penY / FONT_TEX_SIZE,
+                                       texWidth = (float)(bmp.Width) / FONT_TEX_SIZE,
+                                       texHeight = (float)(bmp.Rows)  / FONT_TEX_SIZE,
+
+//                                     texCoord = new Rectangle(
+//                                             penX / FONT_TEX_SIZE,
+//                                             penY / FONT_TEX_SIZE,
+//                                             (bmp.Width) / FONT_TEX_SIZE,
+//                                             (bmp.Rows)  / FONT_TEX_SIZE),
+                                       dims = new Size(bmp.Width , bmp.Rows),
+                                       bmpLeft = slot.BitmapLeft, bmpTop = slot.BitmapTop, advanceX = slot.Advance.X>>6,advanceY = slot.Advance.Y>>6
+                               };
+
+                               if (bmp.Rows>maxBmpHeight)
+                                       maxBmpHeight=bmp.Rows;
+
+                               penX += bmp.Width;
+                       }
+
+                       if (penX>0 || penY>0)
+                               setTextureData(texPage, buffer);
+               }
+
+               public override string ToString()
+               {
+                       string tmp = Name;
+                       if (Style != FontStyle.Normal)
+                               tmp += "," + Style.ToString ();
+                       if (Flags != FontFlag.None)
+                               tmp += "," + Flags.ToString ();
+                       return tmp;
+               }
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Font/FontFlag.cs b/src/OpenGL/GLBackend/Font/FontFlag.cs
new file mode 100644 (file)
index 0000000..f5c9cf5
--- /dev/null
@@ -0,0 +1,18 @@
+using System;
+
+namespace go
+{
+       [Flags]
+       public enum FontFlag
+       {
+               None = 0x00,
+               Sans = 0x01,
+               Serif = 0x02,
+               Mono = 0x04,
+               Condensed = 0x08,
+               Medium = 0x16,
+               Book = 0x32,
+               ExtraLight = 0x64
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Font/FontShader (copier).cs b/src/OpenGL/GLBackend/Font/FontShader (copier).cs
new file mode 100644 (file)
index 0000000..8036db5
--- /dev/null
@@ -0,0 +1,146 @@
+using System;
+using OpenTK.Graphics.OpenGL;
+
+namespace go.GLBackend
+{
+       public class FontShader : Shader
+       {
+               public FontShader ()
+               {
+                       vertSource = @"
+                               #version 130
+
+                               precision highp float;
+
+                               uniform mat4 projection_matrix;
+                               uniform mat4 modelview_matrix;
+
+                               in vec2 in_position;
+                               in vec2 in_tex;
+                               out vec2 texCoord;
+
+
+                               void main(void)
+                               {
+                                       texCoord = in_tex;
+                                       gl_Position = projection_matrix * modelview_matrix * vec4(in_position,0, 1);
+                               }";
+
+                       fragSource = @"
+                               #version 130
+                               precision highp float;
+
+                               uniform vec4 color;
+                               uniform sampler2D tex;
+                               uniform sampler2D stencil;
+                               uniform vec2 resolution;
+
+                               in vec2 texCoord;
+                               out vec4 out_frag_color;
+
+                               vec3
+                               energy_distribution( vec4 previous, vec4 current, vec4 next )
+                               {
+                                       float primary = 1.0/3.0;
+                                       float secondary = 1.0/3.0;
+                                       float tertiary = 0.0;
+
+                                       // Energy distribution as explained on:
+                                       // http://www.grc.com/freeandclear.htm
+                                       //
+                                       // .. v..
+                                       // RGB RGB RGB
+                                       // previous.g + previous.b + current.r + current.g + current.b
+                                       //
+                                       // . .v. .
+                                       // RGB RGB RGB
+                                       // previous.b + current.r + current.g + current.b + next.r
+                                       //
+                                       // ..v ..
+                                       // RGB RGB RGB
+                                       // current.r + current.g + current.b + next.r + next.g
+
+                                       float r =
+                                       tertiary * previous.g +
+                                       secondary * previous.b +
+                                       primary * current.r +
+                                       secondary * current.g +
+                                       tertiary * current.b;
+
+                                       float g =
+                                       tertiary * previous.b +
+                                       secondary * current.r +
+                                       primary * current.g +
+                                       secondary * current.b +
+                                       tertiary * next.r;
+
+                                       float b =
+                                       tertiary * current.r +
+                                       secondary * current.g +
+                                       primary * current.b +
+                                       secondary * next.r +
+                                       tertiary * next.g;
+
+                                       return vec3(r,g,b);
+                               }
+                               void main(void)
+                               {
+                                   float a = texture( tex, texCoord).r;
+
+                                   if (a==0.)
+                                       discard;
+
+                                       float x = gl_FragCoord.x / resolution.x;
+                                   float s = mod(x,x);
+
+                                       vec4 current = color * texture( tex, texCoord).r;
+                                       vec4 previous = color * texture( tex, texCoord + vec2(-x,0)).r;
+                                       vec4 next = color * texture( tex, texCoord + vec2(x,0)).r;
+
+                                       float r = current.r;
+                                       float g = current.g;
+                                       float b = current.b;
+
+                                       if( s <= 0.333 )
+                                       {
+                                               float z = s/0.333;
+                                               r = mix(current.r, previous.b, z);
+                                               g = mix(current.g, current.r, z);
+                                               b = mix(current.b, current.g, z);
+                                       }
+                                       else if( s <= 0.666 )
+                                       {
+                                               float z = (s-0.33)/0.333;
+                                               r = mix(previous.b, previous.g, z);
+                                               g = mix(current.r, previous.b, z);
+                                               b = mix(current.g, current.r, z);
+                                       }
+                                       else if( s < 1.0 )
+                                       {
+                                               float z = (s-0.66)/0.334;
+                                               r = mix(previous.g, previous.r, z);
+                                               g = mix(previous.b, previous.g, z);
+                                               b = mix(current.r, previous.b, z);
+                                       }
+
+
+                                       out_frag_color = vec4(energy_distribution(previous, current, next),1);                                  
+                               }";
+
+                       Compile ();
+
+               }
+
+               protected override void BindVertexAttributes ()
+               {
+                       base.BindVertexAttributes ();
+                       GL.BindAttribLocation(pgmId, 1, "in_tex");
+               }
+               protected override void BindSamplesSlots ()
+               {
+                       GL.Uniform1(GL.GetUniformLocation (pgmId, "tex"),0);
+                       //GL.Uniform1(GL.GetUniformLocation (pgmId, "stencil"),1);
+               }
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Font/FontShader.cs b/src/OpenGL/GLBackend/Font/FontShader.cs
new file mode 100644 (file)
index 0000000..c12c45c
--- /dev/null
@@ -0,0 +1,124 @@
+using System;
+using OpenTK.Graphics.OpenGL;
+
+namespace go.GLBackend
+{
+       public class FontShader : Shader
+       {
+               protected int coef1Location, coef2Location, coef3Location, coefALocation;
+               public float coef1 {
+                       set {GL.Uniform1 (coef1Location, value);}
+               }
+               public float coef2 {
+                       set {GL.Uniform1 (coef2Location, value);}
+               }
+               public float coef3 {
+                       set {GL.Uniform1 (coef3Location, value);}
+               }
+               public float coefA {
+                       set {GL.Uniform1 (coefALocation, value);}
+               }
+               public FontShader ()
+               {
+
+                       vertSource = @"
+                               #version 130
+
+                               precision highp float;
+
+                               uniform mat4 projection_matrix;
+                               uniform mat4 modelview_matrix;
+
+                               in vec2 in_position;
+                               in vec2 in_tex;
+                               out vec2 texCoord;
+
+
+                               void main(void)
+                               {
+                                       texCoord = in_tex;
+                                       gl_Position = projection_matrix * modelview_matrix * vec4(in_position,0, 1);
+                               }";
+
+                       fragSource = @"
+                               #version 130
+                               precision highp float;
+
+                               uniform vec4 color;
+                               uniform sampler2D tex;
+                               uniform sampler2D backTex;
+                               uniform sampler2D stencil;
+                               uniform vec2 resolution;
+                               uniform float coef1;
+                               uniform float coef2;
+                               uniform float coef3;
+                               uniform float coefA;
+
+
+                               in vec2 texCoord;
+                               out vec4 out_frag_color;
+
+                               void main(void)
+                               {
+                                       vec2 uv         = gl_FragCoord.xy / resolution;
+                                       vec2 pix        = 1.0 / resolution;
+
+                                   float       c               = texture( tex, texCoord).r;
+                                       vec4    bc              = texture( backTex, uv);
+
+                                       vec4 diff       = bc - color;
+
+                                   if (c==0.)
+                                       discard;                                        
+
+//                                     if (c > 0.75)
+//                                             out_frag_color = vec4(color.rgb,c);
+//                                     else{
+                                               float p = texture( tex, texCoord + vec2(-pix.x,0)).r;
+                                               float n = texture( tex, texCoord + vec2( pix.x,0)).r;
+                                               
+                                               vec3 current = vec3(0,0,0);
+                                       
+                                               float a = n - c;
+                                               current.r += coef1 * a * diff.r;
+                                               current.g += coef2 * a * diff.g;
+                                               current.b += coef3 * a * diff.b;
+                                               //current.a *= coefA * a * diff.a;
+                                       
+                                               a = p - c;
+                                               current.r += coef3 * a * diff.r;
+                                               current.g += coef2 * a * diff.g;
+                                               current.b += coef1 * a * diff.b;
+                                               //current.a *= coefA * a * diff.a;
+                                       
+                                               out_frag_color = vec4(color.rgb+current,c*coefA);
+
+//                                     }                                       
+                               }";
+
+                       Compile ();
+
+               }
+               protected override void GetUniformLocations ()
+               {
+                       base.GetUniformLocations ();
+
+                       coef1Location = GL.GetUniformLocation (pgmId, "coef1");
+                       coef2Location = GL.GetUniformLocation (pgmId, "coef2");
+                       coef3Location = GL.GetUniformLocation (pgmId, "coef3");
+                       coefALocation = GL.GetUniformLocation (pgmId, "coefA");
+               }
+               protected override void BindVertexAttributes ()
+               {
+                       base.BindVertexAttributes ();
+                       GL.BindAttribLocation(pgmId, 1, "in_tex");
+               }
+               protected override void BindSamplesSlots ()
+               {
+                       GL.Uniform1(GL.GetUniformLocation (pgmId, "tex"),0);
+                       GL.Uniform1(GL.GetUniformLocation (pgmId, "backTex"),1);
+                       //GL.Uniform1(GL.GetUniformLocation (pgmId, "stencil"),1);
+               }
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Font/FontSlant.cs b/src/OpenGL/GLBackend/Font/FontSlant.cs
new file mode 100644 (file)
index 0000000..9888970
--- /dev/null
@@ -0,0 +1,42 @@
+//
+// Mono.Cairo.FontSlant.cs
+//
+// Authors:
+//   Duncan Mak (duncan@ximian.com)
+//   Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace go.GLBackend
+{
+       [Serializable]
+       public enum FontSlant
+       {
+               Normal,
+               Italic,
+               Oblique
+       }
+}
diff --git a/src/OpenGL/GLBackend/Font/FontStyle.cs b/src/OpenGL/GLBackend/Font/FontStyle.cs
new file mode 100644 (file)
index 0000000..3e30001
--- /dev/null
@@ -0,0 +1,15 @@
+using System;
+
+namespace go
+{
+       [Flags]
+       public enum FontStyle
+       {
+               Normal = 0x00,
+               Bold = 0x01,
+               Italic = 0x02,
+               Oblique = 0x4,
+               Underlined = 0x8
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Font/FontWeight.cs b/src/OpenGL/GLBackend/Font/FontWeight.cs
new file mode 100644 (file)
index 0000000..4122326
--- /dev/null
@@ -0,0 +1,41 @@
+//
+// Mono.Cairo.FontWeight.cs
+//
+// Authors:
+//   Duncan Mak (duncan@ximian.com)
+//   Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace go.GLBackend
+{
+       [Serializable]
+       public enum FontWeight
+       {
+               Normal,
+               Bold,
+       }
+}
diff --git a/src/OpenGL/GLBackend/Font/TextExtents.cs b/src/OpenGL/GLBackend/Font/TextExtents.cs
new file mode 100644 (file)
index 0000000..7ba8122
--- /dev/null
@@ -0,0 +1,98 @@
+//
+// Mono.Cairo.TextExtents.cs
+//
+// Authors:
+//   Duncan Mak (duncan@ximian.com)
+//   Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace go.GLBackend
+{
+       [StructLayout (LayoutKind.Sequential)]
+       public struct TextExtents
+       {
+               double xbearing;
+               double ybearing;
+               double width;
+               double height;
+               double xadvance;
+               double yadvance;
+               
+               public double XBearing {
+                       get { return xbearing; }
+                       set { xbearing = value; }
+               }
+               
+               public double YBearing {
+                       get { return ybearing; }
+                       set { ybearing = value; }
+               }
+               
+               public double Width {
+                       get { return width; }
+                       set { width = value; }
+               }
+               
+               public double Height {
+                       get { return height; }
+                       set { height = value; }
+               }
+               
+               public double XAdvance {
+                       get { return xadvance; }
+                       set { xadvance = value; }
+               }
+               
+               public double YAdvance {
+                       get { return yadvance; }
+                       set { yadvance = value; }
+               }
+
+               public override bool Equals (object obj)
+               {
+                       if (obj is TextExtents)
+                               return this == (TextExtents)obj;
+                       return false;
+               }
+
+               public override int GetHashCode ()
+               {
+                       return (int)XBearing ^ (int)YBearing ^ (int)Width ^ (int)Height ^ (int)XAdvance ^ (int)YAdvance;
+               }
+
+               public static bool operator == (TextExtents extents, TextExtents other)
+               {
+                       return extents.XBearing == other.XBearing && extents.YBearing == other.YBearing && extents.Width == other.Width && extents.Height == other.Height && extents.XAdvance == other.XAdvance && extents.YAdvance == other.YAdvance;
+               }
+
+               public static bool operator != (TextExtents extents, TextExtents other)
+               {
+                       return !(extents == other);
+               }
+       }
+}
diff --git a/src/OpenGL/GLBackend/Font/glFont.cs b/src/OpenGL/GLBackend/Font/glFont.cs
new file mode 100644 (file)
index 0000000..fdfb001
--- /dev/null
@@ -0,0 +1,90 @@
+using System;
+using SharpFont;
+using OpenTK.Graphics.OpenGL;
+using System.Collections.Generic;
+using System.IO;
+using System.Diagnostics;
+
+namespace go
+{
+       public class glFont
+       {
+               Dictionary<int, glGlyph> glyphs = new Dictionary<int,glGlyph>();
+
+               public static void dumpFontsDirectories(string _path)
+               {
+                       List<string> stylesList = new List<string> ();
+                       List<string> namesList = new List<string> ();
+                       List<string> attribsList = new List<string> ();
+
+                       DirectoryInfo dir = new DirectoryInfo (_path);
+                       try
+                       {
+                               using (Library lib = new Library())
+                               {
+                                       Console.WriteLine("FreeType version: " + lib.Version + "\n");
+
+                                       foreach (FileInfo f in dir.GetFiles("*.ttf",SearchOption.AllDirectories)) {
+                                               try {
+                                                       
+                                                       Face face = new Face(lib,f.FullName, 0);
+
+                                                       Console.Write(System.IO.Path.GetFileNameWithoutExtension(f.Name) + " => ");
+                                                       Console.WriteLine("{0} Faces:{1} Flags:{2}\nStyle:{3} StyleFlags:{4}\n",
+                                                               face.FamilyName,
+                                                               face.FaceCount,
+                                                               face.FaceFlags,
+                                                               face.StyleName,
+                                                               face.StyleFlags);
+                                                       string[] styles = face.StyleName.Split(' ');
+                                                       foreach (string s in styles) {
+                                                               if (stylesList.Contains(s))
+                                                                       continue;
+                                                               stylesList.Add(s);
+                                                       }
+
+                                                       string[] names = face.FamilyName.Split(' ');
+                                                       if (!namesList.Contains(names[0]))
+                                                               namesList.Add(names[0]);
+                                                       for (int i = 1; i < names.Length; i++) {
+                                                               if (attribsList.Contains(names[i]))
+                                                                       continue;
+                                                               attribsList.Add(names[i]);
+                                                       }
+
+                                                       face.Dispose();
+                                               }
+                                               catch (FreeTypeException ee)
+                                               {
+                                                       Console.Write(ee.Error.ToString() + ": " + f.FullName);
+                                               }
+                                       }
+                               }
+                       }
+                       catch (FreeTypeException e)
+                       {
+                               Console.Write(e.Error.ToString());
+                       }
+                       Console.Write ("Names => ");
+                       foreach (string s in namesList) {
+                               Console.Write (s + " ");
+                       }
+                       Console.Write ("\n\nAttrib => ");
+                       foreach (string s in attribsList) {
+                               Console.Write (s + " ");
+                       }
+
+                       Console.Write ("\n\nStyles => ");
+                       foreach (string s in stylesList) {
+                               Console.Write (s + " ");
+                       }
+               }
+
+               public glFont (string _fontPath)
+               {
+
+               }
+
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Font/glGlyph.cs b/src/OpenGL/GLBackend/Font/glGlyph.cs
new file mode 100644 (file)
index 0000000..548567d
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+
+namespace go
+{
+       public struct glGlyph
+       {
+               public int texId;
+               public Rectangle texCoord;
+               public float texX;
+               public float texY;
+               public float texWidth;
+               public float texHeight;
+               public Size dims;
+               public int bmpLeft;
+               public int bmpTop;
+               public long advanceX;
+               public long advanceY;
+
+
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Path.cs b/src/OpenGL/GLBackend/Path.cs
new file mode 100644 (file)
index 0000000..510b49c
--- /dev/null
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using OpenTK;
+
+namespace go
+{
+       public class Path : List<Vector2>
+       {
+               public bool IsClosed;
+
+               public Path () : base()
+               {
+               }
+               public Path (IEnumerable<Vector2> collection) : base(collection){
+               }                       
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Shader (copier).cs b/src/OpenGL/GLBackend/Shader (copier).cs
new file mode 100644 (file)
index 0000000..3f719ee
--- /dev/null
@@ -0,0 +1,135 @@
+using System;
+using OpenTK.Graphics.OpenGL;
+using System.Diagnostics;
+using OpenTK;
+
+namespace go.GLBackend
+{
+       public class TestShader
+       {
+               string vertexShaderSource = @"
+                       #version 130
+
+                       //precision highp float;
+
+                       uniform float lw;
+                       uniform mat4 projection_matrix;
+                       uniform mat4 modelview_matrix;
+
+                       in vec2 in_position;
+                       in vec2 in_tex;
+
+                       out vec2 texcoord;
+
+                       void main(void)
+                       {
+                               texcoord = in_tex;
+                               gl_Position = projection_matrix * modelview_matrix * vec4(in_position,0, 1);
+                       }";
+
+               string fragmentShaderSource = @"
+                       #version 130
+
+                       //precision highp float;
+                       uniform float lw;
+                       uniform vec4 color;
+
+                       in vec2 texcoord;
+                       out vec4 out_frag_color;
+
+                       void main(void)
+                       {
+//                             float smoothWidth = 1.0 / lineWidth;
+//
+//                             if (texcoord.y < smoothWidth)                                                           
+//                                     out_frag_color = vec4(color,texcoord.y/smoothWidth);
+//                             else if (texcoord.y > 1.0 - smoothWidth)
+//                                     out_frag_color = vec4(color,(1.0-texcoord.y)/smoothWidth);
+//                             else
+//                                     out_frag_color = vec4(color,1.0);
+                               out_frag_color = color;
+                       }";
+
+               int vertexShaderHandle,
+                       fragmentShaderHandle,
+                       shaderProgramHandle,
+                       modelviewMatrixLocation,
+                       projectionMatrixLocation,
+                       colorLocation,
+                       lineWidthLocation;
+
+               Matrix4 projectionMatrix, 
+                               modelviewMatrix;
+
+               double lineWidth = 1.0;
+
+               public TestShader ()
+               {
+                       vertexShaderHandle = GL.CreateShader(ShaderType.VertexShader);
+                       fragmentShaderHandle = GL.CreateShader(ShaderType.FragmentShader);
+
+                       GL.ShaderSource(vertexShaderHandle, vertexShaderSource);
+                       GL.ShaderSource(fragmentShaderHandle, fragmentShaderSource);
+
+                       GL.CompileShader(vertexShaderHandle);
+                       GL.CompileShader(fragmentShaderHandle);
+
+                       Debug.WriteLine(GL.GetShaderInfoLog(vertexShaderHandle));
+                       Debug.WriteLine(GL.GetShaderInfoLog(fragmentShaderHandle));
+
+                       // Create program
+                       shaderProgramHandle = GL.CreateProgram();
+
+                       GL.AttachShader(shaderProgramHandle, vertexShaderHandle);
+                       GL.AttachShader(shaderProgramHandle, fragmentShaderHandle);
+
+                       GL.BindAttribLocation(shaderProgramHandle, 0, "in_position");
+                       GL.BindAttribLocation(shaderProgramHandle, 1, "in_tex");
+
+                       GL.LinkProgram(shaderProgramHandle);
+                       Debug.WriteLine(GL.GetProgramInfoLog(shaderProgramHandle));
+                       GL.UseProgram(shaderProgramHandle);
+
+
+                       lineWidthLocation = GL.GetUniformLocation (shaderProgramHandle, "lw");
+                       projectionMatrixLocation = GL.GetUniformLocation(shaderProgramHandle, "projection_matrix");
+                       modelviewMatrixLocation = GL.GetUniformLocation(shaderProgramHandle, "modelview_matrix");
+                       colorLocation = GL.GetUniformLocation (shaderProgramHandle, "color");
+
+               }
+
+               int savedPgm = 0;
+               public virtual void Enable(){
+                       GL.GetInteger (GetPName.CurrentProgram, out savedPgm);
+                       GL.UseProgram (shaderProgramHandle);
+               }
+               public virtual void Disable(){
+                       GL.UseProgram (savedPgm);
+               }
+
+               public Matrix4 ProjectionMatrix{
+                       set { 
+                               projectionMatrix = value;
+                               GL.UniformMatrix4(projectionMatrixLocation, false, ref projectionMatrix);  
+                       }
+               }
+               public Matrix4 ModelViewMatrix {
+                       set { 
+                               modelviewMatrix = value;
+                               GL.UniformMatrix4 (modelviewMatrixLocation, false, ref modelviewMatrix); 
+                       }
+               }
+               public double LineWidth {
+                       set {
+                               lineWidth = value;
+                               GL.Uniform1 (lineWidthLocation, (float)lineWidth);
+                       }
+               }
+               public Vector4 Color {
+                       set {
+                               GL.Uniform4 (colorLocation, value);
+                       }
+               }
+       }
+}
+
diff --git a/src/OpenGL/GLBackend/Surface.cs b/src/OpenGL/GLBackend/Surface.cs
new file mode 100644 (file)
index 0000000..010a0f5
--- /dev/null
@@ -0,0 +1,103 @@
+using System;
+using OpenTK.Graphics.OpenGL;
+
+namespace go.GLBackend
+{
+       [Serializable]
+       public enum Format
+       {
+               Argb32,
+               Rgb24,
+               A8,
+               A1,
+               Rgb16565,
+               ARGB32,
+               RGB24
+       }
+       [Serializable]
+       public enum LineJoin
+       {
+               Miter,
+               Round,
+               Bevel
+       }
+       [Serializable]
+       public enum LineCap
+       {
+               Butt,
+               Round,
+               Square
+       }
+       public class Surface : IDisposable
+       {
+               public static int samples;
+
+               public int      texId,
+                                       width,
+                                       height;
+               Format format;
+
+               public PixelFormat PixelFormat;
+               public PixelInternalFormat InternalFormat;
+
+               public Surface (int _width, int _height)
+               {
+                       format = Format.Argb32;
+                       width = _width;
+                       height = _height;
+
+                       createTexture ();
+               }
+
+               public Surface (Format _format,int _width, int _height)
+               {
+                       format = _format;
+                       width = _width;
+                       height = _height;
+
+                       InternalFormat = PixelInternalFormat.Rgba;
+                       PixelFormat = PixelFormat.Bgra;
+
+                       createTexture ();
+               }
+
+               public Surface CreateSimilar()
+               {
+                       return new Surface (format, width, height);
+               }
+                       
+               void createTexture()
+               {
+                       texId = GL.GenTexture();
+                       GL.BindTexture(TextureTarget.Texture2D, texId);
+                       GL.TexImage2D(TextureTarget.Texture2D,0,
+                               PixelInternalFormat.Rgba, width, height,0,PixelFormat.Bgra,PixelType.UnsignedByte,IntPtr.Zero);
+                       GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
+                       GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
+                       GL.BindTexture(TextureTarget.Texture2D, 0);
+               }
+
+
+               public void Save(string fileName)
+               {
+                       GL.BindTexture(TextureTarget.Texture2D, texId);
+                       System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+                       System.Drawing.Imaging.BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height),
+                               System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+                       GL.GetTexImage(TextureTarget.Texture2D, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
+                       bmp.UnlockBits(data);
+                       bmp.RotateFlip (System.Drawing.RotateFlipType.RotateNoneFlipY);
+                       bmp.Save(fileName);
+                       GL.BindTexture(TextureTarget.Texture2D, 0);
+               }
+
+               #region IDisposable implementation
+               public void Dispose ()
+               {
+                       if (GL.IsTexture (texId))
+                               GL.DeleteTexture (texId);
+               }
+               #endregion
+       }
+}
+
index 4e5584c89a60c83da1b5317b484bbb94f8740193..364b66e3cf650b87caca2abb0d8de6d637fd498d 100755 (executable)
@@ -201,11 +201,14 @@ namespace go
                {\r
                        GL.GetInteger (GetPName.Viewport, viewport);\r
                        GL.Viewport (0, 0, ClientRectangle.Width, ClientRectangle.Height);\r
+                       bool blend = GL.GetBoolean (GetPName.Blend);\r
+                       GL.Enable (EnableCap.Blend);\r
+                       GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);\r
                        shader.Enable ();\r
                        shader.ProjectionMatrix = projectionMatrix;\r
                        shader.ModelViewMatrix = modelviewMatrix;\r
                        shader.Color = new Vector4(1f,1f,1f,1f);\r
-                       //if (dirtyZone != Rectangle.Empty) {\r
+//                     //if (dirtyZone != Rectangle.Empty) {\r
                        GL.ActiveTexture (TextureUnit.Texture0);\r
                        GL.BindTexture (TextureTarget.Texture2D, texID);\r
                        GL.TexSubImage2D (TextureTarget.Texture2D, 0,\r
@@ -216,6 +219,9 @@ namespace go
 \r
                        GL.BindTexture(TextureTarget.Texture2D, 0);\r
 \r
+                       if (!blend)\r
+                               GL.Disable (EnableCap.Blend);\r
+\r
                        shader.Disable ();\r
                        GL.Viewport (viewport [0], viewport [1], viewport [2], viewport [3]);\r
                }\r