【问题标题】:lwjgl 3 , glUniformMatrix4 causes jre to crashlwjgl 3 , glUniformMatrix4 导致 jre 崩溃
【发布时间】:2015-03-21 20:36:49
【问题描述】:

我正在使用 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);

    }

对不起,如果以前有人问过这个问题,我在网上搜索并没有找到任何有用的东西。提前谢谢你。

【问题讨论】:

    标签: java opengl lwjgl vertex-shader


    【解决方案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();
    

    【讨论】:

    • 您的解决方案解决了问题。非常感谢!
    • 嗨,我正在做这件事,但我仍然遇到崩溃。你知道为什么吗?这是我的代码:pastebin.com/CWxrHymy
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 2011-10-19
    • 2014-10-23
    • 1970-01-01
    相关资源
    最近更新 更多