protected void InitializeUltralight() { // setup logging LoggerLogMessageCallback cb = LoggerCallback; Ultralight.SetLogger(new Logger { LogMessage = cb }); using var cfg = new Config(); var cachePath = Path.Combine(AssetDirectory, "Cache"); cfg.SetCachePath(cachePath); var resourcePath = Path.Combine(AssetDirectory, "resources"); cfg.SetResourcePath(resourcePath); cfg.SetUseGpuRenderer(false); cfg.SetEnableImages(true); cfg.SetEnableJavaScript(true); AppCore.EnablePlatformFontLoader(); AppCore.EnablePlatformFileSystem(AssetDirectory); _renderer = new Renderer(cfg); }
public static void Main() { Ultralight.SetLogger(new Logger { LogMessage = (LogLevel logLevel, string msg) => { switch (logLevel) { case LogLevel.Error: case LogLevel.Warning: Console.Error.WriteLine(msg); break; case LogLevel.Info: default: Console.WriteLine(msg); break; } } }); AppCore.EnablePlatformFontLoader(); AppCore.EnablePlatformFileSystem("./"); Program program = new(); program.Init(); program.CreatePipeline(); program.InitUltralight(); program.Run(); program = null; }
private static async Task Main(string[] args) { Ultralight.SetLogger(new Logger { LogMessage = Log }); AppCore.EnablePlatformFontLoader(); AppCore.EnablePlatformFileSystem("assets"); var settings = new Settings(); var config = new Config(); config.SetEnableJavaScript(true); config.SetEnableImages(true); config.SetResourcePath("resources"); config.SetCachePath("cache"); config.SetUseGpuRenderer(true); var app = new App(settings, config); var monitor = app.GetMainMonitor(); uint windowWidth = app.GetMainMonitor().GetWidth() - 100; uint windowHeight = app.GetMainMonitor().GetHeight() - 100; var window = new Window(monitor, windowWidth, windowHeight, false, WindowFlags.Titled); window.SetTitle("Super browser"); app.SetWindow(window); var renderer = app.GetRenderer(); var session = new Session(renderer, false, "Session1"); var mainView = new View(renderer, windowWidth, windowHeight, true, session); mainView.SetAddConsoleMessageCallback(JsConsoleMessage, default); mainView.LoadUrl("file:///index.html"); var mainOverlay = new Overlay(window, mainView, 0, 0); mainOverlay.Show(); app.Run(); }
public static unsafe void Main(string[] args) { // setup logging LoggerLogMessageCallback cb = LoggerCallback; Ultralight.SetLogger(new Logger { LogMessage = cb }); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Console.OutputEncoding = Encoding.UTF8; Ansi.WindowsConsole.TryEnableVirtualTerminalProcessing(); } var asmPath = typeof(DemoProgram).Assembly.Location; var asmDir = Path.GetDirectoryName(asmPath) !; var tempDir = Path.GetTempPath(); // find a place to stash instance storage string storagePath; do { storagePath = Path.Combine(tempDir, Guid.NewGuid().ToString()); } while (Directory.Exists(storagePath) || File.Exists(storagePath)); var cfg = Config.Create(); { var cachePath = String.Create(Path.Combine(storagePath, "Cache")); cfg->SetCachePath(cachePath); cachePath->Destroy(); } { var resourcePath = String.Create(Path.Combine(asmDir, "resources")); cfg->SetResourcePath(resourcePath); resourcePath->Destroy(); } cfg->SetUseGpuRenderer(false); cfg->SetEnableImages(true); cfg->SetEnableJavaScript(false); AppCore.EnablePlatformFontLoader(); { var assetsPath = String.Create(Path.Combine(asmDir, "assets")); AppCore.EnablePlatformFileSystem(assetsPath); assetsPath->Destroy(); } var renderer = Renderer.Create(cfg); var sessionName = String.Create("Demo"); var session = Session.Create(renderer, false, sessionName); var view = View.Create(renderer, 640, 480, false, session, false); { var htmlString = String.Create("<i>Loading...</i>"); Console.WriteLine($"Loading HTML: {htmlString->Read()}"); view->LoadHtml(htmlString); htmlString->Destroy(); } var loaded = false; view->SetFinishLoadingCallback((data, caller, frameId, isMainFrame, url) => { Console.WriteLine($"Loading Finished, URL: 0x{(ulong) url:X8} {url->Read()}"); loaded = true; }, null); while (!loaded) { Ultralight.Update(renderer); Ultralight.Render(renderer); } /* * { * var surface = view->GetSurface(); * var bitmap = surface->GetBitmap(); * var pixels = bitmap->LockPixels(); * RenderAnsi<Bgra32>(pixels, bitmap->GetWidth(), bitmap->GetHeight(), bitmap->GetBpp()); * Console.WriteLine(); * bitmap->UnlockPixels(); * bitmap->SwapRedBlueChannels(); * //bitmap->WritePng("Loading.png"); * } */ loaded = false; { var urlString = String.Create("file:///index.html"); Console.WriteLine($"Loading URL: {urlString->Read()}"); view->LoadUrl(urlString); urlString->Destroy(); } while (!loaded) { //Ultralight.Update(renderer); renderer->Update(); //Ultralight.Render(renderer); renderer->Render(); } { var urlStrPtr = view->GetUrl(); Console.WriteLine($"After Loaded View GetURL: 0x{(ulong) urlStrPtr:X8} {urlStrPtr->Read()}"); } { var surface = view->GetSurface(); var bitmap = surface->GetBitmap(); var pixels = bitmap->LockPixels(); RenderAnsi <Bgra32>(pixels, bitmap->GetWidth(), bitmap->GetHeight()); bitmap->UnlockPixels(); bitmap->SwapRedBlueChannels(); //bitmap->WritePng("Loaded.png"); } view->Destroy(); session->Destroy(); renderer->Destroy(); cfg->Destroy(); try { Directory.Delete(storagePath, true); } catch { /* ok */ } //Console.WriteLine("Press any key to exit."); //Console.ReadKey(true); }
private static unsafe void Main(string[] args) { var parsedOpts = Parser.Default.ParseArguments <Options>(args); parsedOpts.WithParsed(opts => { if (opts.Context != null) { _useEgl = opts.Context.Contains("egl"); } if (opts.GlApi != null) { _automaticFallback = false; _useOpenGl = !opts.GlApi.Contains("es"); _useOpenGl = true; } if (opts.GlMajorVersion != null) { _automaticFallback = false; _glMaj = opts.GlMajorVersion.Value; } if (opts.GlMinorVersion != null) { _automaticFallback = false; _glMin = opts.GlMinorVersion.Value; } }); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Console.OutputEncoding = Encoding.UTF8; Ansi.WindowsConsole.TryEnableVirtualTerminalProcessing(); } AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; AppDomain.CurrentDomain.FirstChanceException += OnFirstChanceException; //InjectNsight(); //InjectRenderDoc(); var options = WindowOptions.Default; var size = new Size(1024, 576); var title = "UltralightSharp - Silk.NET"; options.Size = size; options.Title = title; options.VSync = VSyncMode.On; options.TransparentFramebuffer = false; options.PreferredDepthBufferBits = null; //options.VSync = true; /* * if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { * var asmDir = Path.GetDirectoryName(new Uri(typeof(Program).Assembly.CodeBase!).LocalPath)!; * var glfwPath = Path.Combine(asmDir, "libglfw.so.3"); * const string sysGlfwPath = "/lib/libglfw.so.3"; * if (File.Exists(sysGlfwPath)) { * var sb = new StringBuilder(1024); * var sbSize = (UIntPtr)sb.Capacity; * var used = (long)Libc.readlink(glfwPath, sb, sbSize); * if (used >= 0) { * var link = sb.ToString(0, (int)(used - 1)); * if (link != sysGlfwPath) { * File.Delete(glfwPath); * Libc.symlink(sysGlfwPath, glfwPath); * } * } * else { * // not a link * File.Delete(glfwPath); * Libc.symlink(sysGlfwPath, glfwPath); * Cleanup += () => { * File.Delete(glfwPath); * }; * } * } * } */ _glfw = Glfw.GetApi(); Console.WriteLine($"GLFW v{_glfw.GetVersionString()}"); if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { _glfw.InitHint(InitHint.CocoaMenubar, false); _glfw.InitHint(InitHint.CocoaChdirResources, false); } _glfw = GlfwProvider.GLFW.Value; { // setup logging Ultralight.SetLogger(new Logger { LogMessage = LoggerCallback }); var tempDir = Path.GetTempPath(); // find a place to stash instance storage do { _storagePath = Path.Combine(tempDir, Guid.NewGuid().ToString()); }while (Directory.Exists(_storagePath) || File.Exists(_storagePath)); AppCore.EnablePlatformFontLoader(); AppCore.EnablePlatformFileSystem(AssetsDir); } /* afaik GLFW already does this, this was just to check * if (_useEgl || _automaticFallback) { * Console.WriteLine("Binding to LibEGL..."); * var eglLib = new UnmanagedLibrary( * new CustomEglLibNameContainer().GetLibraryName(), * LibraryLoader.GetPlatformDefaultLoader() * ); * var q = eglLib.LoadFunction("eglQueryAPI"); * IL.Push(q); * IL.Emit.Calli(StandAloneMethodSig.UnmanagedMethod(CallingConvention.Cdecl, typeof(EGLEnum))); * IL.Pop(out EGLEnum api); * Console.WriteLine($"EGL API Target: {api}"); * var b = eglLib.LoadFunction("eglBindAPI"); * if (_useOpenGL && api != EGLEnum.OpenglApi) { * IL.Push(EGLEnum.OpenglApi); * IL.Push(b); * IL.Emit.Calli(StandAloneMethodSig.UnmanagedMethod(CallingConvention.Cdecl, typeof(bool), * typeof(EGLEnum))); * IL.Pop(out bool success); * Console.Error.WriteLine(!success * ? "Couldn't bind EGL to OpenGL" * : "EGL now bound to OpenGL"); * } * else if (!_useOpenGL && api != EGLEnum.OpenglESApi){ * IL.Push(EGLEnum.OpenglESApi); * IL.Push(b); * IL.Emit.Calli(StandAloneMethodSig.UnmanagedMethod(CallingConvention.Cdecl, typeof(bool), * typeof(EGLEnum))); * IL.Pop(out bool success); * Console.Error.WriteLine(!success * ? "Couldn't bind EGL to OpenGL ES" * : "EGL now bound to OpenGL ES"); * } * } */ if (_automaticFallback) { Console.WriteLine("Checking for supported context..."); for (;;) { SetGlfwWindowHints(); Console.WriteLine( _useOpenGl ? "Attempting OpenGL v3.2 (Core)" : $"Attempting OpenGL ES v{_majOES}.0"); var wh = _glfw.CreateWindow(1024, 576, title, null, null); if (wh != null) { Console.WriteLine( _useOpenGl ? "Created Window with OpenGL v3.2 (Core)" : $"Created Window with OpenGL ES v{_majOES}.0"); _glfw.DestroyWindow(wh); break; } var code = _glfw.GetError(out char *pDesc); if (code == ErrorCode.NoError || pDesc == null) { throw new PlatformNotSupportedException("Can't create a window via GLFW. Unknown error."); } var strLen = new ReadOnlySpan <byte>((byte *)pDesc, 32768).IndexOf <byte>(0); if (strLen == -1) { strLen = 0; } var str = new string((sbyte *)pDesc, 0, strLen, Encoding.UTF8); var errMsg = $"{code}: {str}"; Console.Error.WriteLine(errMsg); if (code != ErrorCode.VersionUnavailable) { throw new GlfwException(errMsg); } // attempt sequence: OpenGL ES 3.0, OpenGL 3.2, OpenGL ES 2.0 if (!_useOpenGl && _majOES == 3) { _useOpenGl = true; } else if (_majOES == 3 && _useOpenGl) { _useOpenGl = false; _majOES = 2; } else { throw new GlfwException(errMsg); } } } SetGlfwWindowHints(); if (_useOpenGl) { options.API = new GraphicsAPI( ContextAPI.OpenGL, ContextProfile.Core, ContextFlags.ForwardCompatible, new APIVersion(_automaticFallback ? 3 : _glMaj, _automaticFallback ? 2 : _glMin) ); } else { options.API = new GraphicsAPI( ContextAPI.OpenGLES, ContextProfile.Core, ContextFlags.ForwardCompatible, new APIVersion(_automaticFallback ? _majOES : _glMaj, _automaticFallback ? 0 : _glMin) ); } options.IsVisible = true; options.WindowBorder = WindowBorder.Resizable; options.WindowState = WindowState.Normal; Console.WriteLine("Creating window..."); _snView = Window.Create(options); _snView.Load += OnLoad; _snView.Render += OnRender; _snView.Update += OnUpdate; _snView.Closing += OnClose; _snView.Resize += OnResize; var glCtx = _snView.GLContext; if (!_useOpenGl) { Console.WriteLine("Binding to LibGLES..."); _gl = LibraryActivator.CreateInstance <GL> ( new CustomGlEsLibNameContainer().GetLibraryName(), TemporarySuperInvokeClass.GetLoader(glCtx) ); } Console.WriteLine("Initializing window..."); _snView.Initialize(); if (_snView.Handle == IntPtr.Zero) { var code = _glfw.GetError(out char *pDesc); if (code == ErrorCode.NoError || pDesc == null) { throw new PlatformNotSupportedException("Can't create a window via GLFW. Unknown error."); } var strLen = new ReadOnlySpan <byte>((byte *)pDesc, 32768).IndexOf <byte>(0); if (strLen == -1) { strLen = 0; } var str = new string((sbyte *)pDesc, 0, strLen, Encoding.UTF8); throw new GlfwException($"{code}: {str}"); } Console.WriteLine("Starting main loop..."); _snView.Run(); }
public static void Main(string[] args) { // setup logging LoggerLogMessageCallback cb = LoggerCallback; Ultralight.SetLogger(new Logger { LogMessage = cb }); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Console.OutputEncoding = Encoding.UTF8; Ansi.WindowsConsole.TryEnableVirtualTerminalProcessing(); } var asmPath = new Uri(typeof(DemoProgram).Assembly.CodeBase !).LocalPath; var asmDir = Path.GetDirectoryName(asmPath) !; var tempDir = Path.GetTempPath(); // find a place to stash instance storage string storagePath; do { storagePath = Path.Combine(tempDir, Guid.NewGuid().ToString()); } while (Directory.Exists(storagePath) || File.Exists(storagePath)); { using var cfg = new Config(); var cachePath = Path.Combine(storagePath, "Cache"); cfg.SetCachePath(cachePath); var resourcePath = Path.Combine(asmDir, "resources"); cfg.SetResourcePath(resourcePath); cfg.SetUseGpuRenderer(false); cfg.SetEnableImages(true); cfg.SetEnableJavaScript(false); AppCore.EnablePlatformFontLoader(); { var assetsPath = Path.Combine(asmDir, "assets"); AppCore.EnablePlatformFileSystem(assetsPath); } using var renderer = new Renderer(cfg); var sessionName = "Demo"; using var session = new Session(renderer, false, sessionName); using var view = new View(renderer, 640, 480, false, session); { var htmlString = "<i>Loading...</i>"; Console.WriteLine($"Loading HTML: {htmlString}"); view.LoadHtml(htmlString); } var loaded = false; view.SetFinishLoadingCallback((data, caller, frameId, isMainFrame, url) => { Console.WriteLine($"Loading Finished, URL: {url}"); loaded = true; }, default); while (!loaded) { renderer.Update(); renderer.Render(); } loaded = false; { var urlString = "file:///index.html"; Console.WriteLine($"Loading URL: {urlString}"); view.LoadUrl(urlString); } while (!loaded) { renderer.Update(); renderer.Render(); } { var urlStr = view.GetUrl(); Console.WriteLine($"After Loaded View GetURL: {urlStr}"); } { var surface = view.GetSurface(); var bitmap = surface.GetBitmap(); var pixels = bitmap.LockPixels(); RenderAnsi <Bgra32>(pixels, bitmap.GetWidth(), bitmap.GetHeight(), 2, borderless: true); bitmap.UnlockPixels(); //bitmap.SwapRedBlueChannels(); //bitmap.WritePng("Loaded.png"); } } try { Directory.Delete(storagePath, true); } catch { /* ok */ } if (!Environment.UserInteractive || Console.IsInputRedirected) { return; } Console.Write("Press any key to exit."); Console.ReadKey(true); Console.WriteLine(); }
private static unsafe void Main(string[] args) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Console.OutputEncoding = Encoding.UTF8; Ansi.WindowsConsole.TryEnableVirtualTerminalProcessing(); } //InjectNsight(); //InjectRenderDoc(); var options = WindowOptions.Default; options.API = new GraphicsAPI( ContextAPI.OpenGLES, ContextProfile.Core, ContextFlags.ForwardCompatible, new APIVersion(3, 1) ); options.Size = new Size(1024, 576); options.Title = "OpenGL ES 3.1+ (Silk.NET)"; _wnd = Silk.NET.Windowing.Window.Create(options); _wnd.Load += OnLoad; _wnd.Render += OnRender; _wnd.Update += OnUpdate; _wnd.Closing += OnClose; _wnd.Resize += OnResize; { // setup logging Ultralight.SetLogger(new Logger { LogMessage = LoggerCallback }); var asmPath = new Uri(typeof(Program).Assembly.CodeBase !).LocalPath; var asmDir = Path.GetDirectoryName(asmPath) !; var tempDir = Path.GetTempPath(); // find a place to stash instance storage string storagePath; do { storagePath = Path.Combine(tempDir, Guid.NewGuid().ToString()); }while (Directory.Exists(storagePath) || File.Exists(storagePath)); using var cfg = new Config(); var cachePath = Path.Combine(storagePath, "Cache"); cfg.SetCachePath(cachePath); var resourcePath = Path.Combine(asmDir, "resources"); cfg.SetResourcePath(resourcePath); cfg.SetUseGpuRenderer(true); cfg.SetEnableImages(true); cfg.SetEnableJavaScript(false); //cfg.SetForceRepaint(true); Ultralight.SetGpuDriver(new GpuDriver { BeginSynchronize = () => { //Console.WriteLine("BeginSynchronize"); }, EndSynchronize = () => { //Console.WriteLine("EndSynchronize"); }, NextGeometryId = () => { var id = (uint)GeometryEntries.Add(new GeometryEntry()) + 1; Console.WriteLine($"NextGeometryId: {id}"); return(id); }, CreateGeometry = (id, vertices, indices) => { Console.WriteLine($"CreateGeometry: {id}"); var index = (int)id - 1; var entry = GeometryEntries[index]; CheckGl(); var vao = _gl.GenVertexArray(); entry.VertexArray = vao; _gl.BindVertexArray(vao); LabelObject(ObjectIdentifier.VertexArray, vao, $"Ultralight Geometry VAO {id}"); CheckGl(); var buf = _gl.GenBuffer(); entry.Vertices = buf; _gl.BindBuffer(BufferTargetARB.ArrayBuffer, buf); LabelObject(ObjectIdentifier.Buffer, buf, $"Ultralight Geometry VBO {id}"); _gl.BufferData(BufferTargetARB.ArrayBuffer, vertices.Size, vertices.DataSpan, BufferUsageARB.DynamicDraw); CheckGl(); switch (vertices.Format) { case VertexBufferFormat._2F4Ub2F2F28F: { const uint stride = 140; _gl.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, stride, (void *)0); _gl.VertexAttribPointer(1, 4, VertexAttribPointerType.UnsignedByte, true, stride, (void *)8); _gl.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, stride, (void *)12); _gl.VertexAttribPointer(3, 2, VertexAttribPointerType.Float, false, stride, (void *)20); _gl.VertexAttribPointer(4, 4, VertexAttribPointerType.Float, false, stride, (void *)28); _gl.VertexAttribPointer(5, 4, VertexAttribPointerType.Float, false, stride, (void *)44); _gl.VertexAttribPointer(6, 4, VertexAttribPointerType.Float, false, stride, (void *)60); _gl.VertexAttribPointer(7, 4, VertexAttribPointerType.Float, false, stride, (void *)76); _gl.VertexAttribPointer(8, 4, VertexAttribPointerType.Float, false, stride, (void *)92); _gl.VertexAttribPointer(9, 4, VertexAttribPointerType.Float, false, stride, (void *)108); _gl.VertexAttribPointer(10, 4, VertexAttribPointerType.Float, false, stride, (void *)124); CheckGl(); _gl.EnableVertexAttribArray(0); _gl.EnableVertexAttribArray(1); _gl.EnableVertexAttribArray(2); _gl.EnableVertexAttribArray(3); _gl.EnableVertexAttribArray(4); _gl.EnableVertexAttribArray(5); _gl.EnableVertexAttribArray(6); _gl.EnableVertexAttribArray(7); _gl.EnableVertexAttribArray(8); _gl.EnableVertexAttribArray(9); _gl.EnableVertexAttribArray(10); CheckGl(); break; } case VertexBufferFormat._2F4Ub2F: { const uint stride = 20; _gl.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, stride, (void *)0); _gl.VertexAttribPointer(1, 4, VertexAttribPointerType.UnsignedByte, true, stride, (void *)8); _gl.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, stride, (void *)12); CheckGl(); _gl.EnableVertexAttribArray(0); _gl.EnableVertexAttribArray(1); _gl.EnableVertexAttribArray(2); CheckGl(); break; } default: throw new NotImplementedException(vertices.Format.ToString()); } buf = _gl.GenBuffer(); entry.Indices = buf; _gl.BindBuffer(BufferTargetARB.ElementArrayBuffer, buf); LabelObject(ObjectIdentifier.Buffer, buf, $"Ultralight Geometry EBO {id}"); _gl.BufferData(BufferTargetARB.ElementArrayBuffer, indices.Size, indices.Data, BufferUsageARB.StaticDraw); CheckGl(); }, UpdateGeometry = (id, vertices, indices) => { Console.WriteLine($"UpdateGeometry: {id}"); var index = (int)id - 1; var entry = GeometryEntries[index]; CheckGl(); _gl.BindVertexArray(entry.VertexArray); CheckGl(); _gl.BindBuffer(BufferTargetARB.ArrayBuffer, entry.Vertices); _gl.BufferData(BufferTargetARB.ArrayBuffer, vertices.Size, vertices.DataSpan, BufferUsageARB.DynamicDraw); CheckGl(); _gl.BindBuffer(BufferTargetARB.ElementArrayBuffer, entry.Vertices); _gl.BufferData(BufferTargetARB.ElementArrayBuffer, vertices.Size, vertices.DataSpan, BufferUsageARB.DynamicDraw); CheckGl(); _gl.BindBuffer(BufferTargetARB.ElementArrayBuffer, entry.Indices); _gl.BufferData(BufferTargetARB.ElementArrayBuffer, indices.Size, indices.Data, BufferUsageARB.StaticDraw); CheckGl(); }, DestroyGeometry = id => { Console.WriteLine($"DestroyGeometry: {id}"); var index = (int)id - 1; var entry = GeometryEntries.RemoveAt(index); _gl.DeleteBuffer(entry.Indices); _gl.DeleteBuffer(entry.Vertices); _gl.DeleteVertexArray(entry.Indices); CheckGl(); }, NextRenderBufferId = () => { var id = (uint)RenderBufferEntries.Add(new RenderBufferEntry()) + 1; Console.WriteLine($"NextRenderBufferId: {id}"); return(id); }, CreateRenderBuffer = (id, buffer) => { Console.WriteLine($"CreateRenderBuffer: {id}"); var index = (int)id - 1; var entry = RenderBufferEntries[index]; CheckGl(); var fb = _gl.GenFramebuffer(); entry.FrameBuffer = fb; _gl.BindFramebuffer(FramebufferTarget.Framebuffer, fb); LabelObject(ObjectIdentifier.Framebuffer, fb, $"Ultralight RenderBuffer {id}"); CheckGl(); var texIndex = (int)buffer.TextureId - 1; var texEntry = TextureEntries[texIndex]; var tex = texEntry.Texure; _gl.BindTexture(TextureTarget.Texture2D, tex); _gl.FramebufferTexture2D( FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, tex, 0); entry.TextureEntry = texEntry; CheckGl(); _gl.DrawBuffers(1, stackalloc[] { DrawBufferMode.ColorAttachment0 }); var result = _gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (result != GLEnum.FramebufferComplete) { Console.Error.WriteLine($"Error creating FBO: {result}"); Console.Error.Flush(); Debugger.Break(); } CheckGl(); },