Java 在 LWJGL 中加载纹理时发生致命的运行时错误

Java fatal runtime error while loading texture in LWJGL

由于 ig7icd64.dll 文件中的 EXCEPTION_ACCESS_VIOLATION,我的程序崩溃了。

我正在使用 LWJGL 库和此处找到的一些外部 jar 创建一个简单的项目:https://github.com/CodingAP/LWJGL-3-Tutorial.git(仅使用 slick-util3)以及从资源文件 ('.png') 加载纹理时程序崩溃。

我有很多 classes 正在使用很多 GLXX.gl[function_name_here], 但我会解释为什么我没有列出所有这些。

我创建了一个 window 和一个 Window class,它只是设置了一个 GLFW 上下文并且工作得很好。

我有一个模型 class,它由 UntexturedModel 和 TexturedModel 扩展。这些设置 VertexArrays 和 VertexBuffers 并正常运行。 我什至有一个着色器 class,它读取两个着色器文件并正确应用它们。

public class UntexturedModel extends Model {

private int vertexArrayID, vertexBufferID, indicesBufferID, vertexCount;

public UntexturedModel(float[] vertices, int[] indices) {
    vertexArrayID = super.createVertexArray();
    indicesBufferID = super.bindIndicesBuffer(indices);
    vertexBufferID = super.storeData(0, 3, vertices);
    vertexCount = indices.length;
    GL30.glBindVertexArray(0);
}

public void destroy () {
    GL30.glDeleteVertexArrays(vertexArrayID);
    GL15.glDeleteBuffers(vertexBufferID);
    GL15.glDeleteBuffers(indicesBufferID);
}

// I have not included the getters for the IDs due to the space available
}

这扩展了以下模型 class:

public class Model {

protected int createVertexArray() {
    int vertexArrayID = GL30.glGenVertexArrays();
    GL30.glBindVertexArray(vertexArrayID);
    return vertexArrayID;
}

protected int storeData (int attributeNumber, int coordSize, float[] data) {

    FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
    buffer.put(data);
    buffer.flip();

    int bufferID = GL15.glGenBuffers();
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferID);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);

    GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);

    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

    return bufferID;
}

protected int bindIndicesBuffer (int[] indices) {

    IntBuffer buffer = BufferUtils.createIntBuffer(indices.length);
    buffer.put(indices);
    buffer.flip();

    int bufferID = GL15.glGenBuffers();
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, bufferID);
    GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);

    return bufferID;
}
}

TexturedModel 在本质上与 UntexturedModel 相同,但有一个额外的 float[] textureCoords,它是使用 storeData(1, 2, textureCoords) 添加的;它还具有使用外部 jars 的属性 Material:

public class Material {

private int textureID;

public Material (String file) {
    try {

        textureID = TextureLoader.getTexture("png", new FileInputStream("res/" + file)).getTextureID();
        // Possible error location: TextureLoader is an external jar

    } catch (IOException e) {
        System.err.println("Error: Couldn't load texture");
        System.exit(-1);
    }
}

public void destroy () {
    GL11.glDeleteTextures(textureID);
}
// I'm ignoring getters once again
}

使用 UntexturedModel class 效果很好,即使是着色器文件。我将在下面包含 BasicShader 和 Shader classes:

public abstract class Shader {

private int vertexShaderID, fragmentShaderID, programID;
private String vertexFile, fragmentFile;

public Shader (String vertexFile, String fragmentFile) {
    this.vertexFile = vertexFile;
    this.fragmentFile = fragmentFile;
}

public void create () {
    programID = GL20.glCreateProgram();

    vertexShaderID = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);

    GL20.glShaderSource(vertexShaderID, readFile(vertexFile));
    GL20.glCompileShader(vertexShaderID);

    if (GL20.glGetShaderi(vertexShaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
        System.err.println("Error: Vertex Shader - " + GL20.glGetShaderInfoLog(vertexShaderID));
    }

    fragmentShaderID = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);

    GL20.glShaderSource(fragmentShaderID, readFile(fragmentFile));
    GL20.glCompileShader(fragmentShaderID);

    if (GL20.glGetShaderi(fragmentShaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
        System.err.println("Error: Fragment Shader - " + GL20.glGetShaderInfoLog(fragmentShaderID));
    }

    GL20.glAttachShader(programID, vertexShaderID);
    GL20.glAttachShader(programID, fragmentShaderID);

    GL20.glLinkProgram(programID);

    if (GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS) == GL11.GL_FALSE) {
        System.err.println("Error: Program Linking - " + GL20.glGetShaderInfoLog(programID));
    }

    GL20.glValidateProgram(programID);

    if (GL20.glGetProgrami(programID, GL20.GL_VALIDATE_STATUS) == GL11.GL_FALSE) {
        System.err.println("Error: Program Validation - " + GL20.glGetShaderInfoLog(programID));
    }
}

public abstract void bindAllAttributes();

public void bindAttribute (int index, String location) {
    GL20.glBindAttribLocation(programID, index, location);
}

public void bind () {
    GL20.glUseProgram(programID);
}

public void destroy () {
    GL20.glDetachShader(programID, vertexShaderID);
    GL20.glDetachShader(programID, fragmentShaderID);

    GL20.glDeleteShader(vertexShaderID);
    GL20.glDeleteShader(fragmentShaderID);

    GL20.glDeleteProgram(programID);
}

private String readFile (String path) {
    BufferedReader reader;
    StringBuilder builder = new StringBuilder();

    try {

        reader = new BufferedReader(new FileReader(path));

        String line = reader.readLine();

        while (line != null) {

            builder.append(line + '\n');
            line = reader.readLine();
        }

    } catch (IOException e) {
        System.err.println("Error: Exception while reading from file");
    }

    return builder.toString();
}
}

public class BasicShader extends Shader {

private static final String VERTEX_FILE = ".\src\shaders\basicVertexShader.vs";
private static final String FRAGMENT_FILE = ".\src\shaders\basicFragmentShader.fs";

public BasicShader() {
    super(VERTEX_FILE, FRAGMENT_FILE);
}

@Override
public void bindAllAttributes () {
    super.bindAttribute(0, "position");
    super.bindAttribute(1, "textCoords");
}
}

我已经测试了着色器文件(basicVertexShader.vs 和 basicFragmentShader.fs)并且它们按预期工作。

我试过以下方法: 查看 .dll 文件是否被删除。 重新安装 Java(包括 jdk 和 jre) 重新安装 Eclipse 将 Graohics 驱动程序更新为英特尔建议的版本

我正在使用 Windows 10 和 Lenovo Thinkpad。

如果需要任何其他信息,请在下面询问。

更新:

堆栈:[0x0000000002b10000,0x0000000002c10000],sp=0x0000000002c0bf40,空闲 space=1007k 原生框架:(J=编译 Java 代码,j=解释,Vv=VM 代码,C=原生代码)

C [ig7icd64.dll+0x933b0]

C [ig7icd64.dll+0x17b4b2]

C [ig7icd64.dll+0x215514]

C [ig7icd64.dll+0x6d1ee]

C [ig7icd64.dll+0x243745]

C [ig7icd64.dll+0x92555]

C [ig7icd64.dll+0x2a3af8]

C [ig7icd64.dll+0x2a3e09]

C [ig7icd64.dll+0x2a57ba]

C 0x0000000002d88c67

Java 帧:(J=编译 Java 代码,j=解释,Vv=VM 代码)

j org.lwjgl.opengl.GL11C.nglDrawElements(IIIJ)V+0

j org.lwjgl.opengl.GL11C.glDrawElements(IIIJ)V+4

j org.lwjgl.opengl.GL11.glDrawElements(IIIJ)V+4

j render.Renderer.renderTexturedModel(Lrender/TexturedModel;)V+43(渲染器是一个 class,它只执行 glDrawElements() 函数;没什么特别的)

j main.Main.main([Ljava/lang/String;)V+191

v ~StubRoutines::call_stub

更新: 我解决了这个问题。它位于 Model.storeData()。我不使用 attributeNumber 或 coordSize。关闭

[关闭] 正如您在我上次编辑中看到的,我的错误在于 Model class。我实际上并没有在 storeData() 函数中使用 indexsize 参数,这意味着我试图将数组存储在同一个列表中,所以程序崩溃了。谢谢大家。