【问题标题】:OpenGL context not working, but does not throw errorsOpenGL 上下文不工作,但不会抛出错误
【发布时间】:2020-09-09 01:42:37
【问题描述】:

我正在使用带有 OpenGL/Wiggle 的 C# 在本机 Win32 窗口上创建 OpenGL 上下文。我的代码中没有任何错误,但是当我尝试将上下文的背景颜色更改为黑色时,它保持白色。
Main()

static void Main()
    {
        MSG Msg = new MSG();
        int rv;
        if (Program.RegisterClass() == 0)
            return;
        if (Program.Create() == 0)
            return;
        // Main message loop:
        while ((rv = User32.GetMessage(out Msg, IntPtr.Zero, 0, 0)) > 0)
        {
            User32.TranslateMessage(ref Msg);
            User32.DispatchMessage(ref Msg);
        }
    }

RegisterClass()

WNDCLASSEX wcex = new WNDCLASSEX();
        wcex.style = User32.CS.DBLCLKS | User32.CS.HREDRAW | User32.CS.VREDRAW | User32.CS.OWNDC;
        wcex.cbSize = (uint)Marshal.SizeOf(wcex);
        wcex.lpfnWndProc = WndProc;
        wcex.cbClsExtra = 0;
        wcex.cbWndExtra = 0;
        wcex.hIcon = User32.LoadIcon(IntPtr.Zero, (IntPtr)User32.IDI_APPLICATION);
        wcex.hCursor = User32.LoadCursor(IntPtr.Zero, (int)User32.IDC_ARROW);
        wcex.hIconSm = IntPtr.Zero;
        wcex.hbrBackground = (IntPtr)(User32.COLOR_WINDOW + 1);
        wcex.lpszMenuName = null;
        wcex.lpszClassName = "HelloClass";
        if (User32.RegisterClassEx(ref wcex) == 0)
        {
            User32.MessageBox(IntPtr.Zero, "RegisterClassEx failed", "appName",
                (int)(User32.MB_OK | User32.MB_ICONEXCLAMATION | User32.MB_SETFOREGROUND));
            return (0);
        }
        return (1);

创建()

public static int Create() 
    {
        IntPtr fakewnd = User32.CreateWindowEx(
        0,
        "HelloClass",
        "OpenGL Window",
        User32.WS.CLIPSIBLINGS | User32.WS.CLIPCHILDREN,
        0, 0,
        250, 250,
        IntPtr.Zero, IntPtr.Zero,
        IntPtr.Zero, IntPtr.Zero
        );

        IntPtr fakedc = User32.GetDC(fakewnd);
        WGL.MakeCurrent(fakedc, IntPtr.Zero);

        PixelFormatDescriptor desk = new PixelFormatDescriptor(PFD.Default);
        int deskID = DeviceContext.ChoosePixelFormat(fakedc, ref desk);

        DeviceContext.SetPixelFormat(fakedc, deskID, ref desk);         

        IntPtr fakerc = WGL.CreateContext(fakedc);
        if (fakerc == IntPtr.Zero) { throw new Exception("Could not create rendering context."); }

        if (WGL.MakeCurrent(fakedc, fakerc) == false) throw new Exception("Could not make rendering context current.");

        WGL.LoadWGLExtensions();
        WGL.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
        WGL.DeleteContext(fakerc);
        User32.ReleaseDC(fakewnd, fakedc);
        User32.DestroyWindow(fakewnd);

        IntPtr wnd = User32.CreateWindowEx(
            0,
            "HelloClass",
            "OpenGL Window 2",
            User32.WS.CLIPSIBLINGS | User32.WS.CLIPCHILDREN | User32.WS.OVERLAPPEDWINDOW | User32.WS.VISIBLE,
            0, 0,
            250, 250,
            IntPtr.Zero, IntPtr.Zero,
            IntPtr.Zero, IntPtr.Zero
            );
        IntPtr dc = User32.GetDC(wnd);

        Dictionary<WGL.wglPixelFormatAttributeARB, object> attribs = new Dictionary<WGL.wglPixelFormatAttributeARB, object>();
        attribs.Add(WGL.wglPixelFormatAttributeARB.DRAW_TO_WINDOW_ARB, 1);
        attribs.Add(WGL.wglPixelFormatAttributeARB.SUPPORT_OPENGL_ARB, 1);
        attribs.Add(WGL.wglPixelFormatAttributeARB.DOUBLE_BUFFER_ARB, 1);
        attribs.Add(WGL.wglPixelFormatAttributeARB.PIXEL_TYPE_ARB, WGL.wglPixelTypeARB.RGBA_ARB);
        attribs.Add(WGL.wglPixelFormatAttributeARB.ACCELERATION_ARB, WGL.wglAccelerationModeARB.FULL_ACCELERATION_ARB);
        attribs.Add(WGL.wglPixelFormatAttributeARB.COLOR_BITS_ARB, 32);
        attribs.Add(WGL.wglPixelFormatAttributeARB.ALPHA_BITS_ARB, 8);
        attribs.Add(WGL.wglPixelFormatAttributeARB.DEPTH_BITS_ARB, 24);
        attribs.Add(WGL.wglPixelFormatAttributeARB.STENCIL_BITS_ARB, 8);
        attribs.Add(WGL.wglPixelFormatAttributeARB.SAMPLE_BUFFERS_ARB, 1);
        attribs.Add(WGL.wglPixelFormatAttributeARB.SAMPLES_ARB, 4);

        int pixelFormatID;
        bool status = WGL.ChoosePixelFormatARB(dc, attribs, out pixelFormatID);
        if (!status) throw new Exception("Pixel format could not be set.");

        PixelFormatDescriptor ndesk = new PixelFormatDescriptor();
        DeviceContext.DescribePixelFormat(dc, pixelFormatID, 0, out ndesk);
        DeviceContext.SetPixelFormat(dc, pixelFormatID, ref ndesk);
        int major = Gl.GetInteger(GetPName.MajorVersion);
        int minor = Gl.GetInteger(GetPName.MinorVersion);

        int[] contextAttribs = new int[]
        {
            (int)WGL.wglContextAttributeARB.CONTEXT_MAJOR_VERSION_ARB, major,
            (int)WGL.wglContextAttributeARB.CONTEXT_MINOR_VERSION_ARB, minor,
            (int)WGL.wglContextProfileMaskARB.CONTEXT_CORE_PROFILE_BIT_ARB, 0
        };
        IntPtr rc = WGL.CreateContextAttribsARB(dc, IntPtr.Zero, contextAttribs);
        if (rc == null) throw new Exception("Could not create rendering context.");         
        if (!WGL.MakeCurrent(dc, rc)) throw new Exception("Could not make rendering context current.");     
        return 1;       
    }

WndProc(IntPtr, uint, IntPtr, IntPtr)

private static IntPtr WndProc(IntPtr hWnd, uint message, IntPtr wParam, IntPtr lParam)
    {
        switch (message)
        {
            case User32.WM.PAINT:
                {
                    IntPtr hDC;
                    PAINT ps = new PAINT();
                    hDC = User32.BeginPaint(hWnd, out ps);

                    Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
                    Gl.Viewport(0, 0, 250, 250);
                    Gl.ClearColor(0, 0, 0, 1);                  

                    User32.EndPaint(hWnd, ref ps);
                    return IntPtr.Zero;
                }
            case User32.WM.DESTROY:
                //User32.PostQuitMessage(0);
                return IntPtr.Zero;
            //case Win32.WM_CREATE:
            //    return IntPtr.Zero;
            default:
                return (User32.DefWindowProc(hWnd, message, wParam, lParam));
        }
    }

我正在使用自定义 Wiggle/Win32/Gdi 包装器和 OpenGL4CSharp。有谁知道我的代码有什么问题?我已经摆弄了几个小时,但我无法找出问题所在。

【问题讨论】:

  • glClearColor() 应该在 glClear() 之前。 glViewport() 也一样
  • @ScottMudge glViewport 不影响 glClear。 (当然glClearColor 效果glClear
  • @ScottMudge 我尝试了这三行的所有命令,但它仍然没有任何作用。
  • 那么很可能 OpenGL 根本无法正常工作。检查 OpenGL 错误状态。

标签: c# winapi opengl


【解决方案1】:

我发现了问题!问题是我没有正确加载 WGL 扩展。它现在运行良好。

【讨论】:

    猜你喜欢
    • 2015-01-04
    • 2019-12-06
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多