OpenGL渲染顺序(EXCEPTION_ACCESS_VIOLATION)

时间:2018-12-01 02:08:46

标签: java opengl lwjgl

我正在尝试渲染2D正方形,但是我的程序崩溃了。我认为我的方法顺序不正确。我正在使用LWJGL3,以及jars Lwjgl,GLFW和OpenGL。 stacktrace显示错误是EXCEPTION_ACCESS_VIOLATION,并且错误是在第一个openGL函数上(取决于哪个是第一个)(在当前代码中是GL20.glGetAttribLocation()(在此处的指导https://github.com/SilverTiger/lwjgl3-tutorial/wiki/Rendering之后) 我也没有使用legacyGL

如果您遇到此问题: 添加行GLFW.makeContextCurrent(window)和Gl.createCapabilities()

主要:

public class DungeonRunners {
private double lastTick;

private float timeCount;

private int fps;
private int fpsCount;
private int ups;
private int upsCount;

public static void main(String[] args) {
    System.out.println("LWJGL Version: " + Version.getVersion());
    int width = 1240;
    int height = 720;
    boolean legacyGL = false;
    for (int i = 0; i < args.length; i++) {
        String arg = args[i];
        if(arg.equals("width:")) {
            try {
                width = Integer.parseInt(args[i+1]);
                i++;
            } catch (NumberFormatException ignored) { }
        } else if(arg.equals("height:")) {
            try {
                height = Integer.parseInt(args[i+1]);
            } catch (NumberFormatException ignored) { }
        } else if(arg.equals("-useLegacyGL")) {
            legacyGL = true;
        }
    }
    DungeonRunners dungeonRunners = new DungeonRunners();
    dungeonRunners.start(width, height, legacyGL);
}

private void start(int width, int height, Boolean legacyGL) {
    long window;
    GLFW.glfwInit();
    if(!legacyGL) {
        GLFW.glfwDefaultWindowHints();
        GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
        GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);
        GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
        GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GLFW.GLFW_TRUE);
        window = GLFW.glfwCreateWindow(width, height, "Dungeon Runners", MemoryUtil.NULL, MemoryUtil.NULL);
    } else {
        GLFW.glfwDefaultWindowHints();
        GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 2);
        GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 1);
        window = GLFW.glfwCreateWindow(width, height, "Dungeon Runners", MemoryUtil.NULL, MemoryUtil.NULL);
    }
    RenderEngine engine = new RenderEngine(legacyGL);
    while(!GLFW.glfwWindowShouldClose(window)) {
        update();
        engine.frame();
    }
}

private void update() {
    if (timeCount > 1f) {
        fps = fpsCount;
        fpsCount = 0;

        ups = upsCount;
        upsCount = 0;

        timeCount -= 1f;
    }
}

private float getDelta() {
    double time = getTime();
    float delta = (float) (time - lastTick);
    lastTick = time;
    timeCount += delta;
    return delta;
}

public double getTime() {
    return System.nanoTime() / 1000000000.0;
}

private void updateFPS() {
    fpsCount++;
}

private void updateUPS() {
    upsCount++;
}
}

代码很容易解释,这是我的RenderEngine类:

public class RenderEngine {

private int shaderProgram;

public RenderEngine(Boolean legacyGL) {
    setVertexAttribs();
    bindImage();
    int vao = GL30.glGenVertexArrays();
    GL30.glBindVertexArray(vao);
    setupShaders(legacyGL);
    GL20.glUseProgram(shaderProgram);
    setUniformVars();
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
    GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 3);
}

private void bindImage() {
    try (MemoryStack stack = MemoryStack.stackPush()) {
        FloatBuffer vertices = stack.mallocFloat(3 * 6);
        vertices.put(-0.6f).put(-0.4f).put(0f).put(1f).put(0f).put(0f);
        vertices.put(0.6f).put(-0.4f).put(0f).put(0f).put(1f).put(0f);
        vertices.put(0f).put(0.6f).put(0f).put(0f).put(0f).put(1f);
        vertices.flip();
        int vbo = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);
        MemoryStack.stackPop();
    }
}

public void frame() {

}

private void setUniformVars() {
    int uniModel = GL20.glGetUniformLocation(shaderProgram, "model");
    UtilMatrix4f model = new UtilMatrix4f();
    GL20.glUniformMatrix4fv(uniModel, false, model.getBuffer());

    int uniView = GL20.glGetUniformLocation(shaderProgram, "view");
    UtilMatrix4f view = new UtilMatrix4f();
    GL20.glUniformMatrix4fv(uniView, false, view.getBuffer());

    int uniProjection = GL20.glGetUniformLocation(shaderProgram, "projection");
    float ratio = 640f / 480f;
    UtilMatrix4f projection = UtilMatrix4f.orthographic(-ratio, ratio, -1f, 1f, -1f, 1f);
    GL20.glUniformMatrix4fv(uniProjection, false, projection.getBuffer());
}

private void setVertexAttribs() {
    int floatSize = 4;
    int posAttrib = GL20.glGetAttribLocation(shaderProgram, "position");
    GL20.glEnableVertexAttribArray(posAttrib);
    GL20.glVertexAttribPointer(posAttrib, 3, GL11.GL_FLOAT, false, 6 * floatSize, 0);
    int colAttrib = GL20.glGetAttribLocation(shaderProgram, "color");
    GL20.glEnableVertexAttribArray(colAttrib);
    GL20.glVertexAttribPointer(colAttrib, 3, GL11.GL_FLOAT, false, 6 * floatSize, 3 * floatSize);
}

private void setupShaders(boolean legacyGL) {
    int vertexShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
    if(legacyGL)
        GL20.glShaderSource(vertexShader, "src\\main\\java\\bigbade\\dungeonrunners\\renderer\\shaders\\legacyVertexShader.txt");
    else
        GL20.glShaderSource(vertexShader, "src\\main\\java\\bigbade\\dungeonrunners\\renderer\\shaders\\vertexShader.txt");
    GL20.glCompileShader(vertexShader);
    int status = GL20.glGetShaderi(vertexShader, GL20.GL_COMPILE_STATUS);
    if (status != GL11.GL_TRUE) {
        throw new RuntimeException(GL20.glGetShaderInfoLog(vertexShader));
    }
    int fragmentShader = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
    if(legacyGL)
        GL20.glShaderSource(vertexShader, "src\\main\\java\\bigbade\\dungeonrunners\\renderer\\shaders\\legacyFragmentShader.txt");
    else
        GL20.glShaderSource(fragmentShader, "src\\main\\java\\bigbade\\dungeonrunners\\renderer\\shaders\\fragmentShader.txt");
    GL20.glCompileShader(fragmentShader);
    status = GL20.glGetShaderi(fragmentShader, GL20.GL_COMPILE_STATUS);
    if (status != GL11.GL_TRUE) {
        throw new RuntimeException(GL20.glGetShaderInfoLog(fragmentShader));
    }
    shaderProgram = GL20.glCreateProgram();
    GL20.glAttachShader(shaderProgram, vertexShader);
    GL20.glAttachShader(shaderProgram, fragmentShader);
    GL30.glBindFragDataLocation(shaderProgram, 0, "fragColor");
    GL20.glLinkProgram(shaderProgram);
    status = GL20.glGetProgrami(shaderProgram, GL20.GL_LINK_STATUS);
    if (status != GL11.GL_TRUE) {
        throw new RuntimeException(GL20.glGetProgramInfoLog(shaderProgram));
    }
}
}

0 个答案:

没有答案