/// <inheritdoc /> public override void CopyRenderTarget(RenderTarget source, RenderTarget dest, Rectangle?sourceRect = null, Rectangle?destRect = null, bool smooth = false) { GLThread.ExecuteGLThread(() => { RenderTarget srcTarget = source ?? Engine.Renderer.BaseTarget; RenderTarget destTarget = dest ?? Engine.Renderer.BaseTarget; Vector2 sourceSize = srcTarget.Size; Vector2 destSize = destTarget.Size; Rectangle srcRect = sourceRect ?? new Rectangle(0, 0, sourceSize); Rectangle dstRect = destRect ?? new Rectangle(0, 0, destSize); uint srcPointer = (uint)((GlRenderTarget)srcTarget)?.Pointer; uint destPointer = (uint)((GlRenderTarget)destTarget)?.Pointer; Gl.BindFramebuffer(FramebufferTarget.ReadFramebuffer, srcPointer); Gl.BindFramebuffer(FramebufferTarget.DrawFramebuffer, destPointer); Gl.BlitFramebuffer((int)srcRect.X, (int)srcRect.Y, (int)srcRect.Width, (int)srcRect.Height, (int)dstRect.X, (int)dstRect.Y, (int)dstRect.Width, (int)dstRect.Height, ClearBufferMask.ColorBufferBit, smooth ? BlitFramebufferFilter.Linear : BlitFramebufferFilter.Nearest); // Restore bindings and so on. Engine.Renderer.EnsureRenderTarget(); }); }
/// <inheritdoc /> public override uint GetBoundVertexArrayBuffer() { int id = 0; GLThread.ExecuteGLThread(() => Gl.Get(Gl.VERTEX_ARRAY_BINDING, out id)); return((uint)id); }
/// <inheritdoc /> public override RenderTarget CreateRenderTarget(Vector2 size, bool smooth = false, TextureInternalFormat internalFormat = TextureInternalFormat.Rgba, TexturePixelFormat pixelFormat = TexturePixelFormat.Rgba, bool attachStencil = false) { RenderTarget resultTarget = null; InternalFormat intFormat = (InternalFormat)Enum.Parse(typeof(InternalFormat), internalFormat.ToString()); PixelFormat glFormat = (PixelFormat)Enum.Parse(typeof(PixelFormat), pixelFormat.ToString()); GLThread.ExecuteGLThread(() => { // Create the FBO which rendering will be done to. uint newFbo = Gl.GenFramebuffer(); Gl.BindFramebuffer(FramebufferTarget.Framebuffer, newFbo); // Create the texture. uint renderTexture = Gl.GenTexture(); Gl.BindTexture(TextureTarget.Texture2d, renderTexture); Gl.TexImage2D(TextureTarget.Texture2d, 0, intFormat, (int)size.X, (int)size.Y, 0, glFormat, PixelType.UnsignedByte, IntPtr.Zero); Gl.TexParameter(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, smooth ? Gl.LINEAR : Gl.NEAREST); Gl.TexParameter(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, smooth ? Gl.LINEAR : Gl.NEAREST); // Attach the texture to the frame buffer. Gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2d, renderTexture, 0); // Attach color components. int[] modes = { Gl.COLOR_ATTACHMENT0 }; Gl.DrawBuffers(modes); // Create render buffer. uint depthBuffer = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer); Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, InternalFormat.Depth24Stencil8, (int)size.X, (int)size.Y); Gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, attachStencil ? FramebufferAttachment.DepthStencilAttachment : FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, depthBuffer); // Check status. FramebufferStatus status = Gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (status != FramebufferStatus.FramebufferComplete) { Engine.Log.Warning($"Framebuffer creation failed. Error code {status}.", MessageSource.GL); } // Create the texture object. Texture targetTexture = new GLTexture(renderTexture, new Vector2(size.X, size.Y), null, $"FBO {newFbo} Texture"); // Create the render target object. resultTarget = new GlRenderTarget(newFbo, size, targetTexture); // Clear the target. ClearScreen(); CheckError("creating scale fbo"); // Restore bindings and so on. Engine.Renderer?.EnsureRenderTarget(); }); return(resultTarget); }
/// <inheritdoc /> public override uint GetBoundRenderTarget() { int id = 0; GLThread.ExecuteGLThread(() => Gl.Get(Gl.DRAW_FRAMEBUFFER_BINDING, out id)); return((uint)id); }
/// <summary> /// Submit that an error has happened. Handles logging and closing of the engine safely. /// </summary> /// <param name="ex">The exception connected with the error occured.</param> public static void SubmitError(Exception ex) { // Log the error. Engine.Log.Error(ex); // Check if suppressing errors. if (SuppressErrors) { return; } // Dispose of the host because you don't want to be stuck in fullscreen with an error. GLThread.ExecuteGLThread(() => { Engine.Host.Dispose(); }); // If the debugger is attached, break so the error can be inspected. if (Debugger.IsAttached) { Debugger.Break(); } // Display the error box. Engine.Host.DisplayErrorMessage($"Fatal error occured!\n{ex}"); // Check whether to crash - and do so. if (Engine.Flags.CrashOnError) { Engine.Quit(); } }
/// <inheritdoc /> public override uint GetBoundDataBuffer() { int id = 0; GLThread.ExecuteGLThread(() => Gl.Get(Gl.ARRAY_BUFFER_BINDING, out id)); return((uint)id); }
/// <inheritdoc /> public override bool BindIndexBuffer(uint bufferId) { #if DEBUG uint actualBound = GetBoundIndexBuffer(); if (BoundIndexBuffer != 0 && BoundIndexBuffer != actualBound) { Engine.Log.Warning($"Bound index buffer was thought to be {BoundIndexBuffer} but is actually {actualBound}.", MessageSource.GL); } #endif // Check if already bound. if (BoundIndexBuffer != 0 && BoundIndexBuffer == bufferId) { return(false); } GLThread.ExecuteGLThread(() => { Gl.BindBuffer(BufferTarget.ElementArrayBuffer, bufferId); BoundIndexBuffer = bufferId; CheckError("after binding index buffer"); }); return(true); }
public void Load() { _tileMntTexture = Engine.AssetLoader.Get <TextureAsset>("Image/mnt.png"); _tileGrs1Texture = Engine.AssetLoader.Get <TextureAsset>("Image/grs1.png"); _tileGrs2Texture = Engine.AssetLoader.Get <TextureAsset>("Image/grs2.png"); // _ubuntuFontAsset = Engine.AssetLoader.Get<FontAsset>("font/UbuntuMono-R.ttf").GetAtlas(16f); GenHeightMap(); GetTileMap(); Rectangle boundsOfMap = Rectangle.BoundsFromPolygonPoints(new[] { tiles[0, 0].Vertex0, tiles[MAP_WIDTH - 1, 0].Vertex1, tiles[MAP_WIDTH - 1, MAP_HEIGHT - 1].Vertex2, tiles[0, MAP_HEIGHT - 1].Vertex3, }); quadTree = new QuadTree <TileQuadrilateral>(boundsOfMap, 100); foreach (var tile in tiles) { quadTree.Add(tile); } GLThread.ExecuteGLThread(() => { _frameBuffer = new FrameBuffer(new Texture(Engine.Renderer.DrawBuffer.Size)); }); }
public override void Load() { // These operations need to be performed on the GL thread. // This can be further optimized by creating the objects on another thread and then just passing them. GLThread.ExecuteGLThread(() => { // Create a new map buffer. _buffer = new QuadMapBuffer(Renderer.MaxRenderable); // Map buffer. int x = 0; int y = 0; const int size = 5; for (int i = 0; i < Renderer.MaxRenderable; i++) { // Add objects one after another of a random color. Color randomColor = new Color(Utilities.GenerateRandomNumber(0, 255), Utilities.GenerateRandomNumber(0, 255), Utilities.GenerateRandomNumber(0, 255)); _buffer.MapNextQuad(new Vector3(x * size, y * size, 1), new Vector2(size, size), randomColor); x++; if (x * size < 960) { continue; } x = 0; y++; } }); }
/// <inheritdoc /> public override void SetTextureSmooth(bool smooth) { GLThread.ExecuteGLThread(() => { Gl.TexParameter(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, smooth ? Gl.LINEAR : Gl.NEAREST); Gl.TexParameter(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, smooth ? Gl.LINEAR : Gl.NEAREST); }); }
/// <inheritdoc /> public override void DeleteTexture(uint pointer) { GLThread.ExecuteGLThread(() => { Gl.DeleteTextures(pointer); CheckError("after texture deletion"); }); }
public void ThreadInvocationScheduleNew() { int resp = GLThread.ExecuteGLThread(DoWork, "adsad", "gegwe", "hhrhr"); if (resp != 15) { throw new Exception("whaa"); } }
/// <summary> /// Create a shader program from shader strings. /// </summary> /// <param name="fragmentShader">The program's fragment shader.</param> /// <param name="vertexShader">The program's vertex shader.</param> public ShaderProgram(string vertexShader, string fragmentShader) { GLThread.ExecuteGLThread(() => { Shader vert = string.IsNullOrEmpty(vertexShader) ? DefaultVertShader : new Shader(ShaderType.VertexShader, vertexShader); Shader frag = string.IsNullOrEmpty(fragmentShader) ? DefaultFragShader : new Shader(ShaderType.FragmentShader, fragmentShader); Init(vert, frag); }); }
/// <inheritdoc /> public override void SetClipRect(int x, int y, int width, int height) { GLThread.ExecuteGLThread(() => { Gl.Enable(EnableCap.ScissorTest); Gl.Scissor(x, (int)(Engine.Renderer.CurrentTarget.Size.Y - height - y), width, height); CheckError("setting clip rect"); }); }
/// <inheritdoc /> public override RenderTarget CreateMSAARenderTarget(int samples, Vector2 size, TextureInternalFormat internalFormat = TextureInternalFormat.Rgba, bool attachStencil = false) { RenderTarget resultTarget = null; InternalFormat intFormat = (InternalFormat)Enum.Parse(typeof(InternalFormat), internalFormat.ToString()); GLThread.ExecuteGLThread(() => { // Create the FBO. uint newFbo = Gl.GenFramebuffer(); Gl.BindFramebuffer(FramebufferTarget.Framebuffer, newFbo); // Create the texture. uint renderTexture = Gl.GenTexture(); Gl.BindTexture(TextureTarget.Texture2dMultisample, renderTexture); Gl.TexImage2DMultisample(TextureTarget.Texture2dMultisample, samples, intFormat, (int)size.X, (int)size.Y, true); // Attach the texture to the frame buffer. Gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2dMultisample, renderTexture, 0); // Attach color components. int[] modes = { Gl.COLOR_ATTACHMENT0 }; Gl.DrawBuffers(modes); // Create render buffer. uint depthBuffer = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer); Gl.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, samples, InternalFormat.Depth24Stencil8, (int)size.X, (int)size.Y); Gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, attachStencil ? FramebufferAttachment.DepthStencilAttachment : FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, depthBuffer); // Check status. FramebufferStatus status = Gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (status != FramebufferStatus.FramebufferComplete) { Engine.Log.Warning($"MSAA Framebuffer creation failed. Error code {status}.", MessageSource.GL); } // Construct a texture object for it. Texture targetTexture = new GLTexture(renderTexture, new Vector2(size.X, size.Y), null, $"MSAA{samples} FBO Texture"); // Create the render target object. resultTarget = new GlRenderTarget(newFbo, size, targetTexture); // Clear the target. ClearScreen(); CheckError("creating msaa fbo"); // Restore bindings and so on. Engine.Renderer?.EnsureRenderTarget(); }); return(resultTarget); }
/// <inheritdoc /> public override bool BindTexture(uint pointer, uint slot = 0) { GLThread.ExecuteGLThread(() => { Gl.ActiveTexture(TextureUnit.Texture0 + (int)slot); Gl.BindTexture(TextureTarget.Texture2d, pointer); CheckError("after binding texture"); }); return(true); }
/// <inheritdoc /> public override uint CreateTexture() { uint newTexture = 0; GLThread.ExecuteGLThread(() => { newTexture = Gl.GenTexture(); CheckError("after texture creation"); }); return(newTexture); }
protected virtual void UploadTexture(Vector2 size, byte[] bgraPixels, bool flipped) { GLThread.ExecuteGLThread(() => { PerfProfiler.ProfilerEventStart($"Uploading Image {Name}", "Loading"); Texture = new Texture(size, bgraPixels) { FlipY = flipped }; PerfProfiler.ProfilerEventEnd($"Uploading Image {Name}", "Loading"); }); }
/// <inheritdoc /> public override StreamBuffer CreateStreamBuffer(uint vbo, uint vao, uint ibo, uint objectSize, uint size, uint indicesPerObject, bool polygonMode = false) { StreamBuffer streamBuffer = null; GLThread.ExecuteGLThread(() => { // Create a GL stream buffer. streamBuffer = new GlStreamBuffer(vbo, vao, ibo, objectSize, size * objectSize, indicesPerObject, polygonMode ? PrimitiveType.TriangleFan : PrimitiveType.Triangles); }); return(streamBuffer); }
/// <inheritdoc /> public override void SetTextureMask(uint r = 0xff000000, uint g = 0x00ff0000, uint b = 0x0000ff00, uint a = 0x000000ff) { GLThread.ExecuteGLThread(() => { Gl.TexParameter(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleR, MaskMeaning(r)); Gl.TexParameter(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleG, MaskMeaning(g)); Gl.TexParameter(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleB, MaskMeaning(b)); Gl.TexParameter(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleA, MaskMeaning(a)); CheckError("setting texture mask"); }); }
/// <inheritdoc /> public override void UploadToIndexBuffer(IntPtr data, uint size) { if (BoundIndexBuffer == 0) { Engine.Log.Warning("You are trying to upload data, but no index buffer is bound.", MessageSource.GL); } GLThread.ExecuteGLThread(() => { Gl.BufferData(BufferTarget.ElementArrayBuffer, size, data, BufferUsage.StaticDraw); CheckError("after uploading index buffer data from pointer"); }); }
public void ThreadInvocationScheduleOld() { var resp = 0; GLThread.ExecuteGLThread(() => { resp = DoWork("adsad", "gegwe", "hhrhr"); }); if (resp != 15) { throw new Exception("whaa"); } }
/// <inheritdoc /> public override void DestroyDataBuffer(uint bufferId) { GLThread.ExecuteGLThread(() => { Gl.DeleteBuffers(bufferId); CheckError("after deleting data buffer"); }); // Revert binding if deleted bound. if (bufferId == BoundDataBuffer) { BoundDataBuffer = 0; } }
/// <inheritdoc /> public override void DestroyVertexArrayBuffer(uint bufferId) { GLThread.ExecuteGLThread(() => { Gl.DeleteVertexArrays(bufferId); CheckError("after deleting vertex array buffer"); }); // Revert binding if deleted bound. if (bufferId == BoundVertexArrayBuffer) { BoundVertexArrayBuffer = 0; } }
/// <inheritdoc /> public override uint CreateDataBuffer() { uint newBufferId = 0; GLThread.ExecuteGLThread(() => { // Create buffer. newBufferId = Gl.GenBuffer(); CheckError("after data buffer creation"); }); return(newBufferId); }
/// <inheritdoc /> public override void MapIndexBuffer(IntPtr data, uint size, uint offset = 0) { if (BoundIndexBuffer == 0) { Engine.Log.Warning("You are trying to map data, but no index buffer is bound.", MessageSource.GL); } IntPtr offsetPtr = (IntPtr)offset; GLThread.ExecuteGLThread(() => { Gl.BufferSubData(BufferTarget.ElementArrayBuffer, offsetPtr, size, data); CheckError("after uploading index buffer data from pointer"); }); }
/// <inheritdoc /> public override void AttachDataBufferToVertexArray(uint dataBufferId, uint vertexArrayBufferId, uint shaderIndex, uint componentCount, DataType dataType, bool normalized, uint stride, IntPtr offset) { GLThread.ExecuteGLThread(() => { BindVertexArrayBuffer(vertexArrayBufferId); BindDataBuffer(dataBufferId); Gl.EnableVertexAttribArray(shaderIndex); CheckError($"after enabling vertex array attributes {shaderIndex}"); Gl.VertexAttribPointer(shaderIndex, (int)componentCount, ToGLPointerType(dataType), normalized, (int)stride, offset); CheckError($"after setting vertex array attribute {shaderIndex}"); }); }
/// <inheritdoc /> public override uint CreateVertexArrayBuffer() { uint newBufferId = 0; GLThread.ExecuteGLThread(() => { // Create buffer. newBufferId = Gl.GenVertexArray(); CheckError("after vertex array buffer creation"); }); return(newBufferId); }
/// <summary> /// Uploads the provided vertex data to the GPU. /// </summary> /// <param name="data">The vertex data for this VBO.</param> public void Upload(ushort[] data) { if (_pointer == -1) { throw new Exception("Cannot upload data to a destroyed buffer."); } Count = data.Length; GLThread.ExecuteGLThread(() => { Bind(); GL.BufferData(BufferTarget.ElementArrayBuffer, data.Length * sizeof(ushort), data, BufferUsageHint.StaticDraw); Unbind(); }); }
/// <inheritdoc /> public override void UploadToIndexBuffer <T>(T[] data) { if (BoundIndexBuffer == 0) { Engine.Log.Warning("You are trying to upload data, but no index buffer is bound.", MessageSource.GL); } int byteSize = Marshal.SizeOf(data[0]); GLThread.ExecuteGLThread(() => { Gl.BufferData(BufferTarget.ElementArrayBuffer, (uint)(data.Length * byteSize), data, BufferUsage.StaticDraw); CheckError("after uploading index buffer data"); }); }