【问题标题】:EXCEPTION_ACCESS_VIOLATION on glDrawElements when using Windows使用 Windows 时 glDrawElements 上的 EXCEPTION_ACCESS_VIOLATION
【发布时间】:2018-09-30 04:26:53
【问题描述】:

我正在使用 Java 8 和 LWJGL 制作带有 GLFW 和 OpenGL 的游戏引擎。我有一个通用的 IndexedVAO 类,其中包含我所有的 VAO 代码以简化事情。以下是相关部分:

构造函数

    GL30.glBindVertexArray(vertexArrayObject);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferObject);
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
    for(VertexAttribPointer prr : format.parts) {
        GL20.glEnableVertexAttribArray(prr.index);
        GL20.glVertexAttribPointer(prr.index, prr.size, prr.type,
            prr.normalized, prr.stride, prr.ptr);
    }
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    GL30.glBindVertexArray(0);

上传功能

    data.flip();
    index.flip();
    this.numberOfIndicies = index.limit() / 2;
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferObject);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, data, bufferUse);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
    GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, index, bufferUse);
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);

绘图功能

    GL30.glBindVertexArray(vertexArrayObject);
    GL11.glDrawElements(this.drawmode, this.numberOfIndicies, GL11.GL_UNSIGNED_SHORT, 0L);
    GL30.glBindVertexArray(0);

该代码在 linux 上运行良好,但今天我在 windows 机器上尝试了它并得到了 EXCEPTION_ACCESS_VIOLATION jvm 崩溃。当我检查 JVM 崩溃时生成的 hs_err_pid#### 文件时,我发现错误是由调用 glDrawElements 引起的。这是整个应用程序中的第一个 glDrawElements 调用,注释掉它只是将异常移到下一个。我整个下午都在移动代码并进行研究,但我一无所获。它与着色器无关,glDrawArrays 在它的位置上工作,并且考虑到它在 linux 上运行良好意味着它与任何顶点生成代码无关,因为它们都是相同的 java 代码。

两台机器之间的一个主要硬件差异是windows机器有一个较旧的radeon显卡,而linux机器有一个最近的geforce卡,两者都有最新的驱动程序。我在 radeon 机器上启动了 linux,看看是否是供应商之间的不一致,但是当我等待 30 分钟让 java 安装一切正常时,这意味着这是特定于操作系统的。为了验证我让我的朋友在他的 Windows 10 机器上测试它,他也得到了 EXCEPTION_ACCESS_VIOLATION。

TL; DR:上面的代码在 linux 上工作,但在 windows 上会导致 EXCEPTION_ACCESS_VIOLATION jvm 崩溃

【问题讨论】:

  • 您是否有有效的 OpenGL 上下文 > 3.0 请求? @Spektre:是的,您可以在没有证据的情况下抱怨窗户并声称(错误的)事情,或者您可以尝试帮助操作。
  • @BDL 如果您仔细观察,我试图提供帮助...解决方案是重新安装正确的 gfx 驱动程序。这现在是 Win10 的一个臭名昭著的“错误”……除此之外(他们现在对驱动程序做了什么是可怕的)
  • draw 函数中的 ACCESS_VIOLATION 通常有以下两个原因之一:1)draw 函数本身未加载,因此程序尝试执行空函数指针,或 2)draw 函数尝试访问超出其大小的缓冲区。不幸的是,我们看不到任何在 VAO 设置中传递的值,也看不到绘制了哪些数据。
  • @Spektre 是的,两台 Windows 机器都使用供应商特定的驱动程序,而不是 Windows 更新驱动程序。
  • @BDL 我在 glfw 窗口提示中请求 opengl 3.3 上下文并打印 opengl 版本说它是两台机器上的 3.3 核心配置文件

标签: java opengl lwjgl glfw


【解决方案1】:

感谢@derhass 和@Spektre,问题在于 AMD 的 Windows 驱动程序无法正确处理未在 4 字节边界上对齐的顶点组件,因此使用字节存储法线或 rgb 颜色会使驱动程序崩溃,因为组件只有三个字节长。奇怪的是,即使它是读取顶点数据的同一张卡,它如何在 linux 上工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多