using StgSharp.Controlling; using StgSharp.Math; using System; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Text; namespace StgSharp.Graphics { public static unsafe partial class Graphic { /// /// sets the framebuffer resize callback of the specified , ///which is called when the framebuffer of the specified is resized. /// /// The Form instance to be controlled /// Method hadler [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SetFrameBufferSizeCallback(Form form, FrameBufferSizeHadler handler) { internalIO.glfwSetFramebufferSizeCallback(form.windowID, handler); } /// /// Call glClearColor in OpenGL /// specifies the red, green, blue, and alpha values used by glClear to clear the color buffers. /// Values specified by glClearColor are clamped to the range [0,1] /// /// Specify the red values used when the color buffers are cleared. /// Specify the red values used when the color buffers are cleared. /// Specify the red values used when the color buffers are cleared. /// Specify the red values used when the color buffers are cleared. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ClearColor(float R, float G, float B, float A) { glClearColor(R, G, B, A); } /// /// Conpile the provided shader code in string form. /// /// A string represent the shader's code /// An enum represent the type of the shader to /// conpile, including vertex shader and fragment shader. /// An uint value as the only mark of conpiled shader public static unsafe uint CompileShader(string shaderCode, ShaderType shaderType) { uint shaderID; shaderCode += '\0'; byte[] buffer = Encoding.ASCII.GetBytes(shaderCode); fixed (byte* data = &buffer[0]) { shaderID = internalIO.InternalLoadShaderCode(data, (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); } return shaderID; } /// /// Creates a form and its associated context. /// /// Required width /// Required width /// Tittle of the window /// /// /// The instance of created form /// public static unsafe Form CreateWindow( int width, int height, string tittle, IntPtr monitor, Form share) { byte[] tittleBytes = Encoding.UTF8.GetBytes(tittle); IntPtr windowPtr; if (share == null) { windowPtr = internalIO.glfwCreateWindow( width, height, tittleBytes, monitor, IntPtr.Zero); } else { windowPtr = internalIO.glfwCreateWindow( width, height, tittleBytes, monitor, share.windowID); } if ((long)windowPtr == -1 || (long)windowPtr == -2) { throw new Exception("Cannot create window instance!"); } else { Form form = new Form(); form.Size = new Vec2d(width, height); form.windowID = windowPtr; return form; } } public static unsafe uint CreatGraphicProgram() { return glCreateProgram(); } public static IntPtr GetProcAddress(string name) { IntPtr ret = internalIO.glfwGetProcAddress(name); return ret; } public static unsafe bool GetWindowShouldClose(Form form) { return internalIO.glfwWindowShouldClose(form.windowID) != 0; } public static unsafe void GLswapBuffers(Form form) { if (form.windowID == IntPtr.Zero) { return; } internalIO.glfwSwapBuffers(form.windowID); } public static unsafe void MakeContexCurrent(Form form) { if (form.windowID == IntPtr.Zero) { return; } internalIO.glfwMakeContextCurrent(form.windowID); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void SetBufferData(BufferType bufferType, T bufferData, BufferReadType readType) where T : IMat { int size = Marshal.SizeOf(bufferData); glBufferData( (int)bufferType, size, &bufferData, (int)readType); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void SetBufferData(BufferType bufferType, T[] bufferArray, BufferReadType readType) where T : struct, IConvertible { int size = bufferArray.Length * Marshal.SizeOf(typeof(T)); fixed (void* bufferPtr = &bufferArray[0]) glBufferData( (int)bufferType, size, bufferPtr, (int)readType); } } }