using StgSharp.Math; using System; using System.Collections.Concurrent; 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 { internal unsafe struct GLonUpdateInternal : IglFunc { public IntPtr ActiveTexturePtr; public IntPtr AttachShaderPtr; public IntPtr BindBufferPtr; internal IntPtr ClearColorPtr; internal IntPtr ClearGraphicErrorPtr; internal IntPtr CompileShaderPtr; internal GLparamQueue paramQueue; private GLcontext* gl; public GLonUpdateInternal(GLcontext* api) { gl = api; } public void ActivePointer() { IglFunc gl = this; ActiveTexturePtr = Marshal.GetFunctionPointerForDelegate(gl.ActiveTexture); AttachShaderPtr = Marshal.GetFunctionPointerForDelegate(gl.AttachShader); BindBufferPtr = Marshal.GetFunctionPointerForDelegate(gl.BindBuffer); CompileShaderPtr = Marshal.GetFunctionPointerForDelegate(gl.CompileShader); } void IglFunc.ActiveTexture(uint type) { uint t; paramQueue.TryDequeue(out t); gl->glActiveTexture(t); } void IglFunc.AfterAlign(Form form, Action action) { throw new NotImplementedException(); } void IglFunc.AlignFrame(Form form) { throw new NotImplementedException(); } void IglFunc.AttachShader(glHandle program, glHandle shader) { uint p, s; paramQueue.TryDequeue(out p, out s); gl->glAttachShader(p, s); } void IglFunc.BindBuffer(BufferType bufferType, uint index) { uint t, i; paramQueue.TryDequeue(out t, out i); gl->glBindBuffer(t, i); } void IglFunc.BindTexture(uint type, uint texture) { uint t, te; paramQueue.TryDequeue(out t, out te); gl->glBindTexture(t, te); } void IglFunc.BindVertexArray(uint index) { uint i; paramQueue.TryDequeue(out i); gl->glBindVertexArray(i); } void IglFunc.Clear(MaskBufferBit mask) { uint mt; paramQueue.TryDequeue(out mt); gl->glClear(mt); } void IglFunc.ClearColor(float R, float G, float B, float A) { float r, g, b, a; paramQueue.TryDequeue(out r, out g, out b, out a); gl->glClearColor(r, g, b, a); } void IglFunc.ClearGraphicError() { while (gl->glGetError() != 0) { } } glHandle IglFunc.CompileShader(string shaderCode, ShaderType shaderType) { IntPtr shaderHandle, codeHandle; paramQueue.TryDequeue(out codeHandle, out shaderHandle); uint shaderID; shaderCode += '\0'; shaderID = InternalIO.InternalLoadShaderCode(shaderCode, (int)shaderType); if (shaderID == 0) { IntPtr logPtr = InternalIO.InternalReadLog(); string log; try { byte[] logByte = new byte[512]; Marshal.Copy(logPtr, logByte, 0, 512); log = Encoding.UTF8.GetString(logByte); log = log.Replace("\0", ""); bool isUseful = false; foreach (char item in log) { if (!char.IsControl(item)) { isUseful = true; break; } } if (!isUseful) { throw new Exception(); } } catch (Exception) { log = "Failed to compile shader.\nFailed to get GLSL compiler log"; } InternalIO.InternalWriteLog(log, LogType.Error); } *(uint*)shaderHandle = shaderID; return default; } glHandle IglFunc.CreateProgram() { throw new NotImplementedException(); } glHandle IglFunc.CreateProgram(int count) { throw new NotImplementedException(); } IntPtr IglFunc.CreateWindowHandle(int width, int height, string tittle, IntPtr monitor, Form share) { throw new NotImplementedException(); } glHandle IglFunc.CreatGraphicProgram() { throw new NotImplementedException(); } void IglFunc.DeleteBuffer(uint handle) { throw new NotImplementedException(); } void IglFunc.DeleteBuffers(glHandle handle) { throw new NotImplementedException(); } void IglFunc.DeleteVertexArrays(glHandle arrays) { throw new NotImplementedException(); } void IglFunc.DrawElements(GepmetryType mode, uint count, Type type, IntPtr ptr) { throw new NotImplementedException(); } void IglFunc.GenBuffers(uint count, glHandle ptr) { throw new NotImplementedException(); } void IglFunc.GenTextures(uint count, glHandle ptr) { throw new NotImplementedException(); } void IglFunc.GenVertexArrays(uint count, glHandle ptr) { throw new NotImplementedException(); } void IglFunc.GetGraphicError() { throw new NotImplementedException(); } int IglFunc.GetUniformLocation(uint program, byte* ptr) { throw new NotImplementedException(); } bool IglFunc.GetWindowShouldClose(Form form) { throw new NotImplementedException(); } void IglFunc.MakeContexCurrent(Form form) { throw new NotImplementedException(); } void IglFunc.SetBufferData(BufferType bufferType, T bufferData, BufferUsage usage) { throw new NotImplementedException(); } void IglFunc.SetBufferData(BufferType bufferType, T[] bufferArray, BufferUsage usage) { throw new NotImplementedException(); } void IglFunc.SetFrameBufferSizeCallback(IntPtr id, FrameBufferSizeHandler handler) { throw new NotImplementedException(); } void IglFunc.SetValue(Uniform uniform, float v0, float v1, float v2, float v3) { throw new NotImplementedException(); } void IglFunc.SetValue(Uniform uniform, Vec4d vec) { throw new NotImplementedException(); } void IglFunc.SetValue(Uniform uniform, float v0, float v1, float v2) { throw new NotImplementedException(); } void IglFunc.SetValue(Uniform uniform, float v0, float v1) { throw new NotImplementedException(); } void IglFunc.SetValue(Uniform uniform, float v0) { throw new NotImplementedException(); } void IglFunc.SetValue(Uniform uniform, int i0) { throw new NotImplementedException(); } void IglFunc.SetValue(Uniform uniform, Vec4d vec) { throw new NotImplementedException(); } void IglFunc.SetVertexAttribute(uint index, int size, Type t, bool normalized, uint stride, int pointer) { throw new NotImplementedException(); } void IglFunc.SetWindowShouldClose(Form form, bool mark) { throw new NotImplementedException(); } void IglFunc.SwapBuffers(Form form) { throw new NotImplementedException(); } void IglFunc.TextureImage2d(uint target, int level, uint internalformat, uint width, uint height, uint format, uint type, void* pixels) { throw new NotImplementedException(); } void IglFunc.TextureParameter(uint target, uint pname, int param) { throw new NotImplementedException(); } void IglFunc.UseProgram(uint program) { throw new NotImplementedException(); } void IglFunc.Viewport(int x, int y, uint width, uint height) { throw new NotImplementedException(); } } internal unsafe class GLparamQueue { private ConcurrentQueue paramQueue; public GLparamQueue() { paramQueue = new ConcurrentQueue(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Enqueue(Vec4d v) { paramQueue.Enqueue(v); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Enqueue(uint u0) { M128 m = default; m.UInt32[0] = u0; paramQueue.Enqueue(m); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Enqueue(uint u0, uint u1) { M128 m = default; m.UInt32[0] = u0; m.UInt32[1] = u1; paramQueue.Enqueue(m); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Enqueue(float f0, float f1, float f2, float f3) { M128 m = default; m.Single[0] = f0; m.Single[1] = f1; m.Single[2] = f2; m.Single[3] = f3; paramQueue.Enqueue(m); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Enqueue(IntPtr p0, IntPtr p1) { M128 m = default; m.IntPtr0 = p0; m.IntPtr1 = p1; paramQueue.Enqueue(m); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void TryDequeue(out IntPtr p0, out IntPtr p1) { M128 ret; if (paramQueue.TryDequeue(out ret)) { p0 = ret.IntPtr0; p1 = ret.IntPtr1; } else { InternalIO.InternalWriteLog("No param in buffer when calling gl function.", LogType.Error); throw new Exception(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void TryDequeue(out float f0, out float f1, out float f2, out float f3) { M128 ret; if (paramQueue.TryDequeue(out ret)) { f0 = ret.UInt32[0]; f1 = ret.UInt32[1]; f2 = ret.UInt32[2]; f3 = ret.UInt32[3]; } else { InternalIO.InternalWriteLog("No param in buffer when calling gl function.", LogType.Error); throw new Exception(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void TryDequeue(out uint u0) { M128 ret; if (paramQueue.TryDequeue(out ret)) { u0 = ret.UInt32[0]; } else { InternalIO.InternalWriteLog("No param in buffer when calling gl function.", LogType.Error); throw new Exception(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void TryDequeue(out uint u0, out uint u1) { M128 ret; if (paramQueue.TryDequeue(out ret)) { u0 = ret.UInt32[0]; u1 = ret.UInt32[1]; } else { InternalIO.InternalWriteLog("No param in buffer when calling gl function.", LogType.Error); throw new Exception(); } } } }