1using Silk.NET.OpenGLES;
2using System.Diagnostics;
7using System.Runtime.InteropServices;
14 public static IntPtr m_eglDisplay;
15 public static IntPtr m_eglSurface;
16 public static IntPtr m_eglContext;
74 if (hwnd == IntPtr.Zero) {
75 throw new Exception(
"Failed to get window handle");
79 if (m_eglDisplay == IntPtr.Zero) {
80 throw new Exception(
"eglGetDisplay failed");
83 throw new Exception(
"eglInitialize failed");
85 int[] configAttribs = [
104 IntPtr[] configs =
new IntPtr[1];
105 if (!
Egl.
ChooseConfig(m_eglDisplay, configAttribs, configs, 1, out
int numConfigs)) {
106 throw new Exception(
"eglChooseConfig failed");
108 IntPtr config = configs[0];
114 if (m_eglSurface == IntPtr.Zero) {
115 throw new Exception(
"eglCreateWindowSurface failed");
118 m_eglContext =
Egl.
CreateContext(m_eglDisplay, config, IntPtr.Zero, contextAttribs);
119 if (m_eglContext == IntPtr.Zero) {
120 throw new Exception(
"eglCreateContext failed");
122 if (!
Egl.
MakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)) {
123 throw new Exception(
"eglMakeCurrent failed");
139#if DEBUG && !IOS && !BROWSER
141 GL.DebugMessageCallback(DebugMessageDelegate, IntPtr.Zero.ToPointer());
142 GL.Enable(EnableCap.DebugOutput);
145 int[] bits =
new int[6];
146 for (
int i = 0; i < 6; i++) {
147 bits[i] =
GL.GetInteger((GetPName)(i + 3410));
150 string OpenGLVendor = $
"OpenGL ES, Vendor={GL.GetStringS(StringName.Vendor) ?? string.Empty}";
151 Display.DeviceDescription =
152 $
"{OpenGLVendor}, Renderer={GL.GetStringS(StringName.Renderer) ?? string.Empty}, Version={GL.GetStringS(StringName.Version) ?? string.Empty}, R={bits[0]} G={bits[1]} B={bits[2]} A={bits[3]}, D={bits[4]} S={bits[5]}, MaxTextureSize={GL_MAX_TEXTURE_SIZE}";
153 Log.
Information($
"Initialized display device: {Display.DeviceDescription}");
154 string extensions =
GL.GetStringS(StringName.Extensions);
212 public static bool Enable(EnableCap state) {
233 value =
GL.IsEnabled(state);
242 if (value != clearColor) {
243 GL.ClearColor(color.
X, color.
Y, color.
Z, color.
W);
250 GL.ClearDepth(depth);
257 GL.ClearStencil(stencil);
262 public static void CullFace(TriangleFace cullFace) {
264 GL.CullFace(cullFace);
269 public static void FrontFace(FrontFaceDirection frontFace) {
271 GL.FrontFace(frontFace);
276 public static void DepthFunc(DepthFunction depthFunction) {
278 GL.DepthFunc(depthFunction);
286 GL.ColorMask((colorMask & 8) != 0, (colorMask & 4) != 0, (colorMask & 2) != 0, (colorMask & 1) != 0);
293 GL.DepthMask(depthMask);
303 GL.PolygonOffset(factor, units);
311 GL.BlendColor(blendColor.
X, blendColor.
Y, blendColor.
Z, blendColor.
W);
318 GL.BlendEquation(blendEquation);
325 public static void BlendEquationSeparate(BlendEquationModeEXT blendEquationColor, BlendEquationModeEXT blendEquationAlpha) {
328 GL.BlendEquationSeparate(blendEquationColor, blendEquationAlpha);
335 public static void BlendFunc(BlendingFactor blendFuncSource, BlendingFactor blendFuncDestination) {
338 GL.BlendFunc(blendFuncSource, blendFuncDestination);
349 BlendingFactor blendFuncDestinationColor,
350 BlendingFactor blendFuncSourceAlpha,
351 BlendingFactor blendFuncDestinationAlpha) {
356 GL.BlendFuncSeparate(blendFuncSourceColor, blendFuncDestinationColor, blendFuncSourceAlpha, blendFuncDestinationAlpha);
367 uint uIndex = (uint)index;
369 GL.EnableVertexAttribArray(uIndex);
374 GL.DisableVertexAttribArray(uIndex);
379 public static void BindTexture(TextureTarget target,
int texture,
bool forceBind) {
380 uint uTexture = (uint)texture;
381 if (target == TextureTarget.Texture2D) {
383 GL.BindTexture(target, uTexture);
391 GL.BindTexture(target, uTexture);
397 GL.ActiveTexture(textureUnit);
402 public static void BindBuffer(BufferTargetARB target,
int buffer) {
403 uint uBuffer = (uint)buffer;
405 case BufferTargetARB.ArrayBuffer:
407 GL.BindBuffer(target, uBuffer);
411 case BufferTargetARB.ElementArrayBuffer:
413 GL.BindBuffer(target, uBuffer);
417 default:
GL.BindBuffer(target, uBuffer);
break;
423 GL.BindFramebuffer(FramebufferTarget.Framebuffer, (uint)framebuffer);
430 GL.UseProgram((uint)program);
439 GL.DeleteProgram((uint)program);
452 GL.DeleteTexture((uint)texture);
459 uint uFramebuffer = (uint)framebuffer;
460 GL.DeleteFramebuffers(1, in uFramebuffer);
464 if (target == BufferTargetARB.ArrayBuffer) {
472 if (target == BufferTargetARB.ElementArrayBuffer
476 uint uBuffer = (uint)buffer;
477 GL.DeleteBuffers(1u, in uBuffer);
486 int y = Display.RenderTarget ==
null ? Display.BackbufferSize.Y - viewport.Y - viewport.Height : viewport.
Y;
487 GL.Viewport(viewport.
X, y, (uint)viewport.
Width, (uint)viewport.
Height);
495 if (!isScissorEnabled) {
501 if (!(value != scissorRectangle2)) {
506 scissorRectangle.Top = Display.BackbufferSize.Y - scissorRectangle.Top - scissorRectangle.
Height;
508 GL.Scissor(scissorRectangle.
Left, scissorRectangle.
Top, (uint)scissorRectangle.
Width, (uint)scissorRectangle.
Height);
518 Enable(EnableCap.CullFace);
523 Enable(EnableCap.CullFace);
529 Enable(EnableCap.ScissorTest);
532 Disable(EnableCap.ScissorTest);
536 Enable(EnableCap.PolygonOffsetFill);
540 Disable(EnableCap.PolygonOffsetFill);
552 Enable(EnableCap.DepthTest);
596 if (renderTarget !=
null) {
599 GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, (uint)renderTarget.
m_depthBuffer);
612 int? elementArrayBuffer) {
615 string log =
GL.GetProgramInfoLog((uint)shader.
m_program);
616 if(!
string.IsNullOrEmpty(log)) Console.WriteLine(
"Program Link Error: " + log);
618 if (!
string.IsNullOrEmpty(log)) Console.WriteLine(
"Shader Compile Error: " + log);
623 BindBuffer(BufferTargetARB.ArrayBuffer, arrayBuffer);
624 if (elementArrayBuffer.HasValue) {
625 BindBuffer(BufferTargetARB.ElementArrayBuffer, elementArrayBuffer.Value);
633 for (
int i = 0; i < vertexAttribData.Length; i++) {
634 if (vertexAttribData[i].Size != 0) {
635 GL.VertexAttribPointer(
637 vertexAttribData[i].Size,
638 vertexAttribData[i].Type,
639 vertexAttribData[i].Normalize,
641 (vertexOffset + vertexAttribData[i].Offset).ToPointer()
663 switch (shaderParameter.
Type) {
666 shaderParameter.IsChanged =
false;
670 shaderParameter.IsChanged =
false;
674 shaderParameter.IsChanged =
false;
678 shaderParameter.IsChanged =
false;
681 GL.UniformMatrix4(shaderParameter.
Location, (uint)shaderParameter.
Count,
false, shaderParameter.
Value);
682 shaderParameter.IsChanged =
false;
684 default:
throw new InvalidOperationException(
"Unsupported shader parameter type.");
691 throw new InvalidOperationException(
"Too many simultaneous textures.");
700 if (texture2D !=
null) {
701 if (samplerState ==
null) {
708 || value != samplerState) {
712 TextureTarget.Texture2D,
713 TextureParameterName.TextureMaxAnisotropy,
718 TextureTarget.Texture2D,
719 TextureParameterName.TextureMinFilter,
723 TextureTarget.Texture2D,
724 TextureParameterName.TextureMagFilter,
728 TextureTarget.Texture2D,
729 TextureParameterName.TextureWrapS,
733 TextureTarget.Texture2D,
734 TextureParameterName.TextureWrapT,
737#if !MOBILE && !BROWSER
738 GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinLod, samplerState.
MinLod);
739 GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLod, samplerState.
MaxLod);
748 shaderParameter.IsChanged =
false;
752 throw new InvalidOperationException($
"Associated SamplerState is not set for texture \"{shaderParameter.Name}\".");
756 ClearBufferMask all = ClearBufferMask.None;
757 if (color.HasValue) {
758 all |= ClearBufferMask.ColorBufferBit;
762 if (depth.HasValue) {
763 all |= ClearBufferMask.DepthBufferBit;
769 if (stencil.HasValue) {
770 all |= ClearBufferMask.StencilBufferBit;
773 if (all != ClearBufferMask.None) {
775 if (
Disable(EnableCap.ScissorTest)) {
792 catch (Exception ex) {
793 Log.
Error(
"Failed to recreate graphics resources. Reason: {0}", ex.Message);
799 GL.GetFloat(GetPName.LineWidth, out
float width);
800 return width == 0f ? 1f : width;
802 set =>
GL.LineWidth(value);
806 out VertexAttribPointerType type,
807 out
bool normalize) {
808 switch (vertexElementFormat) {
810 type = VertexAttribPointerType.Float;
814 type = VertexAttribPointerType.Float;
818 type = VertexAttribPointerType.Float;
822 type = VertexAttribPointerType.Float;
826 type = VertexAttribPointerType.UnsignedByte;
830 type = VertexAttribPointerType.UnsignedByte;
834 type = VertexAttribPointerType.Short;
838 type = VertexAttribPointerType.Short;
842 type = VertexAttribPointerType.Short;
846 type = VertexAttribPointerType.Short;
849 default:
throw new InvalidOperationException(
"Unsupported vertex element format.");
854 return indexFormat
switch {
857 _ =>
throw new InvalidOperationException(
"Unsupported index format.")
869 _ =>
throw new InvalidOperationException(
"Unsupported shader parameter type.")
874 return primitiveType
switch {
882 _ =>
throw new InvalidOperationException(
"Unsupported primitive type.")
887 switch (filterMode) {
890 return TextureMinFilter.Nearest;
892 return TextureMinFilter.NearestMipmapNearest;
895 return TextureMinFilter.Linear;
897 return TextureMinFilter.LinearMipmapLinear;
900 return TextureMinFilter.Linear;
902 return TextureMinFilter.LinearMipmapLinear;
905 return TextureMinFilter.Nearest;
907 return TextureMinFilter.NearestMipmapLinear;
910 return TextureMinFilter.Linear;
912 return TextureMinFilter.LinearMipmapNearest;
915 return TextureMinFilter.Nearest;
917 return TextureMinFilter.NearestMipmapNearest;
920 return TextureMinFilter.Nearest;
922 return TextureMinFilter.NearestMipmapLinear;
925 return TextureMinFilter.Linear;
927 return TextureMinFilter.LinearMipmapNearest;
930 return TextureMinFilter.Linear;
932 return TextureMinFilter.LinearMipmapLinear;
933 default:
throw new InvalidOperationException(
"Unsupported texture filter mode.");
938 return filterMode
switch {
948 _ =>
throw new InvalidOperationException(
"Unsupported texture filter mode.")
953 return addressMode
switch {
956 _ =>
throw new InvalidOperationException(
"Unsupported texture address mode.")
961 return compareFunction
switch {
970 _ =>
throw new InvalidOperationException(
"Unsupported texture address mode.")
975 return blendFunction
switch {
979 _ =>
throw new InvalidOperationException(
"Unsupported blend function.")
984 return blend
switch {
987 Blend.SourceColor => BlendingFactor.SrcColor,
988 Blend.InverseSourceColor => BlendingFactor.OneMinusSrcColor,
989 Blend.DestinationColor => BlendingFactor.DstColor,
990 Blend.InverseDestinationColor => BlendingFactor.OneMinusDstColor,
991 Blend.SourceAlpha => BlendingFactor.SrcAlpha,
992 Blend.InverseSourceAlpha => BlendingFactor.OneMinusSrcAlpha,
993 Blend.DestinationAlpha => BlendingFactor.DstAlpha,
994 Blend.InverseDestinationAlpha => BlendingFactor.OneMinusDstAlpha,
995 Blend.BlendFactor => BlendingFactor.ConstantColor,
996 Blend.InverseBlendFactor => BlendingFactor.OneMinusConstantColor,
997 Blend.SourceAlphaSaturation => BlendingFactor.SrcAlphaSaturate,
998 _ =>
throw new InvalidOperationException(
"Unsupported blend.")
1003 return blend
switch {
1006 Blend.SourceColor => BlendingFactor.SrcColor,
1007 Blend.InverseSourceColor => BlendingFactor.OneMinusSrcColor,
1008 Blend.DestinationColor => BlendingFactor.DstColor,
1009 Blend.InverseDestinationColor => BlendingFactor.OneMinusDstColor,
1010 Blend.SourceAlpha => BlendingFactor.SrcAlpha,
1011 Blend.InverseSourceAlpha => BlendingFactor.OneMinusSrcAlpha,
1012 Blend.DestinationAlpha => BlendingFactor.DstAlpha,
1013 Blend.InverseDestinationAlpha => BlendingFactor.OneMinusDstAlpha,
1014 Blend.BlendFactor => BlendingFactor.ConstantColor,
1015 Blend.InverseBlendFactor => BlendingFactor.OneMinusConstantColor,
1016 Blend.SourceAlphaSaturation => BlendingFactor.SrcAlphaSaturate,
1017 _ =>
throw new InvalidOperationException(
"Unsupported blend.")
1022 return depthFormat
switch {
1029 _ =>
throw new InvalidOperationException(
"Unsupported DepthFormat.")
1033 public static void DebugMessageDelegate (GLEnum source, GLEnum type,
int id, GLEnum severity,
int length, nint message, nint userParam) {
1034 if (type == GLEnum.DebugTypeOther) {
1037 string messageText = Marshal.PtrToStringAnsi(message, length);
1038 Console.WriteLine($
"[{type.ToString().Substring(9)}] {messageText}");
1039 if (type == GLEnum.DebugTypeError) {
1044 [Conditional(
"DEBUG")]
static void ApplyWorkaroundFixingInvocations()
Blend ColorDestinationBlend
BlendFunction AlphaBlendFunction
BlendFunction ColorBlendFunction
Blend AlphaDestinationBlend
bool DepthBufferWriteEnable
bool DepthBufferTestEnable
CompareFunction DepthBufferFunction
static void HandleDeviceLost()
static void HandleDeviceReset()
static RenderTarget2D RenderTarget
static IntPtr CreateContext(IntPtr dpy, IntPtr config, IntPtr shareContext, int[] attribList)
static bool MakeCurrent(IntPtr dpy, IntPtr draw, IntPtr read, IntPtr ctx)
static IntPtr GetProcAddress(string proc)
static bool ChooseConfig(IntPtr dpy, int[] attribList, IntPtr[] configs, int configSize, out int numConfig)
static IntPtr CreateWindowSurface(IntPtr dpy, IntPtr config, IntPtr nativeWindow, int[] attribList)
static IntPtr GetDisplay(IntPtr displayId)
const int ContextClientVersion
static bool Initialize(IntPtr dpy, out int major, out int minor)
static FrontFaceDirection m_frontFace
static int[] m_activeTexturesByUnit
static ? float m_clearDepth
static RasterizerState m_rasterizerState
static BlendingFactor m_blendFuncSource
static Shader m_lastShader
static float m_polygonOffsetFactor
static int m_elementArrayBuffer
static BlendingFactor TranslateBlendSrc(Blend blend)
static void TranslateVertexElementFormat(VertexElementFormat vertexElementFormat, out VertexAttribPointerType type, out bool normalize)
static DepthStencilState m_depthStencilState
static void DeleteFramebuffer(int framebuffer)
static int GL_MAX_TEXTURE_SIZE
static void HandleContextLost()
static void ClearStencil(int stencil)
static BlendEquationModeEXT m_blendEquation
static BlendingFactor m_blendFuncSourceColor
static BlendEquationModeEXT m_blendEquationColor
static TriangleFace m_cullFace
static BlendingFactor m_blendFuncSourceAlpha
static int m_mainFramebuffer
static bool GL_KHR_texture_compression_astc_ldr
static Vector4 m_blendColor
static void ColorMask(int colorMask)
static BlendState m_blendState
static TextureMinFilter TranslateTextureFilterModeMin(TextureFilterMode filterMode, bool isMipmapped)
static int m_lastArrayBuffer
static ? Rectangle m_scissorRectangle
static IntPtr m_lastVertexOffset
static void DeleteBuffer(BufferTargetARB target, int buffer)
static DepthFunction TranslateCompareFunction(CompareFunction compareFunction)
static ? Vector4 m_clearColor
static float m_polygonOffsetUnits
static void BlendColor(Vector4 blendColor)
static void ApplyDepthStencilState(DepthStencilState state)
static void UseProgram(int program)
static BlendingFactor m_blendFuncDestination
static bool Enable(EnableCap state)
static ? int m_clearStencil
static void CullFace(TriangleFace cullFace)
static int m_mainDepthbuffer
static DepthFunction m_depthFunction
static void DeleteProgram(int program)
static int GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
static ? bool[] m_vertexAttribArray
static void ClearColor(Vector4 color)
static ShaderParameterType TranslateActiveUniformType(UniformType type)
static bool GL_EXT_texture_filter_anisotropic
static void ApplyRasterizerState(RasterizerState state)
static void PolygonOffset(float factor, float units)
static BlendEquationModeEXT m_blendEquationAlpha
static TextureMagFilter TranslateTextureFilterModeMag(TextureFilterMode filterMode)
static void BindFramebuffer(int framebuffer)
static void Clear(RenderTarget2D renderTarget, Vector4? color, float? depth, int? stencil)
static BlendingFactor TranslateBlendDest(Blend blend)
static void DepthFunc(DepthFunction depthFunction)
static void VertexAttribArray(int index, bool enable)
static void ActiveTexture(TextureUnit textureUnit)
static void ApplyViewportScissor(Viewport viewport, Rectangle scissorRectangle, bool isScissorEnabled)
static void ApplyBlendState(BlendState state)
static TextureUnit m_activeTextureUnit
static void BlendFuncSeparate(BlendingFactor blendFuncSourceColor, BlendingFactor blendFuncDestinationColor, BlendingFactor blendFuncSourceAlpha, BlendingFactor blendFuncDestinationAlpha)
static TextureWrapMode TranslateTextureAddressMode(TextureAddressMode addressMode)
static ? bool m_depthMask
static Silk.NET.OpenGLES.PrimitiveType TranslatePrimitiveType(PrimitiveType primitiveType)
static Dictionary< int, SamplerState > m_textureSamplerStates
static BlendingFactor m_blendFuncDestinationAlpha
static void InitializeCache()
static void BlendEquationSeparate(BlendEquationModeEXT blendEquationColor, BlendEquationModeEXT blendEquationAlpha)
static void CheckGLError()
static BlendingFactor m_blendFuncDestinationColor
static bool GL_OES_packed_depth_stencil
static bool DepthMask(bool depthMask)
static void BindBuffer(BufferTargetARB target, int buffer)
static bool IsEnabled(EnableCap state)
static unsafe void ApplyShaderAndBuffers(Shader shader, VertexDeclaration vertexDeclaration, IntPtr vertexOffset, int arrayBuffer, int? elementArrayBuffer)
static DrawElementsType TranslateIndexFormat(IndexFormat indexFormat)
static ? Viewport m_viewport
static VertexDeclaration m_lastVertexDeclaration
static int m_mainColorbuffer
static void ApplyRenderTarget(RenderTarget2D renderTarget)
static void FrontFace(FrontFaceDirection frontFace)
static BlendEquationModeEXT TranslateBlendFunction(BlendFunction blendFunction)
static void BlendEquation(BlendEquationModeEXT blendEquation)
static void BindTexture(TextureTarget target, int texture, bool forceBind)
static InternalFormat TranslateDepthFormat(DepthFormat depthFormat)
static void ClearDepth(float depth)
static bool Disable(EnableCap state)
static void DeleteTexture(int texture)
static Dictionary< EnableCap, bool > m_enableDisableStates
static void BlendFunc(BlendingFactor blendFuncSource, BlendingFactor blendFuncDestination)
float SlopeScaleDepthBias
TextureAddressMode AddressModeU
TextureFilterMode FilterMode
TextureAddressMode AddressModeV
virtual VertexAttributeData[] GetVertexAttribData(VertexDeclaration vertexDeclaration)
ShaderParameter[] m_parameters
virtual void PrepareForDrawing()
readonly ShaderParameterType Type
readonly VertexElement[] m_elements
static void Error(object message)
static void Information(object message)
@ MinPointMagLinearMipLinear
@ MinLinearMagPointMipLinear
@ MinLinearMagPointMipPoint
@ MinPointMagLinearMipPoint