我正在使用lwjgl 3并学习现代的opengl(3)。我想将统一矩阵发送到顶点着色器,以便我可以应用变换。我试过了,程序因这个错误而崩溃

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000073a9820d, pid=8644, tid=2760
#
# JRE version: Java(TM) SE Runtime Environment (8.0_31-b13) (build 1.8.0_31-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.31-b07 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [nvoglv64.DLL+0xd5820d]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# E:\Copy\Code\Personal\atei-graphics\GraphicsProject\hs_err_pid8644.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#


显然我做错了。

问题似乎在这行代码中

    glUniformMatrix4(uniformMatrixLocation, false, mvp.getBuffer());


如果我删除了这一行代码,程序将无错误执行。

我尝试传递对角矩阵以检查问题是否出在矩阵本身上,但我仍然得到相同的结果

mvp是我传递给着色器的对角矩阵。
UniformMatrixLocation保持我在此行代码中找到的位置

    glGetUniformLocation(shaderProgram.programId, "MVP");


它不会返回负数,因此这里可能没有错误。

我正在将此库用于Mat4类
https://github.com/jroyalty/jglm

Bellow是我的代码的一个“可行的”示例,我所能获得的规模很小。

    //glfw create windows and etc

    int programId = glCreateProgram();

    int vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShaderId, FileUtils.readFile("shaders/vertex.glsl"));
    glCompileShader(vertexShaderId);
    if (glGetShaderi(vertexShaderId, GL_COMPILE_STATUS) == GL_FALSE) {
        throw new RuntimeException("Error creating vertex shader\n"
                + glGetShaderInfoLog(vertexShaderId, glGetShaderi(vertexShaderId, GL_INFO_LOG_LENGTH)));
    }
    glAttachShader(programId, vertexShaderId);
    int fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShaderId, FileUtils.readFile("shaders/fragment.glsl"));
    glCompileShader(fragmentShaderId);
    if (glGetShaderi(fragmentShaderId, GL_COMPILE_STATUS) == GL_FALSE) {
        throw new RuntimeException("Error creating vertex shader\n"
                + glGetShaderInfoLog(fragmentShaderId, glGetShaderi(fragmentShaderId, GL_INFO_LOG_LENGTH)));
    }
    glAttachShader(programId, fragmentShaderId);
    glLinkProgram(programId);
    if (glGetProgrami(programId, GL_LINK_STATUS) == GL_FALSE) {
        throw new RuntimeException("Unable to link shader program:");
    }

    /*
        Hold the location of the matrix in the shader
    */
    int uniformMatrixLocation = glGetUniformLocation(programId, "MVP");


    float[] vertices = {
        +0.0f, +0.8f, 0,
        -0.8f, -0.8f, 0,
        +0.8f, -0.8f, 0
    };

    int vaoId = glGenVertexArrays();
    glBindVertexArray(vaoId);

    FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
    verticesBuffer.put(vertices).flip();

    int vboId = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboId);
    glBufferData(GL_ARRAY_BUFFER, verticesBuffer ,GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
    glBindVertexArray(0);

    glClearColor(0,0,0,1);
    while (glfwWindowShouldClose(window) == GL_FALSE) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
        glUseProgram(programId);

        Mat4 mvp = new Mat4(1.0f);//diagonal matrix , should just show a triangle on the screen

        /*
            Crashes here
        */
        //glUniformMatrix4(uniformMatrixLocation, false, mvp.getBuffer());

        glBindVertexArray(vaoId);
        glEnableVertexAttribArray(0);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        glDisableVertexAttribArray(0);
        glBindVertexArray(0);

        glUseProgram(0);

        glfwPollEvents();
        glfwSwapBuffers(window); // swap the color buffers
    }

    //dispose stuff no point showing them here


顶点着色器

    #version 330 core


    layout(location = 0) in vec3 position;

    uniform mat4 MVP;

    void main(){

         gl_Position =  MVP*vec4(position,1);

    }


片段着色器

    #version 330 core

    out vec4 color;

    void main()
    {

         color = vec4(1,1,1,1);

    }


打扰一下,如果以前有人问过这个问题,我在网上搜索,没有发现任何有用的信息。先感谢您。

最佳答案

由于您正在传递LWJGL从Mat4.getBuffer()返回的堆上浮动缓冲区,因此很可能发生崩溃。 JWJGL requires that you pass it direct buffers


LWJGL要求传递给它的所有NIO缓冲区都是直接缓冲区。直接缓冲区实际上包装了一个指向堆外内存的地址,即本机指针。这是LWJGL可以安全地将数据从Java代码传递到本机代码,反之亦然的唯一方法,而不会影响性能。它不支持堆上Java数组(或包装它们的普通NIO缓冲区),因为当本机代码访问它们时,JVM的垃圾收集器可能会在内存中四处移动数组。另外,Java数组具有未指定的布局,即它们不一定在内存中是连续的。


您可以像使用顶点一样使用BufferUtils类:

FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16).put(mvp.getBuffer()).flip();

...

glUniformMatrix4(uniformMatrixLocation, false, matrixBuffer);


如果那不起作用,请尝试以下方法:

FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16).put(new float[] {
    1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f}).flip();

关于java - lwjgl 3,glUniformMatrix4导致jre崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61727093/

10-11 02:40