From: jpbruyere Date: Sun, 14 Aug 2016 19:39:08 +0000 (+0200) Subject: CrowIDE project creation X-Git-Tag: v0.5.1~28^2~42 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=d7351424c8fad3563e579bd0a9c94c444bad4b72;p=jp%2Fcrow.git CrowIDE project creation --- diff --git a/Crow.sln b/Crow.sln index 725fe4ec..2823f92d 100644 --- a/Crow.sln +++ b/Crow.sln @@ -5,6 +5,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Crow", "Crow.csproj", "{C29 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{74289092-9F70-4941-AFCB-DFD7BE2140B6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrowIDE", "CrowIDE\CrowIDE.csproj", "{B6D911CD-1D09-42FC-B300-9187190F2AE1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Debug|Any CPU.Build.0 = Debug|Any CPU {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Any CPU.ActiveCfg = Release|Any CPU {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Any CPU.Build.0 = Release|Any CPU + {B6D911CD-1D09-42FC-B300-9187190F2AE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6D911CD-1D09-42FC-B300-9187190F2AE1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6D911CD-1D09-42FC-B300-9187190F2AE1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B6D911CD-1D09-42FC-B300-9187190F2AE1}.Release|Any CPU.Build.0 = Release|Any CPU {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Debug|Any CPU.Build.0 = Debug|Any CPU {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/CrowIDE/CrowIDE.csproj b/CrowIDE/CrowIDE.csproj new file mode 100644 index 00000000..ce7149d6 --- /dev/null +++ b/CrowIDE/CrowIDE.csproj @@ -0,0 +1,91 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {B6D911CD-1D09-42FC-B300-9187190F2AE1} + Exe + CrowIDE + CrowIDE + v4.5 + $(SolutionDir)build/$(Configuration) + $(SolutionDir)build/obj/$(Configuration) + + + + + + 0.4 + CrowIDE.CrowIDE + + + true + full + false + DEBUG; + prompt + 4 + false + $(SolutionDir)build\obj\$(Configuration) + $(SolutionDir)build\$(Configuration) + + + none + true + prompt + 0 + false + $(SolutionDir)build\obj\$(Configuration) + $(SolutionDir)build\$(Configuration) + + + + + + + + gtk-sharp-3.0 + + + gtk-sharp-2.0 + + + gio-sharp-3.0 + + + glib-sharp-3.0 + + + $(SolutionDir)packages\OpenTK.Next.1.2.2336.6514-pre\lib\net20\OpenTK.dll + + + + + + {C2980F9B-4798-4C05-99E2-E174810F7C7B} + Crow + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + \ No newline at end of file diff --git a/CrowIDE/OpenGL/Shader.cs b/CrowIDE/OpenGL/Shader.cs new file mode 100644 index 00000000..0f355fcd --- /dev/null +++ b/CrowIDE/OpenGL/Shader.cs @@ -0,0 +1,335 @@ +// +// Shader.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.Diagnostics; +using System.IO; +using OpenTK; +using OpenTK.Graphics.OpenGL; + +namespace Crow +{ + public class Shader : IDisposable + { + #region CTOR + public Shader () + { + Init (); + } + public Shader (string vertResPath, string fragResPath = null, string geomResPath = null) + { + VertSourcePath = vertResPath; + FragSourcePath = fragResPath; + GeomSourcePath = geomResPath; + + loadSourcesFiles (); + + Init (); + } + #endregion + + public string VertSourcePath, + FragSourcePath, + GeomSourcePath; + #region Sources + protected string _vertSource = @" + #version 330 + precision lowp float; + + uniform mat4 mvp; + + layout(location = 0) in vec3 in_position; + layout(location = 1) in vec2 in_tex; + + out vec2 texCoord; + + void main(void) + { + texCoord = in_tex; + gl_Position = mvp * vec4(in_position, 1.0); + }"; + + protected string _fragSource = @" + #version 330 + precision lowp float; + + uniform sampler2D tex; + + in vec2 texCoord; + out vec4 out_frag_color; + + void main(void) + { + out_frag_color = texture( tex, texCoord);//vec4(1,0,0,1); + }"; + 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 + public int vsId, fsId, gsId, pgmId, mvpLocation; + + Matrix4 mvp = Matrix4.Identity; + #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 virtual Matrix4 MVP{ + set { mvp = value; } + get { return mvp; } + } + #endregion + + #region Public functions + /// + /// configure sources and compile + /// + public virtual void Init() + { + Compile (); + } + public void Reload(){ + loadSourcesFiles (); + Compile (); + } + public void SetSource(ShaderType shaderType, string _source){ + switch (shaderType) { + case ShaderType.FragmentShader: + fragSource = _source; + return; + case ShaderType.VertexShader: + vertSource = _source; + return; + case ShaderType.GeometryShader: + geomSource = _source; + return; + } + } + public string GetSource(ShaderType shaderType){ + switch (shaderType) { + case ShaderType.FragmentShader: + return fragSource; + case ShaderType.VertexShader: + return vertSource; + case ShaderType.GeometryShader: + return geomSource; + } + return ""; + } + public string GetSourcePath(ShaderType shaderType){ + switch (shaderType) { + case ShaderType.FragmentShader: + return FragSourcePath; + case ShaderType.VertexShader: + return VertSourcePath; + case ShaderType.GeometryShader: + return GeomSourcePath; + } + return ""; + } + 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() + { + mvpLocation = GL.GetUniformLocation(pgmId, "mvp"); + } + protected virtual void BindSamplesSlots(){ + GL.Uniform1(GL.GetUniformLocation (pgmId, "tex"), 0); + } + public void SetMVP(Matrix4 _mvp){ + GL.UniformMatrix4(mvpLocation, false, ref _mvp); + } + public virtual void Enable(){ + GL.UseProgram (pgmId); + } + 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 loadSourcesFiles(){ + Stream s; + + if (!string.IsNullOrEmpty (VertSourcePath)) { + s = Crow.Interface.GetStreamFromPath (VertSourcePath); + if (s != null) { + using (StreamReader sr = new StreamReader (s)) { + vertSource = sr.ReadToEnd (); + } + } + } + + if (!string.IsNullOrEmpty (FragSourcePath)) { + s = Crow.Interface.GetStreamFromPath (FragSourcePath); + if (s != null) { + using (StreamReader sr = new StreamReader (s)) { + fragSource = sr.ReadToEnd (); + } + } + } + + if (!string.IsNullOrEmpty (GeomSourcePath)) { + s = Crow.Interface.GetStreamFromPath (GeomSourcePath); + if (s != null) { + using (StreamReader sr = new StreamReader (s)) { + geomSource = sr.ReadToEnd (); + } + } + } + } + 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); + } + } + public override string ToString () + { + return string.Format ("{0} {1} {2}", VertSourcePath, FragSourcePath, GeomSourcePath); + } + + #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/CrowIDE/OpenGL/Texture.cs b/CrowIDE/OpenGL/Texture.cs new file mode 100644 index 00000000..e6bec071 --- /dev/null +++ b/CrowIDE/OpenGL/Texture.cs @@ -0,0 +1,94 @@ +// +// Texture.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.Drawing; +using OpenTK.Graphics.OpenGL; +using System.Drawing.Imaging; +using System.IO; +using System.Diagnostics; + +namespace Crow +{ + public class Texture + { + public string Map; + public int texRef; + public int Width; + public int Height; + + public Texture(string _mapPath, bool flipY = true) + { + using (Stream s = Interface.GetStreamFromPath (_mapPath)) { + + try { + Map = _mapPath; + + Bitmap bitmap = new Bitmap (s); + + if (flipY) + bitmap.RotateFlip (RotateFlipType.RotateNoneFlipY); + + BitmapData data = bitmap.LockBits (new System.Drawing.Rectangle (0, 0, bitmap.Width, bitmap.Height), + ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + + createTexture (data.Scan0, data.Width, data.Height); + + bitmap.UnlockBits (data); + + GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear); + GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + + GL.GenerateMipmap (GenerateMipmapTarget.Texture2D); + + } catch (Exception ex) { + Debug.WriteLine ("Error loading texture: " + Map + ":" + ex.Message); + } + } + } + + public Texture(int width, int height) + { + createTexture (IntPtr.Zero, width, height); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp); + } + + void createTexture(IntPtr data, int width, int height) + { + Width = width; + Height = height; + + GL.GenTextures(1, out texRef); + GL.BindTexture(TextureTarget.Texture2D, texRef); + GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, + OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data); + } + + public static implicit operator int(Texture t) + { + return t == null ? 0: t.texRef; + } + } + +} diff --git a/CrowIDE/OpenGL/vaoMesh.cs b/CrowIDE/OpenGL/vaoMesh.cs new file mode 100644 index 00000000..c0b24528 --- /dev/null +++ b/CrowIDE/OpenGL/vaoMesh.cs @@ -0,0 +1,221 @@ +// +// vaoMesh.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 OpenTK; +using OpenTK.Graphics.OpenGL; + +namespace Crow +{ + public class vaoMesh : IDisposable + { + public int vaoHandle, + positionVboHandle, + texVboHandle, + eboHandle; + + public Vector3[] positions; + public Vector2[] texCoords; + public int[] indices; + + public vaoMesh() + { + } + + public vaoMesh (Vector3[] _positions, Vector2[] _texCoord, int[] _indices) + { + positions = _positions; + texCoords = _texCoord; + indices = _indices; + + CreateBuffers (); + } + + public vaoMesh (float x, float y, float z, float width, float height, float TileX = 1f, float TileY = 1f) + { + positions = + new Vector3[] { + new Vector3 (x - width / 2, y + height / 2, z), + new Vector3 (x - width / 2, y - height / 2, z), + new Vector3 (x + width / 2, y + height / 2, z), + new Vector3 (x + width / 2, y - height / 2, z) + }; + texCoords = new Vector2[] { + new Vector2 (0, TileY), + new Vector2 (0, 0), + new Vector2 (TileX, TileY), + new Vector2 (TileX, 0) + }; + indices = new int[] { 0, 1, 2, 3 }; + + CreateBuffers (); + } + public static vaoMesh CreateCube(){ + vaoMesh tmp = new vaoMesh (); + tmp.positions = new Vector3[] + { + new Vector3(-1.0f, -1.0f, -1.0f), + new Vector3( -1.0f, -1.0f, 1.0f), + new Vector3( 1.0f, -1.0f, -1.0f), + new Vector3(1.0f, -1.0f, 1.0f), + new Vector3(1.0f, 1.0f, -1.0f), + new Vector3( 1.0f, 1.0f, 1.0f), + new Vector3( -1.0f, 1.0f, -1.0f), + new Vector3(-1.0f, 1.0f, 1.0f) + }; + tmp.indices = new int[] + { + // front face + 0, 2, 1, 1, 2, 3, + // top face + 2, 4, 3, 3, 4, 5, + // back face + 4, 6, 5, 5, 6, 7, + // left face + 6, 0, 7, 7, 0, 1, + // bottom face + 1, 3, 7, 7, 3, 5, + // right face +// 1, 5, 6, 6, 2, 1, + }; + tmp.texCoords = new Vector2[] + { + new Vector2(0, 0), + new Vector2(0, 1), + new Vector2(1, 0), + new Vector2(1, 1), + new Vector2(0, 0), + new Vector2(0, 1), + new Vector2(1, 0), + new Vector2(1, 1), + }; + tmp.CreateBuffers (); + return tmp; +// Normals = new Vector3[] +// { +// new Vector3(-1.0f, -1.0f, 1.0f), +// new Vector3( 1.0f, -1.0f, 1.0f), +// new Vector3( 1.0f, 1.0f, 1.0f), +// new Vector3(-1.0f, 1.0f, 1.0f), +// new Vector3(-1.0f, -1.0f, -1.0f), +// new Vector3( 1.0f, -1.0f, -1.0f), +// new Vector3( 1.0f, 1.0f, -1.0f), +// new Vector3(-1.0f, 1.0f, -1.0f), +// }; +// +// Colors = new int[] +// { +// Utilities.ColorToRgba32(Color.DarkRed), +// Utilities.ColorToRgba32(Color.DarkRed), +// Utilities.ColorToRgba32(Color.Gold), +// Utilities.ColorToRgba32(Color.Gold), +// Utilities.ColorToRgba32(Color.DarkRed), +// Utilities.ColorToRgba32(Color.DarkRed), +// Utilities.ColorToRgba32(Color.Gold), +// Utilities.ColorToRgba32(Color.Gold), +// }; + } + public void CreateBuffers(){ + CreateVBOs (); + CreateVAOs (); + } + protected void CreateVBOs() + { + positionVboHandle = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle); + GL.BufferData(BufferTarget.ArrayBuffer, + new IntPtr(positions.Length * Vector3.SizeInBytes), + positions, BufferUsageHint.StaticDraw); + + if (texCoords != null) { + texVboHandle = GL.GenBuffer (); + GL.BindBuffer (BufferTarget.ArrayBuffer, texVboHandle); + GL.BufferData (BufferTarget.ArrayBuffer, + new IntPtr (texCoords.Length * Vector2.SizeInBytes), + texCoords, BufferUsageHint.StaticDraw); + } + + GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + + if (indices != null) { + eboHandle = GL.GenBuffer (); + GL.BindBuffer (BufferTarget.ElementArrayBuffer, eboHandle); + GL.BufferData (BufferTarget.ElementArrayBuffer, + new IntPtr (sizeof(uint) * indices.Length), + indices, BufferUsageHint.StaticDraw); + GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); + } + } + protected void CreateVAOs() + { + vaoHandle = GL.GenVertexArray(); + GL.BindVertexArray(vaoHandle); + + GL.EnableVertexAttribArray(0); + GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle); + GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0); + + if (texCoords != null) { + GL.EnableVertexAttribArray (1); + GL.BindBuffer (BufferTarget.ArrayBuffer, texVboHandle); + GL.VertexAttribPointer (1, 2, VertexAttribPointerType.Float, true, Vector2.SizeInBytes, 0); + } + if (indices != null) + GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle); + + GL.BindVertexArray(0); + } + + public void Render(BeginMode _primitiveType){ + GL.BindVertexArray(vaoHandle); + if (indices == null) + GL.DrawArrays (_primitiveType, 0, positions.Length); + else + GL.DrawElements(_primitiveType, indices.Length, + DrawElementsType.UnsignedInt, IntPtr.Zero); + GL.BindVertexArray (0); + } + public void Render(BeginMode _primitiveType, int[] _customIndices){ + GL.BindVertexArray(vaoHandle); + GL.DrawElements(_primitiveType, _customIndices.Length, + DrawElementsType.UnsignedInt, _customIndices); + GL.BindVertexArray (0); + } + public void Render(BeginMode _primitiveType, int instances){ + + GL.BindVertexArray(vaoHandle); + GL.DrawElementsInstanced(_primitiveType, indices.Length, + DrawElementsType.UnsignedInt, IntPtr.Zero, instances); + GL.BindVertexArray (0); + } + + #region IDisposable implementation + public void Dispose () + { + GL.DeleteBuffer (positionVboHandle); + GL.DeleteBuffer (texVboHandle); + GL.DeleteBuffer (eboHandle); + GL.DeleteVertexArray (vaoHandle); + } + #endregion + + } +} \ No newline at end of file diff --git a/CrowIDE/OpenTKGameWindow.cs b/CrowIDE/OpenTKGameWindow.cs new file mode 100644 index 00000000..b3851904 --- /dev/null +++ b/CrowIDE/OpenTKGameWindow.cs @@ -0,0 +1,334 @@ +// +// 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.Threading; +using OpenTK; +using OpenTK.Graphics.OpenGL; + +namespace Crow +{ + public class OpenTKGameWindow : GameWindow, IValueChange + { + #region IValueChange implementation + public event EventHandler ValueChanged; + public virtual void NotifyValueChanged(string MemberName, object _value) + { + if (ValueChanged != null) + ValueChanged.Invoke(this, new ValueChangeEventArgs(MemberName, _value)); + } + #endregion + + public Interface CrowInterface; + + #region FPS + int frameCpt = 0; + int _fps = 0; + + public int fps { + get { return _fps; } + set { + if (_fps == value) + return; + + _fps = value; + + if (_fps > fpsMax) { + fpsMax = _fps; + ValueChanged.Raise(this, new ValueChangeEventArgs ("fpsMax", fpsMax)); + } else if (_fps < fpsMin) { + fpsMin = _fps; + ValueChanged.Raise(this, new ValueChangeEventArgs ("fpsMin", fpsMin)); + } + + ValueChanged.Raise(this, new ValueChangeEventArgs ("fps", _fps)); + #if MEASURE_TIME + ValueChanged.Raise (this, new ValueChangeEventArgs ("update", + this.CrowInterface.updateTime.ElapsedTicks.ToString () + " ticks")); + ValueChanged.Raise (this, new ValueChangeEventArgs ("layouting", + this.CrowInterface.layoutTime.ElapsedTicks.ToString () + " ticks")); + ValueChanged.Raise (this, new ValueChangeEventArgs ("drawing", + this.CrowInterface.drawingTime.ElapsedTicks.ToString () + " ticks")); + ValueChanged.Raise (this, new ValueChangeEventArgs ("clipping", + this.CrowInterface.clippingTime.ElapsedTicks.ToString () + " ticks")); + #endif + } + } + + public int fpsMin = int.MaxValue; + public int fpsMax = 0; + + void resetFps () + { + fpsMin = int.MaxValue; + fpsMax = 0; + _fps = 0; + } + public string update = ""; + public string drawing = ""; + public string layouting = ""; + public string clipping = ""; + #endregion + + #region ctor + public OpenTKGameWindow(int _width = 800, int _height = 600, string _title="Crow", + int colors = 32, int depth = 24, int stencil = 0, int samples = 1, + int major=3, int minor=3) + : this(_width, _height, new OpenTK.Graphics.GraphicsMode(colors, depth, stencil, samples), + _title,GameWindowFlags.Default,DisplayDevice.Default, + major,minor,OpenTK.Graphics.GraphicsContextFlags.Default) + { + } + public OpenTKGameWindow (int width, int height, OpenTK.Graphics.GraphicsMode mode, string title, GameWindowFlags options, DisplayDevice device, int major, int minor, OpenTK.Graphics.GraphicsContextFlags flags) + : base(width,height,mode,title,options,device,major,minor,flags) + { + CrowInterface = new Interface (); + + Thread t = new Thread (interfaceThread); + t.IsBackground = true; + t.Start (); + } + + #endregion + + void interfaceThread() + { + CrowInterface.Quit += Quit; + CrowInterface.MouseCursorChanged += CrowInterface_MouseCursorChanged; + while (CrowInterface.ClientRectangle.Size.Width == 0) + Thread.Sleep (5); + + while (true) { + CrowInterface.Update (); + Thread.Sleep (1); + } + } + + public void Quit (object sender, EventArgs e) + { + this.Exit (); + } + void CrowInterface_MouseCursorChanged (object sender, MouseCursorChangedEventArgs e) + { + this.Cursor = new MouseCursor( + (int)e.NewCursor.Xhot, + (int)e.NewCursor.Yhot, + (int)e.NewCursor.Width, + (int)e.NewCursor.Height, + e.NewCursor.data); + } + + #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; + public event EventHandler KeyboardKeyUp; + + #endregion + + #region graphic context + public int texID; + public Shader shader; + public vaoMesh quad; + public Matrix4 projection; + + void createContext() + { + #region 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, CrowInterface.bmp); + + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + + GL.BindTexture(TextureTarget.Texture2D, 0); + #endregion + } + void OpenGLDraw() + { + bool blend, depthTest; + GL.GetBoolean (GetPName.Blend, out blend); + GL.GetBoolean (GetPName.DepthTest, out depthTest); + GL.Enable (EnableCap.Blend); + GL.Disable (EnableCap.DepthTest); + + shader.Enable (); + shader.SetMVP (projection); + GL.ActiveTexture (TextureUnit.Texture0); + GL.BindTexture (TextureTarget.Texture2D, texID); + lock (CrowInterface.RenderMutex) { + if (CrowInterface.IsDirty) { + GL.TexSubImage2D (TextureTarget.Texture2D, 0, + CrowInterface.DirtyRect.Left, CrowInterface.DirtyRect.Top, + CrowInterface.DirtyRect.Width, CrowInterface.DirtyRect.Height, + OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, CrowInterface.dirtyBmp); + CrowInterface.IsDirty = false; + } + } + quad.Render (BeginMode.TriangleStrip); + GL.BindTexture(TextureTarget.Texture2D, 0); + + if (!blend) + GL.Disable (EnableCap.Blend); + if (depthTest) + GL.Enable (EnableCap.DepthTest); + } + #endregion + + /// + /// Override this method for your OpenGL rendering calls + /// + public virtual void OnRender(FrameEventArgs e) + { + } + /// + /// Override this method to customize clear method between frames + /// + public virtual void GLClear() + { + GL.Clear (ClearBufferMask.ColorBufferBit|ClearBufferMask.DepthBufferBit); + } + + #region Game win overrides + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + this.KeyPress += new EventHandler(OpenTKGameWindow_KeyPress); + Keyboard.KeyDown += new EventHandler(Keyboard_KeyDown); + Keyboard.KeyUp += new EventHandler(Keyboard_KeyUp); + 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"); + + projection = OpenTK.Matrix4.CreateOrthographicOffCenter (-0.5f, 0.5f, -0.5f, 0.5f, 1, -1); + + shader = new Shader (); + quad = new Crow.vaoMesh (0, 0, 0, 1, 1, 1, -1); + } + + protected override void OnUpdateFrame(FrameEventArgs e) + { + base.OnUpdateFrame(e); + fps = (int)RenderFrequency; + + + if (frameCpt > 50) { + resetFps (); + frameCpt = 0; + GC.Collect(); + GC.WaitForPendingFinalizers(); + NotifyValueChanged("memory", GC.GetTotalMemory (false).ToString()); + } + frameCpt++; + } + protected override void OnRenderFrame(FrameEventArgs e) + { + GLClear (); + + base.OnRenderFrame(e); + + OnRender (e); + OpenGLDraw (); + + SwapBuffers (); + } + + protected override void OnResize(EventArgs e) + { + base.OnResize (e); + CrowInterface.ProcessResize( + new Rectangle( + 0, + 0, + this.ClientRectangle.Width, + this.ClientRectangle.Height)); + createContext (); + GL.Viewport (0, 0, ClientRectangle.Width, ClientRectangle.Height); + } + #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) + { + if (!CrowInterface.ProcessMouseMove (otk_e.X, otk_e.Y)) + MouseMove.Raise (sender, otk_e); + } + void Mouse_ButtonUp(object sender, OpenTK.Input.MouseButtonEventArgs otk_e) + { + if (!CrowInterface.ProcessMouseButtonUp ((int)otk_e.Button)) + MouseButtonUp.Raise (sender, otk_e); + } + void Mouse_ButtonDown(object sender, OpenTK.Input.MouseButtonEventArgs otk_e) + { + if (!CrowInterface.ProcessMouseButtonDown ((int)otk_e.Button)) + MouseButtonDown.Raise (sender, otk_e); + } + void Mouse_WheelChanged(object sender, OpenTK.Input.MouseWheelEventArgs otk_e) + { + if (!CrowInterface.ProcessMouseWheelChanged (otk_e.DeltaPrecise)) + MouseWheelChanged.Raise (sender, otk_e); + } + #endregion + + #region keyboard Handling + void Keyboard_KeyDown(object sender, OpenTK.Input.KeyboardKeyEventArgs otk_e) + { + if (!CrowInterface.ProcessKeyDown((int)otk_e.Key)) + KeyboardKeyDown.Raise (this, otk_e); + } + void Keyboard_KeyUp(object sender, OpenTK.Input.KeyboardKeyEventArgs otk_e) + { + if (!CrowInterface.ProcessKeyUp((int)otk_e.Key)) + KeyboardKeyUp.Raise (this, otk_e); + } + void OpenTKGameWindow_KeyPress (object sender, OpenTK.KeyPressEventArgs e) + { + CrowInterface.ProcessKeyPress (e.KeyChar); + } + #endregion + } +} diff --git a/CrowIDE/src/CrowIDE.cs b/CrowIDE/src/CrowIDE.cs new file mode 100644 index 00000000..f873ad4c --- /dev/null +++ b/CrowIDE/src/CrowIDE.cs @@ -0,0 +1,53 @@ +// +// HelloCube.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 OpenTK; +using OpenTK.Graphics.OpenGL; +using Crow; + +namespace CrowIDE +{ + class CrowIDE : OpenTKGameWindow + { + [STAThread] + static void Main () + { + CrowIDE win = new CrowIDE (); + win.Run (30); + } + + public CrowIDE () + : base(800, 600,"UIEditor") + { + } + + protected override void OnLoad (EventArgs e) + { + base.OnLoad (e); + + //this.CrowInterface.LoadInterface ("#CrowIDE.ui.imlEditor.crow").DataSource = this; + GraphicObject go = this.CrowInterface.LoadInterface (@"ui/test.crow"); + go.DataSource = this; + Interface i = go.CurrentInterface; + } + } +} \ No newline at end of file diff --git a/CrowIDE/src/ImlVisualEditor.cs b/CrowIDE/src/ImlVisualEditor.cs new file mode 100644 index 00000000..9229d8af --- /dev/null +++ b/CrowIDE/src/ImlVisualEditor.cs @@ -0,0 +1,94 @@ +// +// ImlVisualEditor.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 Crow; +using System.Threading; +using System.Xml.Serialization; +using System.ComponentModel; + +namespace CrowIDE +{ + public class ImlVisualEditor : GraphicObject + { + string imlPath; + Interface imlVE; + + [XmlAttributeAttribute][DefaultValue("")] + public virtual string ImlPath { + get { return imlPath; } + set { + if (imlPath == value) + return; + imlPath = value; + NotifyValueChanged ("ImlPath", imlPath); + } + } + bool drawGrid; + [XmlAttributeAttribute()][DefaultValue(true)] + public virtual bool DrawGrid { + get { return drawGrid; } + set { + if (drawGrid == value) + return; + drawGrid = value; + NotifyValueChanged ("DrawGrid", drawGrid); + RegisterForRedraw (); + } + } + int gridSpacing; + [XmlAttributeAttribute()][DefaultValue(10)] + public virtual int GridSpacing { + get { return gridSpacing; } + set { + if (gridSpacing == value) + return; + gridSpacing = value; + NotifyValueChanged ("GridSpacing", gridSpacing); + RegisterForRedraw (); + } + } + public ImlVisualEditor () : base() + { + imlVE = new Interface (); + + } + protected override void onDraw (Cairo.Context gr) + { + base.onDraw (gr); + if (!drawGrid) + return; + + + Rectangle cb = ClientRectangle; + + int nbLines = cb.Width / gridSpacing ; + double x = gridSpacing + cb.Center.X - nbLines * gridSpacing; + for (int i = 0; i < nbLines; i++) { + gr.MoveTo (x-0.5, cb.Y); + gr.LineTo (x-0.5, cb.Y); + } + + gr.LineWidth = 1.0; + Foreground.SetAsSource (gr, cb); + gr.Stroke (); + } + } +} diff --git a/CrowIDE/ui/imlEditor.crow b/CrowIDE/ui/imlEditor.crow new file mode 100644 index 00000000..d1aa315c --- /dev/null +++ b/CrowIDE/ui/imlEditor.crow @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + diff --git a/CrowIDE/ui/test.crow b/CrowIDE/ui/test.crow new file mode 100644 index 00000000..4036b729 --- /dev/null +++ b/CrowIDE/ui/test.crow @@ -0,0 +1,4 @@ + + +