<Compile Include="src\GraphicObjects\Checkbox.cs" />\r
<Compile Include="src\Font.cs" />\r
<Compile Include="src\TextChangeEventArgs.cs" />\r
+ <Compile Include="src\OpenGL\QuadVAO.cs" />\r
+ <Compile Include="src\OpenGL\Shader.cs" />\r
+ <Compile Include="src\OpenGL\TexturedShader.cs" />\r
+ <Compile Include="src\OpenGL\VertexArrayObject.cs" />\r
</ItemGroup>\r
<ItemGroup>\r
<Reference Include="System" />\r
<Folder Include="Images\" />\r
<Folder Include="Images\Icons\" />\r
<Folder Include="src\CompilerServices\" />\r
+ <Folder Include="src\OpenGL\" />\r
</ItemGroup>\r
<ItemGroup>\r
<None Include="Images\Icons\icon_alert.gif">\r
\r
ctx.Restore(); \r
}\r
-\r
-//\r
-// public override void Paint(ref Cairo.Context ctx, Rectangles clip = null)\r
-// {\r
-// if (!Visible)//check if necessary??\r
-// return;\r
-//\r
-// ctx.Save();\r
-//\r
-// Rectangle tmp;\r
-// tmp = Parent.ContextCoordinates(Slot);\r
-//// ctx.Rectangle(tmp);\r
-//// ctx.Clip();\r
-//\r
-//// if (clip != null)\r
-//// clip.clip(ctx);\r
-//\r
-// if (bmp == null)\r
-// UpdateGraphic ();\r
-//\r
-//\r
-//\r
-// int stride = 4 * Slot.Width;\r
-// using (ImageSurface source = new ImageSurface(bmp, Format.Argb32, tmp.Width, tmp.Height, stride)) {\r
-// ctx.SetSourceSurface (source, tmp.X, tmp.Y);\r
-// ctx.Paint ();\r
-// }\r
-//\r
-//\r
-// //clip to client zone\r
-//// ctx.Rectangle(Parent.ContextCoordinates(ClientRectangle + Slot.Position));\r
-//// ctx.Clip();\r
-//\r
-// //ctx.Translate (scrollX, scrollY);\r
-//\r
-// if (clip != null) \r
-// clip.Srcoll (this);\r
-////\r
-//// //clip.stroke (ctx, Color.Green);\r
-////\r
-////// if (scrollY < 0)\r
-////// Debug.WriteLine ("..");\r
-//// }\r
-//\r
-//\r
-//\r
-// if (child != null)\r
-// child.Paint(ref ctx, clip);\r
-//\r
-// ctx.Restore(); \r
-// }\r
-\r
}\r
}\r
--- /dev/null
+using System;
+using OpenTK;
+
+namespace go
+{
+ 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 })
+ {
+
+ }
+ }
+}
+
--- /dev/null
+using System;
+using OpenTK.Graphics.OpenGL;
+using System.Diagnostics;
+using OpenTK;
+
+namespace go.GLBackend
+{
+ public class Shader : IDisposable
+ {
+ #region CTOR
+ public Shader ()
+ {
+ Compile ();
+ }
+ #endregion
+
+
+ #region Sources
+ protected string _vertSource = @"
+ #version 130
+
+ precision highp float;
+
+ uniform mat4 projection_matrix;
+ uniform mat4 modelview_matrix;
+
+ in vec2 in_position;
+
+ void main(void)
+ {
+ gl_Position = projection_matrix * modelview_matrix * vec4(in_position,0, 1);
+ }";
+
+ protected string _fragSource = @"
+ #version 130
+ precision highp float;
+
+ uniform vec4 color;
+ uniform bool stencilTest;
+ uniform sampler2D stencil;
+ uniform vec2 resolution;
+
+ out vec4 out_frag_color;
+
+ void main(void)
+ {
+ if (stencilTest)
+ {
+ vec2 uv = gl_FragCoord.xy/resolution;
+ vec4 s = texture( stencil, uv);
+ if (s.r == 0.0)
+ discard;
+ }
+ out_frag_color = color;
+ }";
+ string _geomSource = "";
+ #endregion
+
+ #region Private and protected fields
+ protected int vsId, fsId, gsId, pgmId, savedPgmId = 0,
+ modelviewMatrixLocation,
+ projectionMatrixLocation,
+ colorLocation,stencilTestLocation,resolutionLocation;
+
+ Matrix4 projectionMatrix,
+ modelviewMatrix;
+ #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 {
+ projectionMatrix = value;
+ GL.UniformMatrix4(projectionMatrixLocation, false, ref projectionMatrix);
+ }
+ }
+ public Matrix4 ModelViewMatrix {
+ set {
+ modelviewMatrix = value;
+ GL.UniformMatrix4 (modelviewMatrixLocation, false, ref modelviewMatrix);
+ }
+ }
+
+ public Vector4 Color {
+ set {GL.Uniform4 (colorLocation, value);}
+ }
+
+ public bool StencilTest {
+ set {
+ if (value)
+ GL.Uniform1 (stencilTestLocation, 1);
+ else
+ GL.Uniform1 (stencilTestLocation, 0);
+ }
+ }
+
+ public Vector2 Resolution {
+ set { GL.Uniform2 (resolutionLocation, value); }
+ }
+
+ #endregion
+
+ #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 ();
+
+ GL.LinkProgram(pgmId);
+ GL.ValidateProgram(pgmId);
+
+ string info;
+ GL.GetProgramInfoLog(pgmId, out info);
+ Debug.WriteLine(info);
+
+ Enable ();
+
+ GetUniformLocations ();
+ BindSamplesSlots ();
+
+ Disable ();
+ }
+ protected virtual void BindVertexAttributes()
+ {
+ GL.BindAttribLocation(pgmId, 0, "in_position");
+ }
+ protected virtual void GetUniformLocations()
+ {
+ projectionMatrixLocation = GL.GetUniformLocation(pgmId, "projection_matrix");
+ modelviewMatrixLocation = GL.GetUniformLocation(pgmId, "modelview_matrix");
+ colorLocation = GL.GetUniformLocation (pgmId, "color");
+ stencilTestLocation = GL.GetUniformLocation (pgmId, "stencilTest");
+ resolutionLocation = GL.GetUniformLocation (pgmId, "resolution");
+ }
+ protected virtual void BindSamplesSlots(){
+ GL.Uniform1(GL.GetUniformLocation (pgmId, "stencil"),0);
+ }
+
+ public virtual void Enable(){
+ GL.GetInteger (GetPName.CurrentProgram, out savedPgmId);
+ GL.UseProgram (pgmId);
+ }
+ public virtual void Disable(){
+ GL.UseProgram (savedPgmId);
+ }
+ 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 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
+ }
+}
+
--- /dev/null
+using System;
+using OpenTK.Graphics.OpenGL;
+
+namespace go.GLBackend
+{
+ public class TexturedShader : Shader
+ {
+ public TexturedShader ()
+ {
+ vertSource = @"
+ #version 130
+
+ precision highp float;
+
+ uniform mat4 projection_matrix;
+ uniform mat4 modelview_matrix;
+
+ in vec2 in_position;
+ in vec2 in_tex;
+ out vec2 texCoord;
+
+
+ void main(void)
+ {
+ texCoord = in_tex;
+ gl_Position = projection_matrix * modelview_matrix * vec4(in_position,0, 1);
+ }";
+
+ fragSource = @"
+ #version 130
+ precision highp float;
+
+ uniform vec4 color;
+ uniform sampler2D tex;
+ uniform sampler2D stencil;
+
+ in vec2 texCoord;
+ out vec4 out_frag_color;
+
+ void main(void)
+ {
+// vec4 s = texture( stencil, texCoord);
+// if (s.r == 0)
+// discard;
+ vec4 t = texture( tex, texCoord);
+ out_frag_color = t;
+ }";
+
+ Compile ();
+
+ }
+
+ protected override void BindVertexAttributes ()
+ {
+ base.BindVertexAttributes ();
+ GL.BindAttribLocation(pgmId, 1, "in_tex");
+ }
+ protected override void BindSamplesSlots ()
+ {
+ GL.Uniform1(GL.GetUniformLocation (pgmId, "tex"),0);
+ GL.Uniform1(GL.GetUniformLocation (pgmId, "stencil"),1);
+ }
+ }
+}
+
--- /dev/null
+using System;
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+
+namespace go
+{
+ 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<Vector2>(BufferTarget.ArrayBuffer,
+ new IntPtr(positionVboData.Length * Vector2.SizeInBytes),
+ positionVboData, BufferUsageHint.StaticDraw);
+
+ texVboHandle = GL.GenBuffer();
+ GL.BindBuffer(BufferTarget.ArrayBuffer, texVboHandle);
+ GL.BufferData<Vector2>(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
+ }
+}
+
// DisplayDevice.Default,\r
// 3,0,OpenTK.Graphics.GraphicsContextFlags.Default)\r
public OpenTKGameWindow(int _width, int _height, string _title="golib")\r
- : base(_width, _height, new OpenTK.Graphics.GraphicsMode(32, 24, 0, 8), _title)\r
+ : base(_width, _height, new OpenTK.Graphics.GraphicsMode(32, 24, 0, 0), \r
+ _title,GameWindowFlags.Default,DisplayDevice.Default,\r
+ 3,2,OpenTK.Graphics.GraphicsContextFlags.Debug|OpenTK.Graphics.GraphicsContextFlags.ForwardCompatible)\r
+// public OpenTKGameWindow(int _width, int _height, string _title="golib")\r
+// : base(_width, _height, new OpenTK.Graphics.GraphicsMode(32, 24, 0, 8), _title)\r
{\r
VSync = VSyncMode.On;\r
} \r
#endregion\r
\r
#region graphic contexte\r
+ bool recreateContext = true;\r
+\r
Context ctx;\r
Surface surf;\r
byte[] bmp;\r
int texID;\r
- int dispList;\r
+\r
+ QuadVAO uiQuad;\r
+ go.GLBackend.Shader shader;\r
+ Matrix4 projectionMatrix, \r
+ modelviewMatrix;\r
+\r
Rectangle dirtyZone = Rectangle.Empty;\r
\r
+ void createContext()\r
+ {\r
+ createOpenGLSurface ();\r
+ if (uiQuad != null)\r
+ uiQuad.Dispose ();\r
+ uiQuad = new QuadVAO (0, 0, ClientRectangle.Width, ClientRectangle.Height,0,1,1,-1);\r
+ projectionMatrix = Matrix4.CreateOrthographicOffCenter \r
+ (0, ClientRectangle.Width, ClientRectangle.Height, 0, 0, 1);\r
+ modelviewMatrix = Matrix4.Identity;\r
+ redrawClip.AddRectangle (ClientRectangle);\r
+ recreateContext = false;\r
+ }\r
void createOpenGLSurface()\r
{\r
currentWindow = this;\r
int stride = 4 * ClientRectangle.Width;\r
int bmpSize = Math.Abs (stride) * ClientRectangle.Height;\r
bmp = new byte[bmpSize];\r
- //bmp = Enumerable.Repeat((byte)0, bmpSize).ToArray();\r
-\r
- if (dispList > 0)\r
- GL.DeleteLists (dispList, 1);\r
\r
//create texture\r
if (texID > 0)\r
}\r
void OpenGLDraw()\r
{\r
+ shader.Enable ();\r
+ shader.ProjectionMatrix = projectionMatrix;\r
+ shader.ModelViewMatrix = modelviewMatrix;\r
+ shader.Color = new Vector4(1f,1f,1f,1f);\r
//if (dirtyZone != Rectangle.Empty) {\r
- GL.BindTexture (TextureTarget.Texture2D, texID);\r
- GL.TexSubImage2D (TextureTarget.Texture2D, 0,\r
- 0, 0, ClientRectangle.Width, ClientRectangle.Height,\r
+ GL.ActiveTexture (TextureUnit.Texture0);\r
+ GL.BindTexture (TextureTarget.Texture2D, texID);\r
+ GL.TexSubImage2D (TextureTarget.Texture2D, 0,\r
+ 0, 0, ClientRectangle.Width, ClientRectangle.Height,\r
OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp);\r
-// GL.TexSubImage2D (TextureTarget.Texture2D, 0,\r
-// dirtyZone.X, dirtyZone.Y, ClientRectangle.Width, dirtyZone.Height,\r
-// OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp);\r
- // dirtyZone = Rectangle.Empty;\r
-// if (dispList > 0)\r
-// GL.DeleteLists (dispList, 1);\r
- //surf.WriteToPng (@"/home/jp/test.png");\r
- //}\r
-\r
-// if (dispList > 0) {\r
-// GL.CallList (dispList);\r
-// return;\r
-// }\r
-//\r
-// dispList = GL.GenLists (1);\r
-// GL.NewList (dispList, ListMode.CompileAndExecute);\r
-// {\r
- GL.Viewport(0, 0, ClientRectangle.Width, ClientRectangle.Height);\r
- GL.PushAttrib (AttribMask.EnableBit);\r
- GL.Color4 (Color.White);\r
- GL.ActiveTexture (TextureUnit.Texture0);\r
- GL.BindTexture (TextureTarget.Texture2D, texID);\r
- GL.Enable (EnableCap.Texture2D);\r
-\r
- GL.MatrixMode (MatrixMode.Modelview);\r
-\r
- GL.PushMatrix ();\r
- GL.LoadIdentity ();\r
-\r
- GL.MatrixMode (MatrixMode.Projection);\r
-\r
- GL.PushMatrix ();\r
- GL.LoadIdentity ();\r
-\r
- Matrix4 ortho2D = Matrix4.CreateOrthographicOffCenter \r
- (ClientRectangle.Left, ClientRectangle.Right, ClientRectangle.Bottom, ClientRectangle.Top, 0, 1);\r
- GL.LoadMatrix (ref ortho2D);\r
-\r
- GL.Disable (EnableCap.Lighting);\r
- GL.Enable (EnableCap.AlphaTest);\r
- GL.AlphaFunc (AlphaFunction.Greater, 0.0f);\r
- GL.Enable (EnableCap.Blend);\r
- GL.BlendFunc (BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);\r
-\r
- GL.Begin (PrimitiveType.Quads);\r
- {\r
- GL.TexCoord2 (0, 0);\r
- GL.Vertex2 (ClientRectangle.Left, ClientRectangle.Top);\r
- GL.TexCoord2 (0, 1);\r
- GL.Vertex2 (ClientRectangle.Left, ClientRectangle.Bottom);\r
- GL.TexCoord2 (1, 1);\r
- GL.Vertex2 (ClientRectangle.Right, ClientRectangle.Bottom);\r
- GL.TexCoord2 (1, 0);\r
- GL.Vertex2 (ClientRectangle.Right, ClientRectangle.Top);\r
- }\r
- GL.End ();\r
-\r
- GL.PopMatrix ();\r
-\r
- GL.MatrixMode (MatrixMode.Modelview);\r
- GL.PopMatrix ();\r
\r
- GL.PopAttrib ();\r
+ uiQuad.Render (PrimitiveType.TriangleStrip);\r
\r
-// }\r
-// GL.EndList ();\r
+ GL.BindTexture(TextureTarget.Texture2D, 0);\r
\r
+ shader.Disable ();\r
}\r
\r
#endregion\r
protected override void OnRenderFrame(FrameEventArgs e)\r
{\r
base.OnRenderFrame(e);\r
- if (recreateContext) {\r
- createOpenGLSurface ();\r
- redrawClip.AddRectangle (ClientRectangle);\r
- recreateContext = false;\r
- }\r
+ if (recreateContext)\r
+ createContext ();\r
OpenGLDraw ();\r
}\r
protected override void OnLoad(EventArgs e)\r
Console.WriteLine("GLSL version: " + GL.GetString (StringName.ShadingLanguageVersion));\r
Console.WriteLine("*************************************\n");\r
\r
- createOpenGLSurface ();\r
- }\r
- protected override void OnUnload(EventArgs e)\r
- {\r
- if (dispList > 0)\r
- GL.DeleteLists (dispList, 1);\r
+ int matl = GL.GetInteger (GetPName.MaxArrayTextureLayers);\r
+ int mts = GL.GetInteger (GetPName.MaxTextureSize);\r
+ shader = new go.GLBackend.TexturedShader ();\r
+ }\r
+ protected override void OnUnload(EventArgs e)\r
+ {\r
if (texID > 0)\r
GL.DeleteTexture (texID);\r
//ctx.Dispose ();\r
- surf.Dispose ();\r
- }\r
- bool recreateContext=true;\r
- protected override void OnResize(EventArgs e)\r
+ //surf.Dispose ();\r
+ }\r
+\r
+ protected override void OnResize(EventArgs e)\r
{\r
base.OnResize (e);\r
recreateContext = true;\r