C#Win32:窗口将不显示OpenGL
使用Tao框架,OpenGL/WGL/WinAPI的C#bindings,我试图使一个空白的WinAPI窗口显示OpenGL图形。这个代码似乎不起作用。窗口打开了,但什么也没画。大多数OpenGL/GDI代码都是从Tao的SimplePenglControl镜像而来的。C#Win32:窗口将不显示OpenGL,c#,opengl,C#,Opengl,使用Tao框架,OpenGL/WGL/WinAPI的C#bindings,我试图使一个空白的WinAPI窗口显示OpenGL图形。这个代码似乎不起作用。窗口打开了,但什么也没画。大多数OpenGL/GDI代码都是从Tao的SimplePenglControl镜像而来的。 有人知道我做错了什么吗?如果您试图使用高于1.1的OpenGL,您需要创建一个OpenGL 1.1窗口,从那里声明一个新的OpenGL 3.x窗口,然后在打开第二个窗口的同时关闭第一个窗口。我不确定您正在使用的库,或者它是
有人知道我做错了什么吗?如果您试图使用高于1.1的OpenGL,您需要创建一个OpenGL 1.1窗口,从那里声明一个新的OpenGL 3.x窗口,然后在打开第二个窗口的同时关闭第一个窗口。我不确定您正在使用的库,或者它是否与更现代的框架兼容,可能是它是为较早的.NET版本设计的,并且正在使用不推荐使用的函数。他们有github页面吗?这个库很旧,但仍然可以使用。它并没有官方的github页面,但这里有一个源代码:oh-wow,这很旧,OGL2.1。TBH我会放弃那个库,要么创建自己的库,要么看看其他库,因为它太旧了。也许可以看看这个:上面的一个有9年历史,是OGL 4.2如果您试图使用OpenGL高于1.1的版本,您需要创建一个OpenGL 1.1窗口,从那里声明一个新的OpenGL 3.x窗口,然后关闭第一个窗口,同时打开第二个窗口。我不确定您正在使用的库,或者它是否与更现代的框架兼容,可能是它是为较早的.NET版本设计的,并且正在使用不推荐使用的函数。他们有github页面吗?这个库很旧,但仍然可以使用。它并没有官方的github页面,但这里有一个源代码:oh-wow,这很旧,OGL2.1。TBH我会放弃那个库,要么创建自己的库,要么看看其他库,因为它太旧了。也许可以看看这个:上面的一个已经9岁了,是OGL 4.2
public static string Hello = "Hello";
public static string AppName = "DrawHello Program";
public static string ClassName = "DrawHelloClass";
public static int screenx = 250;
public static int screeny = 250;
public static int width = 640;
public static int height = 480;
public static IntPtr hWnd;
public static IntPtr renderingContext = IntPtr.Zero;
public static IntPtr deviceContext = IntPtr.Zero;
public static byte accumBits = 0; // Accumulation buffer bits
public static byte colorBits = 32; // Color buffer bits
public static byte depthBits = 16; // Depth buffer bits
public static byte stencilBits = 0; // Stencil buffer bits
public static int logScaleX = 96; // DPI Resolution in X dir
public static int logScaleY = 96;
public static void redraw()
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex3f(0.5F, 0.5F, 0.5F); Gl.glVertex3f(-0.5F, 0.5F, 0.5F);
Gl.glVertex3f(-0.5F, -0.5F, 0.5F); Gl.glVertex3f(0.5F, -0.5F, 0.5F);
Gl.glVertex3f(-0.5F, -0.5F, -0.5F); Gl.glVertex3f(-0.5F, 0.5F, -0.5F);
Gl.glVertex3f(0.5F, 0.5F, -0.5F); Gl.glVertex3f(0.5F, -0.5F, -0.5F);
Gl.glVertex3f(0.5F, 0.5F, 0.5F); Gl.glVertex3f(0.5F, 0.5F, -0.5F);
Gl.glVertex3f(-0.5F, 0.5F, -0.5F); Gl.glVertex3f(-0.5F, 0.5F, 0.5F);
Gl.glVertex3f(-0.5F, -0.5F, -0.5F); Gl.glVertex3f(0.5F, -0.5F, -0.5F);
Gl.glVertex3f(0.5F, -0.5F, 0.5F); Gl.glVertex3f(-0.5F, -0.5F, 0.5F);
Gl.glVertex3f(0.5F, 0.5F, 0.5F); Gl.glVertex3f(0.5F, -0.5F, 0.5F);
Gl.glVertex3f(0.5F, -0.5F, -0.5F); Gl.glVertex3f(0.5F, 0.5F, -0.5F);
Gl.glVertex3f(-0.5F, -0.5F, -0.5F); Gl.glVertex3f(-0.5F, -0.5F, 0.5F);
Gl.glVertex3f(-0.5F, 0.5F, 0.5F); Gl.glVertex3f(-0.5F, 0.5F, -0.5F);
Gl.glEnd();
}
[STAThread]
static void Main()
{
Win32.MSG Msg = new Win32.MSG();
int rv;
if (Program.RegisterClass() == 0)
return;
if (Program.Create() == 0)
return;
// Main message loop:
while ((rv = Win32.GetMessage(out Msg, IntPtr.Zero, 0, 0)) > 0)
{
Win32.TranslateMessage(ref Msg);
Win32.DispatchMessage(ref Msg);
}
}
private static int RegisterClass()
{
Win32.WNDCLASSEX wcex = new Win32.WNDCLASSEX();
wcex.style = Win32.ClassStyles.DoubleClicks;
wcex.cbSize = (uint)Marshal.SizeOf(wcex);
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hIcon = Win32.LoadIcon(IntPtr.Zero, (IntPtr)Win32.IDI_APPLICATION);
wcex.hCursor = Win32.LoadCursor(IntPtr.Zero, (int)Win32.IDC_ARROW);
wcex.hIconSm = IntPtr.Zero;
wcex.hbrBackground = (IntPtr)(10);
wcex.lpszMenuName = null;
wcex.lpszClassName = ClassName;
if (Win32.RegisterClassEx(ref wcex) == 0)
{
Win32.MessageBox(IntPtr.Zero, "RegisterClassEx failed", AppName,
(int)(Win32.MB_OK | Win32.MB_ICONEXCLAMATION | Win32.MB_SETFOREGROUND));
return (0);
}
return (1);
}
private static int Create()
{
hWnd = Win32.CreateWindowEx(0, ClassName, AppName, Win32.WS_OVERLAPPEDWINDOW | Win32.WS_VISIBLE,
screenx, screeny, width, height, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
InitializeContexts();
if (hWnd != IntPtr.Zero)
return (1);
Win32.MessageBox(IntPtr.Zero, "CreateWindow failed", AppName,
(int)(Win32.MB_OK | Win32.MB_ICONEXCLAMATION | Win32.MB_SETFOREGROUND));
return (0);
}
private static IntPtr WndProc(IntPtr hWnd, uint message, IntPtr wParam, IntPtr lParam)
{
switch (message)
{
case Win32.WM_PAINT:
{
IntPtr hDC;
Win32.PAINTSTRUCT ps = new Win32.PAINTSTRUCT();
hDC = Win32.BeginPaint(hWnd, out ps);
redraw();
Gdi.SwapBuffersFast(deviceContext);
Win32.EndPaint(hWnd, ref ps);
return IntPtr.Zero;
}
case Win32.WM_DESTROY:
DestroyContexts();
Win32.PostQuitMessage(0);
return IntPtr.Zero;
//case Win32.WM_CREATE:
// return IntPtr.Zero;
default:
return (Win32.DefWindowProc(hWnd, message, wParam, lParam));
}
}
public static void MakeCurrent()
{
Wgl.wglMakeCurrent(deviceContext, renderingContext);
}
public static void InitializeContexts()
{
int pixelFormat;
Gdi.PIXELFORMATDESCRIPTOR pfd = new Gdi.PIXELFORMATDESCRIPTOR();// The pixel format descriptor
pfd.nSize = (short)Marshal.SizeOf(pfd); // Size of the pixel format descriptor
pfd.nVersion = 1; // Version number (always 1)
pfd.dwFlags = Gdi.PFD_DRAW_TO_WINDOW | // Format must support windowed mode
Gdi.PFD_SUPPORT_OPENGL | // Format must support OpenGL
Gdi.PFD_DOUBLEBUFFER; // Must support double buffering
pfd.iPixelType = (byte)Gdi.PFD_TYPE_RGBA; // Request an RGBA format
pfd.cColorBits = (byte)colorBits; // Select our color depth
pfd.cRedBits = 0; // Individual color bits ignored
pfd.cRedShift = 0;
pfd.cGreenBits = 0;
pfd.cGreenShift = 0;
pfd.cBlueBits = 0;
pfd.cBlueShift = 0;
pfd.cAlphaBits = 0; // No alpha buffer
pfd.cAlphaShift = 0; // Alpha shift bit ignored
pfd.cAccumBits = accumBits; // Accumulation buffer
pfd.cAccumRedBits = 0; // Individual accumulation bits ignored
pfd.cAccumGreenBits = 0;
pfd.cAccumBlueBits = 0;
pfd.cAccumAlphaBits = 0;
pfd.cDepthBits = depthBits; // Z-buffer (depth buffer)
pfd.cStencilBits = stencilBits; // No stencil buffer
pfd.cAuxBuffers = 0; // No auxiliary buffer
pfd.iLayerType = (byte)Gdi.PFD_MAIN_PLANE; // Main drawing layer
pfd.bReserved = 0; // Reserved
pfd.dwLayerMask = 0; // Layer masks ignored
pfd.dwVisibleMask = 0;
pfd.dwDamageMask = 0;
deviceContext = User.GetDC(hWnd);
pixelFormat = Gdi.ChoosePixelFormat(deviceContext, ref pfd);
logScaleX = Gdi.GetDeviceCaps(deviceContext, (int)Gdi.DevCaps.LOGPIXELSX);
logScaleY = Gdi.GetDeviceCaps(deviceContext, (int)Gdi.DevCaps.LOGPIXELSY);
renderingContext = Wgl.wglCreateContext(deviceContext);
MakeCurrent();
Kernel.SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
}
public static void DestroyContexts()
{
Wgl.wglMakeCurrent(IntPtr.Zero, IntPtr.Zero);
Wgl.wglDeleteContext(renderingContext);
User.ReleaseDC(hWnd, deviceContext);
renderingContext = IntPtr.Zero;
deviceContext = IntPtr.Zero;
}