Files
stgsharp/源代码/StgSharp/Graphics/GLFunc.cs
T

195 lines
6.8 KiB
C#

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
{
/// <summary>
/// sets the framebuffer resize callback of the specified <see cref="Form"/>,
///which is called when the framebuffer of the specified <see cref="Form"/> is resized.
/// </summary>
/// <param name="form">The Form instance to be controlled</param>
/// <param name="handler">Method hadler </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SetFrameBufferSizeCallback(Form form, FrameBufferSizeHadler handler)
{
internalIO.glfwSetFramebufferSizeCallback(form.windowID, handler);
}
/// <summary>
/// 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]
/// </summary>
/// <param name="R">Specify the red values used when the color buffers are cleared.</param>
/// <param name="G">Specify the red values used when the color buffers are cleared.</param>
/// <param name="B">Specify the red values used when the color buffers are cleared.</param>
/// <param name="A">Specify the red values used when the color buffers are cleared.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ClearColor(float R, float G, float B, float A)
{
glClearColor(R, G, B, A);
}
/// <summary>
/// Conpile the provided shader code in string form.
/// </summary>
/// <param name="shaderCode">A string represent the shader's code</param>
/// <param name="shaderType">An <see cref="ShaderType"/> enum represent the type of the shader to
/// conpile, including vertex shader and fragment shader.</param>
/// <returns>An uint value as the only mark of conpiled shader</returns>
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;
}
/// <summary>
/// Creates a form and its associated context.
/// </summary>
/// <param name="width">Required width</param>
/// <param name="height">Required width</param>
/// <param name="tittle">Tittle of the window </param>
/// <param name="monitor"></param>
/// <param name="share"></param>
/// <returns>The instance of created form</returns>
/// <exception cref="Exception"></exception>
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<T>(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<T>(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);
}
}
}