From: jpbruyere Date: Fri, 19 Feb 2016 10:06:44 +0000 (+0100) Subject: free Crow base from OpenTK X-Git-Tag: v0.4~93^2~15 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=328c6d4eab1127cd9799540f253deda66060b68a;p=jp%2Fcrow.git free Crow base from OpenTK --- diff --git a/Crow.csproj b/Crow.csproj index 2c519d58..2a048cee 100644 --- a/Crow.csproj +++ b/Crow.csproj @@ -65,7 +65,6 @@ - @@ -90,10 +89,6 @@ - - - - @@ -156,9 +151,6 @@ glib-sharp-3.0 - - ..\opentk\Binaries\OpenTK\Release\OpenTK.dll - @@ -179,7 +171,6 @@ - diff --git a/Crow.sln b/Crow.sln index 27ea466c..1498135b 100644 --- a/Crow.sln +++ b/Crow.sln @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDevelop.Diagram", "..\M EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTest", "UnitTest\UnitTest.csproj", "{7BAE4448-E8F4-48B3-BB11-FA78E7F4506B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OTKCrow", "OTKCrow\OTKCrow.csproj", "{350D4F49-9901-4998-9903-BCA7D48DA58C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Linux_x86 = Debug|Linux_x86 @@ -19,6 +21,10 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {232716B4-D19D-4FD7-B310-94A98FD926F0}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU {232716B4-D19D-4FD7-B310-94A98FD926F0}.Release|Linux_x86.ActiveCfg = Debug|Any CPU + {350D4F49-9901-4998-9903-BCA7D48DA58C}.Debug|Linux_x86.ActiveCfg = Debug|Linux_x86 + {350D4F49-9901-4998-9903-BCA7D48DA58C}.Debug|Linux_x86.Build.0 = Debug|Linux_x86 + {350D4F49-9901-4998-9903-BCA7D48DA58C}.Release|Linux_x86.ActiveCfg = Release|Linux_x86 + {350D4F49-9901-4998-9903-BCA7D48DA58C}.Release|Linux_x86.Build.0 = Release|Linux_x86 {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Debug|Linux_x86.Build.0 = Debug|Any CPU {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Linux_x86.ActiveCfg = Release|Any CPU diff --git a/CrowGdk/CrowGdk.csproj b/CrowGdk/CrowGdk.csproj new file mode 100644 index 00000000..57a3f0cf --- /dev/null +++ b/CrowGdk/CrowGdk.csproj @@ -0,0 +1,45 @@ + + + + Debug + Linux_x86 + 8.0.30703 + 2.0 + {90D93DD6-ADBD-4BB6-AE62-20DBF83F7185} + Exe + CrowGdk + CrowGdk + v4.5 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + + {C2980F9B-4798-4C05-99E2-E174810F7C7B} + Crow + + + + + + + + + \ No newline at end of file diff --git a/OTKCrow/OTKCrow.csproj b/OTKCrow/OTKCrow.csproj new file mode 100644 index 00000000..6fc4f854 --- /dev/null +++ b/OTKCrow/OTKCrow.csproj @@ -0,0 +1,57 @@ + + + + Debug + Linux_x86 + 8.0.30703 + 2.0 + {350D4F49-9901-4998-9903-BCA7D48DA58C} + Library + OTKCrow + OTKCrow + 0.4 + v4.5 + + + true + full + false + bin\Debug + DEBUG;MEASURE_TIME + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + + ..\..\opentk\Binaries\OpenTK\Release\OpenTK.dll + + + + + + + + + + + + + + + + + {C2980F9B-4798-4C05-99E2-E174810F7C7B} + Crow + + + \ No newline at end of file diff --git a/OTKCrow/OpenGL/QuadVAO.cs b/OTKCrow/OpenGL/QuadVAO.cs new file mode 100644 index 00000000..36231cc1 --- /dev/null +++ b/OTKCrow/OpenGL/QuadVAO.cs @@ -0,0 +1,44 @@ +using System; +using OpenTK; + +namespace Crow +{ + public class QuadVAO : VertexArrayObject + { + public QuadVAO (float x, float y, float width, float height):base( + new Vector2[] { + new Vector2 (x, y), + new Vector2 (x, y + height), + new Vector2 (x + width, y), + new Vector2 (x + width, y + height) + }, + new Vector2[] { + new Vector2 (0, 1), + new Vector2 (0, 0), + new Vector2 (1, 1), + new Vector2 (1, 0) + }, + new int[] { 0, 1, 2, 3 }) + { + + } + public QuadVAO (float x, float y, float width, float height, + float texX, float texY, float texW, float texH):base( + new Vector2[] { + new Vector2 (x, y), + new Vector2 (x, y + height), + new Vector2 (x + width, y), + new Vector2 (x + width, y + height) + }, + new Vector2[] { + new Vector2 (texX, texY+texH), + new Vector2 (texX, texY), + new Vector2 (texX+texW, texY+texH), + new Vector2 (texX+texW, texY) + }, + new int[] { 0, 1, 2, 3 }) + { + + } + } +} diff --git a/OTKCrow/OpenGL/Shader.cs b/OTKCrow/OpenGL/Shader.cs new file mode 100644 index 00000000..b4603ad8 --- /dev/null +++ b/OTKCrow/OpenGL/Shader.cs @@ -0,0 +1,307 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using OpenTK; +using OpenTK.Graphics.OpenGL; + +namespace Crow +{ + public class Shader : IDisposable + { + #region CTOR + public Shader () + { + Compile (); + } + public Shader (string vertResId, string fragResId) + { + + Stream s = tryGetStreamForResource (vertResId); + if (s != null) { + using (StreamReader sr = new StreamReader (s)) { + vertSource = sr.ReadToEnd (); + } + } + + s = tryGetStreamForResource (fragResId); + if (s != null) { + using (StreamReader sr = new StreamReader (s)) { + fragSource = sr.ReadToEnd (); + } + } + + Compile (); + } + Stream tryGetStreamForResource(string resId){ + if (string.IsNullOrEmpty (resId)) + return null; + + Stream s = Assembly.GetEntryAssembly (). + GetManifestResourceStream (resId); + return s == null ? + Assembly.GetExecutingAssembly (). + GetManifestResourceStream (resId) : + s; + } + #endregion + + #region Sources + protected string _vertSource = @" + #version 330 + + precision highp float; + + uniform mat4 Projection; + uniform mat4 ModelView; + uniform mat4 Model; + uniform mat4 Normal; + + in vec2 in_position; + in vec2 in_tex; + + out vec2 texCoord; + + + void main(void) + { + texCoord = in_tex; + gl_Position = Projection * ModelView * Model * vec4(in_position, 0, 1); + }"; + + protected string _fragSource = @" + #version 330 + precision highp float; + + uniform vec4 color; + uniform sampler2D tex; + + in vec2 texCoord; + out vec4 out_frag_color; + + void main(void) + { + out_frag_color = texture( tex, texCoord); + }"; + string _geomSource = @""; +// #version 330 +// layout(triangles) in; +// layout(triangle_strip, max_vertices=3) out; +// void main() +// { +// for(int i=0; i<3; i++) +// { +// gl_Position = gl_in[i].gl_Position; +// EmitVertex(); +// } +// EndPrimitive(); +// }"; + #endregion + + #region Private and protected fields + protected int vsId, fsId, gsId, pgmId, + modelViewLocation, + modelLocation, + projectionLocation, + normalLocation, + colorLocation; + + Matrix4 projectionMat = Matrix4.Identity, + modelMat = Matrix4.Identity, + modelViewMat = Matrix4.Identity; + Vector4 color = new Vector4(1,1,1,1); + int texture; + #endregion + + + #region Public properties + public virtual string vertSource + { + get { return _vertSource;} + set { _vertSource = value; } + } + public virtual string fragSource + { + get { return _fragSource;} + set { _fragSource = value; } + } + public virtual string geomSource + { + get { return _geomSource; } + set { _geomSource = value; } + } + + public Matrix4 ProjectionMatrix{ + set { projectionMat = value; } + get { return projectionMat; } + } + public Matrix4 ModelViewMatrix { + set { modelViewMat = value; } + get { return modelViewMat; } + } + public Matrix4 ModelMatrix { + set { modelMat = value; } + get { return modelMat; } + } + public Vector4 Color { + set { color = value; } + get { return color; } + } + + public int Texture { + get { return texture; } + set { texture = value; } + } + + #endregion + + void updateNormalMatrix() + { + Matrix4 normalMat = (modelViewMat).Inverted(); + normalMat.Transpose (); + GL.UniformMatrix4 (normalLocation, false, ref normalMat); + } + + #region Public functions + public virtual void Compile() + { + Dispose (); + + pgmId = GL.CreateProgram(); + + if (!string.IsNullOrEmpty(vertSource)) + { + vsId = GL.CreateShader(ShaderType.VertexShader); + compileShader(vsId, vertSource); + } + if (!string.IsNullOrEmpty(fragSource)) + { + fsId = GL.CreateShader(ShaderType.FragmentShader); + compileShader(fsId, fragSource); + + } + if (!string.IsNullOrEmpty(geomSource)) + { + gsId = GL.CreateShader(ShaderType.GeometryShader); + compileShader(gsId,geomSource); + } + + if (vsId != 0) + GL.AttachShader(pgmId, vsId); + if (fsId != 0) + GL.AttachShader(pgmId, fsId); + if (gsId != 0) + GL.AttachShader(pgmId, gsId); + + BindVertexAttributes (); + + string info; + GL.LinkProgram(pgmId); + GL.GetProgramInfoLog(pgmId, out info); + + if (!string.IsNullOrEmpty (info)) { + Debug.WriteLine ("Linkage:"); + Debug.WriteLine (info); + } + + info = null; + + GL.ValidateProgram(pgmId); + GL.GetProgramInfoLog(pgmId, out info); + if (!string.IsNullOrEmpty (info)) { + Debug.WriteLine ("Validation:"); + Debug.WriteLine (info); + } + + GL.UseProgram (pgmId); + + GetUniformLocations (); + BindSamplesSlots (); + + Disable (); + } + + protected virtual void BindVertexAttributes() + { + GL.BindAttribLocation(pgmId, 0, "in_position"); + GL.BindAttribLocation(pgmId, 1, "in_tex"); + } + protected virtual void GetUniformLocations() + { + projectionLocation = GL.GetUniformLocation(pgmId, "Projection"); + modelViewLocation = GL.GetUniformLocation(pgmId, "ModelView"); + modelLocation = GL.GetUniformLocation(pgmId, "Model"); + normalLocation = GL.GetUniformLocation(pgmId, "Normal"); + colorLocation = GL.GetUniformLocation (pgmId, "color"); + + } + protected virtual void BindSamplesSlots(){ + GL.Uniform1(GL.GetUniformLocation (pgmId, "tex"), 0); + } + + public virtual void Enable(){ + GL.UseProgram (pgmId); + + GL.UniformMatrix4(projectionLocation, false, ref projectionMat); + GL.UniformMatrix4 (modelLocation, false, ref modelMat); + GL.UniformMatrix4 (modelViewLocation, false, ref modelViewMat); + updateNormalMatrix (); + GL.Uniform4 (colorLocation, color); + + if (texture < 0) + return; + + GL.ActiveTexture (TextureUnit.Texture0); + GL.BindTexture(TextureTarget.Texture2D, texture); + } + public virtual void Disable(){ + GL.UseProgram (0); + } + public static void Enable(Shader s) + { + if (s == null) + return; + s.Enable (); + } + public static void Disable(Shader s) + { + if (s == null) + return; + s.Disable (); + } + #endregion + + void compileShader(int shader, string source) + { + GL.ShaderSource(shader, source); + GL.CompileShader(shader); + + string info; + GL.GetShaderInfoLog(shader, out info); + Debug.WriteLine(info); + + int compileResult; + GL.GetShader(shader, ShaderParameter.CompileStatus, out compileResult); + if (compileResult != 1) + { + Debug.WriteLine("Compile Error!"); + Debug.WriteLine(source); + } + } + + #region IDisposable implementation + public virtual void Dispose () + { + if (GL.IsProgram (pgmId)) + GL.DeleteProgram (pgmId); + + if (GL.IsShader (vsId)) + GL.DeleteShader (vsId); + if (GL.IsShader (fsId)) + GL.DeleteShader (fsId); + if (GL.IsShader (gsId)) + GL.DeleteShader (gsId); + } + #endregion + } +} diff --git a/OTKCrow/OpenGL/TexturedShader.cs b/OTKCrow/OpenGL/TexturedShader.cs new file mode 100644 index 00000000..9e29b690 --- /dev/null +++ b/OTKCrow/OpenGL/TexturedShader.cs @@ -0,0 +1,41 @@ +using System; +using OpenTK.Graphics.OpenGL; + +namespace Crow +{ + public class TexturedShader : Shader + { + public TexturedShader () + { + + fragSource = @" + #version 130 + precision highp float; + + uniform sampler2D tex; + + in vec2 texCoord; + out vec4 out_frag_color; + + void main(void) + { + out_frag_color = texture( tex, texCoord); + }"; + + Compile (); + + } + + protected override void BindSamplesSlots () + { + base.BindSamplesSlots (); + + GL.Uniform1(GL.GetUniformLocation (pgmId, "stencil"),1); + } + public override void Enable () + { + base.Enable (); + + } + } +} diff --git a/OTKCrow/OpenGL/VertexArrayObject.cs b/OTKCrow/OpenGL/VertexArrayObject.cs new file mode 100644 index 00000000..c7b685d9 --- /dev/null +++ b/OTKCrow/OpenGL/VertexArrayObject.cs @@ -0,0 +1,93 @@ +using System; +using OpenTK; +using OpenTK.Graphics.OpenGL; + +namespace Crow +{ + public class VertexArrayObject : IDisposable + { + public int vaoHandle, + positionVboHandle, + texVboHandle, + eboHandle; + + Vector2[] positionVboData; + public int[] indicesVboData; + Vector2[] texVboData; + + public VertexArrayObject (Vector2[] _positions, Vector2[] _texCoord, int[] _indices) + { + positionVboData = _positions; + texVboData = _texCoord; + indicesVboData = _indices; + + CreateVBOs (); + CreateVAOs (); + } + + void deleteVAOs() + { + GL.DeleteBuffer (positionVboHandle); + GL.DeleteBuffer (texVboHandle); + GL.DeleteBuffer (eboHandle); + GL.DeleteVertexArray (vaoHandle); + } + + void CreateVBOs() + { + positionVboHandle = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle); + GL.BufferData(BufferTarget.ArrayBuffer, + new IntPtr(positionVboData.Length * Vector2.SizeInBytes), + positionVboData, BufferUsageHint.StaticDraw); + + texVboHandle = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ArrayBuffer, texVboHandle); + GL.BufferData(BufferTarget.ArrayBuffer, + new IntPtr(texVboData.Length * Vector2.SizeInBytes), + texVboData, BufferUsageHint.StaticDraw); + // + eboHandle = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle); + GL.BufferData(BufferTarget.ElementArrayBuffer, + new IntPtr(sizeof(uint) * indicesVboData.Length), + indicesVboData, BufferUsageHint.StaticDraw); + + GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); + } + + void CreateVAOs() + { + vaoHandle = GL.GenVertexArray(); + GL.BindVertexArray(vaoHandle); + + GL.EnableVertexAttribArray(0); + GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle); + GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, true, Vector2.SizeInBytes, 0); + + GL.EnableVertexAttribArray(1); + GL.BindBuffer(BufferTarget.ArrayBuffer, texVboHandle); + GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, true, Vector2.SizeInBytes, 0); + + GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle); + + GL.BindVertexArray(0); + } + + public void Render(PrimitiveType _primitiveType){ + GL.BindVertexArray(vaoHandle); + GL.DrawElements(_primitiveType, indicesVboData.Length, + DrawElementsType.UnsignedInt, IntPtr.Zero); + GL.BindVertexArray (0); + } + + + #region IDisposable implementation + public void Dispose () + { + deleteVAOs (); + } + #endregion + } +} diff --git a/OTKCrow/OpenTKGameWindow.cs b/OTKCrow/OpenTKGameWindow.cs new file mode 100644 index 00000000..111163b4 --- /dev/null +++ b/OTKCrow/OpenTKGameWindow.cs @@ -0,0 +1,669 @@ +// +// OpenTKGameWindow.cs +// +// Author: +// Jean-Philippe Bruyère +// +// Copyright (c) 2016 jp +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading; +using System.Xml; +using Cairo; +using OpenTK; +using OpenTK.Graphics.OpenGL; + +namespace Crow +{ + public class OpenTKGameWindow : GameWindow, ILayoutable, IGOLibHost + { + #region ctor +// public OpenTKGameWindow(int _width, int _height, string _title="golib") +// : base(_width, _height, new OpenTK.Graphics.GraphicsMode(32, 24, 0, 1), _title, +// GameWindowFlags.Fullscreen, +// DisplayDevice.Default, +// 3,0,OpenTK.Graphics.GraphicsContextFlags.Default) + public OpenTKGameWindow(int _width, int _height, string _title="Crow") + : base(_width, _height, new OpenTK.Graphics.GraphicsMode(32, 24, 0, 1), + _title,GameWindowFlags.Default,DisplayDevice.GetDisplay(DisplayIndex.Second), + 3,3,OpenTK.Graphics.GraphicsContextFlags.Debug) +// public OpenTKGameWindow(int _width, int _height, string _title="golib") +// : base(_width, _height, new OpenTK.Graphics.GraphicsMode(32, 24, 0, 8), _title) + { + //VSync = VSyncMode.On; + currentWindow = this; + //Load cursors + XCursor.Cross = XCursorFile.Load("#Crow.Images.Icons.Cursors.cross").Cursors[0]; + XCursor.Default = XCursorFile.Load("#Crow.Images.Icons.Cursors.arrow").Cursors[0]; + XCursor.NW = XCursorFile.Load("#Crow.Images.Icons.Cursors.top_left_corner").Cursors[0]; + XCursor.NE = XCursorFile.Load("#Crow.Images.Icons.Cursors.top_right_corner").Cursors[0]; + XCursor.SW = XCursorFile.Load("#Crow.Images.Icons.Cursors.bottom_left_corner").Cursors[0]; + XCursor.SE = XCursorFile.Load("#Crow.Images.Icons.Cursors.bottom_right_corner").Cursors[0]; + XCursor.H = XCursorFile.Load("#Crow.Images.Icons.Cursors.sb_h_double_arrow").Cursors[0]; + XCursor.V = XCursorFile.Load("#Crow.Images.Icons.Cursors.sb_v_double_arrow").Cursors[0]; + } + #endregion + + public List GraphicObjects = new List(); + public Color Background = Color.Transparent; + + internal static OpenTKGameWindow currentWindow; + + Rectangles _redrawClip = new Rectangles();//should find another way to access it from child + List _gobjsToRedraw = new List(); + + #region IGOLibHost implementation + public Rectangles clipping { + get { return _redrawClip; } + set { _redrawClip = value; } + } + public XCursor MouseCursor { + set { + if (value == null) { + Cursor = null; + return; + } + Cursor = new MouseCursor + ((int)value.Xhot, (int)value.Yhot, (int)value.Width, (int)value.Height,value.data);; } + } + public List gobjsToRedraw { + get { return _gobjsToRedraw; } + set { _gobjsToRedraw = value; } + } + public void AddWidget(GraphicObject g) + { + g.Parent = this; + GraphicObjects.Insert (0, g); + + g.RegisterForLayouting (LayoutingType.Sizing); + } + public void DeleteWidget(GraphicObject g) + { + g.Visible = false;//trick to ensure clip is added to refresh zone + g.ClearBinding(); + GraphicObjects.Remove (g); + } + public void PutOnTop(GraphicObject g) + { + if (GraphicObjects.IndexOf(g) > 0) + { + GraphicObjects.Remove(g); + GraphicObjects.Insert(0, g); + //g.registerClipRect (); + } + } + public void Quit () + { + this.Exit (); + } + + #region focus + GraphicObject _activeWidget; //button is pressed on widget + GraphicObject _hoverWidget; //mouse is over + GraphicObject _focusedWidget; //has keyboard (or other perif) focus + + public GraphicObject activeWidget + { + get { return _activeWidget; } + set + { + if (_activeWidget == value) + return; + + if (_activeWidget != null) + _activeWidget.IsActive = false; + + _activeWidget = value; + + if (_activeWidget != null) + _activeWidget.IsActive = true; + } + } + public GraphicObject hoverWidget + { + get { return _hoverWidget; } + set { + if (_hoverWidget == value) + return; + _hoverWidget = value; + } + } + public GraphicObject FocusedWidget { + get { return _focusedWidget; } + set { + if (_focusedWidget == value) + return; + if (_focusedWidget != null) + _focusedWidget.onUnfocused (this, null); + _focusedWidget = value; + if (_focusedWidget != null) + _focusedWidget.onFocused (this, null); + } + } + #endregion + + #endregion + + /// Remove all Graphic objects from top container + public void ClearInterface() + { + int i = 0; + while (GraphicObjects.Count>0) { + //TODO:parent is not reset to null because object will be added + //to ObjectToRedraw list, and without parent, it fails + GraphicObject g = GraphicObjects [i]; + g.Visible = false; + g.ClearBinding (); + GraphicObjects.RemoveAt (0); + } + } + public GraphicObject FindByName (string nameToFind) + { + foreach (GraphicObject w in GraphicObjects) { + GraphicObject r = w.FindByName (nameToFind); + if (r != null) + return r; + } + return null; + } + #region Events + //those events are raised only if mouse isn't in a graphic object + public event EventHandler MouseWheelChanged; + public event EventHandler MouseButtonUp; + public event EventHandler MouseButtonDown; + public event EventHandler MouseClick; + public event EventHandler MouseMove; + public event EventHandler KeyboardKeyDown; + #endregion + + #region graphic contexte + Context ctx; + Surface surf; + byte[] bmp; + int texID; + + public QuadVAO uiQuad, uiQuad2; + Crow.Shader shader; + int[] viewport = new int[4]; + + void createContext() + { + createOpenGLSurface (); + + if (uiQuad != null) + uiQuad.Dispose (); + uiQuad = new QuadVAO (0, 0, ClientRectangle.Width, ClientRectangle.Height, 0, 1, 1, -1); + uiQuad2 = new QuadVAO (0, 0, ClientRectangle.Width, ClientRectangle.Height, 0, 0, 1, 1); + + shader.ProjectionMatrix = Matrix4.CreateOrthographicOffCenter + (0, ClientRectangle.Width, ClientRectangle.Height, 0, 0, 1); + + clipping.AddRectangle (ClientRectangle); + } + void createOpenGLSurface() + { + currentWindow = this; + + int stride = 4 * ClientRectangle.Width; + int bmpSize = Math.Abs (stride) * ClientRectangle.Height; + bmp = new byte[bmpSize]; + + //create texture + if (GL.IsTexture(texID)) + GL.DeleteTexture (texID); + GL.GenTextures(1, out texID); + GL.ActiveTexture (TextureUnit.Texture0); + GL.BindTexture(TextureTarget.Texture2D, texID); + + GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, + ClientRectangle.Width, ClientRectangle.Height, 0, + OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp); + + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + + GL.BindTexture(TextureTarget.Texture2D, 0); + + shader.Texture = texID; + } + void OpenGLDraw() + { + GL.GetInteger (GetPName.Viewport, viewport); + GL.Viewport (0, 0, ClientRectangle.Width, ClientRectangle.Height); + + shader.Enable (); + + if (isDirty) { + byte[] tmp = new byte[4 * DirtyRect.Width * DirtyRect.Height]; + for (int y = 0; y < DirtyRect.Height; y++) { + Array.Copy(bmp, + ((DirtyRect.Top + y) * ClientRectangle.Width * 4) + DirtyRect.Left * 4, + tmp, y * DirtyRect.Width * 4, DirtyRect.Width *4); + } + GL.TexSubImage2D (TextureTarget.Texture2D, 0, + DirtyRect.Left, DirtyRect.Top, DirtyRect.Width, DirtyRect.Height, + OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, tmp); + isDirty = false; + } + uiQuad.Render (PrimitiveType.TriangleStrip); + + GL.BindTexture(TextureTarget.Texture2D, 0); + + shader.Disable (); + GL.Viewport (viewport [0], viewport [1], viewport [2], viewport [3]); + } + #endregion + + #if MEASURE_TIME + public Stopwatch updateTime = new Stopwatch (); + public Stopwatch layoutTime = new Stopwatch (); + public Stopwatch guTime = new Stopwatch (); + public Stopwatch drawingTime = new Stopwatch (); + #endif + + bool isDirty = false; + Rectangle DirtyRect; + + #region update + void update () + { + if (mouseRepeatCount > 0) { + int mc = mouseRepeatCount; + mouseRepeatCount -= mc; + for (int i = 0; i < mc; i++) { + FocusedWidget.onMouseClick (this, new MouseButtonEventArgs (Mouse.X, Mouse.Y, MouseButton.Left, true)); + } + } + #if MEASURE_TIME + layoutTime.Reset (); + guTime.Reset (); + drawingTime.Reset (); + updateTime.Restart (); + #endif + + GraphicObject[] invGOList = new GraphicObject[GraphicObjects.Count]; + GraphicObjects.CopyTo (invGOList, 0); + invGOList = invGOList.Reverse ().ToArray (); + + #if MEASURE_TIME + layoutTime.Start (); + #endif + //Debug.WriteLine ("======= Layouting queue start ======="); + + while (Interface.LayoutingQueue.Count > 0) { + LayoutingQueueItem lqi = Interface.LayoutingQueue.Dequeue (); + lqi.ProcessLayouting (); + } + + #if MEASURE_TIME + layoutTime.Stop (); + #endif + + //Debug.WriteLine ("otd:" + gobjsToRedraw.Count.ToString () + "-"); + //final redraw clips should be added only when layout is completed among parents, + //that's why it take place in a second pass + GraphicObject[] gotr = new GraphicObject[gobjsToRedraw.Count]; + gobjsToRedraw.CopyTo (gotr); + gobjsToRedraw.Clear (); + foreach (GraphicObject p in gotr) { + p.IsQueuedForRedraw = false; + p.Parent.RegisterClip (p.LastPaintedSlot); + p.Parent.RegisterClip (p.getSlot()); + } + + #if MEASURE_TIME + updateTime.Stop (); + drawingTime.Start (); + #endif + + using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) { + using (ctx = new Context (surf)){ + + + if (clipping.count > 0) { + //Link.draw (ctx); + clipping.clearAndClip(ctx); + + foreach (GraphicObject p in invGOList) { + if (!p.Visible) + continue; + if (!clipping.intersect (p.Slot)) + continue; + ctx.Save (); + + p.Paint (ref ctx); + + ctx.Restore (); + } + + #if DEBUG_CLIP_RECTANGLE + clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5)); + #endif + + if (isDirty) + DirtyRect += clipping.Bounds; + else + DirtyRect = clipping.Bounds; + isDirty = true; + + DirtyRect.Left = Math.Max (0, DirtyRect.Left); + DirtyRect.Top = Math.Max (0, DirtyRect.Top); + DirtyRect.Width = Math.Min (ClientRectangle.Width - DirtyRect.Left, DirtyRect.Width); + DirtyRect.Height = Math.Min (ClientRectangle.Height - DirtyRect.Top, DirtyRect.Height); + + clipping.Reset (); + } + + #if MEASURE_TIME + drawingTime.Stop (); + #endif + //surf.WriteToPng (@"/mnt/data/test.png"); + } + } +// if (ToolTip.isVisible) { +// ToolTip.panel.processkLayouting(); +// if (ToolTip.panel.layoutIsValid) +// ToolTip.panel.Paint(ref ctx); +// } +// Debug.WriteLine("INTERFACE: layouting: {0} ticks \t graphical update {1} ticks \t drawing {2} ticks", +// layoutTime.ElapsedTicks, +// guTime.ElapsedTicks, +// drawingTime.ElapsedTicks); +// Debug.WriteLine("INTERFACE: layouting: {0} ms \t graphical update {1} ms \t drawing {2} ms", +// layoutTime.ElapsedMilliseconds, +// guTime.ElapsedMilliseconds, +// drawingTime.ElapsedMilliseconds); + +// Debug.WriteLine("UPDATE: {0} ticks \t, {1} ms", +// updateTime.ElapsedTicks, +// updateTime.ElapsedMilliseconds); + } + #endregion + + #region loading + public GraphicObject LoadInterface (string path) + { + GraphicObject tmp = Interface.Load (path, this); + AddWidget (tmp); + return tmp; + } + #endregion + + public virtual void OnRender(FrameEventArgs e) + { + } + public virtual void GLClear() + { + GL.Clear (ClearBufferMask.ColorBufferBit); + } + + #region Game win overrides + protected override void OnUpdateFrame(FrameEventArgs e) + { + base.OnUpdateFrame(e); + update (); + } + protected override void OnRenderFrame(FrameEventArgs e) + { + GLClear (); + + + base.OnRenderFrame(e); + + OnRender (e); + OpenGLDraw (); + + + SwapBuffers (); + } + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + Keyboard.KeyDown += new EventHandler(Keyboard_KeyDown); + Mouse.WheelChanged += new EventHandler(Mouse_WheelChanged); + Mouse.ButtonDown += new EventHandler(Mouse_ButtonDown); + Mouse.ButtonUp += new EventHandler(Mouse_ButtonUp); + Mouse.Move += new EventHandler(Mouse_Move); + + GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + Console.WriteLine("\n\n*************************************"); + Console.WriteLine("GL version: " + GL.GetString (StringName.Version)); + Console.WriteLine("GL vendor: " + GL.GetString (StringName.Vendor)); + Console.WriteLine("GLSL version: " + GL.GetString (StringName.ShadingLanguageVersion)); + Console.WriteLine("*************************************\n"); + + shader = new Crow.TexturedShader (); + } + + protected override void OnResize(EventArgs e) + { + base.OnResize (e); + createContext (); + foreach (GraphicObject g in GraphicObjects) + g.RegisterForLayouting (LayoutingType.All); + } + #endregion + + #region Mouse Handling + void update_mouseButtonStates(ref MouseState e, OpenTK.Input.MouseState otk_e){ + for (int i = 0; i < MouseState.MaxButtons; i++) { + if (otk_e.IsButtonDown ((OpenTK.Input.MouseButton)i)) + e.EnableBit (i); + } + } + void Mouse_Move(object sender, OpenTK.Input.MouseMoveEventArgs otk_e) + { + MouseMoveEventArgs e = new MouseMoveEventArgs (otk_e.X, otk_e.Y, otk_e.XDelta, otk_e.YDelta); + MouseState ms = e.Mouse; + update_mouseButtonStates (ref ms, otk_e.Mouse); + e.Mouse = ms; + + if (_activeWidget != null) { + //first, ensure object is still in the graphic tree + if (_activeWidget.HostContainer == null) { + activeWidget = null; + } else { + + //send move evt even if mouse move outside bounds + _activeWidget.onMouseMove (this, e); + return; + } + } + + if (hoverWidget != null) { + //first, ensure object is still in the graphic tree + if (hoverWidget.HostContainer == null) { + hoverWidget = null; + } else { + //check topmost graphicobject first + GraphicObject tmp = hoverWidget; + GraphicObject topc = null; + while (tmp is GraphicObject) { + topc = tmp; + tmp = tmp.Parent as GraphicObject; + } + int idxhw = GraphicObjects.IndexOf (topc); + if (idxhw != 0) { + int i = 0; + while (i < idxhw) { + if (GraphicObjects [i].MouseIsIn (e.Position)) { + hoverWidget.onMouseLeave (this, e); + GraphicObjects [i].checkHoverWidget (e); + return; + } + i++; + } + } + + + if (hoverWidget.MouseIsIn (e.Position)) { + hoverWidget.checkHoverWidget (e); + return; + } else { + hoverWidget.onMouseLeave (this, e); + //seek upward from last focused graph obj's + while (hoverWidget.Parent as GraphicObject != null) { + hoverWidget = hoverWidget.Parent as GraphicObject; + if (hoverWidget.MouseIsIn (e.Position)) { + hoverWidget.checkHoverWidget (e); + return; + } else + hoverWidget.onMouseLeave (this, e); + } + } + } + } + + //top level graphic obj's parsing + for (int i = 0; i < GraphicObjects.Count; i++) { + GraphicObject g = GraphicObjects[i]; + if (g.MouseIsIn (e.Position)) { + g.checkHoverWidget (e); + PutOnTop (g); + return; + } + } + hoverWidget = null; + MouseMove.Raise (this, otk_e); + } + void Mouse_ButtonUp(object sender, OpenTK.Input.MouseButtonEventArgs otk_e) + { + MouseButtonEventArgs e = new MouseButtonEventArgs (otk_e.X, otk_e.Y, (Crow.MouseButton)otk_e.Button, otk_e.IsPressed); + MouseState ms = e.Mouse; + update_mouseButtonStates (ref ms, otk_e.Mouse); + e.Mouse = ms; + + if (_activeWidget == null) { + MouseButtonUp.Raise (this, otk_e); + return; + } + + if (mouseRepeatThread != null) { + mouseRepeatOn = false; + mouseRepeatThread.Abort(); + mouseRepeatThread.Join (); + } + + _activeWidget.onMouseUp (this, e); + activeWidget = null; + } + void Mouse_ButtonDown(object sender, OpenTK.Input.MouseButtonEventArgs otk_e) + { + MouseButtonEventArgs e = new MouseButtonEventArgs (otk_e.X, otk_e.Y, (Crow.MouseButton)otk_e.Button, otk_e.IsPressed); + MouseState ms = e.Mouse; + update_mouseButtonStates (ref ms, otk_e.Mouse); + e.Mouse = ms; + + if (hoverWidget == null) { + MouseButtonDown.Raise (this, otk_e); + return; + } + + hoverWidget.onMouseDown(hoverWidget,new BubblingMouseButtonEventArg(e)); + + if (FocusedWidget == null) + return; + if (!FocusedWidget.MouseRepeat) + return; + mouseRepeatThread = new Thread (mouseRepeatThreadFunc); + mouseRepeatThread.Start (); + } + void Mouse_WheelChanged(object sender, OpenTK.Input.MouseWheelEventArgs otk_e) + { + MouseWheelEventArgs e = new MouseWheelEventArgs (otk_e.X, otk_e.Y, otk_e.Value, otk_e.Delta); + MouseState ms = e.Mouse; + update_mouseButtonStates (ref ms, otk_e.Mouse); + e.Mouse = ms; + + if (hoverWidget == null) { + MouseWheelChanged.Raise (this, otk_e); + return; + } + hoverWidget.onMouseWheel (this, e); + } + + volatile bool mouseRepeatOn; + volatile int mouseRepeatCount; + Thread mouseRepeatThread; + void mouseRepeatThreadFunc() + { + mouseRepeatOn = true; + Thread.Sleep (Interface.DeviceRepeatDelay); + while (mouseRepeatOn) { + mouseRepeatCount++; + Thread.Sleep (Interface.DeviceRepeatInterval); + } + mouseRepeatCount = 0; + } + #endregion + + #region keyboard Handling + KeyboardState Keyboad = new KeyboardState (); + void Keyboard_KeyDown(object sender, OpenTK.Input.KeyboardKeyEventArgs otk_e) + { +// if (_focusedWidget == null) { + KeyboardKeyDown.Raise (this, otk_e); +// return; +// } + Keyboad.SetKeyState ((Crow.Key)otk_e.Key, true); + KeyboardKeyEventArgs e = new KeyboardKeyEventArgs((Crow.Key)otk_e.Key, otk_e.IsRepeat,Keyboad); + _focusedWidget.onKeyDown (sender, e); + } + #endregion + + #region ILayoutable implementation + public void RegisterClip(Rectangle r){ + clipping.AddRectangle (r); + } + public bool ArrangeChildren { get { return false; }} + public int LayoutingTries { + get { throw new NotImplementedException (); } + set { throw new NotImplementedException (); } + } + public LayoutingType RegisteredLayoutings { + get { return LayoutingType.None; } + set { throw new NotImplementedException (); } + } + public void RegisterForLayouting (LayoutingType layoutType) { throw new NotImplementedException (); } + public bool UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); } + public Rectangle ContextCoordinates (Rectangle r) => r; + public Rectangle ScreenCoordinates (Rectangle r) => r; + + public ILayoutable Parent { + get { return null; } + set { throw new NotImplementedException (); } + } + public ILayoutable LogicalParent { + get { return null; } + set { throw new NotImplementedException (); } + } + + Rectangle ILayoutable.ClientRectangle { + get { return new Size(this.ClientRectangle.Size.Width,this.ClientRectangle.Size.Height); } + } + public IGOLibHost HostContainer { + get { return this; } + } + public Rectangle getSlot () => ClientRectangle; + public Rectangle getBounds () => ClientRectangle; + #endregion + } +} diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index b7c32c01..d913c6ee 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -269,5 +269,9 @@ {C2980F9B-4798-4C05-99E2-E174810F7C7B} Crow + + {350D4F49-9901-4998-9903-BCA7D48DA58C} + OTKCrow + diff --git a/src/Colors.cs b/src/Colors.cs index d46b71a1..4cb8cd5c 100644 --- a/src/Colors.cs +++ b/src/Colors.cs @@ -70,14 +70,14 @@ namespace Crow double.Parse(c[3])); } - public static implicit operator OpenTK.Vector4(Color c) - { - return new OpenTK.Vector4 ((float)c.R, (float)c.G, (float)c.B, (float)c.A); - } - public static implicit operator Color(OpenTK.Vector4 v) - { - return new Color (v.X, v.Y, v.Z, v.W); - } +// public static implicit operator OpenTK.Vector4(Color c) +// { +// return new OpenTK.Vector4 ((float)c.R, (float)c.G, (float)c.B, (float)c.A); +// } +// public static implicit operator Color(OpenTK.Vector4 v) +// { +// return new Color (v.X, v.Y, v.Z, v.W); +// } public static implicit operator Fill(Color c){ return new SolidColor (c) as Fill; } diff --git a/src/GraphicObjects/FileDialog.cs b/src/GraphicObjects/FileDialog.cs index b1c93119..da85580a 100644 --- a/src/GraphicObjects/FileDialog.cs +++ b/src/GraphicObjects/FileDialog.cs @@ -89,7 +89,7 @@ namespace Crow } public void Show(){ - OpenTKGameWindow.currentWindow.AddWidget(window); + //.AddWidget(window); } void OnSelectedItemChanged (object sender, SelectionChangeEventArgs e) @@ -104,8 +104,8 @@ namespace Crow { selectedFile = e.NewValue as FileInfo; } - void onFileSelect(object sender, OpenTK.Input.MouseButtonEventArgs e){ - OpenTKGameWindow.currentWindow.DeleteWidget(window); + void onFileSelect(object sender, MouseButtonEventArgs e){ + //OpenTKGameWindow.currentWindow.DeleteWidget(window); } } public class DirContainer: IValueChange diff --git a/src/GraphicObjects/Window.cs b/src/GraphicObjects/Window.cs index 757ee080..617670fc 100644 --- a/src/GraphicObjects/Window.cs +++ b/src/GraphicObjects/Window.cs @@ -83,7 +83,7 @@ namespace Crow { base.onMouseMove (sender, e); - OpenTKGameWindow otkgw = HostContainer as OpenTKGameWindow; + IGOLibHost otkgw = HostContainer; if (e.Mouse.IsButtonDown (MouseButton.Left)) { if (!HasFocus) @@ -176,31 +176,31 @@ namespace Crow if (currentDirection != lastDir) { switch (currentDirection) { case Direction.None: - otkgw.Cursor = XCursor.Default; + otkgw.MouseCursor = XCursor.Default; break; case Direction.N: - otkgw.Cursor = XCursor.V; + otkgw.MouseCursor = XCursor.V; break; case Direction.S: - otkgw.Cursor = XCursor.V; + otkgw.MouseCursor = XCursor.V; break; case Direction.E: - otkgw.Cursor = XCursor.H; + otkgw.MouseCursor = XCursor.H; break; case Direction.W: - otkgw.Cursor = XCursor.H; + otkgw.MouseCursor = XCursor.H; break; case Direction.NW: - otkgw.Cursor = XCursor.NW; + otkgw.MouseCursor = XCursor.NW; break; case Direction.NE: - otkgw.Cursor = XCursor.NE; + otkgw.MouseCursor = XCursor.NE; break; case Direction.SW: - otkgw.Cursor = XCursor.SW; + otkgw.MouseCursor = XCursor.SW; break; case Direction.SE: - otkgw.Cursor = XCursor.SE; + otkgw.MouseCursor = XCursor.SE; break; } } @@ -210,8 +210,7 @@ namespace Crow { base.onMouseLeave (sender, e); currentDirection = Direction.None; - OpenTKGameWindow otkgw = HostContainer as OpenTKGameWindow; - otkgw.Cursor = XCursor.Default; + HostContainer.MouseCursor = XCursor.Default; } protected override void loadTemplate(GraphicObject template = null) diff --git a/src/Input/KeyboardState.cs b/src/Input/KeyboardState.cs index ba392cac..283b4a69 100644 --- a/src/Input/KeyboardState.cs +++ b/src/Input/KeyboardState.cs @@ -210,7 +210,7 @@ namespace Crow #region Internal Members - internal void SetKeyState(Key key, bool down) + public void SetKeyState(Key key, bool down) { if (down) { diff --git a/src/Input/MouseEventArgs.cs b/src/Input/MouseEventArgs.cs index 758a5a69..e1f7ae2a 100644 --- a/src/Input/MouseEventArgs.cs +++ b/src/Input/MouseEventArgs.cs @@ -147,7 +147,7 @@ namespace Crow public MouseState Mouse { get { return state; } - internal set { state = value; } + set { state = value; } } #endregion diff --git a/src/Input/MouseState.cs b/src/Input/MouseState.cs index c645062a..e0438fc7 100644 --- a/src/Input/MouseState.cs +++ b/src/Input/MouseState.cs @@ -38,7 +38,7 @@ namespace Crow { #region Fields - internal const int MaxButtons = 16; // we are storing in an ushort + public const int MaxButtons = 16; // we are storing in an ushort Point position; MouseScroll scroll; ushort buttons; @@ -285,7 +285,7 @@ namespace Crow return (buttons & (1 << offset)) != 0; } - internal void EnableBit(int offset) + public void EnableBit(int offset) { ValidateOffset(offset); buttons |= unchecked((ushort)(1 << offset)); diff --git a/src/OpenGL/QuadVAO.cs b/src/OpenGL/QuadVAO.cs deleted file mode 100644 index 08ef680e..00000000 --- a/src/OpenGL/QuadVAO.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using OpenTK; - -namespace Crow -{ - public class QuadVAO : VertexArrayObject - { - public QuadVAO (float x, float y, float width, float height):base( - new Vector2[] { - new Vector2 (x, y), - new Vector2 (x, y + height), - new Vector2 (x + width, y), - new Vector2 (x + width, y + height) - }, - new Vector2[] { - new Vector2 (0, 1), - new Vector2 (0, 0), - new Vector2 (1, 1), - new Vector2 (1, 0) - }, - new int[] { 0, 1, 2, 3 }) - { - - } - public QuadVAO (float x, float y, float width, float height, - float texX, float texY, float texW, float texH):base( - new Vector2[] { - new Vector2 (x, y), - new Vector2 (x, y + height), - new Vector2 (x + width, y), - new Vector2 (x + width, y + height) - }, - new Vector2[] { - new Vector2 (texX, texY+texH), - new Vector2 (texX, texY), - new Vector2 (texX+texW, texY+texH), - new Vector2 (texX+texW, texY) - }, - new int[] { 0, 1, 2, 3 }) - { - - } - } -} - diff --git a/src/OpenGL/Shader.cs b/src/OpenGL/Shader.cs deleted file mode 100644 index f13000d7..00000000 --- a/src/OpenGL/Shader.cs +++ /dev/null @@ -1,308 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Reflection; -using OpenTK; -using OpenTK.Graphics.OpenGL; - -namespace Crow -{ - public class Shader : IDisposable - { - #region CTOR - public Shader () - { - Compile (); - } - public Shader (string vertResId, string fragResId) - { - - Stream s = tryGetStreamForResource (vertResId); - if (s != null) { - using (StreamReader sr = new StreamReader (s)) { - vertSource = sr.ReadToEnd (); - } - } - - s = tryGetStreamForResource (fragResId); - if (s != null) { - using (StreamReader sr = new StreamReader (s)) { - fragSource = sr.ReadToEnd (); - } - } - - Compile (); - } - Stream tryGetStreamForResource(string resId){ - if (string.IsNullOrEmpty (resId)) - return null; - - Stream s = Assembly.GetEntryAssembly (). - GetManifestResourceStream (resId); - return s == null ? - Assembly.GetExecutingAssembly (). - GetManifestResourceStream (resId) : - s; - } - #endregion - - #region Sources - protected string _vertSource = @" - #version 330 - - precision highp float; - - uniform mat4 Projection; - uniform mat4 ModelView; - uniform mat4 Model; - uniform mat4 Normal; - - in vec2 in_position; - in vec2 in_tex; - - out vec2 texCoord; - - - void main(void) - { - texCoord = in_tex; - gl_Position = Projection * ModelView * Model * vec4(in_position, 0, 1); - }"; - - protected string _fragSource = @" - #version 330 - precision highp float; - - uniform vec4 color; - uniform sampler2D tex; - - in vec2 texCoord; - out vec4 out_frag_color; - - void main(void) - { - out_frag_color = texture( tex, texCoord); - }"; - string _geomSource = @""; -// #version 330 -// layout(triangles) in; -// layout(triangle_strip, max_vertices=3) out; -// void main() -// { -// for(int i=0; i<3; i++) -// { -// gl_Position = gl_in[i].gl_Position; -// EmitVertex(); -// } -// EndPrimitive(); -// }"; - #endregion - - #region Private and protected fields - protected int vsId, fsId, gsId, pgmId, - modelViewLocation, - modelLocation, - projectionLocation, - normalLocation, - colorLocation; - - Matrix4 projectionMat = Matrix4.Identity, - modelMat = Matrix4.Identity, - modelViewMat = Matrix4.Identity; - Vector4 color = new Vector4(1,1,1,1); - int texture; - #endregion - - - #region Public properties - public virtual string vertSource - { - get { return _vertSource;} - set { _vertSource = value; } - } - public virtual string fragSource - { - get { return _fragSource;} - set { _fragSource = value; } - } - public virtual string geomSource - { - get { return _geomSource; } - set { _geomSource = value; } - } - - public Matrix4 ProjectionMatrix{ - set { projectionMat = value; } - get { return projectionMat; } - } - public Matrix4 ModelViewMatrix { - set { modelViewMat = value; } - get { return modelViewMat; } - } - public Matrix4 ModelMatrix { - set { modelMat = value; } - get { return modelMat; } - } - public Vector4 Color { - set { color = value; } - get { return color; } - } - - public int Texture { - get { return texture; } - set { texture = value; } - } - - #endregion - - void updateNormalMatrix() - { - Matrix4 normalMat = (modelViewMat).Inverted(); - normalMat.Transpose (); - GL.UniformMatrix4 (normalLocation, false, ref normalMat); - } - - #region Public functions - public virtual void Compile() - { - Dispose (); - - pgmId = GL.CreateProgram(); - - if (!string.IsNullOrEmpty(vertSource)) - { - vsId = GL.CreateShader(ShaderType.VertexShader); - compileShader(vsId, vertSource); - } - if (!string.IsNullOrEmpty(fragSource)) - { - fsId = GL.CreateShader(ShaderType.FragmentShader); - compileShader(fsId, fragSource); - - } - if (!string.IsNullOrEmpty(geomSource)) - { - gsId = GL.CreateShader(ShaderType.GeometryShader); - compileShader(gsId,geomSource); - } - - if (vsId != 0) - GL.AttachShader(pgmId, vsId); - if (fsId != 0) - GL.AttachShader(pgmId, fsId); - if (gsId != 0) - GL.AttachShader(pgmId, gsId); - - BindVertexAttributes (); - - string info; - GL.LinkProgram(pgmId); - GL.GetProgramInfoLog(pgmId, out info); - - if (!string.IsNullOrEmpty (info)) { - Debug.WriteLine ("Linkage:"); - Debug.WriteLine (info); - } - - info = null; - - GL.ValidateProgram(pgmId); - GL.GetProgramInfoLog(pgmId, out info); - if (!string.IsNullOrEmpty (info)) { - Debug.WriteLine ("Validation:"); - Debug.WriteLine (info); - } - - GL.UseProgram (pgmId); - - GetUniformLocations (); - BindSamplesSlots (); - - Disable (); - } - - protected virtual void BindVertexAttributes() - { - GL.BindAttribLocation(pgmId, 0, "in_position"); - GL.BindAttribLocation(pgmId, 1, "in_tex"); - } - protected virtual void GetUniformLocations() - { - projectionLocation = GL.GetUniformLocation(pgmId, "Projection"); - modelViewLocation = GL.GetUniformLocation(pgmId, "ModelView"); - modelLocation = GL.GetUniformLocation(pgmId, "Model"); - normalLocation = GL.GetUniformLocation(pgmId, "Normal"); - colorLocation = GL.GetUniformLocation (pgmId, "color"); - - } - protected virtual void BindSamplesSlots(){ - GL.Uniform1(GL.GetUniformLocation (pgmId, "tex"), 0); - } - - public virtual void Enable(){ - GL.UseProgram (pgmId); - - GL.UniformMatrix4(projectionLocation, false, ref projectionMat); - GL.UniformMatrix4 (modelLocation, false, ref modelMat); - GL.UniformMatrix4 (modelViewLocation, false, ref modelViewMat); - updateNormalMatrix (); - GL.Uniform4 (colorLocation, color); - - if (texture < 0) - return; - - GL.ActiveTexture (TextureUnit.Texture0); - GL.BindTexture(TextureTarget.Texture2D, texture); - } - public virtual void Disable(){ - GL.UseProgram (0); - } - public static void Enable(Shader s) - { - if (s == null) - return; - s.Enable (); - } - public static void Disable(Shader s) - { - if (s == null) - return; - s.Disable (); - } - #endregion - - void compileShader(int shader, string source) - { - GL.ShaderSource(shader, source); - GL.CompileShader(shader); - - string info; - GL.GetShaderInfoLog(shader, out info); - Debug.WriteLine(info); - - int compileResult; - GL.GetShader(shader, ShaderParameter.CompileStatus, out compileResult); - if (compileResult != 1) - { - Debug.WriteLine("Compile Error!"); - Debug.WriteLine(source); - } - } - - #region IDisposable implementation - public virtual void Dispose () - { - if (GL.IsProgram (pgmId)) - GL.DeleteProgram (pgmId); - - if (GL.IsShader (vsId)) - GL.DeleteShader (vsId); - if (GL.IsShader (fsId)) - GL.DeleteShader (fsId); - if (GL.IsShader (gsId)) - GL.DeleteShader (gsId); - } - #endregion - } -} - diff --git a/src/OpenGL/TexturedShader.cs b/src/OpenGL/TexturedShader.cs deleted file mode 100644 index c8f44c26..00000000 --- a/src/OpenGL/TexturedShader.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using OpenTK.Graphics.OpenGL; - -namespace Crow -{ - public class TexturedShader : Shader - { - public TexturedShader () - { - - fragSource = @" - #version 130 - precision highp float; - - uniform sampler2D tex; - - in vec2 texCoord; - out vec4 out_frag_color; - - void main(void) - { - out_frag_color = texture( tex, texCoord); - }"; - - Compile (); - - } - - protected override void BindSamplesSlots () - { - base.BindSamplesSlots (); - - GL.Uniform1(GL.GetUniformLocation (pgmId, "stencil"),1); - } - public override void Enable () - { - base.Enable (); - - } - } -} - diff --git a/src/OpenGL/VertexArrayObject.cs b/src/OpenGL/VertexArrayObject.cs deleted file mode 100644 index c4fde5b4..00000000 --- a/src/OpenGL/VertexArrayObject.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using OpenTK; -using OpenTK.Graphics.OpenGL; - -namespace Crow -{ - public class VertexArrayObject : IDisposable - { - public int vaoHandle, - positionVboHandle, - texVboHandle, - eboHandle; - - Vector2[] positionVboData; - public int[] indicesVboData; - Vector2[] texVboData; - - public VertexArrayObject (Vector2[] _positions, Vector2[] _texCoord, int[] _indices) - { - positionVboData = _positions; - texVboData = _texCoord; - indicesVboData = _indices; - - CreateVBOs (); - CreateVAOs (); - } - - void deleteVAOs() - { - GL.DeleteBuffer (positionVboHandle); - GL.DeleteBuffer (texVboHandle); - GL.DeleteBuffer (eboHandle); - GL.DeleteVertexArray (vaoHandle); - } - - void CreateVBOs() - { - positionVboHandle = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle); - GL.BufferData(BufferTarget.ArrayBuffer, - new IntPtr(positionVboData.Length * Vector2.SizeInBytes), - positionVboData, BufferUsageHint.StaticDraw); - - texVboHandle = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ArrayBuffer, texVboHandle); - GL.BufferData(BufferTarget.ArrayBuffer, - new IntPtr(texVboData.Length * Vector2.SizeInBytes), - texVboData, BufferUsageHint.StaticDraw); - // - eboHandle = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle); - GL.BufferData(BufferTarget.ElementArrayBuffer, - new IntPtr(sizeof(uint) * indicesVboData.Length), - indicesVboData, BufferUsageHint.StaticDraw); - - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); - GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); - } - - void CreateVAOs() - { - vaoHandle = GL.GenVertexArray(); - GL.BindVertexArray(vaoHandle); - - GL.EnableVertexAttribArray(0); - GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle); - GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, true, Vector2.SizeInBytes, 0); - - GL.EnableVertexAttribArray(1); - GL.BindBuffer(BufferTarget.ArrayBuffer, texVboHandle); - GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, true, Vector2.SizeInBytes, 0); - - GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle); - - GL.BindVertexArray(0); - } - - public void Render(PrimitiveType _primitiveType){ - GL.BindVertexArray(vaoHandle); - GL.DrawElements(_primitiveType, indicesVboData.Length, - DrawElementsType.UnsignedInt, IntPtr.Zero); - GL.BindVertexArray (0); - } - - - #region IDisposable implementation - public void Dispose () - { - deleteVAOs (); - } - #endregion - } -} - diff --git a/src/OpenTKGameWindow.cs b/src/OpenTKGameWindow.cs deleted file mode 100644 index fc17eae6..00000000 --- a/src/OpenTKGameWindow.cs +++ /dev/null @@ -1,663 +0,0 @@ -// -// OpenTKGameWindow.cs -// -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2016 jp -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading; -using System.Xml; -using Cairo; -using OpenTK; -using OpenTK.Graphics.OpenGL; - -namespace Crow -{ - public class OpenTKGameWindow : GameWindow, ILayoutable, IGOLibHost - { - #region ctor -// public OpenTKGameWindow(int _width, int _height, string _title="golib") -// : base(_width, _height, new OpenTK.Graphics.GraphicsMode(32, 24, 0, 1), _title, -// GameWindowFlags.Fullscreen, -// DisplayDevice.Default, -// 3,0,OpenTK.Graphics.GraphicsContextFlags.Default) - public OpenTKGameWindow(int _width, int _height, string _title="Crow") - : base(_width, _height, new OpenTK.Graphics.GraphicsMode(32, 24, 0, 1), - _title,GameWindowFlags.Default,DisplayDevice.GetDisplay(DisplayIndex.Second), - 3,3,OpenTK.Graphics.GraphicsContextFlags.Debug) -// public OpenTKGameWindow(int _width, int _height, string _title="golib") -// : base(_width, _height, new OpenTK.Graphics.GraphicsMode(32, 24, 0, 8), _title) - { - //VSync = VSyncMode.On; - currentWindow = this; - //Load cursors - XCursor.Cross = XCursorFile.Load("#Crow.Images.Icons.Cursors.cross").Cursors[0]; - XCursor.Default = XCursorFile.Load("#Crow.Images.Icons.Cursors.arrow").Cursors[0]; - XCursor.NW = XCursorFile.Load("#Crow.Images.Icons.Cursors.top_left_corner").Cursors[0]; - XCursor.NE = XCursorFile.Load("#Crow.Images.Icons.Cursors.top_right_corner").Cursors[0]; - XCursor.SW = XCursorFile.Load("#Crow.Images.Icons.Cursors.bottom_left_corner").Cursors[0]; - XCursor.SE = XCursorFile.Load("#Crow.Images.Icons.Cursors.bottom_right_corner").Cursors[0]; - XCursor.H = XCursorFile.Load("#Crow.Images.Icons.Cursors.sb_h_double_arrow").Cursors[0]; - XCursor.V = XCursorFile.Load("#Crow.Images.Icons.Cursors.sb_v_double_arrow").Cursors[0]; - } - #endregion - - public List GraphicObjects = new List(); - public Color Background = Color.Transparent; - - internal static OpenTKGameWindow currentWindow; - - Rectangles _redrawClip = new Rectangles();//should find another way to access it from child - List _gobjsToRedraw = new List(); - - #region IGOLibHost implementation - public Rectangles clipping { - get { return _redrawClip; } - set { _redrawClip = value; } - } - public XCursor MouseCursor { - set { Cursor = value; } - } - public List gobjsToRedraw { - get { return _gobjsToRedraw; } - set { _gobjsToRedraw = value; } - } - public void AddWidget(GraphicObject g) - { - g.Parent = this; - GraphicObjects.Insert (0, g); - - g.RegisterForLayouting (LayoutingType.Sizing); - } - public void DeleteWidget(GraphicObject g) - { - g.Visible = false;//trick to ensure clip is added to refresh zone - g.ClearBinding(); - GraphicObjects.Remove (g); - } - public void PutOnTop(GraphicObject g) - { - if (GraphicObjects.IndexOf(g) > 0) - { - GraphicObjects.Remove(g); - GraphicObjects.Insert(0, g); - //g.registerClipRect (); - } - } - public void Quit () - { - this.Exit (); - } - - #region focus - GraphicObject _activeWidget; //button is pressed on widget - GraphicObject _hoverWidget; //mouse is over - GraphicObject _focusedWidget; //has keyboard (or other perif) focus - - public GraphicObject activeWidget - { - get { return _activeWidget; } - set - { - if (_activeWidget == value) - return; - - if (_activeWidget != null) - _activeWidget.IsActive = false; - - _activeWidget = value; - - if (_activeWidget != null) - _activeWidget.IsActive = true; - } - } - public GraphicObject hoverWidget - { - get { return _hoverWidget; } - set { - if (_hoverWidget == value) - return; - _hoverWidget = value; - } - } - public GraphicObject FocusedWidget { - get { return _focusedWidget; } - set { - if (_focusedWidget == value) - return; - if (_focusedWidget != null) - _focusedWidget.onUnfocused (this, null); - _focusedWidget = value; - if (_focusedWidget != null) - _focusedWidget.onFocused (this, null); - } - } - #endregion - - #endregion - - /// Remove all Graphic objects from top container - public void ClearInterface() - { - int i = 0; - while (GraphicObjects.Count>0) { - //TODO:parent is not reset to null because object will be added - //to ObjectToRedraw list, and without parent, it fails - GraphicObject g = GraphicObjects [i]; - g.Visible = false; - g.ClearBinding (); - GraphicObjects.RemoveAt (0); - } - } - public GraphicObject FindByName (string nameToFind) - { - foreach (GraphicObject w in GraphicObjects) { - GraphicObject r = w.FindByName (nameToFind); - if (r != null) - return r; - } - return null; - } - #region Events - //those events are raised only if mouse isn't in a graphic object - public event EventHandler MouseWheelChanged; - public event EventHandler MouseButtonUp; - public event EventHandler MouseButtonDown; - public event EventHandler MouseClick; - public event EventHandler MouseMove; - public event EventHandler KeyboardKeyDown; - #endregion - - #region graphic contexte - Context ctx; - Surface surf; - byte[] bmp; - int texID; - - public QuadVAO uiQuad, uiQuad2; - Crow.Shader shader; - int[] viewport = new int[4]; - - void createContext() - { - createOpenGLSurface (); - - if (uiQuad != null) - uiQuad.Dispose (); - uiQuad = new QuadVAO (0, 0, ClientRectangle.Width, ClientRectangle.Height, 0, 1, 1, -1); - uiQuad2 = new QuadVAO (0, 0, ClientRectangle.Width, ClientRectangle.Height, 0, 0, 1, 1); - - shader.ProjectionMatrix = Matrix4.CreateOrthographicOffCenter - (0, ClientRectangle.Width, ClientRectangle.Height, 0, 0, 1); - - clipping.AddRectangle (ClientRectangle); - } - void createOpenGLSurface() - { - currentWindow = this; - - int stride = 4 * ClientRectangle.Width; - int bmpSize = Math.Abs (stride) * ClientRectangle.Height; - bmp = new byte[bmpSize]; - - //create texture - if (GL.IsTexture(texID)) - GL.DeleteTexture (texID); - GL.GenTextures(1, out texID); - GL.ActiveTexture (TextureUnit.Texture0); - GL.BindTexture(TextureTarget.Texture2D, texID); - - GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, - ClientRectangle.Width, ClientRectangle.Height, 0, - OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp); - - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); - - GL.BindTexture(TextureTarget.Texture2D, 0); - - shader.Texture = texID; - } - void OpenGLDraw() - { - GL.GetInteger (GetPName.Viewport, viewport); - GL.Viewport (0, 0, ClientRectangle.Width, ClientRectangle.Height); - - shader.Enable (); - - if (isDirty) { - byte[] tmp = new byte[4 * DirtyRect.Width * DirtyRect.Height]; - for (int y = 0; y < DirtyRect.Height; y++) { - Array.Copy(bmp, - ((DirtyRect.Top + y) * ClientRectangle.Width * 4) + DirtyRect.Left * 4, - tmp, y * DirtyRect.Width * 4, DirtyRect.Width *4); - } - GL.TexSubImage2D (TextureTarget.Texture2D, 0, - DirtyRect.Left, DirtyRect.Top, DirtyRect.Width, DirtyRect.Height, - OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, tmp); - isDirty = false; - } - uiQuad.Render (PrimitiveType.TriangleStrip); - - GL.BindTexture(TextureTarget.Texture2D, 0); - - shader.Disable (); - GL.Viewport (viewport [0], viewport [1], viewport [2], viewport [3]); - } - #endregion - - #if MEASURE_TIME - public Stopwatch updateTime = new Stopwatch (); - public Stopwatch layoutTime = new Stopwatch (); - public Stopwatch guTime = new Stopwatch (); - public Stopwatch drawingTime = new Stopwatch (); - #endif - - bool isDirty = false; - Rectangle DirtyRect; - - #region update - void update () - { - if (mouseRepeatCount > 0) { - int mc = mouseRepeatCount; - mouseRepeatCount -= mc; - for (int i = 0; i < mc; i++) { - FocusedWidget.onMouseClick (this, new MouseButtonEventArgs (Mouse.X, Mouse.Y, MouseButton.Left, true)); - } - } - #if MEASURE_TIME - layoutTime.Reset (); - guTime.Reset (); - drawingTime.Reset (); - updateTime.Restart (); - #endif - - GraphicObject[] invGOList = new GraphicObject[GraphicObjects.Count]; - GraphicObjects.CopyTo (invGOList, 0); - invGOList = invGOList.Reverse ().ToArray (); - - #if MEASURE_TIME - layoutTime.Start (); - #endif - //Debug.WriteLine ("======= Layouting queue start ======="); - - while (Interface.LayoutingQueue.Count > 0) { - LayoutingQueueItem lqi = Interface.LayoutingQueue.Dequeue (); - lqi.ProcessLayouting (); - } - - #if MEASURE_TIME - layoutTime.Stop (); - #endif - - //Debug.WriteLine ("otd:" + gobjsToRedraw.Count.ToString () + "-"); - //final redraw clips should be added only when layout is completed among parents, - //that's why it take place in a second pass - GraphicObject[] gotr = new GraphicObject[gobjsToRedraw.Count]; - gobjsToRedraw.CopyTo (gotr); - gobjsToRedraw.Clear (); - foreach (GraphicObject p in gotr) { - p.IsQueuedForRedraw = false; - p.Parent.RegisterClip (p.LastPaintedSlot); - p.Parent.RegisterClip (p.getSlot()); - } - - #if MEASURE_TIME - updateTime.Stop (); - drawingTime.Start (); - #endif - - using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) { - using (ctx = new Context (surf)){ - - - if (clipping.count > 0) { - //Link.draw (ctx); - clipping.clearAndClip(ctx); - - foreach (GraphicObject p in invGOList) { - if (!p.Visible) - continue; - if (!clipping.intersect (p.Slot)) - continue; - ctx.Save (); - - p.Paint (ref ctx); - - ctx.Restore (); - } - - #if DEBUG_CLIP_RECTANGLE - clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5)); - #endif - - if (isDirty) - DirtyRect += clipping.Bounds; - else - DirtyRect = clipping.Bounds; - isDirty = true; - - DirtyRect.Left = Math.Max (0, DirtyRect.Left); - DirtyRect.Top = Math.Max (0, DirtyRect.Top); - DirtyRect.Width = Math.Min (ClientRectangle.Width - DirtyRect.Left, DirtyRect.Width); - DirtyRect.Height = Math.Min (ClientRectangle.Height - DirtyRect.Top, DirtyRect.Height); - - clipping.Reset (); - } - - #if MEASURE_TIME - drawingTime.Stop (); - #endif - //surf.WriteToPng (@"/mnt/data/test.png"); - } - } -// if (ToolTip.isVisible) { -// ToolTip.panel.processkLayouting(); -// if (ToolTip.panel.layoutIsValid) -// ToolTip.panel.Paint(ref ctx); -// } -// Debug.WriteLine("INTERFACE: layouting: {0} ticks \t graphical update {1} ticks \t drawing {2} ticks", -// layoutTime.ElapsedTicks, -// guTime.ElapsedTicks, -// drawingTime.ElapsedTicks); -// Debug.WriteLine("INTERFACE: layouting: {0} ms \t graphical update {1} ms \t drawing {2} ms", -// layoutTime.ElapsedMilliseconds, -// guTime.ElapsedMilliseconds, -// drawingTime.ElapsedMilliseconds); - -// Debug.WriteLine("UPDATE: {0} ticks \t, {1} ms", -// updateTime.ElapsedTicks, -// updateTime.ElapsedMilliseconds); - } - #endregion - - #region loading - public GraphicObject LoadInterface (string path) - { - GraphicObject tmp = Interface.Load (path, this); - AddWidget (tmp); - return tmp; - } - #endregion - - public virtual void OnRender(FrameEventArgs e) - { - } - public virtual void GLClear() - { - GL.Clear (ClearBufferMask.ColorBufferBit); - } - - #region Game win overrides - protected override void OnUpdateFrame(FrameEventArgs e) - { - base.OnUpdateFrame(e); - update (); - } - protected override void OnRenderFrame(FrameEventArgs e) - { - GLClear (); - - - base.OnRenderFrame(e); - - OnRender (e); - OpenGLDraw (); - - - SwapBuffers (); - } - protected override void OnLoad(EventArgs e) - { - base.OnLoad(e); - - Keyboard.KeyDown += new EventHandler(Keyboard_KeyDown); - Mouse.WheelChanged += new EventHandler(Mouse_WheelChanged); - Mouse.ButtonDown += new EventHandler(Mouse_ButtonDown); - Mouse.ButtonUp += new EventHandler(Mouse_ButtonUp); - Mouse.Move += new EventHandler(Mouse_Move); - - GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - Console.WriteLine("\n\n*************************************"); - Console.WriteLine("GL version: " + GL.GetString (StringName.Version)); - Console.WriteLine("GL vendor: " + GL.GetString (StringName.Vendor)); - Console.WriteLine("GLSL version: " + GL.GetString (StringName.ShadingLanguageVersion)); - Console.WriteLine("*************************************\n"); - - shader = new Crow.TexturedShader (); - } - - protected override void OnResize(EventArgs e) - { - base.OnResize (e); - createContext (); - foreach (GraphicObject g in GraphicObjects) - g.RegisterForLayouting (LayoutingType.All); - } - #endregion - - #region Mouse Handling - void update_mouseButtonStates(ref MouseState e, OpenTK.Input.MouseState otk_e){ - for (int i = 0; i < MouseState.MaxButtons; i++) { - if (otk_e.IsButtonDown ((OpenTK.Input.MouseButton)i)) - e.EnableBit (i); - } - } - void Mouse_Move(object sender, OpenTK.Input.MouseMoveEventArgs otk_e) - { - MouseMoveEventArgs e = new MouseMoveEventArgs (otk_e.X, otk_e.Y, otk_e.XDelta, otk_e.YDelta); - MouseState ms = e.Mouse; - update_mouseButtonStates (ref ms, otk_e.Mouse); - e.Mouse = ms; - - if (_activeWidget != null) { - //first, ensure object is still in the graphic tree - if (_activeWidget.HostContainer == null) { - activeWidget = null; - } else { - - //send move evt even if mouse move outside bounds - _activeWidget.onMouseMove (this, e); - return; - } - } - - if (hoverWidget != null) { - //first, ensure object is still in the graphic tree - if (hoverWidget.HostContainer == null) { - hoverWidget = null; - } else { - //check topmost graphicobject first - GraphicObject tmp = hoverWidget; - GraphicObject topc = null; - while (tmp is GraphicObject) { - topc = tmp; - tmp = tmp.Parent as GraphicObject; - } - int idxhw = GraphicObjects.IndexOf (topc); - if (idxhw != 0) { - int i = 0; - while (i < idxhw) { - if (GraphicObjects [i].MouseIsIn (e.Position)) { - hoverWidget.onMouseLeave (this, e); - GraphicObjects [i].checkHoverWidget (e); - return; - } - i++; - } - } - - - if (hoverWidget.MouseIsIn (e.Position)) { - hoverWidget.checkHoverWidget (e); - return; - } else { - hoverWidget.onMouseLeave (this, e); - //seek upward from last focused graph obj's - while (hoverWidget.Parent as GraphicObject != null) { - hoverWidget = hoverWidget.Parent as GraphicObject; - if (hoverWidget.MouseIsIn (e.Position)) { - hoverWidget.checkHoverWidget (e); - return; - } else - hoverWidget.onMouseLeave (this, e); - } - } - } - } - - //top level graphic obj's parsing - for (int i = 0; i < GraphicObjects.Count; i++) { - GraphicObject g = GraphicObjects[i]; - if (g.MouseIsIn (e.Position)) { - g.checkHoverWidget (e); - PutOnTop (g); - return; - } - } - hoverWidget = null; - MouseMove.Raise (this, otk_e); - } - void Mouse_ButtonUp(object sender, OpenTK.Input.MouseButtonEventArgs otk_e) - { - MouseButtonEventArgs e = new MouseButtonEventArgs (otk_e.X, otk_e.Y, (Crow.MouseButton)otk_e.Button, otk_e.IsPressed); - MouseState ms = e.Mouse; - update_mouseButtonStates (ref ms, otk_e.Mouse); - e.Mouse = ms; - - if (_activeWidget == null) { - MouseButtonUp.Raise (this, otk_e); - return; - } - - if (mouseRepeatThread != null) { - mouseRepeatOn = false; - mouseRepeatThread.Abort(); - mouseRepeatThread.Join (); - } - - _activeWidget.onMouseUp (this, e); - activeWidget = null; - } - void Mouse_ButtonDown(object sender, OpenTK.Input.MouseButtonEventArgs otk_e) - { - MouseButtonEventArgs e = new MouseButtonEventArgs (otk_e.X, otk_e.Y, (Crow.MouseButton)otk_e.Button, otk_e.IsPressed); - MouseState ms = e.Mouse; - update_mouseButtonStates (ref ms, otk_e.Mouse); - e.Mouse = ms; - - if (hoverWidget == null) { - MouseButtonDown.Raise (this, otk_e); - return; - } - - hoverWidget.onMouseDown(hoverWidget,new BubblingMouseButtonEventArg(e)); - - if (FocusedWidget == null) - return; - if (!FocusedWidget.MouseRepeat) - return; - mouseRepeatThread = new Thread (mouseRepeatThreadFunc); - mouseRepeatThread.Start (); - } - void Mouse_WheelChanged(object sender, OpenTK.Input.MouseWheelEventArgs otk_e) - { - MouseWheelEventArgs e = new MouseWheelEventArgs (otk_e.X, otk_e.Y, otk_e.Value, otk_e.Delta); - MouseState ms = e.Mouse; - update_mouseButtonStates (ref ms, otk_e.Mouse); - e.Mouse = ms; - - if (hoverWidget == null) { - MouseWheelChanged.Raise (this, otk_e); - return; - } - hoverWidget.onMouseWheel (this, e); - } - - volatile bool mouseRepeatOn; - volatile int mouseRepeatCount; - Thread mouseRepeatThread; - void mouseRepeatThreadFunc() - { - mouseRepeatOn = true; - Thread.Sleep (Interface.DeviceRepeatDelay); - while (mouseRepeatOn) { - mouseRepeatCount++; - Thread.Sleep (Interface.DeviceRepeatInterval); - } - mouseRepeatCount = 0; - } - #endregion - - #region keyboard Handling - KeyboardState Keyboad = new KeyboardState (); - void Keyboard_KeyDown(object sender, OpenTK.Input.KeyboardKeyEventArgs otk_e) - { -// if (_focusedWidget == null) { - KeyboardKeyDown.Raise (this, otk_e); -// return; -// } - Keyboad.SetKeyState ((Crow.Key)otk_e.Key, true); - KeyboardKeyEventArgs e = new KeyboardKeyEventArgs((Crow.Key)otk_e.Key, otk_e.IsRepeat,Keyboad); - _focusedWidget.onKeyDown (sender, e); - } - #endregion - - #region ILayoutable implementation - public void RegisterClip(Rectangle r){ - clipping.AddRectangle (r); - } - public bool ArrangeChildren { get { return false; }} - public int LayoutingTries { - get { throw new NotImplementedException (); } - set { throw new NotImplementedException (); } - } - public LayoutingType RegisteredLayoutings { - get { return LayoutingType.None; } - set { throw new NotImplementedException (); } - } - public void RegisterForLayouting (LayoutingType layoutType) { throw new NotImplementedException (); } - public bool UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); } - public Rectangle ContextCoordinates (Rectangle r) => r; - public Rectangle ScreenCoordinates (Rectangle r) => r; - - public ILayoutable Parent { - get { return null; } - set { throw new NotImplementedException (); } - } - public ILayoutable LogicalParent { - get { return null; } - set { throw new NotImplementedException (); } - } - - Rectangle ILayoutable.ClientRectangle { - get { return new Size(this.ClientRectangle.Size.Width,this.ClientRectangle.Size.Height); } - } - public IGOLibHost HostContainer { - get { return this; } - } - public Rectangle getSlot () => ClientRectangle; - public Rectangle getBounds () => ClientRectangle; - #endregion - } -} diff --git a/src/XCursor.cs b/src/XCursor.cs index d24b1687..8897753d 100644 --- a/src/XCursor.cs +++ b/src/XCursor.cs @@ -136,10 +136,10 @@ namespace Crow public XCursor () { } - public static implicit operator MouseCursor(XCursor xc) - { - return new MouseCursor((int)xc.Xhot, (int)xc.Yhot, (int)xc.Width, (int)xc.Height,xc.data); - } +// public static implicit operator MouseCursor(XCursor xc) +// { +// return new MouseCursor((int)xc.Xhot, (int)xc.Yhot, (int)xc.Width, (int)xc.Height,xc.data); +// } } }