使用Windows时在glDrawElements上使用EXCEPTION_ACCESS_VIOLATION

时间:2018-09-30 04:26:53

标签: java opengl lwjgl glfw

我正在使用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安装一切正常时,这意味着这是特定于OS的。为了验证我让我的朋友在他的Windows 10计算机上对其进行了测试,并且他还获得了EXCEPTION_ACCESS_VIOLATION。

TL; DR:上面的代码在Linux上有效,但在Windows上会导致EXCEPTION_ACCESS_VIOLATION jvm崩溃

1 个答案:

答案 0 :(得分:1)

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