mirror of
https://gitee.com/csharpui/CPF.git
synced 2025-04-05 17:37:51 +08:00
170 lines
5.9 KiB
C#
170 lines
5.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using CPF.Drawing;
|
|
using CPF.OpenGL;
|
|
|
|
namespace CPF.Windows.OpenGL
|
|
{
|
|
public class WglContext : CPF.OpenGL.IGlContext
|
|
{
|
|
public const int WGL_CONTEXT_MAJOR_VERSION_ARB = 0x2091;
|
|
public const int WGL_CONTEXT_MINOR_VERSION_ARB = 0x2092;
|
|
public const int WGL_CONTEXT_LAYER_PLANE_ARB = 0x2093;
|
|
public const int WGL_CONTEXT_PROFILE_MASK_ARB = 0x9126;
|
|
public const int GL_FRAMEBUFFER_BINDING = 0x8CA6;
|
|
|
|
private IntPtr dc;
|
|
private IntPtr rc;
|
|
IntPtr handle;
|
|
|
|
public WglContext(IntPtr handle)
|
|
{
|
|
this.handle = handle;
|
|
dc = UnmanagedMethods.GetDC(handle);
|
|
var pfd = new PIXELFORMATDESCRIPTOR();
|
|
pfd.nSize = (ushort)Marshal.SizeOf(pfd);
|
|
pfd.nVersion = 1;
|
|
pfd.dwFlags = Wgl.PFD_DRAW_TO_WINDOW | Wgl.PFD_SUPPORT_OPENGL | Wgl.PFD_SUPPORT_COMPOSITION;
|
|
pfd.iPixelType = Wgl.PFD_TYPE_RGBA;
|
|
pfd.cColorBits = 32;
|
|
pfd.cDepthBits = 24;
|
|
pfd.cStencilBits = 8;
|
|
pfd.cAlphaBits = 8;
|
|
pfd.iLayerType = Wgl.PFD_MAIN_PLANE;
|
|
|
|
var format = Wgl.ChoosePixelFormat(dc, ref pfd);
|
|
Wgl.SetPixelFormat(dc, format, ref pfd);
|
|
rc = Wgl.wglCreateContext(dc);
|
|
|
|
//var nPixelFormat = new int[] { -1 };
|
|
//var r = Wgl.wglChoosePixelFormatARB(dc, new int[] {
|
|
//Wgl.WGL_SUPPORT_OPENGL_ARB, 1, // Must support OGL rendering
|
|
//Wgl.WGL_DRAW_TO_WINDOW_ARB, 1, // pf that can run a window
|
|
//Wgl.WGL_ACCELERATION_ARB, Wgl.WGL_FULL_ACCELERATION_ARB, // must be HW accelerated
|
|
|
|
//Wgl.WGL_PIXEL_TYPE_ARB, Wgl.WGL_TYPE_RGBA_ARB,
|
|
//Wgl.WGL_COLOR_BITS_ARB, 32, // 8 bits of each R, G and B
|
|
//Wgl. WGL_DEPTH_BITS_ARB, 24, // 24 bits of depth precision for window
|
|
//Wgl.WGL_STENCIL_BITS_ARB, 8, // 开启模板缓冲区,模板缓冲区位数=8
|
|
//Wgl.WGL_ALPHA_BITS_ARB, 8,
|
|
////Wgl.WGL_SAMPLE_BUFFERS_ARB, 1, // MSAA on,开启多重采样
|
|
////Wgl.WGL_SAMPLES_ARB, 4, // 4x MSAA ,多重采样样本数量为4
|
|
//0, 0
|
|
//}, new float[] { 0, 0 }, 1, nPixelFormat, out var f);
|
|
//r= Wgl.SetPixelFormat(dc, nPixelFormat[0], ref pfd);
|
|
//rc = Wgl.WglCreateContextAttribsArb(dc, IntPtr.Zero,
|
|
//new[]
|
|
//{
|
|
// // major
|
|
// WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
|
|
// // minor
|
|
// WGL_CONTEXT_MINOR_VERSION_ARB, 3,
|
|
// // core profile
|
|
// //WGL_CONTEXT_PROFILE_MASK_ARB, 0,
|
|
// // debug
|
|
// // WGL_CONTEXT_FLAGS_ARB, 1,
|
|
// // end
|
|
// 0, 0
|
|
//});
|
|
|
|
if (rc == IntPtr.Zero)
|
|
{
|
|
Console.WriteLine("无法创建OpenGLContext DC:" + dc + " Handle:" + handle);
|
|
System.Diagnostics.Debug.WriteLine("无法创建OpenGLContext DC:" + dc + " Handle:" + handle);
|
|
}
|
|
else
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("OpenGL Context创建成功");
|
|
Console.WriteLine("OpenGL Context创建成功");
|
|
}
|
|
}
|
|
|
|
public IntPtr RC
|
|
{
|
|
get { return rc; }
|
|
}
|
|
|
|
public IDisposable GRContext { get; set; }
|
|
|
|
public IntPtr GetProcAddress(string name)
|
|
{
|
|
var ptr = Wgl.wglGetProcAddress(name);
|
|
if (ptr == IntPtr.Zero)
|
|
{
|
|
ptr = UnmanagedMethods.GetProcAddress(OpenGl32Handle, name);
|
|
}
|
|
return ptr;
|
|
}
|
|
public static IntPtr OpenGl32Handle = UnmanagedMethods.LoadLibrary("opengl32");
|
|
IntPtr oldRc;
|
|
IntPtr oldDc;
|
|
public void MakeCurrent()
|
|
{
|
|
if (rc != IntPtr.Zero)
|
|
{
|
|
oldDc = Wgl.wglGetCurrentDC();
|
|
oldRc = Wgl.wglGetCurrentContext();
|
|
if (!Wgl.wglMakeCurrent(dc, rc))
|
|
{
|
|
throw new Exception("Could not set the context.");
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SwapBuffers()
|
|
{
|
|
if (rc != IntPtr.Zero)
|
|
{
|
|
if (!Wgl.SwapBuffers(dc))
|
|
{
|
|
throw new Exception("Could not complete SwapBuffers.");
|
|
}
|
|
Wgl.wglMakeCurrent(oldDc, oldRc);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
UnmanagedMethods.ReleaseDC(handle, dc);
|
|
if (rc != IntPtr.Zero)
|
|
{
|
|
Wgl.wglDeleteContext(rc);
|
|
}
|
|
GRContext?.Dispose();
|
|
}
|
|
|
|
|
|
//public override GRGlTextureInfo CreateTexture(SKSizeI textureSize)
|
|
//{
|
|
// var textures = new uint[1];
|
|
// Wgl.glGenTextures(textures.Length, textures);
|
|
// var textureId = textures[0];
|
|
|
|
// Wgl.glBindTexture(Wgl.GL_TEXTURE_2D, textureId);
|
|
// Wgl.glTexImage2D(Wgl.GL_TEXTURE_2D, 0, Wgl.GL_RGBA, textureSize.Width, textureSize.Height, 0, Wgl.GL_RGBA, Wgl.GL_UNSIGNED_BYTE, IntPtr.Zero);
|
|
// Wgl.glBindTexture(Wgl.GL_TEXTURE_2D, 0);
|
|
|
|
// return new GRGlTextureInfo
|
|
// {
|
|
// Id = textureId,
|
|
// Target = Wgl.GL_TEXTURE_2D,
|
|
// Format = Wgl.GL_RGBA8
|
|
// };
|
|
//}
|
|
|
|
//public override void DestroyTexture(uint texture)
|
|
//{
|
|
// Wgl.glDeleteTextures(1, new[] { texture });
|
|
//}
|
|
|
|
public void GetFramebufferInfo(out int framebuffer, out int samples, out int stencil)
|
|
{
|
|
Wgl.glGetIntegerv(GL_FRAMEBUFFER_BINDING, out framebuffer);
|
|
Wgl.glGetIntegerv(3415, out stencil);
|
|
Wgl.glGetIntegerv(32937, out samples);
|
|
}
|
|
}
|
|
}
|