using StgSharp.Logic; using StgSharp.Math; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace StgSharp.Graphics { public abstract partial class glRenderStream: RenderStream { public static T AsMainStreamOf(Form f, (int x, int y, int z) unitCubeSize) where T : glRenderStream { RenderStreamConstructArgs args = new RenderStreamConstructArgs(); args.UnitCubeSize = unitCubeSize; args.Name = f.name; args.Height = f.Height; args.Width = f.Width; T ret = Activator.CreateInstance(typeof(T), args) as T; ret!.InternalInit(); f.WindowID = ret.CanvasHandle; return ret; } protected sealed override void NativeCameraViewTarget(vec3d position, vec3d direction, vec3d up) { NativeCamera.SetViewDirection(position, direction, up); } protected sealed override Uniform NativeCameraUniform(ShaderProgram source, string name) { NativeCamera.GainAllUniforms(source, name); return NativeCamera.convertedUniform; } protected IntPtr glContextHandle { get { return ContextHandle; } set { ContextHandle = value; } } internal unsafe sealed override void CreateCanvas() { byte[] nameCode = Encoding.UTF8.GetBytes(name); CanvasHandle = InternalIO.glfwCreateWindow( Width,Height,nameCode,Monitor,IntPtr.Zero ); NativeCamera = new Camera(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected sealed override void NativeCameraViewRange(Radius fieldOfRange,vec2d offset, (float frontDepth, float backDepth) viewDepth) { NativeCamera.SetViewRange(fieldOfRange,this.Size, offset, viewDepth); } /// /// Init an OpenGl context if current form has not been binded to any context. and set the context binded to /// current form as current OpenGL context. /// /// /// Something goes wrong and StgSharp fails in creating a new OpenGL context. /// public unsafe void MakeAsCurrentContext() { if (ContextHandle == default) { ContextHandle = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(GLcontext))); GLcontext* contextID = (GLcontext*)ContextHandle; contextID->glGetString = (delegate*)IntPtr.Zero; } if (GL.CurrentContextHandle != ContextHandle) { GL.CurrentContextHandle = ContextHandle; Console.WriteLine($"context set as {(ulong)GL.CurrentContextHandle}"); InternalIO.glfwMakeContextCurrent(CanvasHandle); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override void SetSizeLimit(int minWidth, int minHeight, int maxWidth, int maxHeight) { InternalIO.glfwSetWindowSizeLimits(this.CanvasHandle, minWidth, minHeight, maxWidth, maxHeight); } internal sealed override void InternalInit() { CreateCanvas(); MakeAsCurrentContext(); this.LoadGLapi(); Init(); } internal sealed override void InternalDraw( in Dictionary input, in Dictionary output) { MakeAsCurrentContext(); Main(in input, in output); } internal sealed override void InternalTerminate() { Deinit(); } } }