0

当我调用“glXChooseVisual”(在 C# 中也称为 GLX.ChooseVisual)时,它返回一个空 IntPtr。现在让我感到困惑的是,当我构建 NeHe 课程 02 时,基本上使用它工作的相同代码(它是用 C 编写的唯一区别)。

此外,当我从 OpenTK 进入代码并找到它何时调用“glXChooseVisual”时,它会返回一个有效的 Visual ptr,但我目前还找不到任何我丢失的东西。

另外,让我感到困扰的是,我在一年前就曾做过这项工作。我这样做的原因是为了一个跨平台的 API,它不仅限于 OpenGL,所以任何帮助都会很棒。

我已经在 [Ubuntu 11.10 Nvidia 5700] 和 [Fedora 16 Nvidia 6100] 上尝试了所有这些,但它们都失败了。您可以在 Mono-C# 控制台应用程序中复制并粘贴此代码以对其进行测试。

using System;
using System.Runtime.InteropServices;

namespace TestGL
{
    static class GLX
    {
        [DllImport("libX11", EntryPoint = "XOpenDisplay", ExactSpelling = true)]
        public static extern IntPtr XOpenDisplay(IntPtr display_name);

        [DllImport("libX11", EntryPoint = "XDefaultScreen", ExactSpelling = true)]
        public static extern int XDefaultScreen(IntPtr dpy);

        [DllImport("libGL", EntryPoint = "glXChooseVisual", ExactSpelling = true)]
        public static extern IntPtr ChooseVisual(IntPtr dpy, int screen, int[] attribList);

        public const int RGBA   =   4;
        public const int DOUBLEBUFFER   =5;
        public const int RED_SIZE   =   8;
        public const int GREEN_SIZE =   9;
        public const int BLUE_SIZE  =   10;
        public const int ALPHA_SIZE =   11;
        public const int DEPTH_SIZE =   12;
        public const int None = 0x8000;
    }

    class MainClass
    {
        public static void Main (string[] args)
        {
            Console.WriteLine ("Hope this works!");

            //Get DC
            IntPtr dc = GLX.XOpenDisplay(new IntPtr(0));
            int screen = GLX.XDefaultScreen(dc);

            //Set BackBuffer format
            int[] attrListDbl =
            {
                GLX.RGBA,
                GLX.DOUBLEBUFFER,
                GLX.RED_SIZE, 8,
                GLX.GREEN_SIZE, 8,
                GLX.BLUE_SIZE, 8,
                GLX.DEPTH_SIZE, 16,
                0
            };

            IntPtr visual = GLX.ChooseVisual(dc, screen, attrListDbl);
            if (visual == IntPtr.Zero)
            {
                int[] attrListSgl =
                {
                    GLX.RGBA,
                    GLX.RED_SIZE, 8,
                    GLX.GREEN_SIZE, 8,
                    GLX.BLUE_SIZE, 8,
                    GLX.DEPTH_SIZE, 16,
                    0
                };

                visual = GLX.ChooseVisual(dc, screen, attrListSgl);
            }

            if (visual == IntPtr.Zero) 
            {
                Console.WriteLine("Failed to get visual."); 
            }
            else
            {
                Console.WriteLine("Yahoo.");    
            }

            //ctx = GLX.CreateContext(dc, visual, new IntPtr(0), true);
            //GLX.MakeCurrent(dc, handle, ctx);
        }
    }
}
4

2 回答 2

0

您不需要指定调用约定吗?像这样:

[DllImport("libGL", ... , CallingConvention=CallingConvention.Cdecl)]

您还可以检查您的前两个调用是否返回有意义的(非零)值。

于 2012-01-05T16:04:56.923 回答
0

我发现了这个问题。不知道为什么我一年前没有这个问题,但我只需将“libGL”更改为“libgl.so.1”就可以了。

于 2012-01-06T06:13:57.293 回答