C#Win32:窗口将不显示OpenGL

时间:2020-07-29 22:24:45

标签: c# opengl

使用Tao框架,OpenGL / WGL / WinAPI的C#绑定,我试图使空白的WinAPI窗口显示OpenGL图形。此代码似乎不起作用。窗口打开,但是什么也没画。大多数OpenGL / GDI代码都是从Tao的 SimpleOpenGLControl UserControl镜像的。

Tao & Custom Win32 Wrappers

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;
    }


有人知道我做错了吗?

0 个答案:

没有答案
相关问题