【问题标题】:Opengl/SDL2 Help on accessviolation error on nivida cards关于 nvidia 卡上的访问冲突错误的 Opengl/SDL2 帮助
【发布时间】:2018-09-05 17:42:31
【问题描述】:

所以我的代码是

GLCore.TriFromRect(rect1,ref cords);
GLCore.glVertexPointer(2,GlEnums.GL_FLOAT,0,cords);
GLCore.glDrawArrays(GlEnums.GL_TRIANGLES,0,6);

用于绘制矩形。 我正在遵守 opengl 2.0 版,这是我想要支持的版本。 我上面的当前代码适用于使用外部英特尔、ati 和板载英特尔或 ati 显卡的任何其他计算机。

glDrawArrays 函数如何让我在 nivida 卡(例如我的朋友 titan 和 2005 年的 430 geforce)上出现访问冲突。

知道怎么了?

感谢您的宝贵时间。 SDL2 设置为请求 2.0 GL 上下文 并且 nivida 和 intel 卡返回 2.1,而 ati 返回 2.0

GLEnv 设置

//Enable Double Buffering. 1=True 0=False
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DOUBLEBUFFER,1);
//Set the Major and Minor Requested version to 2.0
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION,2);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION,0);
//Keep the GL Context;
GLContext=SDL.SDL_GL_CreateContext(window);
if (GLContext==IntPtr.Zero){
    throw new Exception("Failed to create GL context:"+SDL.SDL_GetError());
}else{
    //Keep a copy of the window handle
    GLWindow=window;
    //Show the window.
    SDL.SDL_ShowWindow(window);
    //Load GL Functions
    Load_GlFunctions();
    //Set Clear Color [Currently White]
    glClearColor(1f,1f,1f,1f);
    //Flush the graphic buffer.
    Flush();
    //Present the buffer.
    Present();
    //Tell the FrontEnd we are ready.
    GLInit=true;
}

编辑 GLCore 的重要部分

internal delegate void Gl3i1p(int i1,int i2,int i3,IntPtr val);
internal delegate void Gl3i1fa(int i1,int i2,int i3,float[] val);
internal delegate void Gl3i(int i1,int i2,int i3);
internal delegate void Gl1i(int i1);
internal static float[255] cords = new float[255];

public static void Flush() {
    GLCore.glClear(GlEnums.GL_COLOR_BUFFER_BIT | GlEnums.GL_DEPTH_BUFFER_BIT);
}

public static void Present() {
    SDL.SDL_GL_SwapWindow(GLCore.GLWindow);
}

internal static T LoadUnmanagedFunction<T>(IntPtr functionpointer){
    var val = Marshal.GetDelegateForFunctionPointer(functionpointer,typeof(T));
    return (T)Convert.ChangeType(val,typeof(T));
}

internal static Gl1i glEnableClientState;
internal static Gl3i1fa glVertexPointer;
internal static Gl3i1fa glTexCoordPointer;
internal static Gl3i glDrawArrays;

private static void Load_GlFunctions(){
    glEnableClientState = LoadUnmanagedFunction<Gl1i>(SDL.SDL_GL_GetProcAddress("glEnableClientState"));
    glVertexPointer = LoadUnmanagedFunction<Gl3i1fa>(SDL.SDL_GL_GetProcAddress("glVertexPointer"));
    glTexCoordPointer = LoadUnmanagedFunction<Gl3i1fa>(SDL.SDL_GL_GetProcAddress("glTexCoordPointer"));
    glDrawArrays = LoadUnmanagedFunction<Gl3i>(SDL.SDL_GL_GetProcAddress("glDrawArrays"));
}

internal static void TranglesFromRect(float x1,float y1,float x2,float y2,ref float[] fill){
    float tmp=0f;
    if (x1 > x2) {
        tmp = x2;
        x2  = x1;
        x1  = tmp;
    }
    if (y1 > y2) {
        tmp = y2;
        y2  = y1;
        y1  = tmp;
    }
    fill[0]  = x1;
    fill[1]  = y1;
    fill[2]  = x2;
    fill[3]  = y1;
    fill[4]  = x2;
    fill[5]  = y2;
    fill[6]  = x2;
    fill[7]  = y2;
    fill[8]  = x1;
    fill[9]  = y2;
    fill[10] = x1;
    fill[11] = y1;
}

【问题讨论】:

  • 是的,我试图让阵列保持活动状态。 cords 是 255 glVertexPointer 的静态浮点数组,使用 marshalas 将数组作为指针传递
  • 请发布用于设置 OGL 环境的 SDL2 命令。
  • @Ripi2 添加为编辑
  • 您要求 SDL 提供 OGL 2.1 版本,而不是 2.0
  • 无粘贴箱。至少将相关函数添加到问题本身,以便我们可以看到真正被调用的内容。并且还请添加cords 的定义(或至少它包含的内容)。以我们现在所拥有的,不可能重现该问题。

标签: c# opengl


【解决方案1】:

glDrawArrays() 从 OpenGL 1.1 开始存在。 Windows 支持此版本,无需获取指向它的函数指针。只需将其用作您首选语言的任何其他常用功能即可。

实际上,尝试使用“GetProcAddress()”方法获取函数指针可能会返回一个空指针,这会导致它一被调用就崩溃。

话虽如此,一些图形驱动程序可能会为每个 OGL 1.1 命令公开一个函数指针。因此,使用 GetProcAddress 可能会返回一个有效的指针。这就解释了为什么您的代码在某些机器上可以工作,而在其他机器上却不行。

我的建议是:不要对 OGL 1.1 中存在的命令使用函数指针

【讨论】:

  • 当我回到家时我会放弃这个。在我的尼维达塔上
  • 不,那没用。 Dllimport 加载它没有问题,英特尔卡可以工作,但它仍然在 nivida 上崩溃
  • 请编辑您的问题并将代码发布到指向glDrawArrays 的位置。这个SO answer 可能会有所帮助。
  • 我觉得这个答案有点误导。当您谈论GetProcAddress 时,您实际上是指wglGetProcAddress()。标准窗口GetProcAddress() 函数实际上将能够加载从opengl32.dll 导出的GL 1.0 和1.1 函数指针。
  • 此外,我的建议是相反的:为每个 GL 函数使用函数指针,甚至不要链接 OpenGL 库。只需在运行时加载它。像 GLAD 这样的 GL 加载器将处理在某些情况下需要两个不同的 GetProcAddress 函数的肮脏细节。但是,这只是我的观点,因此与堆栈溢出无关。
【解决方案2】:

我终于修好了。

在 nivida 上,2D 系统不适用于我的卡片。以 0 表示 Z 传递我的 3D 三角形修复了我的问题并将我的 glDrawArrays 更改为使用 3 而不是 2

感谢那些试图提供帮助的人。

【讨论】:

    猜你喜欢
    • 2021-06-27
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多