EXCEPTION_ACCESS_VIOLATION 在 glDrawElements 上使用 Windows
EXCEPTION_ACCESS_VIOLATION on glDrawElements when using Windows
我正在使用 Java 8 和 LWJGL 制作带有 GLFW 和 OpenGL 的游戏引擎。我有一个通用的 IndexedVAO class,其中包含我所有的 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 crash
感谢@derhass 和@Spektre,问题是 AMD 的 windows 驱动程序无法正确处理未在 4 字节边界上对齐的顶点组件,因此使用字节来存储法线或 rgb 颜色使驱动程序崩溃,因为该组件只有三个字节长。奇怪的是,它如何在 linux 上工作,即使它是读取顶点数据的同一张卡。
我正在使用 Java 8 和 LWJGL 制作带有 GLFW 和 OpenGL 的游戏引擎。我有一个通用的 IndexedVAO class,其中包含我所有的 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 crash
感谢@derhass 和@Spektre,问题是 AMD 的 windows 驱动程序无法正确处理未在 4 字节边界上对齐的顶点组件,因此使用字节来存储法线或 rgb 颜色使驱动程序崩溃,因为该组件只有三个字节长。奇怪的是,它如何在 linux 上工作,即使它是读取顶点数据的同一张卡。